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 - -[![Build examples](https://github.com/espressif/esp32-camera/actions/workflows/build.yml/badge.svg)](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 = "
 " D_UPGRADE_BY_FILE_UPLOAD " "; const char HTTP_FORM_RST_UPG[] PROGMEM = "
" - "

" + "

" "
" @@ -365,7 +365,7 @@ const char HTTP_FORM_RST_UPG[] PROGMEM = // upload via factory partition const char HTTP_FORM_RST_UPG_FCT[] PROGMEM = "
" - "

" + "

" "
" @@ -2296,7 +2296,7 @@ void HandleRestoreConfiguration(void) WSContentStart_P(PSTR(D_RESTORE_CONFIGURATION)); WSContentSendStyle(); WSContentSend_P(HTTP_FORM_RST); - WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_RESTORE)); + WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(".dmp"), PSTR(D_RESTORE)); if (WifiIsInManagerMode()) { WSContentSpaceButton(BUTTON_MAIN); } else { @@ -2566,12 +2566,12 @@ void HandleUpgradeFirmware(void) { WSContentSend_P(HTTP_FORM_UPG, SettingsText(SET_OTAURL)); #ifdef ESP32 if (EspSingleOtaPartition() && !EspRunningFactoryPartition()) { - WSContentSend_P(HTTP_FORM_RST_UPG_FCT, PSTR(D_UPGRADE)); + WSContentSend_P(HTTP_FORM_RST_UPG_FCT, PSTR(".bin,.ota,.hex"), PSTR(D_UPGRADE)); } else { - WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_UPGRADE)); + WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(".bin"), PSTR(D_UPGRADE)); } #else - WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_UPGRADE)); + WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(".bin,.bin.gz,.ota,.hex"), PSTR(D_UPGRADE)); #endif WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); diff --git a/tools/fw_TubeZigbee_efr32/MGM210PA32JIA_ncp-uart-sw_6.7.9.gbl b/tools/fw_TubeZigbee_efr32/MGM210PA32JIA_ncp-uart-sw_6.7.9.ota similarity index 100% rename from tools/fw_TubeZigbee_efr32/MGM210PA32JIA_ncp-uart-sw_6.7.9.gbl rename to tools/fw_TubeZigbee_efr32/MGM210PA32JIA_ncp-uart-sw_6.7.9.ota diff --git a/tools/fw_TubeZigbee_efr32/readme.md b/tools/fw_TubeZigbee_efr32/readme.md index 20e2929c5..677690b99 100644 --- a/tools/fw_TubeZigbee_efr32/readme.md +++ b/tools/fw_TubeZigbee_efr32/readme.md @@ -6,7 +6,7 @@ This firmware is to be used with Tube'z Zigbee EFR32 based gateway: ### Currently recommended versions -- `MGM210PA32JIA_ncp-uart-sw_6.7.9.gbl` - EZSP version 6.7.9 +- `MGM210PA32JIA_ncp-uart-sw_6.7.9.ota` - EZSP version 6.7.9 The device comes pre-flashed with EZSP 6.9.1_2 but there are unresolved issues with Tasmota and we currently only support 6.7.x. You need to downgrade the flash firmware to 6.7.9. Simply use the **Firmware Upggrade** feature of Tasmota, it will automatically detect that the firmware is for the EFR32 and not for Tasmota. From 6e9394984d7541259210fa4fddf685d7d108ec85 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 20 Nov 2022 15:52:40 +0100 Subject: [PATCH 244/319] Update changelogs --- CHANGELOG.md | 2 +- RELEASENOTES.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85b3cc383..f55e008b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,12 @@ 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 ### Changed - Serial Bridge default internal serial rx buffer size from 64 to 256 (#17120) +- Accept filename extensions to GUI file upload input fields (#16875) ### Fixed - ModbusBridge baudrates over 76500 baud (#17106) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7873568d3..38989f621 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -126,7 +126,6 @@ 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) @@ -141,6 +140,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) +- Accept filename extensions to GUI file upload input fields [#16875](https://github.com/arendst/Tasmota/issues/16875) - 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) From 4b52be6a5e9ee37395ca6bfbd45295ff4ad7247f Mon Sep 17 00:00:00 2001 From: joba-1 Date: Sun, 20 Nov 2022 16:28:59 +0100 Subject: [PATCH 245/319] don't touch AP_STA mode only if Rgx is up --- tasmota/tasmota_support/support_wifi.ino | 2 +- tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index 692822384..c294c4c48 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -218,7 +218,7 @@ void WifiBegin(uint8_t flag, uint8_t channel) WifiSetMode(WIFI_STA); // Disable AP mode */ #ifdef USE_WIFI_RANGE_EXTENDER - if (WiFi.getMode() != WIFI_AP_STA) { // Preserve range extender connections (#17103) + if (WiFi.getMode() != WIFI_AP_STA || !RgxApUp()) { // Preserve range extender connections (#17103) WiFi.disconnect(true); // Delete SDK wifi config delay(200); WifiSetMode(WIFI_STA); // Disable AP mode diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino index 88631bb27..3868dde46 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino @@ -149,6 +149,12 @@ typedef struct TRgxSettings RgxSettings; +// externalize to be able to protect Rgx AP from teardown +bool RgxApUp() +{ + return RgxSettings.status == RGX_CONFIGURED || RgxSettings.status == RGX_SETUP_NAPT; +} + // Check the current configuration is complete, updating RgxSettings.status void RgxCheckConfig(void) { From 923ef8202e8868e12b1fa7769315be8489eb8158 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 20 Nov 2022 18:21:46 +0100 Subject: [PATCH 246/319] Zigbee plugin mul/div extended to 16 bits --- .../tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino | 8 ++++---- .../tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino | 4 ++-- tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_7_plugin.ino | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) 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 5298fa5fb..1f921dba7 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 @@ -318,8 +318,8 @@ public: } uint8_t type; // zigbee type, Zunk by default - int8_t multiplier; // multiply by x (ignore if 0 or 1) - int8_t divider; // divide by x (ignore if 0 or 1) + int16_t multiplier; // multiply by x (ignore if 0 or 1) + int16_t divider; // divide by x (ignore if 0 or 1) int16_t base; // add x (ignore if 0) uint16_t cluster; // cluster number uint16_t attribute; // attribute number @@ -354,8 +354,8 @@ public: uint16_t attribute; // attribute to match uint16_t new_cluster; // replace with this cluster uint16_t new_attribute; // replace with this attribute - int8_t multiplier; // multiply by x (ignore if 0 or 1) - int8_t divider; // divide by x (ignore if 0 or 1) + int16_t multiplier; // multiply by x (ignore if 0 or 1) + int16_t divider; // divide by x (ignore if 0 or 1) int16_t base; // add x (ignore if 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 5d34f5fc0..ead5b9ce9 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 @@ -1000,8 +1000,8 @@ void ZCLFrame::parseReadConfigAttributes(uint16_t shortaddr, Z_attribute_list& a } // find the multiplier - int8_t multiplier = 1; - int8_t divider = 1; + int16_t multiplier = 1; + int16_t divider = 1; int16_t base = 0; Z_attribute_match matched_attr = Z_findAttributeMatcherById(shortaddr, cluster, attrid, false); if (matched_attr.found()) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_7_plugin.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_7_plugin.ino index 0e8fa2ce5..75adbc203 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_7_plugin.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_7_plugin.ino @@ -386,7 +386,7 @@ bool ZbUnload(const char *filename_raw) { } // append modifiers like mul/div/manuf -void Z_AppendModifiers(char * buf, size_t buf_len, int8_t multiplier, int8_t divider, int16_t base, uint16_t manuf) { +void Z_AppendModifiers(char * buf, size_t buf_len, uint16_t multiplier, uint16_t divider, int16_t base, uint16_t manuf) { if (multiplier != 0 && multiplier != 1) { ext_snprintf_P(buf, buf_len, "%s,%s%i", buf, Z_MUL, multiplier); } From e4bae0cca6608f8830474380f785b4b8c95bcfce Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 20 Nov 2022 18:32:37 +0100 Subject: [PATCH 247/319] Moved to uint16_t --- .../tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino | 8 ++++---- .../tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) 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 1f921dba7..1b775935c 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 @@ -318,8 +318,8 @@ public: } uint8_t type; // zigbee type, Zunk by default - int16_t multiplier; // multiply by x (ignore if 0 or 1) - int16_t divider; // divide by x (ignore if 0 or 1) + uint16_t multiplier; // multiply by x (ignore if 0 or 1) + uint16_t divider; // divide by x (ignore if 0 or 1) int16_t base; // add x (ignore if 0) uint16_t cluster; // cluster number uint16_t attribute; // attribute number @@ -354,8 +354,8 @@ public: uint16_t attribute; // attribute to match uint16_t new_cluster; // replace with this cluster uint16_t new_attribute; // replace with this attribute - int16_t multiplier; // multiply by x (ignore if 0 or 1) - int16_t divider; // divide by x (ignore if 0 or 1) + uint16_t multiplier; // multiply by x (ignore if 0 or 1) + uint16_t divider; // divide by x (ignore if 0 or 1) int16_t base; // add x (ignore if 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 ead5b9ce9..4faa86a39 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 @@ -1000,8 +1000,8 @@ void ZCLFrame::parseReadConfigAttributes(uint16_t shortaddr, Z_attribute_list& a } // find the multiplier - int16_t multiplier = 1; - int16_t divider = 1; + uint16_t multiplier = 1; + uint16_t divider = 1; int16_t base = 0; Z_attribute_match matched_attr = Z_findAttributeMatcherById(shortaddr, cluster, attrid, false); if (matched_attr.found()) { From d40c24d6d3efadefae6baa3419a38e54845e02ec Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 20 Nov 2022 22:04:30 +0100 Subject: [PATCH 248/319] Berry ArtNet implementation --- .../berry_tasmota/src/embedded/leds.be | 2 +- .../src/solidify/solidified_leds.h | 4 +- tasmota/berry/ArtNet.tapp | Bin 0 -> 17968 bytes tasmota/berry/artnet/artnet_dyn.be | 28 ++ tasmota/berry/artnet/artnet_ui.be | 288 ++++++++++++++++++ tasmota/berry/artnet/autoexec.be | 15 + 6 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 tasmota/berry/ArtNet.tapp create mode 100644 tasmota/berry/artnet/artnet_dyn.be create mode 100644 tasmota/berry/artnet/artnet_ui.be create mode 100644 tasmota/berry/artnet/autoexec.be diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds.be b/lib/libesp32/berry_tasmota/src/embedded/leds.be index 7a1461d90..ecde9b706 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/leds.be +++ b/lib/libesp32/berry_tasmota/src/embedded/leds.be @@ -321,7 +321,7 @@ class Leds : Leds_ntv 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 + var offset_in_matrix = (self.offset + row) * h_bytes self.pix_buffer.setbytes(offset_in_matrix, buf, offset, len) end diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h index c6caa2eab..d7ca9b0bd 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h @@ -1333,8 +1333,8 @@ be_local_closure(Leds_matrix_set_bytes, /* name */ 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 + 0x00180C01, // 0007 ADD R6 R6 R1 + 0x08180C05, // 0008 MUL R6 R6 R5 0x881C0103, // 0009 GETMBR R7 R0 K3 0x8C1C0F04, // 000A GETMET R7 R7 K4 0x5C240C00, // 000B MOVE R9 R6 diff --git a/tasmota/berry/ArtNet.tapp b/tasmota/berry/ArtNet.tapp new file mode 100644 index 0000000000000000000000000000000000000000..d03a2bba3a5672df7e9074724ea642ac41f078e6 GIT binary patch literal 17968 zcmeHP-)|#Fa+c4&ASWje0Rr3w2!b|=HL0~Yq_omn)`~QA>y5Lx*eiIo@CA;+9g-t* zyyVPyX1J1kcLDMi1OWmZlD9l2zy--eo`byP54gu5$bS+bFZsUeAM-<`cK0m%$+EQ^ zc2`$dS65Y6RoCd`C$GP;xxt_R{N>`wAGCkv{q^r}Z1DF78-KXrr+F0Q-Y9r-`h$(v z|Go9)`2XHa$IFX1H(q<=e_z|!cmr@7O?8~+osWZDP15jrkZx{{=YE#46^)xpJ@-?! z@bfghP%D0#DxU>v9!w038IZ(jz5*IeO(lKNaxn^0brz>;9%gwEh0#>Lh0!=(@Jr&4 zp9Ohl5H2UlFbh%;SV!AbVU*>5G!9gJrk(=usgfnwkr9`b1w#N;iE65mp9N}Z0F!y!FwjWqcRp-3-P8Z0wzBn2e%7lGc<)UI5` zqc4JSE}NbNDI{URO(b@3I3D|RHI9=@ZfYT3%Fn^8(Gt9qfoIqWh=e~L2bmQWe~u<_ zC%8gdQ=Nsue4@y6Bd^=oHw!)wBcN@kfym2b%TxE`DEA>=s;9y;6~%c0y{#a+T$+(& zkSSZLuojhs7r~q>nFMDL&oFOm4cc~6qor|Mlwn(i$DLVu%eC63W5$C=K zxf;5jcDFOoSc;}CJvD_RSJ^xW5|zhlU#~&|Nu1A=ABB*}Fpes?r}KE^&pkb;ulCVN z!N3RQKFedfu5clHgdIxbEP>Vw8t@lFmrbl;pJ5T;vJ6v;AfLsPZ3R0pSD_xjJ#{F& zX^^)?jthous|JTR^pcFm6y08lq>2PO3Ns5N~q>}SQT)qPu13|z*_1x z$@WmPWDsj{K8Vd0z;c_zSZbuDt^@8lz)6_qmw-6)=UL!dov_!q=cR!^(Ja*S@Z5hG*Z)u69-4%FLk%Uq&FM)+m7dfTeAw?%y{t)K_+GSJ>CAiX3a zB%|VF98UtQOHV7f54P1V&rJS6mS^!2h8`N(yV&pbwEbfjhbL*A$K!ZjMX*Ea1O@y8 z9MRaB(2t;W4%JST3cKAkG@yTXOIt8b2o70tc?^>nS+Ju49NS}yLkAw(XJd)Wy+=i- zl^ssQMO&4h$M7XS_~@sHg#|h`KAzdc!-jgtGB1y3!A09x0gH-k%7QOzOWWO6J9g*w zl)}y#MXaxD4$bNMRK>mRDh! zwvd|5`d@)J1_%osYRAw{4G%&5U~m+;EfdR|0Ap*kJWrQe$u;7-co-wBoz2oZs)D1t zJ#oi!BSu<)`@M@>y}h40_37UVDI@$yW|#c1MDy8_YM=YJvc`60)-n_H3|OpD3$pP` ze4SkuE>p35%aqS{4m_{3^SNhbxZq2%_~OY3zcHAlV_~)3(;kR$-?$Kte5+}bVD4WI z7vUJkS}=~IN!H%&Y0v%K4|BEK!}+GZSRz~qBOGPM2y^AHOpILzKZOt|f$Y4Ysw_v+ zZhVT0L+QbqotqAg(4aG+1J7-8V+b!cgJ)qtjp&$0nUFe-6`w($Czlc6q?Ik+Gznv> zxkllgh0&zlFczPEjcp}N0vDP}fNeBLzdR2X$s7(>fiI2Evvv5`2Yma+^fycHxD0C} zmOQjpOQ?h4UyF@>Yp|hfxj-av6(J4OI`Y_8S+22WkOmt!Q{fVIJ_``cvCVk?#sKQ+ zdRnlBet7$8-E`=~Y;xLbDfA6e;RPlwLIsEj{4jWQS!w5}!0T|cud)=O(CNI!(iEAX z)0wWr!#?0?03U-~#Ck6NU*J^VRzV0hq^bpg7K5zTVmZ(8NVi%Zp-0*u6n+@*f2Fjs z4|6eO(ENDv!AUv)P+Gdbgx9-9XxRrew68)jzo$!Z6Am-asik(g(*O}U)Eqhh;a#Cv z%V@~Zb4ZBQnpIaVoZASy#WAa?B=wIx79MbWi=noa(yUiVU@d2T^``->RH|;P@wO-* zV#TOUE%ZKpynC>NGhR@##W)2VZKM*mlj7=)VI=Zks9W19#+YH0Z!N4aPl8C~wRFBY z5o`-Tg=}q#w0AaHTwnou;Vx_zOq4(~O(_U6LC8=W7z_o1mF%bUKh)5M`COQuu8Krx z0{!`A60`vzE^EuCnOf3~V|Q^;4k(nWA^{~5KEt7bY9mq%nBCBao;^RNV}$4K2kD78 zMH*{57O=uTizpfC(u~>MY<4!A>cNE%V;P8Qe6;^K$6=+8Pal1xKGF%h_Ws4b-MVwA zRlF=^Ft#?0S=XEcI`YG@(M)tjbawaG$xRRPBC>*|uM!gs#Q(5m1>f~-?Zwt+r+MO% znP2^D{^Ym+;eWo&zqhf$-`{n~%puMio6!8#-+ndz7yQ-}n#~*j0b?+$$tgDR?U8JpAG_z_v#@)A z<|l~ZI|rLLOnI|ulDVKCB1N_jnLxv{OH5gpN!$nN#qRy=7XZ=nCy{)R>!r0LO zS|sswZi*cSL$#w&EX{{JrnDjft7pD4E8NQx07sVtxd@B&HQYN zHfuc|E<@}-PVwbDXt!Kj3(n!qOjg1|J(R<7_~ap1qdpBre7fnM%5@0mg7nptr{*1t zc;fU}>5&-M0iF-CAfoW#8)b zAA}iP|4U{8nZGa_+)&8(=W(R)KOJQH0^xL-NC)Rd4|qunH%AC&jpApu5~J$u&;7%X!dmO*GwyYJ_`>XZKnr zdD(9vMcEo0X+j3~4c&oNO_x;7j=BcssLOc=N8Mx~Nz89w1U^KrMLUAx9f|~q6nrAa z7<&W1H%)!Hn1P`WClzoeqKy$|$jkk*0iE2KAh<(DQV@KbvPJR0W(?0Wy0}9+x43*0 zAu!s@Ci%`&5=Q_G*=L_i1LKb5u;+PqcI3O{1;k;7=R9P_zv@0Gl>^L6mf5WB+PI-S znCz!HZ190*v)hO%cx6bMzl+6JMfTst;@`#Mzey}kjmrGzfeWR1lvJ!hIm2boZ*u}r z<6#syL^52W#x)p8v(#hq8VsXyi$@}Knu8jQNh!%(d|ovd<7zV%9(9~wL&JdC!thxG zp#sBX=FG}Wwnk>-^QzfQmPKIrEHJA8>BiVO`CKK8+!woR54KgV$g8)35IDX16gEBr z<6_*}(mkN#@U-g=@~4EpnIB-HOmPyEe}D^IJy)EMAu_wcAD#Ofk<4Nz&$EwI5alFM^6j>6Z}j+ov2fNTdf_c zOaZOnZE_~0$G1|88sWsh_gI=n#I^!1!?) zE(a0DBPk!LQ5qs~av3j?4ho)!OtSXPU-{ za1WaY2M70lAz?lP?4VA8=+P8E?5!vO6=$|>Z74^JLG(mc+w zF>Bx)-)Rqw>&tArH4AGz;u5s;iV@GsMSls4gs}Ezea-qCAocd`k5M>fc^6D>-zMQk z0!wL}wJ2c1SSW^Itfi-y4c4}V&iOPsERkgxsMe`%eRt!8VV%xd^;@^X*5DT6G2J>q z)_JNAcnu7~t{0v$N$c&1sP}J!==y)vIvpHY3)<>wSe1@u8ciPN>%msjmwo zAQzOCPmrxF%L*{Pg3vaO!YD!Bn91;dOW)K%-$F#fJ1xbOU%y4ar&VSl_{I(Q*m3=2 zjmiSa#8+P5eSJ0e%`TCy+R7!e;~QV%BRGLU{*A1#XE%|K=E@ba<5gBDs_@FYc!EfLzP_+C zFGgP;E_`rPOsXiglLyYSQXbgxD)K<3<}Fw@#?_%KB3vUNmSM0T^DOaUW$v`xAsDBV z&Uxx5$h5(webzZg1Dw9=y_tr%WjTE_`mUCFwo(8m$k8YruY1patNDDMUHRyO;3A?b=oFgThOW**tt6L)GBwU=wyR=57i0HgKI zdXT=9t8%SZVpCeE95({(_C(z89lGD*m|$97Q7wuS@5Cn7CbDJD|>j z>cNg}r{d#-0O zF<;uTcscLlMcaOYoWM)$xoE*!y6QVvxG;6}H}AqQsj<@9vEx;(-5Mn&-|6|+^qgsu z4(ds+GZA&xAYd8|j?F+8qKr_dt>fE@zjo#P!;mWnAlg=*fM&P!-Nbd&!OhoKG};~1 zsTMy;=9evfZ{BYifYCIKT7zSDiH-ea89{7h@QciN^={;Pa=;#3pCQL+gxySXiK!L2)|A&!(s+&w zIk+syH{g|m(WN?h^!SuT2;W+2Yn;!o&24>+OxB9Ln0{rzq$*{%4N&n4fV9d#c;84q z>5!1w6S|Mo1%1aU|3)6wGJxn-+-`Ko(fj6Lg()c4 zWu<l%$V#+W=GVU%S%3$B zl*LGOwY(DJtFvV!MOCP+=UcR6)WHHo=V`{v6eZL2y?9HAvgj*!jd29q zqm3M{T_LYsWnXWt-^gxr3Fad4Pfkxyh95pSt$Xt?iB7!WEBNS)6CnkTzm6>LIAsYx zDhFZq-SZ|3xRtJ=7w$Vz(SL=39;e+vtedsy`i2x!@RW7vhmJk&rApM9x_QK3H$&xB zV2!?gbv%i0;`I$)hw}1rfeXZmyo0U%-xg1<;361%BR^*e{8bd*RWT9$GgsGcfUMn= zu5a2R^aS0ZBnMH;Nw0h}0mEFY2Rp3$u_S#Gpr#5{<5wJH;;r&0=fi4w_ zRp1l+0SGC0o5#4J$NS3wd&|5aK=aAJD$s6VoE)4+ldwcw60^n~{58P%0zQ;_gr$`M zmW2jr85T^{g&v&T)_hdn#v*rwfU=0Btln+VLNxE|>uMyy@bVq(0F0Z3)DkjW18iUS zf+c}pqY3lyrR<1MS8%mvs1`_3os*xu_PsxPechim`H}p&6aMp$f60FhZvK&z@9RHu zQmd*iqr3WIK^fhz@%K;+HQ>4wYXc=E<{Fe&3%<)J|LTVhr78agMwWkHgYl{umodI^ b9~jF*y^h51{}$Qv2L5{hUHGpL`0f7zz1HT{ literal 0 HcmV?d00001 diff --git a/tasmota/berry/artnet/artnet_dyn.be b/tasmota/berry/artnet/artnet_dyn.be new file mode 100644 index 000000000..bfac24463 --- /dev/null +++ b/tasmota/berry/artnet/artnet_dyn.be @@ -0,0 +1,28 @@ +################################################################################# +# dyn class +# +# Allows to use a map with members +# see https://github.com/berry-lang/berry/wiki/Chapter-8 +################################################################################# +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 + +return dyn diff --git a/tasmota/berry/artnet/artnet_ui.be b/tasmota/berry/artnet/artnet_ui.be new file mode 100644 index 000000000..05869a6c4 --- /dev/null +++ b/tasmota/berry/artnet/artnet_ui.be @@ -0,0 +1,288 @@ +####################################################################### +# DMX ArtNet UI for ESP32(C3/S2/S3) +# +####################################################################### + +var artnet_ui = module('artnet_ui') + +################################################################################# +# ArtNet_UI +# +# WebUI +################################################################################# +class ArtNet_UI + + def init() + import persist + + if persist.find("artnet_autorun") == true + # autorun + end + end + + # #################################################################################################### + # Init web handlers + # #################################################################################################### + # Displays a "DMX ArtNet" button on the configuration page + def web_add_config_button() + import webserver + webserver.content_send("

") + end + + # #################################################################################################### + # Get WS2812 gpios + # + # Returns an array of valid WS2812 gpios as defined in the template, or empty array + # #################################################################################################### + def get_ws2812_gpios() + import gpio + var ret = [] + for p:0..31 + if gpio.pin_used(gpio.WS2812, p) + ret.push(p) + end + end + return ret + 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 + + def save_persist(conf) + import persist + persist.artnet_gpio = conf.gpio + persist.artnet_rows = conf.rows + persist.artnet_cols = conf.cols + persist.artnet_offs = conf.offs + persist.artnet_alt = conf.alt + + persist.artnet_univ = conf.univ + + # persist.artnet_addr = conf.addr + persist.artnet_port = conf.port + + persist.artnet_auto = conf.auto + + persist.save() + end + + ####################################################################### + # Display the complete page on `/artnet_ui` + ####################################################################### + def page_artnet_ui() + import webserver + import string + if !webserver.check_privileged_access() return nil end + + # read configuration + var conf = self.read_persist() + + webserver.content_start("ArtNet") #- title of the web page -# + webserver.content_send_style() #- send standard Tasmota styles -# + + # webserver.content_send("

Warning: actions below can brick your device.

") + # webserver.content_send("

 (This feature requires an internet connection)

") + + webserver.content_send("
") + webserver.content_send(string.format(" ArtNet configuration")) + + webserver.content_send("

") + + # WS2812 bus configuration + webserver.content_send(string.format("

WS2812 configuration:

")) + webserver.content_send(string.format( + "" + "") + + webserver.content_send(string.format("") + webserver.content_send(string.format("") + webserver.content_send(string.format("") + + webserver.content_send(string.format("") + + webserver.content_send("") + webserver.content_send(string.format("") + # description + webserver.content_send("") + + webserver.content_send("
GPIO")) + + var ws2812_list = self.get_ws2812_gpios() + var ws2812_gpio + if size(ws2812_list) == 0 + webserver.content_send("**Not configured**") + else + webserver.content_send("") + end + webserver.content_send("
Rows")) + webserver.content_send(string.format("", conf.rows)) + webserver.content_send("
Columns")) + webserver.content_send(string.format("", conf.cols)) + webserver.content_send("
Offset")) + webserver.content_send(string.format("", conf.offs)) + webserver.content_send("
Alternate rows")) + webserver.content_send(string.format("

", conf.alt ? " checked" : "")) + webserver.content_send("
 
DMX universe")) + webserver.content_send(string.format("", conf.univ)) + webserver.content_send("
") + webserver.content_send("This this the universe number for
the first row, and gets incremented
for each row.") + webserver.content_send("

") + + # IP configuration + webserver.content_send(string.format("

IP listener:

")) + webserver.content_send("") + # "") + + webserver.content_send("") + webserver.content_send("
IP mode")) + # webserver.content_send("") + # webserver.content_send("
Port") + # webserver.content_send(string.format("
Port")) + webserver.content_send(string.format("", conf.port)) + webserver.content_send("

") + + # auto-run + webserver.content_send(string.format("

Auto-run at boot:

", conf.auto ? " checked" : "")) + + # button + webserver.content_send("") + webserver.content_send("

") + + webserver.content_send("

") + webserver.content_button(webserver.BUTTON_CONFIGURATION) + webserver.content_stop() + end + + ####################################################################### + # Web Controller, called by POST to `/artnet_ui` + ####################################################################### + def page_artnet_ctl() + import webserver + if !webserver.check_privileged_access() return nil end + + import string + import persist + import introspect + + try + if webserver.has_arg("artnetapply") + + # read argumments, sanity check and put in conf object + var conf = dyn() + + # read gpio + var ws2812_list = self.get_ws2812_gpios() + var gp_ws2812 = int(webserver.arg("ws2812")) + if ws2812_list.find(gp_ws2812) != nil + conf.gpio = gp_ws2812 + else + conf.gpio = -1 + end + + # read rows and cols + var rows = int(webserver.arg("rows")) + if rows < 1 || rows > 999 rows = 1 end + conf.rows = rows + var cols = int(webserver.arg("cols")) + if cols < 1 || cols > 999 cols = 1 end + conf.cols = cols + # alternate + conf.alt = webserver.arg("alt") == 'on' + + # offset + var offs = int(webserver.arg("offs")) + if offs < 0 || offs > 999 offs = 0 end + conf.offs = offs + + # universe + var univ = int(webserver.arg("univ")) + if univ < 0 || univ > 999 univ = 0 end + conf.univ = univ + + # universe + var port = int(webserver.arg("port")) + if port < 1 || port > 65535 port = 6454 end + conf.port = port + + # autorun + conf.auto = webserver.arg("auto") == 'on' + + self.save_persist(conf) + + artnet.stop_global() + artnet.run_from_conf() + + # tasmota.log("BRY: conf=" + str(conf), 2); + webserver.redirect("/cn?") + else + raise "value_error", "Unknown command" + end + except .. as e, m + print(string.format("BRY: Exception> '%s' - %s", e, m)) + #- display error page -# + webserver.content_start("Parameter error") #- title of the web page -# + webserver.content_send_style() #- send standard Tasmota styles -# + + webserver.content_send(string.format("

Exception:
'%s'
%s

", e, m)) + + webserver.content_button(webserver.BUTTON_CONFIGURATION) #- button back to management page -# + webserver.content_stop() #- end of web page -# + end + end + + #- ---------------------------------------------------------------------- -# + # respond to web_add_handler() event to register web listeners + #- ---------------------------------------------------------------------- -# + #- this is called at Tasmota start-up, as soon as Wifi/Eth is up and web server running -# + def web_add_handler() + import webserver + #- we need to register a closure, not just a function, that captures the current instance -# + webserver.on("/artnet_ui", / -> self.page_artnet_ui(), webserver.HTTP_GET) + webserver.on("/artnet_ui", / -> self.page_artnet_ctl(), webserver.HTTP_POST) + end +end +artnet_ui.ArtNet_UI = ArtNet_UI + + +#- create and register driver in Tasmota -# +if tasmota + var artnet_ui_instance = artnet_ui.ArtNet_UI() + tasmota.add_driver(artnet_ui_instance) + ## can be removed if put in 'autoexec.bat' + artnet_ui_instance.web_add_handler() +end + +return artnet_ui + +#- Example + +import partition + +# read +p = partition.Partition() +print(p) + +-# diff --git a/tasmota/berry/artnet/autoexec.be b/tasmota/berry/artnet/autoexec.be new file mode 100644 index 000000000..7f5e9d45c --- /dev/null +++ b/tasmota/berry/artnet/autoexec.be @@ -0,0 +1,15 @@ +# rm ArtNet.tapp; zip ArtNet.tapp -j -0 artnet/* +# +# check if `dyn` class is embedded, or load it +if !global.contains("dyn") + import artnet_dyn + global.dyn = artnet_dyn +end + +import artnet +import artnet_ui + +import persist +if persist.find("artnet_auto") + tasmota.add_rule("Wifi#Connected", def () tasmota.remove_rule("Wifi#Connected", "artnet_run") artnet.run_from_conf() end, "artnet_run") +end From 40294e13fcbca95077908543180c677aeab38f98 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 21 Nov 2022 10:32:13 +0100 Subject: [PATCH 249/319] Fix Serial Bridge Skip count --- tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino index fda65d687..b5b626ad8 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino @@ -156,8 +156,8 @@ 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] == '{')); - 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++; // 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; Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":")); From 21290de9c40ccaff99d8a00381ec6689a65a5541 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 21 Nov 2022 14:07:25 +0100 Subject: [PATCH 250/319] Prep HLK-LD2410 --- tasmota/include/tasmota_template.h | 413 +++++++++++++++-------------- 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 + tasmota/my_user_config.h | 10 +- 29 files changed, 266 insertions(+), 211 deletions(-) diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 288670cca..d1ea6161d 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -201,6 +201,7 @@ enum UserSelectablePins { GPIO_DALI_RX, GPIO_DALI_TX, // Dali GPIO_BP1658CJ_CLK, GPIO_BP1658CJ_DAT,// BP1658CJ GPIO_DINGTIAN_CLK, GPIO_DINGTIAN_SDI, GPIO_DINGTIAN_Q7, GPIO_DINGTIAN_PL, GPIO_DINGTIAN_RCK, // Dingtian relay board - 595's & 165's pins + GPIO_LD2410_TX, GPIO_LD2410_RX, // HLK-LD2410 GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage with max 2045 @@ -449,6 +450,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|" D_SENSOR_BP1658CJ_CLK "|" D_SENSOR_BP1658CJ_DAT "|" D_GPIO_DINGTIAN_CLK "|" D_GPIO_DINGTIAN_SDI "|" D_GPIO_DINGTIAN_Q7 "|" D_GPIO_DINGTIAN_PL "|" D_GPIO_DINGTIAN_RCK "|" + D_SENSOR_LD2410_TX "|" D_SENSOR_LD2410_RX "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -536,8 +538,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #if defined(USE_DALI) && defined(ESP32) - AGPIO(GPIO_DALI_RX), // DALI RX - AGPIO(GPIO_DALI_TX), // DALI TX + AGPIO(GPIO_DALI_RX), // DALI RX + AGPIO(GPIO_DALI_TX), // DALI TX #endif // USE_DALI #ifdef USE_I2C @@ -588,11 +590,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SDIO_D3), #endif // USE_SDCARD - AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output - AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input - AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock - AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select - AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command + AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output + AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input + AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock + AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select + AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command #if defined(USE_DISPLAY) || defined(USE_LVGL) #ifdef USE_DISPLAY_ILI9341 @@ -601,7 +603,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // USE_DISPLAY_ILI9341 #ifdef USE_XPT2046 - AGPIO(GPIO_XPT2046_CS), // XPT2046 SPI Chip Select + AGPIO(GPIO_XPT2046_CS), // XPT2046 SPI Chip Select #endif #ifdef USE_DISPLAY_ILI9488 @@ -628,7 +630,6 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SSD1331_CS), AGPIO(GPIO_SSD1331_DC), #endif // USE_DISPLAY_SSD1331 - #ifdef USE_DISPLAY_MAX7219_MATRIX #undef USE_DISPLAY_MAX7219 #undef USE_DISPLAY_TM1637 @@ -636,7 +637,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MAX7219DIN), AGPIO(GPIO_MAX7219CS), #endif // USE_DISPLAY_MAX7219_MATRIX - +#ifdef USE_DISPLAY_MAX7219 + AGPIO(GPIO_MAX7219CLK), + AGPIO(GPIO_MAX7219DIN), + AGPIO(GPIO_MAX7219CS), +#endif // USE_DISPLAY_MAX7219 #ifdef USE_DISPLAY_TM1637 AGPIO(GPIO_TM1637CLK), AGPIO(GPIO_TM1637DIO), @@ -644,10 +649,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_TM1638DIO), AGPIO(GPIO_TM1638STB), #endif // USE_DISPLAY_TM1637 - AGPIO(GPIO_BACKLIGHT), // Display backlight control - AGPIO(GPIO_OLED_RESET), // OLED Display Reset + AGPIO(GPIO_BACKLIGHT), // Display backlight control + AGPIO(GPIO_OLED_RESET), // OLED Display Reset #ifdef ESP32 - AGPIO(GPIO_EPD_DATA), // Base connection EPD driver + AGPIO(GPIO_EPD_DATA), // Base connection EPD driver #endif #endif // USE_DISPLAY @@ -663,28 +668,28 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SSPI_MAX31865_CS1) + MAX_MAX31865S, #endif - AGPIO(GPIO_TXD), // Serial interface - AGPIO(GPIO_RXD), // Serial interface + AGPIO(GPIO_TXD), // Serial interface + AGPIO(GPIO_RXD), // Serial interface /*-------------------------------------------------------------------------------------------*\ * Single wire sensors \*-------------------------------------------------------------------------------------------*/ #ifdef USE_DHT - AGPIO(GPIO_DHT11), // DHT11 - AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 - AGPIO(GPIO_SI7021), // iTead SI7021 - AGPIO(GPIO_MS01), // Sonoff MS01 - AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 + AGPIO(GPIO_DHT11), // DHT11 + AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 + AGPIO(GPIO_SI7021), // iTead SI7021 + AGPIO(GPIO_MS01), // Sonoff MS01 + AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 #endif #ifdef USE_DS18x20 - AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20 #ifdef ESP8266 - AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20 + 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 + AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO #endif /*-------------------------------------------------------------------------------------------*\ @@ -694,47 +699,47 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_LIGHT #ifdef USE_WS2812 #if (USE_WS2812_HARDWARE == NEO_HW_P9813) - AGPIO(GPIO_P9813_CLK), // P9813 CLOCK - AGPIO(GPIO_P9813_DAT), // P9813 DATA + AGPIO(GPIO_P9813_CLK), // P9813 CLOCK + AGPIO(GPIO_P9813_DAT), // P9813 DATA #else - AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 0),// WS2812 Led string, using RMT on ESP32 + AGPIO(GPIO_WS2812) + (MAX_RMT ? MAX_RMT + 1 : 0), // WS2812 Led string, using RMT on ESP32 #endif // NEO_HW_P9813 #endif #ifdef USE_ARILUX_RF - AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input - AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected + AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input + AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected #endif #ifdef USE_MY92X1 - AGPIO(GPIO_DI), // my92x1 PWM input - AGPIO(GPIO_DCKI), // my92x1 CLK input + AGPIO(GPIO_DI), // my92x1 PWM input + AGPIO(GPIO_DCKI), // my92x1 CLK input #endif // USE_MY92X1 #ifdef USE_SM16716 - AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK - AGPIO(GPIO_SM16716_DAT), // SM16716 DATA - AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT + AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK + AGPIO(GPIO_SM16716_DAT), // SM16716 DATA + AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT #endif // USE_SM16716 #ifdef USE_SM2135 - AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK - AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT, // SM2135 DATA + AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK + AGPIO(GPIO_SM2135_DAT) + MAX_SM2135_DAT, // SM2135 DATA #endif // USE_SM2135 #ifdef USE_SM2335 - AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK - AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT, // SM2335 DATA + 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 + AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK + AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA #endif // USE_BP5758D #ifdef USE_TUYA_MCU - AGPIO(GPIO_TUYA_TX), // Tuya Serial interface - AGPIO(GPIO_TUYA_RX), // Tuya Serial interface + AGPIO(GPIO_TUYA_TX), // Tuya Serial interface + AGPIO(GPIO_TUYA_RX), // Tuya Serial interface #endif #ifdef USE_EXS_DIMMER - AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable + AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable #endif #ifdef USE_ELECTRIQ_MOODL AGPIO(GPIO_ELECTRIQ_MOODL_TX), @@ -750,34 +755,34 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRSEND) + MAX_IRSEND, // IR remote + AGPIO(GPIO_IRSEND) + MAX_IRSEND, // IR remote #if defined(USE_IR_RECEIVE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRRECV), // IR receiver + AGPIO(GPIO_IRRECV), // IR receiver #endif #endif #ifdef USE_RC_SWITCH - AGPIO(GPIO_RFSEND), // RF transmitter - AGPIO(GPIO_RFRECV), // RF receiver + AGPIO(GPIO_RFSEND), // RF transmitter + AGPIO(GPIO_RFRECV), // RF receiver #endif #ifdef USE_RF_SENSOR - AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding + AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding #endif #ifdef USE_SR04 - AGPIO(GPIO_SR04_TRIG), // SR04 Tri/TXgger pin - AGPIO(GPIO_SR04_ECHO), // SR04 Ech/RXo pin + AGPIO(GPIO_SR04_TRIG), // SR04 Tri/TXgger pin + AGPIO(GPIO_SR04_ECHO), // SR04 Ech/RXo pin #endif #ifdef USE_TM1638 - AGPIO(GPIO_TM1638CLK), // TM1638 Clock - AGPIO(GPIO_TM1638DIO), // TM1638 Data I/O - AGPIO(GPIO_TM1638STB), // TM1638 Strobe + AGPIO(GPIO_TM1638CLK), // TM1638 Clock + AGPIO(GPIO_TM1638DIO), // TM1638 Data I/O + AGPIO(GPIO_TM1638STB), // TM1638 Strobe #endif #ifdef USE_HX711 - AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock - AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data + AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock + AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data #endif #ifdef USE_TFMINIPLUS - AGPIO(GPIO_TFMINIPLUS_TX), // TFmini Plus TX pin - AGPIO(GPIO_TFMINIPLUS_RX), // TFmini Plus RX pin + AGPIO(GPIO_TFMINIPLUS_TX), // TFmini Plus TX pin + AGPIO(GPIO_TFMINIPLUS_RX), // TFmini Plus RX pin #endif /*-------------------------------------------------------------------------------------------*\ @@ -786,103 +791,103 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_ENERGY_SENSOR #ifdef USE_HLW8012 - AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) - AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) - AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current - AGPIO(GPIO_HLW_CF), // HLW8012 CF power - AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power + AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) + AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) + AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current + AGPIO(GPIO_HLW_CF), // HLW8012 CF power + AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power #endif #if defined(USE_I2C) && defined(USE_ADE7880) - AGPIO(GPIO_ADE7880_IRQ) + 2, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) + AGPIO(GPIO_ADE7880_IRQ) + 2, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) #endif #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 + 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) + 2, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) + 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 #ifdef USE_CSE7761 - AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) - AGPIO(GPIO_CSE7761_RX), // CSE7761 Serial interface (Dual R3) + AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) + AGPIO(GPIO_CSE7761_RX), // CSE7761 Serial interface (Dual R3) #endif #ifdef USE_CSE7766 - AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) - AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) + AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) + AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) #endif #ifdef USE_MCP39F501 - AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) - AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) - AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) + AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) #endif #if defined(USE_PZEM004T) || defined(USE_PZEM_AC) || defined(USE_PZEM_DC) - AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface + AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface #endif #ifdef USE_PZEM004T - AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface + AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface #endif #ifdef USE_PZEM_AC - AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface + AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface #endif #ifdef USE_PZEM_DC - AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface + AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface #endif #ifdef USE_MODBUS_ENERGY - AGPIO(GPIO_NRG_MBS_TX), // Generic Energy Modbus device + AGPIO(GPIO_NRG_MBS_TX), // Generic Energy Modbus device AGPIO(GPIO_NRG_MBS_RX), #endif #ifdef USE_SDM120 - AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface - AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface + AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface + AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface #endif #ifdef USE_SDM630 - AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface - AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface + AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface + AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface #endif #ifdef USE_DDS2382 - AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface - AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface + AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface + AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface #endif #ifdef USE_DDSU666 - AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface - AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface + AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface + AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface #endif // USE_DDSU666 #ifdef USE_SOLAX_X1 - AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin - AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin - AGPIO(GPIO_SOLAXX1_RTS), // Solax Inverter RTS pin + AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin + AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin + AGPIO(GPIO_SOLAXX1_RTS), // Solax Inverter RTS pin #endif // USE_SOLAX_X1 #ifdef USE_LE01MR - AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin - AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin + AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin + AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin #endif // IFDEF:USE_LE01MR #if defined(USE_BL0940) || defined(USE_BL09XX) - AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) - AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface - AGPIO(GPIO_BL0942_RX), // BL0940 Serial interface + AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) + AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface + AGPIO(GPIO_BL0942_RX), // BL0940 Serial interface #endif #ifdef USE_IEM3000 - AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface - AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface + AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface + AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface #endif #ifdef USE_WE517 - AGPIO(GPIO_WE517_TX), // WE517 Serial interface - AGPIO(GPIO_WE517_RX), // WE517 Serial interface + AGPIO(GPIO_WE517_TX), // WE517 Serial interface + AGPIO(GPIO_WE517_RX), // WE517 Serial interface #endif #ifdef USE_SDM72 - AGPIO(GPIO_SDM72_TX), // SDM72 Serial interface - AGPIO(GPIO_SDM72_RX), // SDM72 Serial interface + AGPIO(GPIO_SDM72_TX), // SDM72 Serial interface + AGPIO(GPIO_SDM72_RX), // SDM72 Serial interface #endif AGPIO(GPIO_ZEROCROSS), #ifdef USE_SDM230 - AGPIO(GPIO_SDM230_TX), // SDM230 Serial interface - AGPIO(GPIO_SDM230_RX), // SDM230 Serial interface + AGPIO(GPIO_SDM230_TX), // SDM230 Serial interface + AGPIO(GPIO_SDM230_RX), // SDM230 Serial interface #endif #ifdef USE_BL6523 - AGPIO(GPIO_BL6523_TX), // BL6523 based Watt meter Serial interface - AGPIO(GPIO_BL6523_RX), // BL6523 based Watt meter Serial interface + AGPIO(GPIO_BL6523_TX), // BL6523 based Watt meter Serial interface + AGPIO(GPIO_BL6523_RX), // BL6523 based Watt meter Serial interface #endif #endif // USE_ENERGY_SENSOR @@ -891,99 +896,107 @@ const uint16_t kGpioNiceList[] PROGMEM = { \*-------------------------------------------------------------------------------------------*/ #ifdef USE_SERIAL_BRIDGE - AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface - AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface + AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface + AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface #endif #ifdef USE_MODBUS_BRIDGE - AGPIO(GPIO_MBR_TX), // Modbus Bridge Serial interface - AGPIO(GPIO_MBR_RX), // Modbus Bridge Serial interface + AGPIO(GPIO_MBR_TX), // Modbus Bridge Serial interface + AGPIO(GPIO_MBR_RX), // Modbus Bridge Serial interface #endif #ifdef USE_TCP_BRIDGE - AGPIO(GPIO_TCP_TX), // TCP Serial bridge - AGPIO(GPIO_TCP_RX), // TCP Serial bridge + AGPIO(GPIO_TCP_TX), // TCP Serial bridge + AGPIO(GPIO_TCP_RX), // TCP Serial bridge #endif #ifdef USE_ZIGBEE - AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RST) + 2, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode + AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RST) + 2, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode #endif #ifdef USE_MHZ19 - AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface - AGPIO(GPIO_MHZ_RXD), // MH-Z19 Serial interface + AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface + AGPIO(GPIO_MHZ_RXD), // MH-Z19 Serial interface #endif #ifdef USE_SENSEAIR - AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface - AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface + AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface + AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface #endif #ifdef USE_NOVA_SDS - AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface - AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface + AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface + AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface #endif #ifdef USE_HPMA - AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface - AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface + AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface + AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface #endif #ifdef USE_PMS5003 - AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface - AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface + AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface + AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface #endif #ifdef USE_VINDRIKTNING - AGPIO(GPIO_VINDRIKTNING_RX), + AGPIO(GPIO_VINDRIKTNING_RX), // Ikea Vindriktning #endif #ifdef USE_HM330X - AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low) + AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low) #endif #if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) || defined(USE_WS2300_WIND_SENSOR) - AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin + AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin #endif -#ifdef USE_WINDMETER +#ifdef USE_WINDMETER // xsns_68_windmeter.ino AGPIO(GPIO_WINDMETER_SPEED), #endif -#ifdef USE_MP3_PLAYER - AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface - AGPIO(GPIO_MP3_DFR562_BUSY),// RB-DFR-562, DFPlayer Mini MP3 Player optional Busy flag +#ifdef USE_MP3_PLAYER // xdrv_14_mp3.ino + AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface + AGPIO(GPIO_MP3_DFR562_BUSY), // RB-DFR-562, DFPlayer Mini MP3 Player optional Busy flag #endif -#ifdef USE_AZ7798 - AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface - AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface +#ifdef USE_AZ7798 // xsns_38_az7798 + AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface + AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface #endif -#ifdef USE_PN532_HSU - AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx - AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx +#ifdef USE_PN532_HSU // xsns_40_pn532.ino + AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx + AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx #endif -#ifdef USE_TASMOTA_CLIENT - AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX - AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX - AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset - AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted +#ifdef USE_TASMOTA_CLIENT // xdrv_31_tasmota_client.ino + AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX + AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX + AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset + AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted #endif -#ifdef USE_RDM6300 +#ifdef USE_RDM6300 // xsns_51_rdm6300.ino AGPIO(GPIO_RDM6300_RX), #endif -#ifdef USE_IBEACON +#ifdef USE_IBEACON // xsns_52_ibeacon.ino AGPIO(GPIO_IBEACON_TX), AGPIO(GPIO_IBEACON_RX), #endif -#ifdef USE_GPS - AGPIO(GPIO_GPS_TX), // GPS serial interface - AGPIO(GPIO_GPS_RX), // GPS serial interface +#ifdef USE_GPS // xsns_60_gps.ino + AGPIO(GPIO_GPS_TX), // GPS serial interface + AGPIO(GPIO_GPS_RX), // GPS serial interface #endif -#ifdef USE_HM10 - AGPIO(GPIO_HM10_TX), // GPS serial interface - AGPIO(GPIO_HM10_RX), // GPS serial interface +#ifdef USE_HM10 // xsns_62_mi_hm10.ino + AGPIO(GPIO_HM10_TX), // HM10 serial interface + AGPIO(GPIO_HM10_RX), // HM10 serial interface #endif -#ifdef USE_OPENTHERM +#ifdef USE_OPENTHERM // xsns_69_opentherm.ino AGPIO(GPIO_BOILER_OT_TX), AGPIO(GPIO_BOILER_OT_RX), #endif -#ifdef USE_AS608 +#ifdef USE_AS608 // xsns_79_as608.ino AGPIO(GPIO_AS608_TX), AGPIO(GPIO_AS608_RX), #endif -#ifdef USE_HRG15 +#ifdef USE_HRG15 // xsns_90_hrg15.ino AGPIO(GPIO_HRG15_TX), AGPIO(GPIO_HRG15_RX), #endif +#ifdef USE_CM110x // xsns_95_cm110x.ino + AGPIO(GPIO_CM11_TXD), // CM110x Serial interface + AGPIO(GPIO_CM11_RXD), // CM110x Serial interface +#endif +#ifdef USE_LD2410 // xsns_102_ld2410.ino + AGPIO(GPIO_LD2410_TX), // HLK-LD2410 Serial interface + AGPIO(GPIO_LD2410_RX), // HLK-LD2410 Serial interface +#endif /*-------------------------------------------------------------------------------------------*\ * Other sensors @@ -994,27 +1007,27 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MGC3130_RESET), #endif #ifdef USE_MAX31855 - AGPIO(GPIO_MAX31855CS), // MAX31855 Serial interface - AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface - AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855CS), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface #endif #ifdef USE_HRE AGPIO(GPIO_HRE_CLOCK), AGPIO(GPIO_HRE_DATA), #endif #ifdef USE_A4988_STEPPER - AGPIO(GPIO_A4988_DIR), // A4988 direction pin - AGPIO(GPIO_A4988_STP), // A4988 step pin + AGPIO(GPIO_A4988_DIR), // A4988 direction pin + AGPIO(GPIO_A4988_STP), // A4988 step pin // folowing are not mandatory - AGPIO(GPIO_A4988_ENA), // A4988 enabled pin + AGPIO(GPIO_A4988_ENA), // A4988 enabled pin AGPIO(GPIO_A4988_MS1) + MAX_A4988_MSS, // A4988 microstep pin1 to pin3 #endif #ifdef USE_DEEPSLEEP AGPIO(GPIO_DEEPSLEEP), #endif #ifdef USE_KEELOQ - AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX - AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX + AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX + AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX #endif #ifdef USE_HRXL AGPIO(GPIO_HRXL_RX), @@ -1023,54 +1036,57 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_DYP_RX), #endif #ifdef USE_AS3935 - AGPIO(GPIO_AS3935), // AS3935 IRQ Pin + AGPIO(GPIO_AS3935), // AS3935 IRQ Pin #endif #ifdef USE_TELEINFO AGPIO(GPIO_TELEINFO_RX), AGPIO(GPIO_TELEINFO_ENABLE), #endif #ifdef USE_MIEL_HVAC - AGPIO(GPIO_MIEL_HVAC_TX), // Mitsubishi Electric HVAC TX pin - AGPIO(GPIO_MIEL_HVAC_RX), // Mitsubishi Electric HVAC RX pin + AGPIO(GPIO_MIEL_HVAC_TX), // Mitsubishi Electric HVAC TX pin + AGPIO(GPIO_MIEL_HVAC_RX), // Mitsubishi Electric HVAC RX pin #endif #ifdef USE_WIEGAND - AGPIO(GPIO_WIEGAND_D0), // Date line D0 of Wiegand devices - AGPIO(GPIO_WIEGAND_D1), // Date line D1 of Wiegand devices + AGPIO(GPIO_WIEGAND_D0), // Date line D0 of Wiegand devices + AGPIO(GPIO_WIEGAND_D1), // Date line D1 of Wiegand devices #endif #ifdef USE_NEOPOOL - AGPIO(GPIO_NEOPOOL_TX), // Sugar Valley RS485 Interface - AGPIO(GPIO_NEOPOOL_RX), // Sugar Valley RS485 Interface + AGPIO(GPIO_NEOPOOL_TX), // Sugar Valley RS485 Interface + AGPIO(GPIO_NEOPOOL_RX), // Sugar Valley RS485 Interface #endif #ifdef USE_PROJECTOR_CTRL - AGPIO(GPIO_PROJECTOR_CTRL_TX), // LCD/DLP Projector Serial Control - AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control + AGPIO(GPIO_PROJECTOR_CTRL_TX), // LCD/DLP Projector Serial Control + AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control #endif #if defined(USE_VL53L0X) or defined (USE_VL53L1X) AGPIO(GPIO_VL53LXX_XSHUT1) + VL53LXX_MAX_SENSORS, // When using multiple VL53LXX. #endif - -#ifdef USE_DISPLAY_MAX7219 - AGPIO(GPIO_MAX7219CLK), - AGPIO(GPIO_MAX7219DIN), - AGPIO(GPIO_MAX7219CS), -#endif // USE_DISPLAY_MAX7219 - -#ifdef USE_CM110x - AGPIO(GPIO_CM11_TXD), // CM110x Serial interface - AGPIO(GPIO_CM11_RXD), // CM110x Serial interface -#endif - #ifdef USE_FLOWRATEMETER AGPIO(GPIO_FLOWRATEMETER_IN) + MAX_FLOWRATEMETER, // Flow meter Pin #endif +#ifdef USE_SHIFT595 + AGPIO(GPIO_SHIFT595_SRCLK), // 74x595 shift register + AGPIO(GPIO_SHIFT595_RCLK), + 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 + /*-------------------------------------------------------------------------------------------*\ * ESP32 specifics \*-------------------------------------------------------------------------------------------*/ #ifdef ESP32 #if CONFIG_IDF_TARGET_ESP32 - AGPIO(GPIO_HALLEFFECT) + 2, // Hall effect sensor connected to GPIO36 and 39 + AGPIO(GPIO_HALLEFFECT) + 2, // Hall effect sensor connected to GPIO36 and 39 #endif // CONFIG_IDF_TARGET_ESP32 #ifdef USE_WEBCAM AGPIO(GPIO_WEBCAM_PWDN), @@ -1089,39 +1105,24 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_ETHERNET AGPIO(GPIO_ETH_PHY_POWER), AGPIO(GPIO_ETH_PHY_MDC), - AGPIO(GPIO_ETH_PHY_MDIO), // Ethernet + AGPIO(GPIO_ETH_PHY_MDIO), // Ethernet #endif // USE_ETHERNET /*-------------------------------------------------------------------------------------------*\ * ESP32 multiple Analog / Digital converter inputs \*-------------------------------------------------------------------------------------------*/ - AGPIO(GPIO_ADC_INPUT) + MAX_ADCS, // Analog inputs - AGPIO(GPIO_ADC_TEMP) + MAX_ADCS, // Thermistor - AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS, // Light sensor - AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button + AGPIO(GPIO_ADC_INPUT) + MAX_ADCS, // Analog inputs + AGPIO(GPIO_ADC_TEMP) + MAX_ADCS, // Thermistor + AGPIO(GPIO_ADC_LIGHT) + MAX_ADCS, // Light sensor + AGPIO(GPIO_ADC_BUTTON) + MAX_KEYS, // Button AGPIO(GPIO_ADC_BUTTON_INV) + MAX_KEYS, - AGPIO(GPIO_ADC_RANGE) + MAX_ADCS, // Range - AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS, // Current - AGPIO(GPIO_ADC_JOY) + MAX_ADCS, // Joystick - AGPIO(GPIO_ADC_PH) + MAX_ADCS, // Analog PH Sensor - AGPIO(GPIO_ADC_MQ) + MAX_ADCS, // Analog MQ Sensor + AGPIO(GPIO_ADC_RANGE) + MAX_ADCS, // Range + AGPIO(GPIO_ADC_CT_POWER) + MAX_ADCS, // Current + AGPIO(GPIO_ADC_JOY) + MAX_ADCS, // Joystick + AGPIO(GPIO_ADC_PH) + MAX_ADCS, // Analog PH Sensor + AGPIO(GPIO_ADC_MQ) + MAX_ADCS, // Analog MQ Sensor #endif // ESP32 - -#ifdef USE_SHIFT595 - AGPIO(GPIO_SHIFT595_SRCLK), // 74x595 shift register - AGPIO(GPIO_SHIFT595_RCLK), - 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 4138c8863..1f0d01973 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index d8d775b2b..4e587a56b 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index defb50b95..af0a776ca 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index f7d204123..4bfb51bc9 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 581617431..dba3f0bec 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index d6c5184e3..18d5f9620 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index ff1ba164a..e3db888b7 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index d246517a7..8357a0d5a 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index f00e77194..9ce54509c 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 RX" #define D_SENSOR_WE517_TX "WE517 TX" #define D_SENSOR_WE517_RX "WE517 RX" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 8f36bb8f8..72957eaa2 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index fe3ef7f3a..e9986eb9e 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 652adaf3a..a11dcb084 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 7aecb90f5..3f78c7b97 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 - RX" #define D_SENSOR_WE517_TX "WE517 - TX" #define D_SENSOR_WE517_RX "WE517 - RX" +#define D_SENSOR_LD2410_TX "LD2410 - RX" +#define D_SENSOR_LD2410_RX "LD2410 - TX" #define D_GPIO_TM1621_CS "TM1621 - CS" #define D_GPIO_TM1621_WR "TM1621 - WR" #define D_GPIO_TM1621_RD "TM1621 - RD" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index f70d84529..1da833a4c 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 54a973983..8ff52404c 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 0c37c4a12..8ecf7fe88 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 5d56e0150..429960c1d 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 20851d0fe..1a6c0a7c6 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 0adc3cf66..e62b42f9f 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 7b5c92433..68fb7ca73 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index b2a2e6727..206f7c838 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index abec120b1..a029d3c1b 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 1000df44e..e074aa4a7 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 9561005bb..18cefca2d 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 6bf27fff4..bf7944ecd 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index a09337d9a..0715a6345 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 393b60a5e..de65182f9 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -702,6 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Rx" +#define D_SENSOR_LD2410_RX "LD2410 Tx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 0ec257898..ee67d9bd4 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -727,16 +727,16 @@ // 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 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_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_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 From 743c162499f6ecdf6171d517208594a0d9d32c33 Mon Sep 17 00:00:00 2001 From: barbudor Date: Mon, 21 Nov 2022 19:42:46 +0100 Subject: [PATCH 251/319] Adding PUT, PATCH and DELETE to Berry webclient --- .../src/HttpClientLight.cpp | 40 ++++++---- .../src/HttpClientLight.h | 8 +- .../berry_tasmota/src/be_webclient_lib.c | 10 ++- .../xdrv_52_3_berry_webclient.ino | 75 ++++++++++++++++++- 4 files changed, 112 insertions(+), 21 deletions(-) diff --git a/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.cpp b/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.cpp index 1c1c6ac32..d8c85b2ac 100644 --- a/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.cpp +++ b/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.cpp @@ -5,8 +5,8 @@ * * Copyright (c) 2015 Markus Sattler. All rights reserved. * This file is part of the HTTPClient for Arduino. - * Port to ESP32 by Evandro Luis Copercini (2017), - * changed fingerprints to CA verification. + * Port to ESP32 by Evandro Luis Copercini (2017), + * changed fingerprints to CA verification. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -78,7 +78,7 @@ public: _recv(recv), _xmit(xmit) { } - + std::unique_ptr create() override { std::unique_ptr p = std::unique_ptr(new BearSSL::WiFiClientSecure_light(_recv, _xmit)); @@ -569,6 +569,20 @@ int HTTPClientLight::PUT(String payload) { return PUT((uint8_t *) payload.c_str(), payload.length()); } +/** + * sends a delete request to the server + * @param payload uint8_t * + * @param size size_t + * @return http code + */ +int HTTPClientLight::DELETE(uint8_t * payload, size_t size) { + return sendRequest("DELETE", payload, size); +} + +int HTTPClientLight::DELETE(String payload) { + return DELETE((uint8_t *) payload.c_str(), payload.length()); +} + /** * sendRequest * @param type const char * "GET", "POST", .... @@ -601,7 +615,7 @@ int HTTPClientLight::sendRequest(const char * type, uint8_t * payload, size_t si } log_d("request type: '%s' redirCount: %d\n", type, redirectCount); - + // connect to server if(!connect()) { if (_secure) { @@ -640,7 +654,7 @@ int HTTPClientLight::sendRequest(const char * type, uint8_t * payload, size_t si // redirect = false; if ( - _followRedirects != HTTPC_DISABLE_FOLLOW_REDIRECTS && + _followRedirects != HTTPC_DISABLE_FOLLOW_REDIRECTS && redirectCount < _redirectLimit && _location.length() > 0 ) { @@ -653,7 +667,7 @@ int HTTPClientLight::sendRequest(const char * type, uint8_t * payload, size_t si // (the RFC require user to accept the redirection) _followRedirects == HTTPC_FORCE_FOLLOW_REDIRECTS || // allow GET and HEAD methods without force - !strcmp(type, "GET") || + !strcmp(type, "GET") || !strcmp(type, "HEAD") ) { redirectCount += 1; @@ -972,7 +986,7 @@ String HTTPClientLight::getString(void) // try to reserve needed memory (noop if _size == -1) if(sstring.reserve((_size + 1))) { writeToStream(&sstring); - return sstring; + return sstring; } else { log_d("not enough memory to reserve a string! need: %d", (_size + 1)); } @@ -1142,7 +1156,7 @@ bool HTTPClientLight::connect(void) log_d("transport level verify failed"); _client->stop(); return false; - } + } #endif if(!_client->connect(_host.c_str(), _port, _connectTimeout)) { log_d("failed connect to %s:%u", _host.c_str(), _port); @@ -1150,7 +1164,7 @@ bool HTTPClientLight::connect(void) } // set Timeout for WiFiClient and for Stream::readBytesUntil() and Stream::readStringUntil() - _client->setTimeout((_tcpTimeout + 500) / 1000); + _client->setTimeout((_tcpTimeout + 500) / 1000); log_d(" connected to %s:%u", _host.c_str(), _port); @@ -1362,8 +1376,8 @@ int HTTPClientLight::writeToStreamDataBlock(Stream * stream, int size) if(readBytes > buff_size) { readBytes = buff_size; } - - // stop if no more reading + + // stop if no more reading if (readBytes == 0) break; @@ -1491,8 +1505,8 @@ bool HTTPClientLight::setURL(const String& url) _port = (_protocol == "https" ? 443 : 80); } - // disconnect but preserve _client. - // Also have to keep the connection otherwise it will free some of the memory used by _client + // disconnect but preserve _client. + // Also have to keep the connection otherwise it will free some of the memory used by _client // and will blow up later when trying to do _client->available() or similar _canReuse = true; disconnect(true); diff --git a/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.h b/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.h index a6d3be7eb..8c3709399 100644 --- a/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.h +++ b/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.h @@ -5,8 +5,8 @@ * * Copyright (c) 2015 Markus Sattler. All rights reserved. * This file is part of the HTTPClient for Arduino. - * Port to ESP32 by Evandro Luis Copercini (2017), - * changed fingerprints to CA verification. + * Port to ESP32 by Evandro Luis Copercini (2017), + * changed fingerprints to CA verification. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -154,7 +154,7 @@ public: ~HTTPClientLight(); /* - * Since both begin() functions take a reference to client as a parameter, you need to + * Since both begin() functions take a reference to client as a parameter, you need to * ensure the client object lives the entire time of the HTTPClientLight */ // bool begin(WiFiClient &client, String url); @@ -194,6 +194,8 @@ public: int POST(String payload); int PUT(uint8_t * payload, size_t size); int PUT(String payload); + int DELETE(uint8_t * payload, size_t size); + int DELETE(String payload); int sendRequest(const char * type, String payload); int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0); int sendRequest(const char * type, Stream * stream, size_t size = 0); diff --git a/lib/libesp32/berry_tasmota/src/be_webclient_lib.c b/lib/libesp32/berry_tasmota/src/be_webclient_lib.c index 87fb0afa2..ace4499a2 100644 --- a/lib/libesp32/berry_tasmota/src/be_webclient_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_webclient_lib.c @@ -1,8 +1,8 @@ /******************************************************************** * Webclient mapped to Arduino framework - * + * * To use: `d = webclient()` - * + * *******************************************************************/ #include "be_constobj.h" @@ -20,6 +20,9 @@ extern int wc_close(bvm *vm); extern int wc_addheader(bvm *vm); extern int wc_GET(bvm *vm); extern int wc_POST(bvm *vm); +extern int wc_PUT(bvm *vm); +extern int wc_PATCH(bvm *vm); +extern int wc_DELETE(bvm *vm); extern int wc_getstring(bvm *vm); extern int wc_writefile(bvm *vm); extern int wc_writeflash(bvm *vm); @@ -49,6 +52,9 @@ class be_class_webclient (scope: global, name: webclient) { add_header, func(wc_addheader) GET, func(wc_GET) POST, func(wc_POST) + PUT, func(wc_PUT) + PATCH, func(wc_PATCH) + DELETE, func(wc_DELETE) get_string, func(wc_getstring) write_file, func(wc_writefile) write_flash, func(wc_writeflash) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webclient.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webclient.ino index 1b9773bb5..09a0d0b91 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webclient.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webclient.ino @@ -76,9 +76,9 @@ String wc_UrlEncode(const String& text) { /*********************************************************************************************\ * Native functions mapped to Berry functions - * + * * import webclient - * + * \*********************************************************************************************/ extern "C" { // Berry: `` @@ -428,6 +428,75 @@ extern "C" { be_raise(vm, kTypeError, nullptr); } + // wc.PUT(string | bytes) -> httpCode:int + int32_t wc_PUT(struct bvm *vm); + int32_t wc_PUT(struct bvm *vm) { + int32_t argc = be_top(vm); + if (argc >= 2 && (be_isstring(vm, 2) || be_isbytes(vm, 2))) { + HTTPClientLight * cl = wc_getclient(vm); + const char * buf = nullptr; + size_t buf_len = 0; + if (be_isstring(vm, 2)) { // string + buf = be_tostring(vm, 2); + buf_len = strlen(buf); + } else { // bytes + buf = (const char*) be_tobytes(vm, 2, &buf_len); + } + uint32_t http_connect_time = millis(); + int32_t httpCode = cl->PUT((uint8_t*)buf, buf_len); + wc_errorCodeMessage(httpCode, http_connect_time); + be_pushint(vm, httpCode); + be_return(vm); /* return code */ + } + be_raise(vm, kTypeError, nullptr); + } + + // wc.PATCH(string | bytes) -> httpCode:int + int32_t wc_PATCH(struct bvm *vm); + int32_t wc_PATCH(struct bvm *vm) { + int32_t argc = be_top(vm); + if (argc >= 2 && (be_isstring(vm, 2) || be_isbytes(vm, 2))) { + HTTPClientLight * cl = wc_getclient(vm); + const char * buf = nullptr; + size_t buf_len = 0; + if (be_isstring(vm, 2)) { // string + buf = be_tostring(vm, 2); + buf_len = strlen(buf); + } else { // bytes + buf = (const char*) be_tobytes(vm, 2, &buf_len); + } + uint32_t http_connect_time = millis(); + int32_t httpCode = cl->PATCH((uint8_t*)buf, buf_len); + wc_errorCodeMessage(httpCode, http_connect_time); + be_pushint(vm, httpCode); + be_return(vm); /* return code */ + } + be_raise(vm, kTypeError, nullptr); + } + + // wc.DELETE(string | bytes) -> httpCode:int + int32_t wc_DELETE(struct bvm *vm); + int32_t wc_DELETE(struct bvm *vm) { + int32_t argc = be_top(vm); + if (argc >= 2 && (be_isstring(vm, 2) || be_isbytes(vm, 2))) { + HTTPClientLight * cl = wc_getclient(vm); + const char * buf = nullptr; + size_t buf_len = 0; + if (be_isstring(vm, 2)) { // string + buf = be_tostring(vm, 2); + buf_len = strlen(buf); + } else { // bytes + buf = (const char*) be_tobytes(vm, 2, &buf_len); + } + uint32_t http_connect_time = millis(); + int32_t httpCode = cl->DELETE((uint8_t*)buf, buf_len); + wc_errorCodeMessage(httpCode, http_connect_time); + be_pushint(vm, httpCode); + be_return(vm); /* return code */ + } + be_raise(vm, kTypeError, nullptr); + } + int32_t wc_getstring(struct bvm *vm); int32_t wc_getstring(struct bvm *vm) { HTTPClientLight * cl = wc_getclient(vm); @@ -547,7 +616,7 @@ extern "C" { be_raisef(vm, "internal_error", "failed, written %i bytes vs %i", written, size); } AddLog(LOG_LEVEL_DEBUG, D_LOG_UPLOAD "flash writing succesful"); - + be_pushint(vm, written); be_return(vm); /* return code */ } From aa4ff5cede936993eb3c7f1b1d625455519de679 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 21 Nov 2022 20:06:50 +0100 Subject: [PATCH 252/319] Added Tempo/BBR contract, fixed display BASE bug --- .../tasmota_xnrg_energy/xnrg_15_teleinfo.ino | 225 ++++++++++++++---- 1 file changed, 177 insertions(+), 48 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino index 1a739084f..1b798ebca 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino @@ -121,22 +121,26 @@ enum TInfoLabel{ LABEL_BASE = 1, LABEL_ADCO, LABEL_ADSC, LABEL_HCHC, LABEL_HCHP, LABEL_EAST, LABEL_EASF01, LABEL_EASF02, + LABEL_HCJB,LABEL_HPJB,LABEL_HCJW,LABEL_HPJW,LABEL_HCJR,LABEL_HPJR, + LABEL_EASF03, LABEL_EASF04, LABEL_EASF05, LABEL_EASF06, LABEL_OPTARIF, LABEL_NGTF, LABEL_ISOUSC, LABEL_PREF, LABEL_PTEC, LABEL_LTARF, LABEL_NTARF, LABEL_PAPP, LABEL_SINSTS, LABEL_IINST, LABEL_IINST1, LABEL_IINST2, LABEL_IINST3, LABEL_IRMS1, LABEL_IRMS2, LABEL_IRMS3, LABEL_TENSION, LABEL_URMS1, LABEL_URMS2, LABEL_URMS3, LABEL_IMAX, LABEL_IMAX1, LABEL_IMAX2, LABEL_IMAX3, LABEL_PMAX, LABEL_SMAXSN, - LABEL_DEMAIN, + LABEL_DEMAIN,LABEL_STGE, LABEL_END }; const char kLabel[] PROGMEM = "|BASE|ADCO|ADSC" "|HCHC|HCHP|EAST|EASF01|EASF02" + "|BBRHCJB|BBRHPJB|BBRHCJW|BBRHPJW|BBRHCJR|BBRHPJR" + "|EASF03|EASF04|EASF05|EASF06" "|OPTARIF|NGTF|ISOUSC|PREF|PTEC|LTARF|NTARF" "|PAPP|SINSTS|IINST|IINST1|IINST2|IINST3|IRMS1|IRMS2|IRMS3" "|TENSION|URMS1|URMS2|URMS3" "|IMAX|IMAX1|IMAX2|IMAX3|PMAX|SMAXSN" - "|DEMAIN" + "|DEMAIN|STGE" ; // Blacklisted label from telemetry @@ -164,12 +168,34 @@ char serialNumber[13] = ""; // Serial number is 12 char long bool tinfo_found = false; int serial_buffer_size; uint32_t total_wh; +uint32_t status_register; int contrat; int tarif; int isousc; int raw_skip; /*********************************************************************************************/ +#ifdef USE_WEBSERVER +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_INDEX_TELEINFO_SELECT[] 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_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}" ; +const char HTTP_ENERGY_IMAX3_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d / %d / %d " D_UNIT_AMPERE "{e}" ; +const char HTTP_ENERGY_PMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_POWER "{m}%d" D_UNIT_WATT "{e}" ; +const char HTTP_ENERGY_PMAX3_TELEINFO[] PROGMEM = "{s}" D_MAX_POWER "{m}%d / %d / %d " D_UNIT_WATT "{e}" ; +const char HTTP_ENERGY_LOAD_BAR[] PROGMEM = "
" + "
" + "%d%%
" + "
"; +#endif // USE_WEBSERVER + + /* ====================================================================== Function: getValueFromLabelIndex @@ -180,16 +206,23 @@ Comments: - ====================================================================== */ char * getValueFromLabelIndex(int labelIndex, char * value) { - char labelName[16]; + if (!value) { + return nullptr; + } + char labelName[17]; + *value = '\0'; + // Get the label name GetTextIndexed(labelName, sizeof(labelName), labelIndex, kLabel); // Get value of label name tinfo.valueGet(labelName, value) ; + // Standard mode has values with space before/after if (tinfo_mode==TINFO_MODE_STANDARD) { Trim(value); } - return value; + + return *value ? value : nullptr; } /* ====================================================================== @@ -438,6 +471,13 @@ void DataCallback(struct _ValueList * me, uint8_t flags) strcpy(serialNumber, me->value); AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: %s set to %s"), me->name, serialNumber); } + // Status + else if (ilabel == LABEL_STGE) + { + status_register = strtol(me->value, nullptr, 16); + AddLog(LOG_LEVEL_DEBUG, PSTR("Status Resister : %s set to %08X"), me->name, status_register); + } + } } } @@ -910,6 +950,130 @@ void TInfoProcess(void) } +#ifdef USE_WEBSERVER +/* ====================================================================== +Function: TInfoShowBASE +Purpose : Display Base contract on WEB Interface +====================================================================== */ +void TInfoShowBASE(char * name, char * value) +{ + if ( tinfo_mode==TINFO_MODE_HISTORIQUE ) { + if (getValueFromLabelIndex(LABEL_BASE, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_BASE, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + } else { + if (getValueFromLabelIndex(LABEL_EAST, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EAST, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + } +} + +/* ====================================================================== +Function: TInfoShowHC +Purpose : Display HC/HP contract on WEB Interface +====================================================================== */ +void TInfoShowHC(char * name, char * value) +{ + if ( tinfo_mode==TINFO_MODE_HISTORIQUE ) { + if (getValueFromLabelIndex(LABEL_HCHC, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_HCHP, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + } else { + int index = 0; + if (getValueFromLabelIndex(LABEL_NTARF, value) ) { + index = atoi(value); + } + if (getValueFromLabelIndex(LABEL_EAST, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EAST, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_EASF01, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EASF01, kLabel); + WSContentSend_P(index==1?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_EASF02, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EASF02, kLabel); + WSContentSend_P(index==2?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + } +} +/* ====================================================================== +Function: TInfoShowBBR +Purpose : Display Bleu Blanc Rouge contract on WEB Interface +====================================================================== */ +void TInfoShowBBR(char * name, char * value) +{ + if ( tinfo_mode==TINFO_MODE_HISTORIQUE ) { + // Contrat Tempo BBR + if (getValueFromLabelIndex(LABEL_HCJB, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCJB, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_HPJB, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HPJB, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_HCJW, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCJW, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_HPJW, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HPJW, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_HCJR, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCJR, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_HPJR, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HPJR, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_DEMAIN, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_DEMAIN, kLabel); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + } else { + int index = 0; + if (getValueFromLabelIndex(LABEL_NTARF, value) ) { + index = atoi(value); + } + if (getValueFromLabelIndex(LABEL_EASF01, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EASF01, kLabel); + WSContentSend_P(index==1?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_EASF02, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EASF02, kLabel); + WSContentSend_P(index==2?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_EASF03, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EASF03, kLabel); + WSContentSend_P(index==3?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_EASF04, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EASF04, kLabel); + WSContentSend_P(index==4?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_EASF05, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EASF05, kLabel); + WSContentSend_P(index==5?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_EASF06, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_EASF06, kLabel); + WSContentSend_P(index==6?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + } + +} +#endif + /* ====================================================================== Function: TInfoShow Purpose : Tasmota callback executed to send telemetry or WEB display @@ -917,25 +1081,6 @@ Input : - Output : - Comments: - ====================================================================== */ -#ifdef USE_WEBSERVER -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_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}" ; -const char HTTP_ENERGY_IMAX3_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d / %d / %d " D_UNIT_AMPERE "{e}" ; -const char HTTP_ENERGY_PMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_POWER "{m}%d" D_UNIT_WATT "{e}" ; -const char HTTP_ENERGY_PMAX3_TELEINFO[] PROGMEM = "{s}" D_MAX_POWER "{m}%d / %d / %d " D_UNIT_WATT "{e}" ; -const char HTTP_ENERGY_LOAD_BAR[] PROGMEM = "
" - "
" - "%d%%
" - "
"; -#endif // USE_WEBSERVER - void TInfoShow(bool json) { // Since it's an Energy device , current, voltage and power are @@ -979,19 +1124,16 @@ void TInfoShow(bool json) } } + // Show indexes depending on contract + if ( contrat == CONTRAT_BAS ) { + TInfoShowBASE(name, value); + } else if ( contrat == CONTRAT_HC ) { + TInfoShowHC(name, value); + } else if ( contrat == CONTRAT_BBR || contrat == CONTRAT_EJP ) { + TInfoShowBBR(name, value); + } + if (tinfo_mode==TINFO_MODE_HISTORIQUE ) { - if (getValueFromLabelIndex(LABEL_BASE, value) ) { - GetTextIndexed(name, sizeof(name), LABEL_BASE, kLabel); - WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); - } - if (getValueFromLabelIndex(LABEL_HCHC, value) ) { - GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel); - WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); - } - if (getValueFromLabelIndex(LABEL_HCHP, value) ) { - GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel); - WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); - } if (Energy.phase_count==3) { int imax[3]; for (int i=LABEL_IMAX1; i<=LABEL_IMAX3; i++) { @@ -1006,7 +1148,6 @@ void TInfoShow(bool json) } } - if (getValueFromLabelIndex(LABEL_PMAX, value) ) { WSContentSend_P(HTTP_ENERGY_PMAX_TELEINFO, atoi(value)); } @@ -1027,18 +1168,6 @@ void TInfoShow(bool json) } } else if (tinfo_mode==TINFO_MODE_STANDARD ) { - if (getValueFromLabelIndex(LABEL_EAST, value) ) { - GetTextIndexed(name, sizeof(name), LABEL_EAST, kLabel); - WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); - } - if (getValueFromLabelIndex(LABEL_EASF01, value) ) { - GetTextIndexed(name, sizeof(name), LABEL_EASF01, kLabel); - WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); - } - if (getValueFromLabelIndex(LABEL_EASF02, value) ) { - GetTextIndexed(name, sizeof(name), LABEL_EASF02, kLabel); - WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); - } if (getValueFromLabelIndex(LABEL_SMAXSN, value) ) { WSContentSend_P(HTTP_ENERGY_PMAX_TELEINFO, atoi(value)); } From 200221acc2329c8be493f9a946f5d0f4898d429a Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 22 Nov 2022 00:41:58 +0100 Subject: [PATCH 253/319] Added TEMPO and status register decoding for standard mode --- .../tasmota_xnrg_energy/xnrg_15_teleinfo.ino | 122 ++++++++++++------ 1 file changed, 85 insertions(+), 37 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino index 1b798ebca..3730a9e2a 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino @@ -106,14 +106,16 @@ const char kTarifName[] PROGMEM = "|Pleines Bleu|Pleines Blanc|Pleines Rouges" ; -// contract name for standard mode +// contract name for standard mode LGTF #define TELEINFO_STD_CONTRACT_BASE PSTR("BASE") -#define TELEINFO_STD_CONTRACT_HCHP PSTR("H CREUSE/PLEINE") +#define TELEINFO_STD_CONTRACT_HCHP PSTR("HC") +#define TELEINFO_STD_CONTRACT_BBR PSTR("BBR") +#define TELEINFO_STD_CONTRACT_EJP PSTR("EJP") -// tariff values for standard mode -#define TELEINFO_STD_TARIFF_BASE PSTR("BASE") -#define TELEINFO_STD_TARIFF_HC PSTR("HEURE CREUSE") -#define TELEINFO_STD_TARIFF_HP PSTR("HEURE PLEINE") +// current tariff values for standard mode (Tarif en cours) +//#define TELEINFO_STD_TARIFF_BASE PSTR("BASE") +//#define TELEINFO_STD_TARIFF_HC PSTR("CREUSE") +//#define TELEINFO_STD_TARIFF_HP PSTR("PLEINE") // Label used to do some post processing and/or calculation @@ -127,7 +129,7 @@ enum TInfoLabel{ LABEL_PAPP, LABEL_SINSTS, LABEL_IINST, LABEL_IINST1, LABEL_IINST2, LABEL_IINST3, LABEL_IRMS1, LABEL_IRMS2, LABEL_IRMS3, LABEL_TENSION, LABEL_URMS1, LABEL_URMS2, LABEL_URMS3, LABEL_IMAX, LABEL_IMAX1, LABEL_IMAX2, LABEL_IMAX3, LABEL_PMAX, LABEL_SMAXSN, - LABEL_DEMAIN,LABEL_STGE, + LABEL_DEMAIN,LABEL_MSG1,LABEL_MSG2,LABEL_STGE, LABEL_END }; @@ -140,7 +142,7 @@ const char kLabel[] PROGMEM = "|PAPP|SINSTS|IINST|IINST1|IINST2|IINST3|IRMS1|IRMS2|IRMS3" "|TENSION|URMS1|URMS2|URMS3" "|IMAX|IMAX1|IMAX2|IMAX3|PMAX|SMAXSN" - "|DEMAIN|STGE" + "|DEMAIN|MSG1|MSG2|STGE" ; // Blacklisted label from telemetry @@ -178,17 +180,19 @@ int raw_skip; #ifdef USE_WEBSERVER 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_INDEX_TELEINFO_SELECT[] PROGMEM = "{s}->%s<-{m}%s " D_UNIT_WATTHOUR "{e}" ; +const char HTTP_ENERGY_INDEX_TELEINFO_SELECT[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "%c{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_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_MSG_TELEINFO_STD[] PROGMEM = "{s}Message %d{m}%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}" ; const char HTTP_ENERGY_IMAX3_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d / %d / %d " D_UNIT_AMPERE "{e}" ; const char HTTP_ENERGY_PMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_POWER "{m}%d" D_UNIT_WATT "{e}" ; const char HTTP_ENERGY_PMAX3_TELEINFO[] PROGMEM = "{s}" D_MAX_POWER "{m}%d / %d / %d " D_UNIT_WATT "{e}" ; +const char HTTP_ENERGY_LABEL_VALUE[] PROGMEM = "{s}%s{m}%s{e}" ; const char HTTP_ENERGY_LOAD_BAR[] PROGMEM = "
" "
" "%d%%
" @@ -345,13 +349,6 @@ void DataCallback(struct _ValueList * me, uint8_t flags) // Current tariff (standard) else if (ilabel == LABEL_LTARF) { - if (!strcmp_P(me->value, TELEINFO_STD_TARIFF_BASE)) { - tarif = TARIF_TH; - } else if (!strcmp_P(me->value, TELEINFO_STD_TARIFF_HC)) { - tarif = TARIF_HC; - } else if (!strcmp_P(me->value, TELEINFO_STD_TARIFF_HP)) { - tarif = TARIF_HP; - } AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Tariff name changed, now '%s'"), me->value); } // Current tariff index (standard) @@ -440,10 +437,14 @@ void DataCallback(struct _ValueList * me, uint8_t flags) // Contract subscribed (standard is in clear text in value) else if (ilabel == LABEL_NGTF) { - if (!strcmp_P(me->value, TELEINFO_STD_CONTRACT_BASE)) { + if (strstr(me->value, TELEINFO_STD_CONTRACT_BASE)) { contrat = CONTRAT_BAS; - } else if (!strcmp_P(me->value, TELEINFO_STD_CONTRACT_HCHP)) { + } else if (strstr(me->value, TELEINFO_STD_CONTRACT_HCHP)) { contrat = CONTRAT_HC; + } else if (strstr(me->value, TELEINFO_STD_CONTRACT_BBR)) { + contrat = CONTRAT_BBR; + } else if (strstr(me->value, TELEINFO_STD_CONTRACT_EJP)) { + contrat = CONTRAT_EJP; } AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Contract changed, now '%s'"), me->value); @@ -503,7 +504,7 @@ bool isBlacklistedLabel(char * name) } /* ====================================================================== -Function: responseDumpTInfo +Function: ResponseAppendTInfo Purpose : add teleinfo values into JSON response Input : 1st separator space if begining of JSON, else comma : select if append all data or just changed one @@ -557,7 +558,15 @@ bool ResponseAppendTInfo(char sep, bool all) } if (!isNumber) { - ResponseAppend_P( PSTR("\"%s\""), me->value ); + // Some values contains space + if (strcmp(me->name, "NGTF")==0 || strcmp(me->name, "LTARF")==0 || strcmp(me->name, "MSG1")==0) { + char trimmed_value[strlen(me->value)+1]; + strcpy(trimmed_value, me->value); + ResponseAppend_P( PSTR("\"%s\""), Trim(trimmed_value) ); + } else { + ResponseAppend_P( PSTR("\"%s\""), me->value ); + } + } else { ResponseAppend_P( PSTR("%ld"), atol(me->value)); } @@ -955,8 +964,10 @@ void TInfoProcess(void) Function: TInfoShowBASE Purpose : Display Base contract on WEB Interface ====================================================================== */ -void TInfoShowBASE(char * name, char * value) +void TInfoShowBASE(void) { + char name[17]; + char value[17]; if ( tinfo_mode==TINFO_MODE_HISTORIQUE ) { if (getValueFromLabelIndex(LABEL_BASE, value) ) { GetTextIndexed(name, sizeof(name), LABEL_BASE, kLabel); @@ -974,8 +985,10 @@ void TInfoShowBASE(char * name, char * value) Function: TInfoShowHC Purpose : Display HC/HP contract on WEB Interface ====================================================================== */ -void TInfoShowHC(char * name, char * value) +void TInfoShowHC(void) { + char name[17]; + char value[17]; if ( tinfo_mode==TINFO_MODE_HISTORIQUE ) { if (getValueFromLabelIndex(LABEL_HCHC, value) ) { GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel); @@ -996,11 +1009,12 @@ void TInfoShowHC(char * name, char * value) } if (getValueFromLabelIndex(LABEL_EASF01, value) ) { GetTextIndexed(name, sizeof(name), LABEL_EASF01, kLabel); - WSContentSend_P(index==1?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO_SELECT, name, value, index==1?'*':' '); } if (getValueFromLabelIndex(LABEL_EASF02, value) ) { GetTextIndexed(name, sizeof(name), LABEL_EASF02, kLabel); - WSContentSend_P(index==2?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO_SELECT, name, value, index==2?'*':' '); + //WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); } } } @@ -1008,8 +1022,10 @@ void TInfoShowHC(char * name, char * value) Function: TInfoShowBBR Purpose : Display Bleu Blanc Rouge contract on WEB Interface ====================================================================== */ -void TInfoShowBBR(char * name, char * value) +void TInfoShowBBR(void) { + char name[17]; + char value[17]; if ( tinfo_mode==TINFO_MODE_HISTORIQUE ) { // Contrat Tempo BBR if (getValueFromLabelIndex(LABEL_HCJB, value) ) { @@ -1038,7 +1054,7 @@ void TInfoShowBBR(char * name, char * value) } if (getValueFromLabelIndex(LABEL_DEMAIN, value) ) { GetTextIndexed(name, sizeof(name), LABEL_DEMAIN, kLabel); - WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, name, value); } } else { int index = 0; @@ -1047,27 +1063,27 @@ void TInfoShowBBR(char * name, char * value) } if (getValueFromLabelIndex(LABEL_EASF01, value) ) { GetTextIndexed(name, sizeof(name), LABEL_EASF01, kLabel); - WSContentSend_P(index==1?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO_SELECT, name, value, index==1?'*':' '); } if (getValueFromLabelIndex(LABEL_EASF02, value) ) { GetTextIndexed(name, sizeof(name), LABEL_EASF02, kLabel); - WSContentSend_P(index==2?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO_SELECT, name, value, index==2?'*':' '); } if (getValueFromLabelIndex(LABEL_EASF03, value) ) { GetTextIndexed(name, sizeof(name), LABEL_EASF03, kLabel); - WSContentSend_P(index==3?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO_SELECT, name, value, index==3?'*':' '); } if (getValueFromLabelIndex(LABEL_EASF04, value) ) { GetTextIndexed(name, sizeof(name), LABEL_EASF04, kLabel); - WSContentSend_P(index==4?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO_SELECT, name, value, index==4?'*':' '); } if (getValueFromLabelIndex(LABEL_EASF05, value) ) { GetTextIndexed(name, sizeof(name), LABEL_EASF05, kLabel); - WSContentSend_P(index==5?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO_SELECT, name, value, index==5?'*':' '); } if (getValueFromLabelIndex(LABEL_EASF06, value) ) { GetTextIndexed(name, sizeof(name), LABEL_EASF06, kLabel); - WSContentSend_P(index==6?HTTP_ENERGY_INDEX_TELEINFO_SELECT:HTTP_ENERGY_INDEX_TELEINFO, name, value); + WSContentSend_P(HTTP_ENERGY_INDEX_TELEINFO_SELECT, name, value, index==6?'*':' '); } } @@ -1126,11 +1142,11 @@ void TInfoShow(bool json) // Show indexes depending on contract if ( contrat == CONTRAT_BAS ) { - TInfoShowBASE(name, value); + TInfoShowBASE(); } else if ( contrat == CONTRAT_HC ) { - TInfoShowHC(name, value); + TInfoShowHC(); } else if ( contrat == CONTRAT_BBR || contrat == CONTRAT_EJP ) { - TInfoShowBBR(name, value); + TInfoShowBBR(); } if (tinfo_mode==TINFO_MODE_HISTORIQUE ) { @@ -1172,11 +1188,43 @@ void TInfoShow(bool json) WSContentSend_P(HTTP_ENERGY_PMAX_TELEINFO, atoi(value)); } if (getValueFromLabelIndex(LABEL_LTARF, value) ) { - WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_STD, value); + WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_STD, Trim(value)); } if (getValueFromLabelIndex(LABEL_NGTF, value) ) { if (isousc) { - WSContentSend_P(HTTP_ENERGY_CONTRAT_TELEINFO, value, isousc); + WSContentSend_P(HTTP_ENERGY_CONTRAT_TELEINFO, Trim(value), isousc); + } + } + if (getValueFromLabelIndex(LABEL_MSG1, value) ) { + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, PSTR("Message 1"), Trim(value)); + } + if (getValueFromLabelIndex(LABEL_MSG2, value) ) { + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, PSTR("Message 2"), Trim(value)); + } + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, PSTR("Contact Sec"), status_register & 0x01 ? "Ouvert":"Fermé"); + if (status_register & 0x08) { + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, PSTR("ADPS"), "En cours"); + } + if (status_register >> 24) { + char txt[32]; + uint8_t sr = status_register >> 24; + uint8_t val = sr & 0x03; + if (val) { + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, PSTR("Jour"), val==1?"Bleu":val==2?"Blanc":"Rouge"); + } + val = (sr >> 2) & 0x03; + if (val) { + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, PSTR("Demain"), val==1?"Bleu":val==2?"Blanc":"Rouge"); + } + val = (sr >> 4) & 0x03; + if (val) { + sprintf_P(txt, PSTR("Pointe mobile %d"), val); + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, PSTR("Préavis"), txt); + } + val = (sr >> 6) & 0x03; + if (val) { + sprintf_P(txt, PSTR("En cours %d"), val); + WSContentSend_P(HTTP_ENERGY_LABEL_VALUE, PSTR("Pointe mobile"), txt); } } } From a93a94666f40d9f8ff54d3eb20fc779f8cb9c8cc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 22 Nov 2022 12:35:30 +0100 Subject: [PATCH 254/319] Fix LD2410 labels --- tasmota/language/af_AF.h | 4 ++-- tasmota/language/bg_BG.h | 4 ++-- tasmota/language/ca_AD.h | 4 ++-- tasmota/language/cs_CZ.h | 4 ++-- tasmota/language/de_DE.h | 4 ++-- tasmota/language/el_GR.h | 4 ++-- tasmota/language/en_GB.h | 4 ++-- tasmota/language/es_ES.h | 4 ++-- tasmota/language/fr_FR.h | 4 ++-- tasmota/language/fy_NL.h | 4 ++-- tasmota/language/he_HE.h | 4 ++-- tasmota/language/hu_HU.h | 4 ++-- tasmota/language/it_IT.h | 4 ++-- tasmota/language/ko_KO.h | 4 ++-- tasmota/language/nl_NL.h | 4 ++-- tasmota/language/pl_PL.h | 4 ++-- tasmota/language/pt_BR.h | 4 ++-- tasmota/language/pt_PT.h | 4 ++-- tasmota/language/ro_RO.h | 4 ++-- tasmota/language/ru_RU.h | 4 ++-- tasmota/language/sk_SK.h | 4 ++-- tasmota/language/sv_SE.h | 4 ++-- tasmota/language/tr_TR.h | 4 ++-- tasmota/language/uk_UA.h | 4 ++-- tasmota/language/vi_VN.h | 4 ++-- tasmota/language/zh_CN.h | 4 ++-- tasmota/language/zh_TW.h | 4 ++-- 27 files changed, 54 insertions(+), 54 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 1f0d01973..b8121b087 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 4e587a56b..cd0012e8a 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index af0a776ca..7afb11656 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 4bfb51bc9..d5e5e0a61 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index dba3f0bec..1986407ab 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 18d5f9620..6357e1973 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index e3db888b7..7fadc258f 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 8357a0d5a..178f62a53 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 9ce54509c..ad2d32073 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 RX" #define D_SENSOR_WE517_TX "WE517 TX" #define D_SENSOR_WE517_RX "WE517 RX" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 72957eaa2..ce6adbaa3 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index e9986eb9e..b1306fff1 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index a11dcb084..ddebe1d65 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 3f78c7b97..3def3f42b 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 - RX" #define D_SENSOR_WE517_TX "WE517 - TX" #define D_SENSOR_WE517_RX "WE517 - RX" -#define D_SENSOR_LD2410_TX "LD2410 - RX" -#define D_SENSOR_LD2410_RX "LD2410 - TX" +#define D_SENSOR_LD2410_TX "LD2410 - TX" +#define D_SENSOR_LD2410_RX "LD2410 - RX" #define D_GPIO_TM1621_CS "TM1621 - CS" #define D_GPIO_TM1621_WR "TM1621 - WR" #define D_GPIO_TM1621_RD "TM1621 - RD" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 1da833a4c..5d459a85f 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 8ff52404c..134d862eb 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 8ecf7fe88..0944dff76 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 429960c1d..080d22e97 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 1a6c0a7c6..967f16b32 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index e62b42f9f..efbd4e48f 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 68fb7ca73..981f4db35 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 206f7c838..9ca297d7a 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index a029d3c1b..9ed5ea3e1 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index e074aa4a7..d94922d38 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 18cefca2d..b3162de1b 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index bf7944ecd..99fa37575 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 0715a6345..6b4948b9e 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index de65182f9..1d828e7a0 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -702,8 +702,8 @@ #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_WE517_TX "WE517 Tx" #define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Rx" -#define D_SENSOR_LD2410_RX "LD2410 Tx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" #define D_GPIO_TM1621_CS "TM1621 CS" #define D_GPIO_TM1621_WR "TM1621 WR" #define D_GPIO_TM1621_RD "TM1621 RD" From 9b37690039331b5cd62e2dafb986aa024ac8ba02 Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 22 Nov 2022 23:29:52 +0100 Subject: [PATCH 255/319] Fix BBR and EJP detection in historique --- tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino index 3730a9e2a..f04b5f730 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino @@ -77,7 +77,7 @@ const char kContratName[] PROGMEM = // Received current contract value for legacy, standard mode has in clear text const char kContratValue[] PROGMEM = - "|BASE|HC..|EJP.|BBR" + "|BASE|HC..|EJP|BBR" ; // all tariff type for legacy, standard mode has in clear text @@ -428,7 +428,7 @@ void DataCallback(struct _ValueList * me, uint8_t flags) // Find the contract index for (contrat = CONTRAT_BAS ; contrat < CONTRAT_END ; contrat++) { GetTextIndexed(contrat_value, sizeof(contrat_value), contrat, kContratValue); - if (!strcmp(contrat_value, me->value)) { + if (strstr(me->value, contrat_value)) { break; } } From 87de2641464a050ddd562405460c9d1730819fcd Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 23 Nov 2022 21:41:35 +0100 Subject: [PATCH 256/319] Improve mdns logging --- tasmota/my_user_config.h | 2 +- tasmota/tasmota_support/support_network.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index ee67d9bd4..5d31cb106 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -1193,7 +1193,7 @@ * Mutual exclude options \*********************************************************************************************/ -#if defined(USE_DISCOVERY) && (defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_AWS_IOT_LIGHT)) +#if defined(ESP8266) && defined(USE_DISCOVERY) && (defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_AWS_IOT_LIGHT)) #error "Select either USE_DISCOVERY or USE_MQTT_AWS_IOT, mDNS takes too much code space and is not needed for AWS IoT" #endif diff --git a/tasmota/tasmota_support/support_network.ino b/tasmota/tasmota_support/support_network.ino index f03edbd75..5dd32cfc1 100644 --- a/tasmota/tasmota_support/support_network.ino +++ b/tasmota/tasmota_support/support_network.ino @@ -31,7 +31,7 @@ void StartMdns(void) { if (!Mdns.begun) { 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)); + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s '%s.local'"), (Mdns.begun) ? PSTR(D_INITIALIZED) : PSTR(D_FAILED), TasmotaGlobal.hostname); } } } From 5c3df72675d015448fe61d31739d830868afa4ac Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 23 Nov 2022 21:57:40 +0100 Subject: [PATCH 257/319] Disable MQTT_HOST_DISCOVERY by default --- tasmota/my_user_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 5d31cb106..3cd730dd6 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -488,7 +488,7 @@ // -- mDNS ---------------------------------------- //#define USE_DISCOVERY // Enable mDNS for the following services (+8k code or +23.5k code with core 2_5_x, +0.3k mem) #define WEBSERVER_ADVERTISE // Provide access to webserver by name .local/ - #define MQTT_HOST_DISCOVERY // Find MQTT host server (overrides MQTT_HOST if found) + // #define MQTT_HOST_DISCOVERY // Find MQTT host server (overrides MQTT_HOST if found) - disabled by default because it causes blocked repeated 3000ms pauses // -- Time ---------------------------------------- #define USE_TIMERS // Add support for up to 16 timers (+2k2 code) From cb53e0ba4e93b77bf4369835ca58c996a7f25628 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 23 Nov 2022 22:26:58 +0100 Subject: [PATCH 258/319] esptool v4.4 / Platform versioning change --- platformio_tasmota32.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index e9d36ada9..38c0209d4 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.3/platform-espressif32-2.0.5.3.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/v.2.0.5/platform-espressif32-v.2.0.5.zip platform_packages = build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} From 7dd00036172fac5ea32867f0c6fa986767a95ed5 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Thu, 24 Nov 2022 09:37:07 +0100 Subject: [PATCH 259/319] Update AC-Dimmer power calculation Power on AC-Dimmer is based on integral over the sinus. Implement mapping table to get a more linear power behavior. --- .../xdrv_04_light_utils.ino | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino index dffc12019..ebe69a08f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino @@ -31,6 +31,17 @@ typedef struct gamma_table_t { uint16_t to_gamma; } gamma_table_t; +const gamma_table_t ac_dimmer_table[] = { // don't put in PROGMEM for performance reasons + { 0, 0 }, + { 5, 144 }, + { 10, 205 }, + { 50, 500 }, + { 90, 795 }, + { 95, 866 }, + { 100, 1000 }, + { 0xFFFF, 0xFFFF } // fail-safe if out of range +}; + const gamma_table_t gamma_table[] = { // don't put in PROGMEM for performance reasons { 1, 1 }, { 4, 1 }, @@ -318,6 +329,11 @@ uint16_t ledGammaReverse_internal(uint16_t vg, const struct gamma_table_t *gt_pt } } +// 10 bits power select to 10 bits timing based on sinus curve +uint16_t ac_zero_cross_power(uint16_t v) { + return ledGamma_internal(v, ac_dimmer_table)/10; +} + // 10 bits in, 10 bits out uint16_t ledGamma10_10(uint16_t v) { return ledGamma_internal(v, gamma_table); @@ -345,4 +361,4 @@ uint16_t ledGammaFast(uint16_t v) { uint16_t leddGammaReverseFast(uint16_t vg) { return ledGammaReverse_internal(vg, gamma_table_fast); -} \ No newline at end of file +} From 8bc46aa0d965c1745cade6c6b4778448553cd234 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Thu, 24 Nov 2022 09:39:46 +0100 Subject: [PATCH 260/319] AC-Dimmer update change to linear power distribution on PWM --- tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino index c865603c8..6f665d27b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino @@ -2191,11 +2191,11 @@ void LightSetOutputs(const uint16_t *cur_col_10) { } if (!Settings->flag4.zerocross_dimmer) { #ifdef ESP32 - TasmotaGlobal.pwm_value[i] = cur_col; // mark the new expected value - // AddLog(LOG_LEVEL_DEBUG_MORE, "analogWrite-%i 0x%03X", i, cur_col); + TasmotaGlobal.pwm_value[i] = ac_zero_cross_power(cur_col); // mark the new expected value + // AddLog(LOG_LEVEL_DEBUG_MORE, "analogWrite-%i 0x%03X", i, cur_col2); #else // ESP32 - analogWrite(Pin(GPIO_PWM1, i), bitRead(TasmotaGlobal.pwm_inverted, i) ? Settings->pwm_range - cur_col : cur_col); - // AddLog(LOG_LEVEL_DEBUG_MORE, "analogWrite-%i 0x%03X", bitRead(TasmotaGlobal.pwm_inverted, i) ? Settings->pwm_range - cur_col : cur_col); + analogWrite(Pin(GPIO_PWM1, i), bitRead(TasmotaGlobal.pwm_inverted, i) ? Settings->pwm_range - ac_zero_cross_power(cur_col) : ac_zero_cross_power(cur_col)); + // AddLog(LOG_LEVEL_DEBUG_MORE, "analogWrite-%i 0x%03X", bitRead(TasmotaGlobal.pwm_inverted, i) ? Settings->pwm_range - cur_col2 : cur_col2); #endif // ESP32 } } From b5448535b2ee6cb302cead123546589f90ca7111 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Thu, 24 Nov 2022 10:51:58 +0100 Subject: [PATCH 261/319] Update dimmer loockup table --- tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino index ebe69a08f..1a4412962 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino @@ -33,13 +33,16 @@ typedef struct gamma_table_t { const gamma_table_t ac_dimmer_table[] = { // don't put in PROGMEM for performance reasons { 0, 0 }, + { 1, 64 }, { 5, 144 }, { 10, 205 }, { 50, 500 }, { 90, 795 }, { 95, 866 }, + { 99, 936 }, { 100, 1000 }, { 0xFFFF, 0xFFFF } // fail-safe if out of range + { 0xFFFF, 0xFFFF } // fail-safe if out of range }; const gamma_table_t gamma_table[] = { // don't put in PROGMEM for performance reasons From e3f0445a5dfb0cff956e8457087f2a866710307b Mon Sep 17 00:00:00 2001 From: stefanbode Date: Thu, 24 Nov 2022 13:56:34 +0100 Subject: [PATCH 262/319] fix duplicate line --- tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino index 1a4412962..11c8359ba 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino @@ -42,7 +42,6 @@ const gamma_table_t ac_dimmer_table[] = { // don't put in PROGMEM for performa { 99, 936 }, { 100, 1000 }, { 0xFFFF, 0xFFFF } // fail-safe if out of range - { 0xFFFF, 0xFFFF } // fail-safe if out of range }; const gamma_table_t gamma_table[] = { // don't put in PROGMEM for performance reasons From fce966800f2fa170c153da9d2f1de712fc3c7ec9 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Thu, 24 Nov 2022 14:09:56 +0100 Subject: [PATCH 263/319] bugfix in comment --- tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino index 6f665d27b..a4c305416 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino @@ -2192,10 +2192,10 @@ void LightSetOutputs(const uint16_t *cur_col_10) { if (!Settings->flag4.zerocross_dimmer) { #ifdef ESP32 TasmotaGlobal.pwm_value[i] = ac_zero_cross_power(cur_col); // mark the new expected value - // AddLog(LOG_LEVEL_DEBUG_MORE, "analogWrite-%i 0x%03X", i, cur_col2); + // AddLog(LOG_LEVEL_DEBUG_MORE, "analogWrite-%i 0x%03X", i, cur_col); #else // ESP32 analogWrite(Pin(GPIO_PWM1, i), bitRead(TasmotaGlobal.pwm_inverted, i) ? Settings->pwm_range - ac_zero_cross_power(cur_col) : ac_zero_cross_power(cur_col)); - // AddLog(LOG_LEVEL_DEBUG_MORE, "analogWrite-%i 0x%03X", bitRead(TasmotaGlobal.pwm_inverted, i) ? Settings->pwm_range - cur_col2 : cur_col2); + // AddLog(LOG_LEVEL_DEBUG_MORE, "analogWrite-%i 0x%03X", bitRead(TasmotaGlobal.pwm_inverted, i) ? Settings->pwm_range - cur_col : cur_col); #endif // ESP32 } } From a381da3a393eba0026fe72237802735dd6616125 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 24 Nov 2022 14:47:26 +0100 Subject: [PATCH 264/319] Revert GUI file accept --- CHANGELOG.md | 3 +++ RELEASENOTES.md | 3 ++- tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 12 ++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f55e008b5..d2cc5933f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,17 +9,20 @@ 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) +- Teleinfo TEMPO (BBR) contract (#17160) ### Breaking Changed ### Changed - Serial Bridge default internal serial rx buffer size from 64 to 256 (#17120) - Accept filename extensions to GUI file upload input fields (#16875) +- AC PWM dimmer lineair power distribution (#17177) ### Fixed - ModbusBridge baudrates over 76500 baud (#17106) ### Removed +- Accept filename extensions to GUI file upload input fields as not functional in some browsers (#16875) ## [12.2.0.4] 20221117 ### Added diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 38989f621..77a0ae6b6 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -127,6 +127,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - 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 ArtNet DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059) +- Teleinfo TEMPO (BBR) contract [#17160](https://github.com/arendst/Tasmota/issues/17160) - 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) @@ -140,13 +141,13 @@ 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) -- Accept filename extensions to GUI file upload input fields [#16875](https://github.com/arendst/Tasmota/issues/16875) - 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) - 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) +- AC PWM dimmer lineair power distribution [#17177](https://github.com/arendst/Tasmota/issues/17177) - Zigbee improved Aqara plug support and completed cluster 0x0702 [#17073](https://github.com/arendst/Tasmota/issues/17073) ### Fixed diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 84018e4f1..b62176159 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 = "
 " D_UPGRADE_BY_FILE_UPLOAD " "; const char HTTP_FORM_RST_UPG[] PROGMEM = "
" - "

" + "

" "
" @@ -365,7 +365,7 @@ const char HTTP_FORM_RST_UPG[] PROGMEM = // upload via factory partition const char HTTP_FORM_RST_UPG_FCT[] PROGMEM = "
" - "

" + "

" "
" @@ -2296,7 +2296,7 @@ void HandleRestoreConfiguration(void) WSContentStart_P(PSTR(D_RESTORE_CONFIGURATION)); WSContentSendStyle(); WSContentSend_P(HTTP_FORM_RST); - WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(".dmp"), PSTR(D_RESTORE)); + WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_RESTORE)); if (WifiIsInManagerMode()) { WSContentSpaceButton(BUTTON_MAIN); } else { @@ -2566,12 +2566,12 @@ void HandleUpgradeFirmware(void) { WSContentSend_P(HTTP_FORM_UPG, SettingsText(SET_OTAURL)); #ifdef ESP32 if (EspSingleOtaPartition() && !EspRunningFactoryPartition()) { - WSContentSend_P(HTTP_FORM_RST_UPG_FCT, PSTR(".bin,.ota,.hex"), PSTR(D_UPGRADE)); + WSContentSend_P(HTTP_FORM_RST_UPG_FCT, PSTR(D_UPGRADE)); } else { - WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(".bin"), PSTR(D_UPGRADE)); + WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_UPGRADE)); } #else - WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(".bin,.bin.gz,.ota,.hex"), PSTR(D_UPGRADE)); + WSContentSend_P(HTTP_FORM_RST_UPG, PSTR(D_UPGRADE)); #endif WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); From 430396832f82cde51ff3ee3370ef20d9753e59e8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 24 Nov 2022 15:09:39 +0100 Subject: [PATCH 265/319] Fix thermostat ramp-off time Fix thermostat ramp-off time (#16424) --- tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino b/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino index ca1f39ec7..ed721bb22 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino @@ -428,6 +428,14 @@ void ThermostatCtrState(uint8_t ctr_output) break; // Ramp-up controller (predictive) case CTR_RAMP_UP: + // If ramp-up off time counter has been initialized + // AND ramp-up off time counter value reached + if ((Thermostat[ctr_output].time_ctr_checkpoint != 0) && + (TasmotaGlobal.uptime >= Thermostat[ctr_output].time_ctr_checkpoint)) { + // Reset times + Thermostat[ctr_output].time_ctr_checkpoint = 0; + Thermostat[ctr_output].timestamp_rampup_start = TasmotaGlobal.uptime; + } break; #ifdef USE_PI_AUTOTUNING // PI autotune From e3cddc42088d1a9fe2c8bfb70ff2d3a4d7b5be9c Mon Sep 17 00:00:00 2001 From: Frederik <5511687+fightforlife@users.noreply.github.com> Date: Thu, 24 Nov 2022 18:05:00 +0100 Subject: [PATCH 266/319] introduce configurable retries and change hassmode --- .../xdrv_85_esp32_ble_eq3_trv.ino | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) 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 67103ce35..3b1ab1760 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 @@ -32,6 +32,7 @@ trv 001A22092EE0 settemp 22.5 trvperiod n - set polling period in seconds (default teleperiod at boot) trvonlyaliased *0/1 - only hear devices with BLEAlias set +trvretries n - set the number of retries (default 4 at boot) trvMatchPrefix 0/*1 - if set, then it will add trvs to the seen list which have mac starting with : macs in macprefixes, currently only 001a22 Note: anything with BLEAlias starting "EQ3" will be added to the seen list. @@ -147,6 +148,7 @@ namespace EQ3_ESP32 { void CmndTrv(void); void CmndTrvPeriod(void); +void CmndTrvRetries(void); void CmndTrvOnlyAliased(void); void CmndTrvMatchPrefix(void); void CmndTrvMinRSSI(void); @@ -155,6 +157,7 @@ void CmndTrvHideFailedPoll(void); const char kEQ3_Commands[] PROGMEM = D_CMND_EQ3"|" "|" "period|" + "retries|" "onlyaliased|" "MatchPrefix|" "MinRSSI|" @@ -163,6 +166,7 @@ const char kEQ3_Commands[] PROGMEM = D_CMND_EQ3"|" void (*const EQ3_Commands[])(void) PROGMEM = { &CmndTrv, &CmndTrvPeriod, + &CmndTrvRetries, &CmndTrvOnlyAliased, &CmndTrvMatchPrefix, &CmndTrvMinRSSI, @@ -234,6 +238,7 @@ eq3_device_tag EQ3Devices[EQ3_NUM_DEVICESLOTS]; SemaphoreHandle_t EQ3mutex = nullptr; int EQ3Period = 300; +int EQ3Retries = 4; uint8_t EQ3OnlyAliased = 0; uint8_t EQ3MatchPrefix = 1; uint8_t opInProgress = 0; @@ -365,7 +370,7 @@ int EQ3DoOp(){ if (!opInProgress){ if (opQueue.size()){ op_t* op = opQueue[0]; - if (EQ3Operation(op->addr, op->towrite, op->writelen, op->cmdtype, 4)){ + if (EQ3Operation(op->addr, op->towrite, op->writelen, op->cmdtype, EQ3Retries)){ opQueue.pop_front(); opInProgress = 1; AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3 %s:Op dequeued len now %d"), addrStr(op->addr, (op->cmdtype & 0x80)), opQueue.size()); @@ -480,16 +485,18 @@ int EQ3ParseOp(BLE_ESP32::generic_sensor_t *op, bool success, int retries){ ResponseAppend_P(PSTR(",\"hassmode\":")); do { + //HASS allowed modes [“auto”, “off”, “cool”, “heat”, “dry”, “fan_only”] //0201283B042A - // its in auto + // If its in auto or holiday, set to auto if ((stat & 3) == 0) { ResponseAppend_P(PSTR("\"auto\"")); break; } - // it's set to 'OFF' + // If its in manual and 4.5°C, set to off if (((stat & 3) == 1) && (status[5] == 9)) { ResponseAppend_P(PSTR("\"off\"")); break; } - // it's actively heating (valve open) + // If its in manual above 4.5°C and valve is open, set to heat if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"heat\"")); break; } - // it's achieved temp (valve closed) - if (((stat & 3) == 1) && (status[5] > 9)) { ResponseAppend_P(PSTR("\"idle\"")); break; } - ResponseAppend_P(PSTR("\"idle\"")); + // If its in manual above 4.5°C and valve is closed, set to off + if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"off\"")); break; } + //Fallback off + ResponseAppend_P(PSTR("\"off\"")); break; } while (0); @@ -1271,16 +1278,16 @@ int EQ3Send(const uint8_t* addr, const char *cmd, char* param, char* param2, int if (!strcmp(param, "auto")){ d[1] = 0x00; } - if (!strcmp(param, "manual")){ + if (!strcmp(param, "manual") || !strcmp(param, "heat" )){ d[1] = 0x40; } - if (!strcmp(param, "on") || !strcmp(param, "heat")) { + if (!strcmp(param, "on")) { int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); char tmp[] = "30"; int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); return res2; } - if (!strcmp(param, "off") || !strcmp(param, "cool")) { + if (!strcmp(param, "off") || !strcmp(param, "cool") || !strcmp(param, "fan_only")) { int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); char tmp[] = "4.5"; int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); @@ -1486,6 +1493,13 @@ void CmndTrvPeriod(void) { ResponseCmndNumber(EQ3Period); } +void CmndTrvRetries(void) { + if (XdrvMailbox.data_len > 0) { + EQ3Retries = XdrvMailbox.payload; + } + ResponseCmndNumber(EQ3Retries); +} + void CmndTrvOnlyAliased(void){ if (XdrvMailbox.data_len > 0) { EQ3OnlyAliased = XdrvMailbox.payload; From 1c29be8749800cb9a6acf20e417166e25e8b6639 Mon Sep 17 00:00:00 2001 From: Frederik <5511687+fightforlife@users.noreply.github.com> Date: Thu, 24 Nov 2022 18:15:43 +0100 Subject: [PATCH 267/319] remove hassmoda changes to create seperate PR --- .../xdrv_85_esp32_ble_eq3_trv.ino | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) 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 3b1ab1760..1a7fe7c0c 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 @@ -485,18 +485,16 @@ int EQ3ParseOp(BLE_ESP32::generic_sensor_t *op, bool success, int retries){ ResponseAppend_P(PSTR(",\"hassmode\":")); do { - //HASS allowed modes [“auto”, “off”, “cool”, “heat”, “dry”, “fan_only”] //0201283B042A - // If its in auto or holiday, set to auto + // its in auto if ((stat & 3) == 0) { ResponseAppend_P(PSTR("\"auto\"")); break; } - // If its in manual and 4.5°C, set to off + // it's set to 'OFF' if (((stat & 3) == 1) && (status[5] == 9)) { ResponseAppend_P(PSTR("\"off\"")); break; } - // If its in manual above 4.5°C and valve is open, set to heat + // it's actively heating (valve open) if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"heat\"")); break; } - // If its in manual above 4.5°C and valve is closed, set to off - if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"off\"")); break; } - //Fallback off - ResponseAppend_P(PSTR("\"off\"")); + // it's achieved temp (valve closed) + if (((stat & 3) == 1) && (status[5] > 9)) { ResponseAppend_P(PSTR("\"idle\"")); break; } + ResponseAppend_P(PSTR("\"idle\"")); break; } while (0); @@ -1278,16 +1276,16 @@ int EQ3Send(const uint8_t* addr, const char *cmd, char* param, char* param2, int if (!strcmp(param, "auto")){ d[1] = 0x00; } - if (!strcmp(param, "manual") || !strcmp(param, "heat" )){ + if (!strcmp(param, "manual")){ d[1] = 0x40; } - if (!strcmp(param, "on")) { + if (!strcmp(param, "on") || !strcmp(param, "heat")) { int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); char tmp[] = "30"; int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); return res2; } - if (!strcmp(param, "off") || !strcmp(param, "cool") || !strcmp(param, "fan_only")) { + if (!strcmp(param, "off") || !strcmp(param, "cool")) { int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); char tmp[] = "4.5"; int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); From 339b8a0b961c25a235afa64b9a1a80263fe30719 Mon Sep 17 00:00:00 2001 From: Frederik <5511687+fightforlife@users.noreply.github.com> Date: Thu, 24 Nov 2022 18:19:12 +0100 Subject: [PATCH 268/319] fix hassmode, idle no longer supported --- .../xdrv_85_esp32_ble_eq3_trv.ino | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) 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 67103ce35..f9bb90a94 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 @@ -480,16 +480,18 @@ int EQ3ParseOp(BLE_ESP32::generic_sensor_t *op, bool success, int retries){ ResponseAppend_P(PSTR(",\"hassmode\":")); do { + //HASS allowed modes [“auto”, “off”, “cool”, “heat”, “dry”, “fan_only”] //0201283B042A - // its in auto + // If its in auto or holiday, set to auto if ((stat & 3) == 0) { ResponseAppend_P(PSTR("\"auto\"")); break; } - // it's set to 'OFF' + // If its in manual and 4.5°C, set to off if (((stat & 3) == 1) && (status[5] == 9)) { ResponseAppend_P(PSTR("\"off\"")); break; } - // it's actively heating (valve open) + // If its in manual above 4.5°C and valve is open, set to heat if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"heat\"")); break; } - // it's achieved temp (valve closed) - if (((stat & 3) == 1) && (status[5] > 9)) { ResponseAppend_P(PSTR("\"idle\"")); break; } - ResponseAppend_P(PSTR("\"idle\"")); + // If its in manual above 4.5°C and valve is closed, set to off + if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"off\"")); break; } + //Fallback off + ResponseAppend_P(PSTR("\"off\"")); break; } while (0); @@ -1271,16 +1273,16 @@ int EQ3Send(const uint8_t* addr, const char *cmd, char* param, char* param2, int if (!strcmp(param, "auto")){ d[1] = 0x00; } - if (!strcmp(param, "manual")){ + if (!strcmp(param, "manual") || !strcmp(param, "heat" )){ d[1] = 0x40; } - if (!strcmp(param, "on") || !strcmp(param, "heat")) { + if (!strcmp(param, "on")) { int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); char tmp[] = "30"; int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); return res2; } - if (!strcmp(param, "off") || !strcmp(param, "cool")) { + if (!strcmp(param, "off") || !strcmp(param, "cool") || !strcmp(param, "fan_only")) { int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); char tmp[] = "4.5"; int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); From 075140e3b75cb147f5eae9c68523a8323f186d19 Mon Sep 17 00:00:00 2001 From: Frederik <5511687+fightforlife@users.noreply.github.com> Date: Thu, 24 Nov 2022 18:33:13 +0100 Subject: [PATCH 269/319] fix valve is closed condition --- tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f9bb90a94..fe2e81b0d 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 @@ -489,7 +489,7 @@ int EQ3ParseOp(BLE_ESP32::generic_sensor_t *op, bool success, int retries){ // If its in manual above 4.5°C and valve is open, set to heat if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"heat\"")); break; } // If its in manual above 4.5°C and valve is closed, set to off - if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"off\"")); break; } + if (((stat & 3) == 1) && (status[5] > 9)) { ResponseAppend_P(PSTR("\"off\"")); break; } //Fallback off ResponseAppend_P(PSTR("\"off\"")); break; From 46b05842829960ad1de818a8201553265f37f8e5 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Fri, 25 Nov 2022 17:04:57 +0100 Subject: [PATCH 270/319] Allow to maintain venetian tilt also on end-position 0 and 100 Requested by user --- .../tasmota_xdrv_driver/xdrv_27_shutter.ino | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 17b2215af..733de46a0 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -391,18 +391,30 @@ void ShutterReportPosition(bool always, uint32_t index) uint32_t i = 0; uint32_t n = TasmotaGlobal.shutters_present; uint8_t shutter_running = 0; + for (i; i < n; i++) { + if (Shutter[i].direction != 0) { + shutter_running++; + } + } + + // Allow function exit if nothing to report (99.9% use case) + if (!always && !shutter_running) return; + if( index != MAX_SHUTTERS) { i = index; n = index+1; + } else { + i = 0; } for (i; i < n; i++) { //AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d Real Pos %d"), i+1,Shutter[i].real_position); - uint32_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); + if (Shutter[i].direction != 0) { ShutterLogPos(i); shutter_running++; } if (i && index == MAX_SHUTTERS) { ResponseAppend_P(PSTR(",")); } + uint32_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); uint32_t target = ShutterRealToPercentPosition(Shutter[i].target_position, i); ResponseAppend_P(JSON_SHUTTER_POS, i+1, (Settings->shutter_options[i] & 1) ? 100-position : position, Shutter[i].direction,(Settings->shutter_options[i] & 1) ? 100-target : target, Shutter[i].tilt_real_pos ); } @@ -587,8 +599,7 @@ void ShutterUpdatePosition(void) Shutter[i].start_position = Shutter[i].real_position; //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Pre: Tilt not match %d -> %d, moving: %d"),Shutter[i].tilt_real_pos,Shutter[i].tilt_target_pos,Shutter[i].tiltmoving); - if (abs(Shutter[i].tilt_real_pos - Shutter[i].tilt_target_pos) > Shutter[i].min_TiltChange && Shutter[i].tiltmoving == 0 - && Settings->shutter_position[i] > 0 && Settings->shutter_position[i] < 100) { + if (abs(Shutter[i].tilt_real_pos - Shutter[i].tilt_target_pos) > Shutter[i].min_TiltChange && Shutter[i].tiltmoving == 0) { AddLog(LOG_LEVEL_INFO, PSTR("SHT: Tilt not match %d -> %d"),Shutter[i].tilt_real_pos,Shutter[i].tilt_target_pos); char databuf[1] = ""; XdrvMailbox.data = databuf; @@ -1200,6 +1211,10 @@ void CmndShutterPosition(void) } } + // if position is either 0 or 100 reset the tilt to avoid tilt moving at the end + if (XdrvMailbox.payload == 0) {Shutter[index].tilt_target_pos = Shutter[index].tilt_config[4];} + if (XdrvMailbox.payload == 100) {Shutter[index].tilt_target_pos = Shutter[index].tilt_config[3];} + int8_t target_pos_percent = (XdrvMailbox.payload < 0) ? (XdrvMailbox.payload == -99 ? ShutterRealToPercentPosition(Shutter[index].real_position, index) : 0) : ((XdrvMailbox.payload > 100) ? 100 : XdrvMailbox.payload); // webgui still send also on inverted shutter the native position. target_pos_percent = ((Settings->shutter_options[index] & 1) && (SRC_WEBGUI != TasmotaGlobal.last_source)) ? 100 - target_pos_percent : target_pos_percent; From 48ae4b247c6418e44c2abe438451f96bcf9498fd Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 26 Nov 2022 09:48:23 +0100 Subject: [PATCH 271/319] Fix intermittent hardware watchdogs Fix intermittent hardware watchdogs in case of high speed software serial flooding --- lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp index 59b6dfe10..43077ad38 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp @@ -162,11 +162,11 @@ 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 +#ifdef ESP8266 serial_buffer_size = size; Serial.setRxBufferSize(serial_buffer_size); - #endif // ESP8266 - #ifdef ESP32 +#endif // ESP8266 +#ifdef ESP32 if (TSerial) { // RX Buffer can't be resized when Serial is already running serial_buffer_size = size; @@ -176,7 +176,7 @@ size_t TasmotaSerial::setRxBufferSize(size_t size) { TSerial->setRxBufferSize(serial_buffer_size); Esp32Begin(); } - #endif // ESP32 +#endif // ESP32 } } else if (m_buffer) { @@ -425,6 +425,9 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { if (next != (int)m_out_pos) { m_buffer[m_in_pos] = rec; m_in_pos = next; + } else { + // Buffer overrun - prep to exit and fix Hardware Watchdog in case of high speed flooding + loop_read = 0; } TM_SERIAL_WAIT_RCV_LOOP; // wait for stop bit From 30f64d3c42cad544eb8b6a1ced9057628c2b3066 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 26 Nov 2022 10:52:42 +0100 Subject: [PATCH 272/319] POC HLK-LD2410 --- .../TasmotaSerial-3.5.0/src/TasmotaSerial.cpp | 4 +- tasmota/language/af_AF.h | 3 + tasmota/language/bg_BG.h | 3 + tasmota/language/ca_AD.h | 3 + tasmota/language/cs_CZ.h | 3 + tasmota/language/de_DE.h | 3 + tasmota/language/el_GR.h | 3 + tasmota/language/en_GB.h | 3 + tasmota/language/es_ES.h | 3 + tasmota/language/fr_FR.h | 3 + tasmota/language/fy_NL.h | 3 + tasmota/language/he_HE.h | 3 + tasmota/language/hu_HU.h | 3 + tasmota/language/it_IT.h | 3 + tasmota/language/ko_KO.h | 3 + tasmota/language/nl_NL.h | 3 + tasmota/language/pl_PL.h | 3 + tasmota/language/pt_BR.h | 3 + tasmota/language/pt_PT.h | 3 + tasmota/language/ro_RO.h | 3 + tasmota/language/ru_RU.h | 3 + tasmota/language/sk_SK.h | 3 + tasmota/language/sv_SE.h | 3 + tasmota/language/tr_TR.h | 3 + tasmota/language/uk_UA.h | 3 + tasmota/language/vi_VN.h | 3 + tasmota/language/zh_CN.h | 3 + tasmota/language/zh_TW.h | 3 + .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 381 ++++++++++++++++++ 29 files changed, 464 insertions(+), 2 deletions(-) create mode 100644 tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp index 43077ad38..82fce4934 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp @@ -426,8 +426,8 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { m_buffer[m_in_pos] = rec; m_in_pos = next; } else { - // Buffer overrun - prep to exit and fix Hardware Watchdog in case of high speed flooding - loop_read = 0; + // Buffer overrun - exit and fix Hardware Watchdog in case of high speed flooding + break; } TM_SERIAL_WAIT_RCV_LOOP; // wait for stop bit diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index b8121b087..fc00c5a2e 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -83,6 +83,9 @@ #define D_DEBUG "Ontfout" #define D_DEWPOINT "Dou punt" #define D_DISABLED "Gedeaktiveer" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Afstand" #define D_DNS_SERVER "DNS" #define D_DO "Opgeloste suurstof" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index cd0012e8a..dc00fa439 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -83,6 +83,9 @@ #define D_DEBUG "Дебъгване" #define D_DEWPOINT "Температура на оросяване" #define D_DISABLED "Забранено" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Разстояние" #define D_DNS_SERVER "Сървър на DNS" #define D_DO "Разтворен кислород" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index 7afb11656..1c36c117a 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -83,6 +83,9 @@ #define D_DEBUG "Depuració" #define D_DEWPOINT "Punt de rossada" #define D_DISABLED "Deshabilitat" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distancia" #define D_DNS_SERVER "Servidor DNS" #define D_DO "Oxígen dissolt" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index d5e5e0a61..80fca7baf 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Zablokováno" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distance" #define D_DNS_SERVER "Server DNS" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 1986407ab..2d487f112 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -83,6 +83,9 @@ #define D_DEBUG "debug" #define D_DEWPOINT "Taupunkt" #define D_DISABLED "deaktiviert" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Abstand" #define D_DNS_SERVER "DNS-Server" #define D_DO "gelöster Sauerstoff" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 6357e1973..eb60cecf9 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Ανενεργό" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Απόσταση" #define D_DNS_SERVER "Διακομιστής DNS" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 7fadc258f..2e8b4af21 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Disabled" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distance" #define D_DNS_SERVER "DNS Server" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 178f62a53..dd86ba6eb 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Punto de Rocío" #define D_DISABLED "Deshabilitado" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distancia" #define D_DNS_SERVER "Servidor DNS" #define D_DO "Oxígeno Disuelto" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index ad2d32073..6dd0eb7ab 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Point de rosée" #define D_DISABLED "Désactivé" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distance" #define D_DNS_SERVER "Serveur DNS" #define D_DO "Oxygène dissout" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index ce6adbaa3..7753d6f13 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debugearje" #define D_DEWPOINT "Dauwpunt" #define D_DISABLED "Útsetten" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Ôfstân" #define D_DNS_SERVER "DNS Server" #define D_DO "Oploste soerstof" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index b1306fff1..783890999 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -83,6 +83,9 @@ #define D_DEBUG "באגים" #define D_DEWPOINT "Dew point" #define D_DISABLED "מבוטל" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "מרחק" #define D_DNS_SERVER "DNS שרת" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index ddebe1d65..149095171 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Harmatpont" #define D_DISABLED "Letiltva" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Távolság" #define D_DNS_SERVER "DNS szerver" #define D_DO "Oldott oxygén" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 3def3f42b..65a356b8f 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Punto rugiada" // #define D_DISABLED "Disabilitato/a" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distanza" #define D_DNS_SERVER "Server DNS" #define D_DO "Ossigeno dissolto" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 5d459a85f..8ff8b12d4 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -83,6 +83,9 @@ #define D_DEBUG "디버그" #define D_DEWPOINT "Dew point" #define D_DISABLED "사용안함" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "거리" #define D_DNS_SERVER "DNS 서버" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 134d862eb..28e55258a 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dauwpunt" #define D_DISABLED "Uitgeschakeld" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Afstand" #define D_DNS_SERVER "DNS Server" #define D_DO "Opgelost zuurstof" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 0944dff76..8b0735959 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Punkt rosy" #define D_DISABLED "Wyłączony" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Odległość" #define D_DNS_SERVER "Serwer DNS" #define D_DO "Rozpuszczalność tlenu" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 080d22e97..25800a0b4 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -83,6 +83,9 @@ #define D_DEBUG "Depurar" #define D_DEWPOINT "Ponto de orvalho" #define D_DISABLED "Desabilitado" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distância" #define D_DNS_SERVER "Servidor DNS" #define D_DO "Oxigênio dissolvido" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 967f16b32..1d36075ea 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -83,6 +83,9 @@ #define D_DEBUG "Depurar" #define D_DEWPOINT "Ponto de Condensação" #define D_DISABLED "Disabilitado" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distância" #define D_DNS_SERVER "Servidor DNS" #define D_DO "Oxigénio Dissolvido" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index efbd4e48f..2bd887f0f 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -83,6 +83,9 @@ #define D_DEBUG "Depanare" #define D_DEWPOINT "Punct de rouă" #define D_DISABLED "Dezactivat" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distanță" #define D_DNS_SERVER "Server DNS" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 981f4db35..4adf8ef54 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -83,6 +83,9 @@ #define D_DEBUG "Отладка" #define D_DEWPOINT "Dew point" #define D_DISABLED "Блокирован" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distance" #define D_DNS_SERVER "DNS Сервер" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 9ca297d7a..29ad8e8f3 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -84,6 +84,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Zablokované" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Vzdialenosť" #define D_DNS_SERVER "Server DNS" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 9ed5ea3e1..6d7d4afd5 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -83,6 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Dew point" #define D_DISABLED "Inaktiverad" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Distans" #define D_DNS_SERVER "DNS-server" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index d94922d38..0213accba 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -83,6 +83,9 @@ #define D_DEBUG "Hata Ayıklama" #define D_DEWPOINT "Dew point" #define D_DISABLED "Etkin Değil" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Mesage" #define D_DNS_SERVER "DNS Sunucu" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index b3162de1b..abe179c74 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -83,6 +83,9 @@ #define D_DEBUG "Налагодження" #define D_DEWPOINT "Tочка роси" #define D_DISABLED "Вимкнено" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Відстань" #define D_DNS_SERVER "Сервер DNS" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 99fa37575..6eaa39736 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -83,6 +83,9 @@ #define D_DEBUG "Tìm lỗi" #define D_DEWPOINT "Điểm sương" #define D_DISABLED "Vô hiệu hóa" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "Khoảng cách" #define D_DNS_SERVER "Máy chủ DNS" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 6b4948b9e..f603c7f55 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -83,6 +83,9 @@ #define D_DEBUG "调试" #define D_DEWPOINT "Dew point" #define D_DISABLED "禁用" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "距离" #define D_DNS_SERVER "DNS服务器" #define D_DO "Disolved Oxygen" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 1d828e7a0..53172c1aa 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -83,6 +83,9 @@ #define D_DEBUG "偵錯" #define D_DEWPOINT "Dew point" #define D_DISABLED "已停用" +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" #define D_DISTANCE "距離" #define D_DNS_SERVER "DNS伺服器" #define D_DO "Disolved Oxygen" diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino new file mode 100644 index 000000000..144b434bf --- /dev/null +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -0,0 +1,381 @@ +/* + xsns_102_ld2410.ino - HLK-LD2410 24GHz smart wave motion sensor support for Tasmota + + SPDX-FileCopyrightText: 2022 Theo Arends + + SPDX-License-Identifier: GPL-3.0-only +*/ + +#ifdef USE_LD2410 +/*********************************************************************************************\ + * HLK-LD2410 24GHz smart wave motion sensor + * + * Inspiration: + * https://community.home-assistant.io/t/mmwave-wars-one-sensor-module-to-rule-them-all/453260/2 + * Resources: + * https://drive.google.com/drive/folders/1p4dhbEJA3YubyIjIIC7wwVsSo8x29Fq-?spm=a2g0o.detail.1000023.17.93465697yFwVxH + * + * Basic comms using Serial Bridge: + * sbaudrate 256000 + * serialdelimiter 254 + * sserialsend5 FDFCFBFA0400FF00010004030201 -> {"SSerialReceived":"FDFCFBFA0800FF0100000100400004030201"} + * sserialsend5 FDFCFBFA0200610004030201 -> {"SSerialReceived":"FDFCFBFA1C0061010000AA0808083232281E140F0F0F0F000028281E1E141414050004030201"} + * sserialsend5 FDFCFBFA0200A00004030201 -> {"SSerialReceived":"FDFCFBFA0C00A0010000000107011615092204030201"} +\*********************************************************************************************/ + +#define XSNS_102 102 + +#define LD2410_CMND_START_CONFIGURATION 0xFF +#define LD2410_CMND_END_CONFIGURATION 0xFE +#define LD2410_CMND_SET_DISTANCE 0x60 +#define LD2410_CMND_READ_PARAMETERS 0x61 +#define LD2410_CMND_START_ENGINEERING 0x62 +#define LD2410_CMND_END_ENGINEERING 0x63 +#define LD2410_CMND_SET_SENSITIVITY 0x64 +#define LD2410_CMND_GET_FIRMWARE 0xA0 +#define LD2410_CMND_SET_BAUDRATE 0xA1 +#define LD2410_CMND_FACTORY_RESET 0xA2 +#define LD2410_CMND_REBOOT 0xA3 + +const uint8_t LD2410_config_header[4] = {0xFD, 0xFC, 0xFB, 0xFA}; +const uint8_t LD2410_config_footer[4] = {0x04, 0x03, 0x02, 0x01}; +const uint8_t LD2410_target_header[4] = {0xF4, 0xF3, 0xF2, 0xF1}; +const uint8_t LD2410_target_footer[4] = {0xF8, 0xF7, 0xF6, 0xF5}; + +#include +TasmotaSerial *LD2410Serial = nullptr; + +struct { + uint8_t *buffer; + uint16_t moving_distance; + uint16_t static_distance; + uint16_t detect_distance; + uint8_t moving_energy; + uint8_t static_energy; + uint8_t init_step; + uint8_t init_retry; + uint8_t byte_counter; + bool valid_response; +} LD2410; + +/********************************************************************************************/ + +uint32_t ToBcd(uint32_t value) { + return ((value >> 4) * 10) + (value & 0xF); +} + +/********************************************************************************************/ + +void Ld1410HandleTargetData(void) { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + // F4 F3 F2 F1 0D 00 02 AA 00 00 00 00 00 00 37 00 00 55 00 F8 F7 F6 F5 - No target + // F4 F3 F2 F1 0D 00 02 AA 00 45 00 3E 00 00 3A 00 00 55 00 F8 F7 F6 F5 - No target + // F4 F3 F2 F1 0D 00 02 AA 03 46 00 34 00 00 3C 00 00 55 00 F8 F7 F6 F5 - Movement and Stationary target + // F4 F3 F2 F1 0D 00 02 AA 02 54 00 00 00 00 64 00 00 55 00 F8 F7 F6 F5 - Stationary target + // F4 F3 F2 F1 0D 00 02 AA 02 96 00 00 00 00 36 00 00 55 00 F8 F7 F6 F5 - Stationary target + // F4 F3 F2 F1 0D 00 02 AA 03 2A 00 64 00 00 64 00 00 55 00 F8 F7 F6 F5 - Movement and Stationary target + // header |len |dt|hd|st|movin|me|stati|se|detec|tr|ck|trailer + if (LD2410.buffer[8] != 0x00) { // Movement and/or Stationary target + LD2410.moving_distance = LD2410.buffer[10] << 8 | LD2410.buffer[9]; + LD2410.moving_energy = LD2410.buffer[11]; + LD2410.static_distance = LD2410.buffer[13] << 8 | LD2410.buffer[12]; + LD2410.static_energy = LD2410.buffer[14]; + LD2410.detect_distance = LD2410.buffer[16] << 8 | LD2410.buffer[15]; + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Type %d, State %d, Moving %d/%d%%, Static %d/%d%%, Detect %d"), + LD2410.buffer[6], LD2410.buffer[8], + LD2410.moving_distance, LD2410.moving_energy, + LD2410.static_distance, LD2410.static_energy, + LD2410.detect_distance); + + if (0x01 == LD2410.buffer[6]) { // Engineering mode data + // Adds 22 extra bytes of data + + } + } else { + LD2410.moving_distance = 0; + LD2410.moving_energy = 0; + LD2410.static_distance = 0; + LD2410.static_energy = 0; + LD2410.detect_distance = 0; + } +} + +void Ld1410HandleConfigData(void) { + if (LD2410_CMND_READ_PARAMETERS == LD2410.buffer[6]) { // 0x61 + // 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 + // FD FC FB FA 1C 00 61 01 00 00 AA 08 08 08 32 32 28 1E 14 0F 0F 0F 0F 00 00 28 28 1E 1E 14 14 14 05 00 04 03 02 01 - Default + // header |len |cw cv|ack |hd|dd|md|sd|moving sensitivity 0..8 |static sensitivity 0..8 |timed|trailer + // | 28| | 0| | 8| 8| 8|50 50 40 30 20 15 15 15 15| 0 0 40 40 30 30 20 20 20| 5| + + + } + else if (LD2410_CMND_START_CONFIGURATION == LD2410.buffer[6]) { // 0xFF + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 + // FD FC FB FA 08 00 FF 01 00 00 01 00 40 00 04 03 02 01 + // header |len |ty |ack |protv|bsize|trailer + // | 8| | 0| 1| 64| + LD2410.valid_response = true; + } + else if (LD2410_CMND_GET_FIRMWARE == LD2410.buffer[6]) { // 0xA0 + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 + // FD FC FB FA 0C 00 A0 01 00 00 00 01 07 01 16 15 09 22 04 03 02 01 + // header |len |ty|hd|ack |ftype|major|minor |trailer + // | 12| | 1| 0| 256| 1.7| 22091516| + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Firmware version V%d.%02d.%02d%02d%02d%02d"), // Firmware version V1.07.22091516 + ToBcd(LD2410.buffer[13]), ToBcd(LD2410.buffer[12]), + ToBcd(LD2410.buffer[17]), ToBcd(LD2410.buffer[16]), ToBcd(LD2410.buffer[15]), ToBcd(LD2410.buffer[14])); + } +} + +bool Ld2410Match(const uint8_t *header, uint32_t offset) { + for (uint32_t i = 0; i < 4; i++) { + if (LD2410.buffer[offset +i] != header[i]) { return false; } + } + return true; +} + +void Ld2410Input(void) { + while (LD2410Serial->available()) { + yield(); // Fix watchdogs + + LD2410.buffer[LD2410.byte_counter++] = LD2410Serial->read(); + if (LD2410.byte_counter < 4) { continue; } // Need first four header bytes + + uint32_t header_start = LD2410.byte_counter -4; // Fix interrupted header transmits + bool target_header = (Ld2410Match(LD2410_target_header, header_start)); // F4F3F2F1 + bool config_header = (Ld2410Match(LD2410_config_header, header_start)); // FDFCFBFA + if ((target_header || config_header) && (header_start != 0)) { + memmove(LD2410.buffer, LD2410.buffer + header_start, 4); // Sync buffer with header + LD2410.byte_counter = 4; + } + if (LD2410.byte_counter < 6) { continue; } // Need packet size bytes + + target_header = (Ld2410Match(LD2410_target_header, 0)); // F4F3F2F1 + config_header = (Ld2410Match(LD2410_config_header, 0)); // FDFCFBFA + if (target_header || config_header) { + uint32_t len = LD2410.buffer[4] +10; // Total packet size + if (len > TM_SERIAL_BUFFER_SIZE) { len = TM_SERIAL_BUFFER_SIZE; } + if (LD2410.byte_counter < len) { continue; } // Need complete packet + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); + + if (target_header) { // F4F3F2F1 + if (Ld2410Match(LD2410_target_footer, len -4)) { // F8F7F6F5 + Ld1410HandleTargetData(); + } + } + else if (config_header) { // FDFCFBFA + if (Ld2410Match(LD2410_config_footer, len -4)) { // 04030201 + Ld1410HandleConfigData(); + } + } + } + LD2410.byte_counter = 0; + } +} + +void Ld2410SendCommand(uint32_t command, uint8_t *val = nullptr, uint32_t val_len = 0); +void Ld2410SendCommand(uint32_t command, uint8_t *val, uint32_t val_len) { + uint32_t len = val_len +12; + uint8_t buffer[len]; + buffer[0] = 0xFD; + buffer[1] = 0xFC; + buffer[2] = 0xFB; + buffer[3] = 0xFA; + buffer[4] = val_len +2; + buffer[5] = 0x00; + buffer[6] = command; + buffer[7] = 0x00; + if (val) { + for (uint32_t i = 0; i < val_len; i++) { + buffer[8 +i] = val[i]; + } + } + buffer[8 +val_len] = 0x04; + buffer[9 +val_len] = 0x03; + buffer[10 +val_len] = 0x02; + buffer[11 +val_len] = 0x01; + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Send %*_H"), len, buffer); + + LD2410Serial->flush(); + LD2410Serial->write(buffer, len); +// LD2410Serial->flush(); +} + +void Ld2410SetConfigMode(bool state) { + if (state) { + uint8_t value[2] = { 0x01, 0x00 }; + Ld2410SendCommand(LD2410_CMND_START_CONFIGURATION, value, sizeof(value)); + } else { + Ld2410SendCommand(LD2410_CMND_END_CONFIGURATION, nullptr, 0); + } +} + +void Ld2410SetBaudrate(uint32_t index) { + uint8_t value[2] = { (uint8_t)index, 0x00 }; + Ld2410SendCommand(LD2410_CMND_SET_BAUDRATE, value, sizeof(value)); +} + +void Ld2410SetAllSensitivity(uint32_t sensitivity) { + // 00 00 FF FF 00 00 01 00 28 00 00 00 02 00 28 00 00 00 + // gates|all gates |motio|sensitivity|stati|sensitivity + uint8_t lsb = sensitivity & 0xFF; + uint8_t msb = (sensitivity >> 8) & 0xFF; + uint8_t value[18] = { 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, lsb, msb, 0x00, 0x00, 0x02, 0x00, lsb, msb, 0x00, 0x00 }; + Ld2410SendCommand(LD2410_CMND_SET_SENSITIVITY, value, sizeof(value)); +} + +/********************************************************************************************/ + +void Ld2410Every250MSecond(void) { + if (LD2410.init_step) { + LD2410.init_step--; + switch (LD2410.init_step) { +/* + // POC using 57600 bps instead of default 256000 bps + case 20: + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Switch to 57600 bps")); + LD2410Serial->flush(); + LD2410Serial->begin(256000); + break; + case 19: + Ld2410SetConfigMode(1); // Stop running mode + break; + case 16: + Ld2410SetBaudrate(4); // 57600 bps + break; + case 14: + Ld2410SendCommand(LD2410_CMND_REBOOT, nullptr, 0); + LD2410Serial->flush(); + LD2410Serial->begin(57600); + break; +*/ + case 10: + Ld2410SetConfigMode(1); // Stop running mode + break; + case 7: + if (!LD2410.valid_response && LD2410.init_retry) { + LD2410.init_retry--; + if (LD2410.init_retry) { +// LD2410.init_step = 21; // Change baudrate + LD2410.init_step = 13; // Retry + } else { + LD2410.init_step = 0; + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Not detected")); + } + } else { + Ld2410SendCommand(LD2410_CMND_GET_FIRMWARE); + } + break; + case 4: + Ld2410SendCommand(LD2410_CMND_READ_PARAMETERS); + break; + case 1: + Ld2410SetConfigMode(0); + break; + } + } else { +/* + // Four times a second might be too much to handle by rules + if (LD2410.moving_energy) { + // Send state change to be captured by rules + // {"Time":"2022-11-26T10:48:16","Switch1":"ON","LD2410":{"Distance":[125.0,0.0,0.0],"Energy":[0,100]}} + MqttPublishSensor(); + } +*/ + } +} + +void Ld2410EverySecond(void) { + if (LD2410.moving_energy) { + // Send state change to be captured by rules + // {"Time":"2022-11-26T10:48:16","Switch1":"ON","LD2410":{"Distance":[125.0,0.0,0.0],"Energy":[0,100]}} + MqttPublishSensor(); + } +} + +void Ld2410Detect(void) { + if (PinUsed(GPIO_LD2410_RX) && PinUsed(GPIO_LD2410_TX)) { + LD2410.buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE); + if (!LD2410.buffer) { return; } + LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2); // Default TM_SERIAL_BUFFER_SIZE (=64) size + if (LD2410Serial->begin(256000)) { + if (LD2410Serial->hardwareSerial()) { ClaimSerial(); } + + LD2410.init_retry = 5; + LD2410.init_step = 13; + } + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + + + + +/*********************************************************************************************\ + * Presentation +\*********************************************************************************************/ + +#ifdef USE_WEBSERVER +const char HTTP_SNS_LD2410_CM[] PROGMEM = + "{s}LD2410 " D_MOVING_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}" + "{s}LD2410 " D_STATIC_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}" + "{s}LD2410 " D_DETECT_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}"; +#endif + +void Ld2410Show(bool json) { + float moving_distance = LD2410.moving_distance; + float static_distance = LD2410.static_distance; + float detect_distance = LD2410.detect_distance; + if (json) { + // cm cm cm % % + ResponseAppend_P(PSTR(",\"LD2410\":{\"" D_JSON_DISTANCE "\":[%1_f,%1_f,%1_f],\"" D_JSON_ENERGY "\":[%d,%d]}"), + &moving_distance, &static_distance, &detect_distance, LD2410.moving_energy, LD2410.static_energy); +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_LD2410_CM, &moving_distance, &static_distance, &detect_distance); +#endif + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns102(uint32_t function) { + bool result = false; + + if (FUNC_INIT == function) { + Ld2410Detect(); + } + else if (LD2410Serial) { + switch (function) { + case FUNC_LOOP: + case FUNC_SLEEP_LOOP: + Ld2410Input(); + break; + case FUNC_EVERY_250_MSECOND: + Ld2410Every250MSecond(); + break; + case FUNC_EVERY_SECOND: + Ld2410EverySecond(); + break; + case FUNC_JSON_APPEND: + Ld2410Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + Ld2410Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_LD2410 From 18453eec97ae8b136eaac6dc530a8d8e1d81dc23 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 26 Nov 2022 17:17:59 +0100 Subject: [PATCH 273/319] Add config commands to POC LD2410 --- .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 250 +++++++++++++----- 1 file changed, 186 insertions(+), 64 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino index 144b434bf..535246108 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -10,21 +10,25 @@ /*********************************************************************************************\ * HLK-LD2410 24GHz smart wave motion sensor * + * LD2410Duration 0 - Set factory default settings + * LD2410Duration 1..65535 - Set no-one duration in seconds (default 5) + * LD2410MovingSens 50,50,40,30,20,15,15,15,15 - Set moving distance sensitivity for up to 9 gates (at 0.75 meter interval) + * LD2410StaticSens 0,0,40,40,30,30,20,20,20 - Set static distance sensitivity for up to 9 gates (at 0.75 meter interval) + * * Inspiration: * https://community.home-assistant.io/t/mmwave-wars-one-sensor-module-to-rule-them-all/453260/2 * Resources: * https://drive.google.com/drive/folders/1p4dhbEJA3YubyIjIIC7wwVsSo8x29Fq-?spm=a2g0o.detail.1000023.17.93465697yFwVxH * - * Basic comms using Serial Bridge: - * sbaudrate 256000 - * serialdelimiter 254 - * sserialsend5 FDFCFBFA0400FF00010004030201 -> {"SSerialReceived":"FDFCFBFA0800FF0100000100400004030201"} - * sserialsend5 FDFCFBFA0200610004030201 -> {"SSerialReceived":"FDFCFBFA1C0061010000AA0808083232281E140F0F0F0F000028281E1E141414050004030201"} - * sserialsend5 FDFCFBFA0200A00004030201 -> {"SSerialReceived":"FDFCFBFA0C00A0010000000107011615092204030201"} + * Internal info: + * - After a LD2410 serial command a response takes 50mS + * - After a LD2410 restart it takes at least 1000mS before commands are allowed \*********************************************************************************************/ #define XSNS_102 102 +#define LD2410_MAX_GATES 8 // 0 to 8 (= 9) - DO NOT CHANGE + #define LD2410_CMND_START_CONFIGURATION 0xFF #define LD2410_CMND_END_CONFIGURATION 0xFE #define LD2410_CMND_SET_DISTANCE 0x60 @@ -50,11 +54,17 @@ struct { uint16_t moving_distance; uint16_t static_distance; uint16_t detect_distance; + uint16_t no_one_duration; + uint8_t moving_sensitivity[LD2410_MAX_GATES +1]; + uint8_t static_sensitivity[LD2410_MAX_GATES +1]; + uint8_t max_moving_distance_gate; + uint8_t max_static_distance_gate; uint8_t moving_energy; uint8_t static_energy; - uint8_t init_step; - uint8_t init_retry; + uint8_t step; + uint8_t retry; uint8_t byte_counter; + uint8_t settings; bool valid_response; } LD2410; @@ -107,8 +117,13 @@ void Ld1410HandleConfigData(void) { // FD FC FB FA 1C 00 61 01 00 00 AA 08 08 08 32 32 28 1E 14 0F 0F 0F 0F 00 00 28 28 1E 1E 14 14 14 05 00 04 03 02 01 - Default // header |len |cw cv|ack |hd|dd|md|sd|moving sensitivity 0..8 |static sensitivity 0..8 |timed|trailer // | 28| | 0| | 8| 8| 8|50 50 40 30 20 15 15 15 15| 0 0 40 40 30 30 20 20 20| 5| - - + LD2410.max_moving_distance_gate = LD2410.buffer[12]; + LD2410.max_static_distance_gate = LD2410.buffer[13]; + for (uint32_t i = 0; i <= LD2410_MAX_GATES; i++) { + LD2410. moving_sensitivity[i] = LD2410.buffer[14 +i]; + LD2410.static_sensitivity[i] = LD2410.buffer[23 +i]; + } + LD2410.no_one_duration = LD2410.buffer[33] << 8 | LD2410.buffer[32]; } else if (LD2410_CMND_START_CONFIGURATION == LD2410.buffer[6]) { // 0xFF // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @@ -122,7 +137,7 @@ void Ld1410HandleConfigData(void) { // FD FC FB FA 0C 00 A0 01 00 00 00 01 07 01 16 15 09 22 04 03 02 01 // header |len |ty|hd|ack |ftype|major|minor |trailer // | 12| | 1| 0| 256| 1.7| 22091516| - AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Firmware version V%d.%02d.%02d%02d%02d%02d"), // Firmware version V1.07.22091516 + AddLog(LOG_LEVEL_INFO, PSTR("LD2: Firmware version V%d.%02d.%02d%02d%02d%02d"), // Firmware version V1.07.22091516 ToBcd(LD2410.buffer[13]), ToBcd(LD2410.buffer[12]), ToBcd(LD2410.buffer[17]), ToBcd(LD2410.buffer[16]), ToBcd(LD2410.buffer[15]), ToBcd(LD2410.buffer[14])); } @@ -201,90 +216,135 @@ void Ld2410SendCommand(uint32_t command, uint8_t *val, uint32_t val_len) { LD2410Serial->flush(); LD2410Serial->write(buffer, len); -// LD2410Serial->flush(); } -void Ld2410SetConfigMode(bool state) { - if (state) { - uint8_t value[2] = { 0x01, 0x00 }; - Ld2410SendCommand(LD2410_CMND_START_CONFIGURATION, value, sizeof(value)); - } else { - Ld2410SendCommand(LD2410_CMND_END_CONFIGURATION, nullptr, 0); - } +void Ld2410SetConfigMode(void) { // 0xFF + uint8_t value[2] = { 0x01, 0x00 }; + Ld2410SendCommand(LD2410_CMND_START_CONFIGURATION, value, sizeof(value)); } -void Ld2410SetBaudrate(uint32_t index) { +void Ld2410SetMaxDistancesAndNoneDuration(uint32_t max_moving_distance_range, uint32_t max_static_distance_range, uint32_t no_one_duration) { // 0x60 + // Distance range value can be set from 1 to 8 (distance gates of 0.75 meter) + // No-one duration value can be set from 1 to 65535 (seconds) + // 00 00 08 00 00 00 01 00 08 00 00 00 02 00 05 00 00 00 + // motio| 8|stati| 8|durat|seconds + uint8_t lsb_nd = no_one_duration & 0xFF; + uint8_t msb_nd = (no_one_duration >> 8) & 0xFF; + uint8_t value[18] = { 0x00, 0x00, (uint8_t)max_moving_distance_range, 0x00, 0x00, 0x00, 0x01, 0x00, (uint8_t)max_static_distance_range, 0x00, 0x00, 0x00, 0x02, 0x00, lsb_nd, msb_nd, 0x00, 0x00 }; + Ld2410SendCommand(LD2410_CMND_SET_DISTANCE, value, sizeof(value)); +} + +void Ld2410SetGateSensitivity(uint32_t gate, uint32_t moving_sensitivity, uint32_t static_sensitivity) { // 0x64 + // Sensitivity value can be set from 0 to 100 (%) for gates 0 to 8 + // 00 00 03 00 00 00 01 00 28 00 00 00 02 00 28 00 00 00 + // gate | 3|motio| 40|stati| 40 + uint8_t value[18] = { 0x00, 0x00, (uint8_t)gate, 0x00, 0x00, 0x00, 0x01, 0x00, (uint8_t)moving_sensitivity, 0x00, 0x00, 0x00, 0x02, 0x00, (uint8_t)static_sensitivity, 0x00, 0x00, 0x00 }; + Ld2410SendCommand(LD2410_CMND_SET_SENSITIVITY, value, sizeof(value)); +} + +void Ld2410SetAllSensitivity(uint32_t sensitivity) { // 0x64 + // Sensitivity value can be set from 0 to 100 + // 00 00 FF FF 00 00 01 00 28 00 00 00 02 00 28 00 00 00 + // gate |all gates |motio| 40|stati| 40 + uint8_t value[18] = { 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, (uint8_t)sensitivity, 0x00, 0x00, 0x00, 0x02, 0x00, (uint8_t)sensitivity, 0x00, 0x00, 0x00 }; + Ld2410SendCommand(LD2410_CMND_SET_SENSITIVITY, value, sizeof(value)); +} + +void Ld2410SetBaudrate(uint32_t index) { // 0xA1 uint8_t value[2] = { (uint8_t)index, 0x00 }; Ld2410SendCommand(LD2410_CMND_SET_BAUDRATE, value, sizeof(value)); } -void Ld2410SetAllSensitivity(uint32_t sensitivity) { - // 00 00 FF FF 00 00 01 00 28 00 00 00 02 00 28 00 00 00 - // gates|all gates |motio|sensitivity|stati|sensitivity - uint8_t lsb = sensitivity & 0xFF; - uint8_t msb = (sensitivity >> 8) & 0xFF; - uint8_t value[18] = { 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, lsb, msb, 0x00, 0x00, 0x02, 0x00, lsb, msb, 0x00, 0x00 }; - Ld2410SendCommand(LD2410_CMND_SET_SENSITIVITY, value, sizeof(value)); -} - /********************************************************************************************/ -void Ld2410Every250MSecond(void) { - if (LD2410.init_step) { - LD2410.init_step--; - switch (LD2410.init_step) { +void Ld2410Every100MSecond(void) { + if (LD2410.step) { + LD2410.step--; + switch (LD2410.step) { + // case 60: Set default settings + case 59: + Ld2410SetConfigMode(); // Stop running mode + break; + case 57: + Ld2410SendCommand(LD2410_CMND_FACTORY_RESET); + break; + case 56: + Ld2410SendCommand(LD2410_CMND_REBOOT); // Wait at least 1 second + break; + case 46: + LD2410.step = 7; + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Settings factory reset")); + break; + + // case 40: Save settings + case 39: + Ld2410SetConfigMode(); // Stop running mode + break; + case 37: + Ld2410SetMaxDistancesAndNoneDuration(8, 8, LD2410.no_one_duration); + break; + case 28 ... 36: { + uint32_t index = LD2410.step -28; + Ld2410SetGateSensitivity(index, LD2410.moving_sensitivity[index], LD2410.static_sensitivity[index]); + } + break; + case 27: + LD2410.step = 3; + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Settings saved")); + break; /* - // POC using 57600 bps instead of default 256000 bps - case 20: + // case 24: pre-POC using 57600 bps instead of default 256000 bps + case 23: AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Switch to 57600 bps")); LD2410Serial->flush(); LD2410Serial->begin(256000); break; - case 19: - Ld2410SetConfigMode(1); // Stop running mode + case 21: + Ld2410SetConfigMode(); // Stop running mode break; - case 16: + case 19: Ld2410SetBaudrate(4); // 57600 bps break; - case 14: - Ld2410SendCommand(LD2410_CMND_REBOOT, nullptr, 0); + case 18: + Ld2410SendCommand(LD2410_CMND_REBOOT); // Wait at least 1 second LD2410Serial->flush(); LD2410Serial->begin(57600); break; */ - case 10: - Ld2410SetConfigMode(1); // Stop running mode + // case 7: Init + case 5: + Ld2410SetConfigMode(); // Stop running mode break; - case 7: - if (!LD2410.valid_response && LD2410.init_retry) { - LD2410.init_retry--; - if (LD2410.init_retry) { -// LD2410.init_step = 21; // Change baudrate - LD2410.init_step = 13; // Retry + case 3: + if (!LD2410.valid_response && LD2410.retry) { + LD2410.retry--; + if (LD2410.retry) { +// LD2410.step = 24; // Change baudrate + LD2410.step = 7; // Retry } else { - LD2410.init_step = 0; + LD2410.step = 0; AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Not detected")); } } else { Ld2410SendCommand(LD2410_CMND_GET_FIRMWARE); } break; - case 4: + case 2: Ld2410SendCommand(LD2410_CMND_READ_PARAMETERS); break; case 1: - Ld2410SetConfigMode(0); + Ld2410SendCommand(LD2410_CMND_END_CONFIGURATION); break; } } else { -/* - // Four times a second might be too much to handle by rules - if (LD2410.moving_energy) { - // Send state change to be captured by rules - // {"Time":"2022-11-26T10:48:16","Switch1":"ON","LD2410":{"Distance":[125.0,0.0,0.0],"Energy":[0,100]}} - MqttPublishSensor(); + if (1 == LD2410.settings) { + LD2410.settings = 0; + LD2410.step = 40; + } + else if (2 == LD2410.settings) { + LD2410.settings = 0; + LD2410.step = 60; } -*/ } } @@ -298,14 +358,14 @@ void Ld2410EverySecond(void) { void Ld2410Detect(void) { if (PinUsed(GPIO_LD2410_RX) && PinUsed(GPIO_LD2410_TX)) { - LD2410.buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE); + LD2410.buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE); // Default TM_SERIAL_BUFFER_SIZE (=64) size if (!LD2410.buffer) { return; } - LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2); // Default TM_SERIAL_BUFFER_SIZE (=64) size + LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2); if (LD2410Serial->begin(256000)) { if (LD2410Serial->hardwareSerial()) { ClaimSerial(); } - LD2410.init_retry = 5; - LD2410.init_step = 13; + LD2410.retry = 4; + LD2410.step = 7; } } } @@ -314,8 +374,67 @@ void Ld2410Detect(void) { * Commands \*********************************************************************************************/ +const char kLd2410Commands[] PROGMEM = "LD2410|" // Prefix + "Duration|MovingSens|StaticSens"; +void (* const Ld2410Command[])(void) PROGMEM = { + &CmndLd2410Duration, &CmndLd2410MovingSensitivity, &CmndLd2410StaticSensitivity }; +void Ld2410Response(void) { + Response_P(PSTR("{\"LD2410\":{\"Duration\":%d,\"Moving\":{\"Gates\":%d,\"Sensitivity\":["), + LD2410.no_one_duration, LD2410.max_moving_distance_gate); + for (uint32_t i = 0; i <= LD2410_MAX_GATES; i++) { + ResponseAppend_P(PSTR("%s%d"), (i==0)?"":",", LD2410.moving_sensitivity[i]); + } + ResponseAppend_P(PSTR("]},\"Static\":{\"Gates\":%d,\"Sensitivity\":["), LD2410.max_static_distance_gate); + for (uint32_t i = 0; i <= LD2410_MAX_GATES; i++) { + ResponseAppend_P(PSTR("%s%d"), (i==0)?"":",", LD2410.static_sensitivity[i]); + } + ResponseAppend_P(PSTR("]}}}")); +} + +void CmndLd2410Duration(void) { + // LD2410Duration 0 - Set default settings + if (0 == XdrvMailbox.payload) { + LD2410.settings = 2; + } + // LD2410Duration 5 + else if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 65535)) { + LD2410.no_one_duration = XdrvMailbox.payload; + LD2410.settings = 1; + } + Ld2410Response(); +} + +void CmndLd2410MovingSensitivity(void) { + // LD2410MovingSens 50,50,40,30,20,15,15,15,15 + uint32_t parm[LD2410_MAX_GATES +1] = { 0 }; + uint32_t count = ParseParameters(LD2410_MAX_GATES +1, parm); + if (count) { + for (uint32_t i = 0; i < count; i++) { + if ((parm[i] >= 0) && (parm[i] <= 100)) { + LD2410.moving_sensitivity[i] = parm[i]; + } + } + LD2410.settings = 1; + } + Ld2410Response(); +} + +void CmndLd2410StaticSensitivity(void) { + // LD2410StaticSens 0,0,40,40,30,30,20,20,20 + uint32_t parm[LD2410_MAX_GATES +1] = { 0 }; + uint32_t count = ParseParameters(LD2410_MAX_GATES +1, parm); + if (count) { + for (uint32_t i = 0; i < count; i++) { + if ((parm[i] >= 0) && (parm[i] <= 100)) { + LD2410.static_sensitivity[i] = parm[i]; + } + } + LD2410.settings = 1; + } + Ld2410Response(); +} /*********************************************************************************************\ * Presentation @@ -359,8 +478,8 @@ bool Xsns102(uint32_t function) { case FUNC_SLEEP_LOOP: Ld2410Input(); break; - case FUNC_EVERY_250_MSECOND: - Ld2410Every250MSecond(); + case FUNC_EVERY_100_MSECOND: + Ld2410Every100MSecond(); break; case FUNC_EVERY_SECOND: Ld2410EverySecond(); @@ -373,6 +492,9 @@ bool Xsns102(uint32_t function) { Ld2410Show(0); break; #endif // USE_WEBSERVER + case FUNC_COMMAND: + result = DecodeCommand(kLd2410Commands, Ld2410Command); + break; } } return result; From 53563d44d8b8e78b8f59e574253cc91b7517a97e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 26 Nov 2022 17:49:25 +0100 Subject: [PATCH 274/319] Add support for HLK-LD2410 24GHz smart wave motion sensor Add support for HLK-LD2410 24GHz smart wave motion sensor --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/my_user_config.h | 1 + tasmota/tasmota_support/support_features.ino | 4 +++- tools/decode-status.py | 4 ++-- 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2cc5933f..3928ddfb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - 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) - Teleinfo TEMPO (BBR) contract (#17160) +- Support for HLK-LD2410 24GHz smart wave motion sensor ### Breaking Changed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 77a0ae6b6..5e456c5c2 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -118,6 +118,7 @@ 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) - 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 HLK-LD2410 24GHz smart wave motion sensor - 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) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 3cd730dd6..9cd29bb80 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -811,6 +811,7 @@ //#define USE_VINDRIKTNING // Add support for IKEA VINDRIKTNING particle concentration sensor (+0k6 code) // #define VINDRIKTNING_SHOW_PM1 // Display undocumented/supposed PM1.0 values // #define VINDRIKTNING_SHOW_PM10 // Display undocumented/supposed PM10 values +//#define USE_LD2410 // Add support for HLK-LD2410 24GHz smart wave motion sensor (+2k8 code) // -- Power monitoring sensors -------------------- #define USE_ENERGY_SENSOR // Add support for Energy Monitors (+14k code) diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino index e337b2a90..b70ed8c93 100644 --- a/tasmota/tasmota_support/support_features.ino +++ b/tasmota/tasmota_support/support_features.ino @@ -855,7 +855,9 @@ void ResponseAppendFeatures(void) #if defined(USE_I2C) && defined(USE_HMC5883L) feature9 |= 0x00000200; // xsns_101_hmc5883l.ino #endif -// feature9 |= 0x00000400; +#ifdef USE_LD2410 + feature9 |= 0x00000400; // xsns_102_ld2410.ino +#endif // feature9 |= 0x00000800; // feature9 |= 0x00001000; diff --git a/tools/decode-status.py b/tools/decode-status.py index 5780173b3..06cab64e5 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_HMC5883L","","", + "USE_DINGTIAN_RELAY","USE_HMC5883L","USE_LD2410","", "","","","", "","","","", "","","","", @@ -321,7 +321,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v12.2.0.4 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v12.2.0.5 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From ac52f67c7eb3eb9e4d600a2da82765b267b218a6 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Sun, 27 Nov 2022 08:52:45 +0100 Subject: [PATCH 275/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 65a356b8f..5592ac8e9 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 10.11.2022 + * Updated until v9.4.0.1 - Last update 27.11.2022 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -83,9 +83,9 @@ #define D_DEBUG "Debug" #define D_DEWPOINT "Punto rugiada" // #define D_DISABLED "Disabilitato/a" -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_DISTANCE "Distanza in movimento" +#define D_STATIC_DISTANCE "Distanza statica" +#define D_DETECT_DISTANCE "Rileva distanza" #define D_DISTANCE "Distanza" #define D_DNS_SERVER "Server DNS" #define D_DO "Ossigeno dissolto" From 220a03f04376622cf3348e217520f4cb7a9c9a50 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 27 Nov 2022 12:11:48 +0100 Subject: [PATCH 276/319] Add LD2410 debugging info --- .../TasmotaSerial-3.5.0/src/TasmotaSerial.cpp | 19 ++++++++++++++++ .../TasmotaSerial-3.5.0/src/TasmotaSerial.h | 4 +++- tasmota/tasmota.ino | 2 +- .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 22 ++++++++++++++----- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp index 82fce4934..ef72dce1c 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp @@ -48,6 +48,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal m_valid = false; m_hardserial = false; m_hardswap = false; + m_overflow = false; m_stop_bits = 1; m_nwmode = nwmode; serial_buffer_size = buffer_size; @@ -267,6 +268,21 @@ bool TasmotaSerial::hardwareSerial(void) { #endif // ESP32 } +bool TasmotaSerial::overflow(void) { + if (m_hardserial) { +#ifdef ESP8266 + return Serial.hasOverrun(); // Returns then clear overrun flag +#endif // ESP8266 +#ifdef ESP32 + return false; // Not implemented +#endif // ESP32 + } else { + bool res = m_overflow; + m_overflow = false; + return res; + } +} + void TasmotaSerial::flush(void) { if (m_hardserial) { #ifdef ESP8266 @@ -305,6 +321,7 @@ int TasmotaSerial::read(void) { #endif // ESP32 } else { if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1; +// m_overflow = false; uint32_t ch = m_buffer[m_out_pos]; m_out_pos = (m_out_pos +1) % serial_buffer_size; return ch; @@ -321,6 +338,7 @@ size_t TasmotaSerial::read(char* buffer, size_t size) { #endif // ESP32 } else { if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) { return 0; } +// m_overflow = false; size_t count = 0; for( ; size && (m_in_pos == m_out_pos) ; --size, ++count) { *buffer++ = m_buffer[m_out_pos]; @@ -427,6 +445,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { m_in_pos = next; } else { // Buffer overrun - exit and fix Hardware Watchdog in case of high speed flooding + m_overflow = true; break; } diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h index 759433d66..e62d75316 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h +++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h @@ -60,7 +60,8 @@ class TasmotaSerial : public Stream { #ifdef ESP32 uint32_t getUart(void) const { return m_uart; } #endif - bool isValid() { return m_valid; } + bool isValid(void) { return m_valid; } + bool overflow(void); using Print::write; @@ -89,6 +90,7 @@ class TasmotaSerial : public Stream { bool m_nwmode; bool m_hardserial; bool m_hardswap; + bool m_overflow; bool m_high_speed = false; bool m_very_high_speed = false; // above 100000 bauds uint8_t *m_buffer = nullptr; diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 137bd80c2..a90a1c069 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -683,7 +683,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); // Main purpose is reacting ASAP on serial data availability or interrupt handling (ADE7880) + XdrvXsnsCall(FUNC_SLEEP_LOOP); // Main purpose is reacting ASAP on serial data availability or interrupt handling (ADE7880) delay(1); } } else { diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino index 535246108..6975efda5 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -21,7 +21,7 @@ * https://drive.google.com/drive/folders/1p4dhbEJA3YubyIjIIC7wwVsSo8x29Fq-?spm=a2g0o.detail.1000023.17.93465697yFwVxH * * Internal info: - * - After a LD2410 serial command a response takes 50mS + * - After a LD2410 serial command a response takes about 10mS * - After a LD2410 restart it takes at least 1000mS before commands are allowed \*********************************************************************************************/ @@ -40,6 +40,8 @@ #define LD2410_CMND_SET_BAUDRATE 0xA1 #define LD2410_CMND_FACTORY_RESET 0xA2 #define LD2410_CMND_REBOOT 0xA3 +#define LD2410_CMND_SET_BLUETOOTH 0xA4 +#define LD2410_CMND_GET_BLUETOOTH_MAC 0xA5 const uint8_t LD2410_config_header[4] = {0xFD, 0xFC, 0xFB, 0xFA}; const uint8_t LD2410_config_footer[4] = {0x04, 0x03, 0x02, 0x01}; @@ -151,6 +153,11 @@ bool Ld2410Match(const uint8_t *header, uint32_t offset) { } void Ld2410Input(void) { + + if (LD2410Serial->overflow()) { + AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Serial buffer overrun")); + } + while (LD2410Serial->available()) { yield(); // Fix watchdogs @@ -178,6 +185,11 @@ void Ld2410Input(void) { if (target_header) { // F4F3F2F1 if (Ld2410Match(LD2410_target_footer, len -4)) { // F8F7F6F5 Ld1410HandleTargetData(); + + // Break to test Hardware Watchdog due to buffer overrun + LD2410.byte_counter = 0; + break; + } } else if (config_header) { // FDFCFBFA @@ -271,8 +283,8 @@ void Ld2410Every100MSecond(void) { case 56: Ld2410SendCommand(LD2410_CMND_REBOOT); // Wait at least 1 second break; - case 46: - LD2410.step = 7; + case 51: + LD2410.step = 12; AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Settings factory reset")); break; @@ -311,7 +323,7 @@ void Ld2410Every100MSecond(void) { LD2410Serial->begin(57600); break; */ - // case 7: Init + // case 12: Init case 5: Ld2410SetConfigMode(); // Stop running mode break; @@ -365,7 +377,7 @@ void Ld2410Detect(void) { if (LD2410Serial->hardwareSerial()) { ClaimSerial(); } LD2410.retry = 4; - LD2410.step = 7; + LD2410.step = 12; } } } From fe8229ea30bc27da8cadc4745b0a2150d1b8059f Mon Sep 17 00:00:00 2001 From: stefanbode Date: Sun, 27 Nov 2022 17:13:23 +0100 Subject: [PATCH 277/319] bugfix zero cross --- tasmota/tasmota_xsns_sensor/xsns_01_counter.ino | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino index 0ebb8663e..42ac79295 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino @@ -277,7 +277,7 @@ void SyncACDimmer(void) // reset trigger for PWM sync ac_zero_cross_dimmer.startReSync = false; // calculate timeoffset to fire PWM based on Dimmer - phaseStart_ToBeClockCycles = (ac_zero_cross_dimmer.tobe_cycle_timeClockCycles * (1024 - (Light.fade_running ? Light.fade_cur_10[i] : Light.fade_start_10[i]))) / 1024; + phaseStart_ToBeClockCycles = (ac_zero_cross_dimmer.tobe_cycle_timeClockCycles * (1024 - ac_zero_cross_power(Light.fade_running ? Light.fade_cur_10[i] : Light.fade_start_10[i]))) / 1024; // Limit range to avoid overshoot and undershoot phaseStart_ToBeClockCycles = tmin(tmax(phaseStart_ToBeClockCycles, 160000), 0.95* ac_zero_cross_dimmer.tobe_cycle_timeClockCycles); @@ -322,9 +322,8 @@ void SyncACDimmer(void) #endif // ESP32 - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("CNT: [%d], shift: %d, dimm_time_CCs %d, phaseShift_CCs %d, currentPWMcylce: %lu, current_cycle_CC: %lu, lastcc %lu, currentSteps %lu, currDIM %lu, last delta:%lu"), - i, ac_zero_cross_dimmer.currentShiftClockCycle[i], phaseStart_ToBeClockCycles,phaseShift_ClockCycles,ac_zero_cross_dimmer.currentPWMCycleCount[i],ac_zero_cross_dimmer.current_cycle_ClockCycles , ac_zero_cross_dimmer.lastCycleCount, ac_zero_cross_dimmer.currentSteps, Light.fade_cur_10[i],phaseStart_ActualClockCycles); - // Light fading + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("CNT: [%d], shift: %d, dimm_time_CCs %d, phaseShift_CCs %d, currentPWMcylce: %lu, current_cycle_CC: %lu, lastcc %lu, currentSteps %lu, currDIM %lu, last delta:%lu"), + i, ac_zero_cross_dimmer.currentShiftClockCycle[i], phaseStart_ToBeClockCycles,phaseShift_ClockCycles,ac_zero_cross_dimmer.currentPWMCycleCount[i],ac_zero_cross_dimmer.current_cycle_ClockCycles , ac_zero_cross_dimmer.lastCycleCount, ac_zero_cross_dimmer.currentSteps, Light.fade_cur_10[i],phaseStart_ActualClockCycles); // Light fading //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("CNT: [%d], curr: %d, final: %d, fading: %d, phase-shift: %d, ON/OFF: %d"),i, Light.fade_cur_10[i], Light.fade_start_10[i], Light.fade_running, phaseStart_ToBeClockCycles,ac_zero_cross_dimmer.PWM_ON[i]); } // do sync onchannel From 3446b0b78cb86149746c60a0f06648f99070bfa8 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Sun, 27 Nov 2022 17:14:51 +0100 Subject: [PATCH 278/319] bugfix --- .../xdrv_04_light_utils.ino | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino index 11c8359ba..e6254b1f8 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino @@ -32,15 +32,15 @@ typedef struct gamma_table_t { } gamma_table_t; const gamma_table_t ac_dimmer_table[] = { // don't put in PROGMEM for performance reasons - { 0, 0 }, - { 1, 64 }, - { 5, 144 }, - { 10, 205 }, - { 50, 500 }, - { 90, 795 }, - { 95, 866 }, - { 99, 936 }, - { 100, 1000 }, + { 0, 0 }, + { 10, 64 }, + { 50, 144 }, + { 100, 205 }, + { 500, 500 }, + { 900, 795 }, + { 950, 866 }, + { 990, 936 }, + { 1024, 1024 }, { 0xFFFF, 0xFFFF } // fail-safe if out of range }; @@ -333,7 +333,7 @@ uint16_t ledGammaReverse_internal(uint16_t vg, const struct gamma_table_t *gt_pt // 10 bits power select to 10 bits timing based on sinus curve uint16_t ac_zero_cross_power(uint16_t v) { - return ledGamma_internal(v, ac_dimmer_table)/10; + return ledGamma_internal(v, ac_dimmer_table); } // 10 bits in, 10 bits out From a0ed3838408cd2a62889d478d2885b666f244359 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 27 Nov 2022 18:08:53 +0100 Subject: [PATCH 279/319] Berry add module `mdns` --- CHANGELOG.md | 1 + lib/libesp32/berry/default/be_modtab.c | 4 + lib/libesp32/berry/src/be_api.c | 25 ++++ lib/libesp32/berry/src/berry.h | 2 + .../berry_tasmota/src/be_mdns_module.cpp | 122 ++++++++++++++++++ .../berry_tasmota/src/be_tasmota_lib.c | 2 + .../xdrv_52_3_berry_tasmota.ino | 8 ++ 7 files changed, 164 insertions(+) create mode 100644 lib/libesp32/berry_tasmota/src/be_mdns_module.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 3928ddfb3..4dad9ab1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - Command ``SetOption35 0..255`` to skip number of received messages in Serial Bridge (default 0) (#17140) - Teleinfo TEMPO (BBR) contract (#17160) - Support for HLK-LD2410 24GHz smart wave motion sensor +- Berry add module ``mdns`` ### Breaking Changed diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c index 5b018304e..62c38ab0c 100644 --- a/lib/libesp32/berry/default/be_modtab.c +++ b/lib/libesp32/berry/default/be_modtab.c @@ -50,6 +50,7 @@ be_extern_native_module(partition_core); be_extern_native_module(crc); be_extern_native_module(crypto); be_extern_native_module(ULP); +be_extern_native_module(mdns); #ifdef USE_ZIGBEE be_extern_native_module(zigbee); #endif // USE_ZIGBEE @@ -173,6 +174,9 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = { &be_native_module(MI32), &be_native_module(BLE), #endif //USE_MI_ESP32 +#ifdef USE_DISCOVERY + &be_native_module(mdns), +#endif // USE_DISCOVERY #endif // TASMOTA /* user-defined modules register end */ NULL /* do not remove */ diff --git a/lib/libesp32/berry/src/be_api.c b/lib/libesp32/berry/src/be_api.c index 763187430..fb2b8e017 100644 --- a/lib/libesp32/berry/src/be_api.c +++ b/lib/libesp32/berry/src/be_api.c @@ -208,6 +208,31 @@ BERRY_API bbool be_isinstance(bvm *vm, int index) return var_isinstance(v); } +static bbool be_isinstanceofbuiltin(bvm *vm, int rel_index, const char *classname) +{ + bbool ret = bfalse; + int index = be_absindex(vm, rel_index); + if (be_isinstance(vm, index)) { + be_getbuiltin(vm, classname); + if (be_isderived(vm, index)) { + ret = btrue; + } + be_pop(vm, 1); + } + return ret; +} + +BERRY_API bbool be_ismapinstance(bvm *vm, int index) +{ + return be_isinstanceofbuiltin(vm, index, "map"); +} + +BERRY_API bbool be_islistinstance(bvm *vm, int index) +{ + return be_isinstanceofbuiltin(vm, index, "list"); +} + + BERRY_API bbool be_ismodule(bvm *vm, int index) { bvalue *v = be_indexof(vm, index); diff --git a/lib/libesp32/berry/src/berry.h b/lib/libesp32/berry/src/berry.h index 6d48e87f2..70ab0f87c 100644 --- a/lib/libesp32/berry/src/berry.h +++ b/lib/libesp32/berry/src/berry.h @@ -464,6 +464,8 @@ BERRY_API bbool be_isfunction(bvm *vm, int index); BERRY_API bbool be_isproto(bvm *vm, int index); BERRY_API bbool be_isclass(bvm *vm, int index); BERRY_API bbool be_isinstance(bvm *vm, int index); +BERRY_API bbool be_ismapinstance(bvm *vm, int index); +BERRY_API bbool be_islistinstance(bvm *vm, int index); BERRY_API bbool be_ismodule(bvm *vm, int index); BERRY_API bbool be_islist(bvm *vm, int index); BERRY_API bbool be_ismap(bvm *vm, int index); diff --git a/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp b/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp new file mode 100644 index 000000000..d0c534d2b --- /dev/null +++ b/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp @@ -0,0 +1,122 @@ +/******************************************************************** + * Berry module `mdns` + * + * To use: `import mdns` + * + * MDNS support + *******************************************************************/ +#include "be_constobj.h" +#include "be_mapping.h" +#include "be_mem.h" + +#ifdef USE_DISCOVERY +#include "mdns.h" +#include + +// +// `mdsn.start([hostname:string]) -> nil` +extern char* NetworkHostname(void); +static void m_mdns_start(struct bvm *vm, const char* hostname) { + esp_err_t err = mdns_init(); + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "could not initialize mdns err=%i", err); + } + if (hostname == NULL) { + hostname = NetworkHostname(); // revert to default hostname if none is specified + } + err = mdns_hostname_set(hostname); + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "could not set hostname err=%i", err); + } +} +BE_FUNC_CTYPE_DECLARE(m_mdns_start, "", "@[s]") + +// +// `msdn.stop() -> nil`` +static void m_mdns_stop(void) { + mdns_free(); +} +BE_FUNC_CTYPE_DECLARE(m_mdns_stop, "", "") + + +static void m_mdns_set_hostname(struct bvm *vm, const char * hostname) { + esp_err_t err = mdns_hostname_set(hostname); + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "mdns set_hostname err=%i", err); + } +} +BE_FUNC_CTYPE_DECLARE(m_mdns_set_hostname, "", "@s") + +// +// `mdns.add_service(service:string, proto:string, port:int, txt:map) -> nil` +// +// Test: +// import mdns mdns.add_service("_arduino","_tcp",1111, {"board":"tasmota", "tcp_check":"no", "ssh_upload":"no", "auth_upload":"no"}) +// +// import mdns mdns.add_service("_matterc","_udp", 5540, {"VP":"65521+32768", "SII":5000, "SAI":300, "T":1, "D":3840, "CM":1, "PH":33, "PI":""}) +static int32_t m_mdns_add_service(struct bvm *vm) { + int32_t top = be_top(vm); + if (top >= 3 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isint(vm, 3)) { + const char* service_type = be_tostring(vm, 1); + const char* proto = be_tostring(vm, 2); + uint16_t port = be_toint(vm, 3); + + mdns_txt_item_t * txt_items = NULL; + int32_t txt_num = 0; + if (top >= 4 && be_ismapinstance(vm, 4)) { + // parse txt map + be_getmember(vm, 4, ".p"); + int32_t map_len = be_data_size(vm, -1); + if (map_len > 0) { + uint32_t i= 0; + txt_items = (mdns_txt_item_t*) be_os_malloc(sizeof(mdns_txt_item_t) * map_len); + if (txt_items != NULL) { + be_pushiter(vm, -1); /* map iterator use 1 register */ + while (be_iter_hasnext(vm, -2) && i < map_len) { + be_iter_next(vm, -2); + const char* key = be_tostring(vm, -2); + const char* val = be_tostring(vm, -1); + size_t key_len = strlen(key)+1; + txt_items[i].key = (const char*)be_os_malloc(key_len); + if (txt_items[i].key) { strcpy((char*)txt_items[i].key, key); } + size_t val_len = strlen(val)+1; + txt_items[i].value = (const char*)be_os_malloc(val_len); + if (txt_items[i].value) { strcpy((char*)txt_items[i].value, val); } + be_pop(vm, 2); + i++; + } + txt_num = i; + } else { + txt_num = 0; // failed to allocate, pretend it's empty + } + be_pop(vm, 1); /* pop iterator */ + } + } + esp_err_t err = mdns_service_add(NULL, service_type, proto, port, txt_items, txt_num); + // free all allocated memory + if (txt_items != NULL) { + for (uint32_t i = 0; i < txt_num; i++) { + if (txt_items[i].key != NULL) { be_os_free((void*)txt_items[i].key); } + if (txt_items[i].value != NULL) { be_os_free((void*)txt_items[i].value); } + } + be_os_free(txt_items); + } + if (err != ESP_OK) { + be_raisef(vm, "internal_error", "mdns service_add err=%i", err); + } + be_return_nil(vm); + } + be_raise(vm, "value_error", "wrong or missing arguments"); +} + +/* @const_object_info_begin +module mdns (scope: global) { + start, ctype_func(m_mdns_start) + stop, ctype_func(m_mdns_stop) + set_hostname, ctype_func(m_mdns_set_hostname) + add_service, func(m_mdns_add_service) +} +@const_object_info_end */ +#include "be_fixed_mdns.h" + +#endif // USE_DISCOVERY \ No newline at end of file diff --git a/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c b/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c index dcef3a479..b3d7c540d 100644 --- a/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c @@ -27,6 +27,7 @@ extern int l_strptime(bvm *vm); extern int l_memory(bvm *vm); extern int l_wifi(bvm *vm); extern int l_eth(bvm *vm); +extern int l_hostname(bvm *vm); extern int l_yield(bvm *vm); extern int l_delay(bvm *vm); extern int l_delay_microseconds(bvm *vm); @@ -101,6 +102,7 @@ class be_class_tasmota (scope: global, name: Tasmota) { memory, func(l_memory) wifi, func(l_wifi) eth, func(l_eth) + hostname, func(l_hostname) yield, func(l_yield) delay, func(l_delay) delay_microseconds, func(l_delay_microseconds) 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 4406c6fca..624bbc5d9 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino @@ -256,6 +256,14 @@ extern "C" { be_raise(vm, kTypeError, nullptr); } + // Berry: tasmota.hostname() -> string + // + int32_t l_hostname(struct bvm *vm); + int32_t l_hostname(struct bvm *vm) { + be_pushstring(vm, NetworkHostname()); + be_return(vm); + } + static void l_push_time(bvm *vm, struct tm *t, const char *unparsed) { be_newobject(vm, "map"); be_map_insert_int(vm, "year", t->tm_year + 1900); From b1eac8eb0587db49ff267d325af8c1b4a5793784 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 27 Nov 2022 18:17:41 +0100 Subject: [PATCH 280/319] Fix Berry mdns comments --- lib/libesp32/berry_tasmota/src/be_mdns_module.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp b/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp index d0c534d2b..843090650 100644 --- a/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp +++ b/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp @@ -15,6 +15,7 @@ // // `mdsn.start([hostname:string]) -> nil` +// start or restart mdns, specify hostname or use tasmota.hostname() if none provided (default) extern char* NetworkHostname(void); static void m_mdns_start(struct bvm *vm, const char* hostname) { esp_err_t err = mdns_init(); @@ -32,13 +33,16 @@ static void m_mdns_start(struct bvm *vm, const char* hostname) { BE_FUNC_CTYPE_DECLARE(m_mdns_start, "", "@[s]") // -// `msdn.stop() -> nil`` +// `msdn.stop() -> nil` +// free all mdns resources static void m_mdns_stop(void) { mdns_free(); } BE_FUNC_CTYPE_DECLARE(m_mdns_stop, "", "") - +// +// `mdns.set_hostname(hostname:string) -> nil` +// change the hostname static void m_mdns_set_hostname(struct bvm *vm, const char * hostname) { esp_err_t err = mdns_hostname_set(hostname); if (err != ESP_OK) { @@ -50,6 +54,8 @@ BE_FUNC_CTYPE_DECLARE(m_mdns_set_hostname, "", "@s") // // `mdns.add_service(service:string, proto:string, port:int, txt:map) -> nil` // +// add a service declaration using the current hostname as instance name, and specify TXT fields as a `map` +// // Test: // import mdns mdns.add_service("_arduino","_tcp",1111, {"board":"tasmota", "tcp_check":"no", "ssh_upload":"no", "auth_upload":"no"}) // From ac187d6829555f9a4e76df24b7b6d5e874e36ae7 Mon Sep 17 00:00:00 2001 From: Anton <35825286+anton-v-a@users.noreply.github.com> Date: Mon, 28 Nov 2022 00:56:22 -0500 Subject: [PATCH 281/319] Adding RF protocol for DEWENWILS Power Strips and Power stakes --- lib/lib_rf/rc-switch/src/RCSwitch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/lib_rf/rc-switch/src/RCSwitch.cpp b/lib/lib_rf/rc-switch/src/RCSwitch.cpp index a02cbb38f..c4e891f1b 100644 --- a/lib/lib_rf/rc-switch/src/RCSwitch.cpp +++ b/lib/lib_rf/rc-switch/src/RCSwitch.cpp @@ -151,7 +151,8 @@ static const RCSwitch::Protocol PROGMEM proto[] = { { 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 - { 250, 0, { 0, 0 }, 1, { 18, 6 }, { 1, 3 }, { 3, 1 }, false, 0 } // 36 Dooya remote DC2700AC for Dooya DT82TV curtains motor + { 250, 0, { 0, 0 }, 1, { 18, 6 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 36 Dooya remote DC2700AC for Dooya DT82TV curtains motor + { 200, 0, { 0, 0 }, 0, { 0, 0 }, { 1, 3 }, { 3, 1} , false, 20} // 37 DEWENWILS Power Strip }; enum { From fcf12e1adb910babc36b4ee33278bf5db716ff50 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 28 Nov 2022 07:41:37 +0100 Subject: [PATCH 282/319] sml_obis_line software flag --- .../tasmota_xdrv_driver/xdrv_10_scripter.ino | 159 +++++++++++++++++- tasmota/tasmota_xsns_sensor/xsns_53_sml.ino | 57 ++++--- 2 files changed, 185 insertions(+), 31 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino index 6ffbe65fb..f28fe2224 100755 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino @@ -76,6 +76,7 @@ keywords if then else endif, or, and are better readable for beginners (others m #define MAX_SARRAY_NUM 32 #endif +void Draw_jpeg(uint8_t *mem, uint16_t jpgsize, uint16_t xp, uint16_t yp, uint8_t scale); uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); char *web_send_line(char mc, char *lp); @@ -182,7 +183,7 @@ void Script_ticker4_end(void) { #endif #if defined(USE_SML_M) && defined (USE_SML_SCRIPT_CMD) -extern uint8_t sml_json_enable; +extern uint8_t sml_options; #endif #if defined(EEP_SCRIPT_SIZE) && !defined(ESP32) @@ -1877,6 +1878,117 @@ if (hsv.S == 0) { } #endif //USE_LIGHT +#ifdef ESP32 +#ifdef JPEG_PICTS +#ifdef STREAM_JPEG_PICTS +struct JPG_TASK { + char boundary[40]; + bool draw; + uint8_t scale; + uint16_t xp; + uint16_t yp; + WiFiClient stream; + HTTPClient http; +} jpg_task; + +// "e8b8c539-047d-4777-a985-fbba6edff11e" + +int32_t fetch_jpg(uint32_t sel, char *url, uint32_t xp, uint32_t yp, uint32_t scale) { + char hbuff[64]; + int32_t httpCode = 0; + const char * headerKeys[] = {"Content-Type", "Content-Length"} ; + const size_t numberOfHeaders = 2; + + switch (sel) { + case 0: + // open + jpg_task.boundary[0] = 0; + jpg_task.draw = false; + jpg_task.xp = xp; + jpg_task.yp = yp; + jpg_task.scale = scale; + sprintf(hbuff,"http://%s", url); + jpg_task.http.begin(jpg_task.stream, hbuff); + jpg_task.http.collectHeaders(headerKeys, numberOfHeaders); + httpCode = jpg_task.http.GET(); + if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { + String boundary = jpg_task.http.header(headerKeys[0]); + char *cp = strchr(boundary.c_str(), '='); + if (cp) { + strcpy(jpg_task.boundary,cp + 1); + } + } else { + AddLog(LOG_LEVEL_INFO,PSTR("HTTP error %d = %s"), httpCode, jpg_task.http.errorToString(httpCode).c_str()); + } + return httpCode; + break; + case 1: + // close + jpg_task.stream.stop(); + jpg_task.http.end(); + break; + case 2: + // get next frame + /*Wc.client.print("--" BOUNDARY "\r\n"); + Wc.client.printf("Content-Type: image/jpeg\r\n" + "Content-Length: %d\r\n" + "\r\n", static_cast(_jpg_buf_len)); + */ + { + if (jpg_task.http.connected()) { + char inbuff[64]; + memset(inbuff, 0, sizeof(inbuff)); + jpg_task.stream.readBytesUntil('\n', inbuff, sizeof(inbuff)); + if (inbuff[0] == '\r') { + memset(inbuff, 0, sizeof(inbuff)); + jpg_task.stream.readBytesUntil('\n', inbuff, sizeof(inbuff)); + } + //AddLog(LOG_LEVEL_INFO, PSTR("boundary = %s"), inbuff); + memset(inbuff, 0, sizeof(inbuff)); + jpg_task.stream.readBytesUntil('\n', inbuff, sizeof(inbuff)); + //AddLog(LOG_LEVEL_INFO, PSTR("type = %s"), inbuff); + memset(inbuff, 0, sizeof(inbuff)); + jpg_task.stream.readBytesUntil('\n', inbuff, sizeof(inbuff)); + //AddLog(LOG_LEVEL_INFO, PSTR("size = %s"), inbuff); + char *cp = strchr(inbuff, ':'); + uint16_t size = 0; + if (cp) { + size = atoi(cp + 1); + } + jpg_task.stream.readBytesUntil('\n', inbuff, sizeof(inbuff)); + + if (size > 0) { + //AddLog(LOG_LEVEL_INFO, PSTR("size = %d"), size); + uint8_t *buff = (uint8_t *)special_malloc(size); + if (buff) { + jpg_task.stream.readBytes(buff, size); + } + if (jpg_task.draw) { + Draw_jpeg(buff, size, jpg_task.xp, jpg_task.yp, jpg_task.scale); + } + if (buff) { + free(buff); + } + } + return size; + } + } + break; + case 3: + // stop drawing + jpg_task.draw = false; + break; + case 4: + // resume drawing + jpg_task.draw = true; + break; + } + return 0; +} +#endif // STREAM_JPEG_PICTS +#endif // JPEG_PICTS +#endif // ESP32 + #ifdef USE_ANGLE_FUNC uint32_t pulse_time_hl; @@ -3575,12 +3687,41 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); #endif // ESP32 break; +#ifdef ESP32 +#ifdef JPEG_PICTS +#ifdef STREAM_JPEG_PICTS + case 'j': + if (!strncmp(lp, "jpg(", 4)) { + lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0); + uint8_t selector = fvar; + switch (selector) { + case 0: + // start streaming + char url[SCRIPT_MAXSSIZE]; + lp = GetStringArgument(lp, OPER_EQU, url, 0); + float xp, yp, scale ; + lp = GetNumericArgument(lp, OPER_EQU, &xp, 0); + lp = GetNumericArgument(lp, OPER_EQU, &yp, 0); + lp = GetNumericArgument(lp, OPER_EQU, &scale, 0); + fvar = fetch_jpg(0, url, xp, yp, scale); + break; + default: + // other cmds + fvar = fetch_jpg(selector, 0, 0, 0, 0); + break; + } + goto nfuncexit; + } + break; +#endif // STREAM_JPEG_PICTS +#endif // JPEG_PICTS +#endif // ESP32 + #ifdef USE_KNX case 'k': if (!strncmp(lp, "knx(", 4)) { float type; lp = GetNumericArgument(lp + 4, OPER_EQU, &type, gv); - SCRIPT_SKIP_SPACES lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv); SCRIPT_SKIP_SPACES KnxSensor(type, fvar); @@ -3942,6 +4083,10 @@ extern void W8960_SetGain(uint8_t sel, uint16_t value); } goto strexit; } + if (!strncmp(lp, "rax", 3)) { + TasmotaGlobal.no_autoexec = 0; + goto exit; + } break; case 's': @@ -4219,7 +4364,7 @@ extern char *SML_GetSVal(uint32_t index); goto nfuncexit; } if (!strncmp(vname, "smlj", 4)) { - fvar = sml_json_enable; + fvar = sml_options; tind->index = SML_JSON_ENABLE; goto exit_settable; } @@ -6663,7 +6808,7 @@ getnext: break; #if defined(USE_SML_M) && defined (USE_SML_SCRIPT_CMD) case SML_JSON_ENABLE: - sml_json_enable = *dfvar; + sml_options = *dfvar; break; #endif } @@ -8047,7 +8192,7 @@ bool ScriptCommand(void) { float *fpd = 0; uint16_t alend; char *cp = get_array_by_name(lp, &fpd, &alend, 0); - if (fpd && cp) { + if (fpd && cp && (!strchr(lp, '[')) ) { // is array Response_P(PSTR("{\"script\":{\"%s\":["), lp); for (uint16_t cnt = 0; cnt < alend; cnt++) { @@ -9948,13 +10093,15 @@ exgc: hmflg = 1; cp++; } + // cnth2016/240 + //todflg=atoi(&label[3]); todflg = strtol(cp, &cp, 10); if (!hmflg) { if (todflg >= entries) todflg = entries - 1; if (todflg < 0) todflg = 0; } - if (*cp=='/') { + if (*cp == '/') { cp++; divflg = strtol(cp, &cp, 10); } diff --git a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino index 6f53b8990..39f5b66cb 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino @@ -543,7 +543,11 @@ char meter_id[MAX_METERS][METER_ID_SIZE]; uint8_t sml_send_blocks; uint8_t sml_100ms_cnt; uint8_t sml_desc_cnt; -uint8_t sml_json_enable = 1; + +#define SML_OPTIONS_JSON_ENABLE 1 +#define SML_OPTIONS_OBIS_LINE 2 +uint8_t sml_options = SML_OPTIONS_JSON_ENABLE; + #ifdef USE_SML_MEDIAN_FILTER // median filter, should be odd size @@ -1613,11 +1617,15 @@ void sml_empty_receiver(uint32_t meters) { void sml_shift_in(uint32_t meters,uint32_t shard) { uint32_t count; -#ifndef SML_OBIS_LINE - if (meter_desc_p[meters].type != 'e' && meter_desc_p[meters].type != 'k' && meter_desc_p[meters].type != 'm' && meter_desc_p[meters].type != 'M' && meter_desc_p[meters].type != 'p' && meter_desc_p[meters].type != 'R' && meter_desc_p[meters].type != 'v') { -#else - if (meter_desc_p[meters].type!= 'o' && meter_desc_p[meters].type != 'e' && meter_desc_p[meters].type != 'k' && meter_desc_p[meters].type != 'm' && meter_desc_p[meters].type != 'M' && meter_desc_p[meters].type != 'p' && meter_desc_p[meters].type != 'R' && meter_desc_p[meters].type != 'v') { -#endif + + bool shift; + if (!(sml_options & SML_OPTIONS_OBIS_LINE)) { + shift = (meter_desc_p[meters].type != 'e' && meter_desc_p[meters].type != 'k' && meter_desc_p[meters].type != 'm' && meter_desc_p[meters].type != 'M' && meter_desc_p[meters].type != 'p' && meter_desc_p[meters].type != 'R' && meter_desc_p[meters].type != 'v'); + } else { + shift = (meter_desc_p[meters].type != 'o' && meter_desc_p[meters].type != 'e' && meter_desc_p[meters].type != 'k' && meter_desc_p[meters].type != 'm' && meter_desc_p[meters].type != 'M' && meter_desc_p[meters].type != 'p' && meter_desc_p[meters].type != 'R' && meter_desc_p[meters].type != 'v'); + } + + if (shift) { // shift in for (count = 0; count < SML_BSIZ - 1; count++) { smltbuf[meters][count] = smltbuf[meters][count + 1]; @@ -1626,20 +1634,20 @@ void sml_shift_in(uint32_t meters,uint32_t shard) { uint8_t iob = (uint8_t)meter_ss[meters]->read(); if (meter_desc_p[meters].type == 'o') { -#ifndef SML_OBIS_LINE - smltbuf[meters][SML_BSIZ-1] = iob & 0x7f; -#else - iob &= 0x7f; - smltbuf[meters][meter_spos[meters]] = iob; - meter_spos[meters]++; - if (meter_spos[meters] >= SML_BSIZ) { - meter_spos[meters] = 0; + if (!(sml_options & SML_OPTIONS_OBIS_LINE)) { + smltbuf[meters][SML_BSIZ-1] = iob & 0x7f; + } else { + iob &= 0x7f; + smltbuf[meters][meter_spos[meters]] = iob; + meter_spos[meters]++; + if (meter_spos[meters] >= SML_BSIZ) { + meter_spos[meters] = 0; + } + if ((iob == 0x0a) || (iob == 0x0d)) { + SML_Decode(meters); + meter_spos[meters] = 0; + } } - if ((iob == 0x0a) || (iob == 0x0d)) { - SML_Decode(meters); - meter_spos[meters] = 0; - } -#endif } else if (meter_desc_p[meters].type=='s') { smltbuf[meters][SML_BSIZ-1]=iob; } else if (meter_desc_p[meters].type=='r') { @@ -1750,11 +1758,10 @@ void sml_shift_in(uint32_t meters,uint32_t shard) { } } sb_counter++; -#ifndef SML_OBIS_LINE - if (meter_desc_p[meters].type != 'e' && meter_desc_p[meters].type != 'm' && meter_desc_p[meters].type != 'M' && meter_desc_p[meters].type != 'k' && meter_desc_p[meters].type != 'p' && meter_desc_p[meters].type != 'R' && meter_desc_p[meters].type != 'v') SML_Decode(meters); -#else - if (meter_desc_p[meters].type != 'o' && meter_desc_p[meters].type != 'e' && meter_desc_p[meters].type != 'm' && meter_desc_p[meters].type != 'M' && meter_desc_p[meters].type != 'k' && meter_desc_p[meters].type != 'p' && meter_desc_p[meters].type != 'R' && meter_desc_p[meters].type != 'v') SML_Decode(meters); -#endif + + if (shift) { + SML_Decode(meters); + } } @@ -3810,7 +3817,7 @@ bool Xsns53(uint32_t function) { break; #endif // USE_SCRIPT case FUNC_JSON_APPEND: - if (sml_json_enable) { + if (sml_options & SML_OPTIONS_JSON_ENABLE) { SML_Show(1); } break; From 47ee69137b5691308e0927b0bd0b963312ffe06f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Nov 2022 18:14:44 +0100 Subject: [PATCH 283/319] Fix TasmotaSerial::read(buffer, size) --- lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp | 9 ++++++--- lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp index ef72dce1c..99241a44f 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp @@ -321,7 +321,6 @@ int TasmotaSerial::read(void) { #endif // ESP32 } else { if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1; -// m_overflow = false; uint32_t ch = m_buffer[m_out_pos]; m_out_pos = (m_out_pos +1) % serial_buffer_size; return ch; @@ -338,9 +337,8 @@ size_t TasmotaSerial::read(char* buffer, size_t size) { #endif // ESP32 } else { if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) { return 0; } -// m_overflow = false; size_t count = 0; - for( ; size && (m_in_pos == m_out_pos) ; --size, ++count) { + for( ; size && (m_in_pos != m_out_pos) ; --size, ++count) { *buffer++ = m_buffer[m_out_pos]; m_out_pos = (m_out_pos +1) % serial_buffer_size; } @@ -359,6 +357,11 @@ int TasmotaSerial::available(void) { } else { int avail = m_in_pos - m_out_pos; if (avail < 0) avail += serial_buffer_size; + +// if (!avail) { +// optimistic_yield(10000); +// } + return avail; } } diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h index e62d75316..b9542699e 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h +++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h @@ -51,6 +51,9 @@ class TasmotaSerial : public Stream { size_t write(uint8_t byte) override; int read(void) override; size_t read(char* buffer, size_t size); + size_t read(uint8_t* buffer, size_t size) { + return read(reinterpret_cast(buffer), size); + } int available(void) override; void flush(void) override; From 143373b0d3107ac01803bc08d81bcc4fe23741b0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 29 Nov 2022 10:51:56 +0100 Subject: [PATCH 284/319] Reduce LD2410 Hardware Watchdogs --- .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 59 ++++++------------- 1 file changed, 17 insertions(+), 42 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino index 6975efda5..474e4e825 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -27,6 +27,7 @@ #define XSNS_102 102 +#define LD2410_BUFFER_SIZE TM_SERIAL_BUFFER_SIZE // 64 #define LD2410_MAX_GATES 8 // 0 to 8 (= 9) - DO NOT CHANGE #define LD2410_CMND_START_CONFIGURATION 0xFF @@ -65,7 +66,6 @@ struct { uint8_t static_energy; uint8_t step; uint8_t retry; - uint8_t byte_counter; uint8_t settings; bool valid_response; } LD2410; @@ -153,52 +153,27 @@ bool Ld2410Match(const uint8_t *header, uint32_t offset) { } void Ld2410Input(void) { + uint32_t size = LD2410Serial->read(LD2410.buffer, LD2410_BUFFER_SIZE); + if (size) { + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), size, LD2410.buffer); - if (LD2410Serial->overflow()) { - AddLog(LOG_LEVEL_DEBUG, PSTR("LD2: Serial buffer overrun")); - } - - while (LD2410Serial->available()) { - yield(); // Fix watchdogs - - LD2410.buffer[LD2410.byte_counter++] = LD2410Serial->read(); - if (LD2410.byte_counter < 4) { continue; } // Need first four header bytes - - uint32_t header_start = LD2410.byte_counter -4; // Fix interrupted header transmits - bool target_header = (Ld2410Match(LD2410_target_header, header_start)); // F4F3F2F1 - bool config_header = (Ld2410Match(LD2410_config_header, header_start)); // FDFCFBFA - if ((target_header || config_header) && (header_start != 0)) { - memmove(LD2410.buffer, LD2410.buffer + header_start, 4); // Sync buffer with header - LD2410.byte_counter = 4; - } - if (LD2410.byte_counter < 6) { continue; } // Need packet size bytes - - target_header = (Ld2410Match(LD2410_target_header, 0)); // F4F3F2F1 - config_header = (Ld2410Match(LD2410_config_header, 0)); // FDFCFBFA + bool target_header = (Ld2410Match(LD2410_target_header, 0)); // F4F3F2F1 + bool config_header = (Ld2410Match(LD2410_config_header, 0)); // FDFCFBFA if (target_header || config_header) { - uint32_t len = LD2410.buffer[4] +10; // Total packet size - if (len > TM_SERIAL_BUFFER_SIZE) { len = TM_SERIAL_BUFFER_SIZE; } - if (LD2410.byte_counter < len) { continue; } // Need complete packet - - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); - - if (target_header) { // F4F3F2F1 - if (Ld2410Match(LD2410_target_footer, len -4)) { // F8F7F6F5 - Ld1410HandleTargetData(); - - // Break to test Hardware Watchdog due to buffer overrun - LD2410.byte_counter = 0; - break; - + uint32_t len = LD2410.buffer[4] +10; // Total packet size + if (size >= len) { // Handle only the first entry (if there are more) + if (target_header) { // F4F3F2F1 + if (Ld2410Match(LD2410_target_footer, len -4)) { // F8F7F6F5 + Ld1410HandleTargetData(); + } } - } - else if (config_header) { // FDFCFBFA - if (Ld2410Match(LD2410_config_footer, len -4)) { // 04030201 - Ld1410HandleConfigData(); + else if (config_header) { // FDFCFBFA + if (Ld2410Match(LD2410_config_footer, len -4)) { // 04030201 + Ld1410HandleConfigData(); + } } } } - LD2410.byte_counter = 0; } } @@ -370,7 +345,7 @@ void Ld2410EverySecond(void) { void Ld2410Detect(void) { if (PinUsed(GPIO_LD2410_RX) && PinUsed(GPIO_LD2410_TX)) { - LD2410.buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE); // Default TM_SERIAL_BUFFER_SIZE (=64) size + LD2410.buffer = (uint8_t*)malloc(LD2410_BUFFER_SIZE); // Default 64 if (!LD2410.buffer) { return; } LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2); if (LD2410Serial->begin(256000)) { From af9f83e7e464fe84e41c6362d64925e8044b7886 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 29 Nov 2022 11:11:39 +0100 Subject: [PATCH 285/319] Bump version v12.2.0.6 --- CHANGELOG.md | 18 ++++++++++++++---- RELEASENOTES.md | 4 +++- tasmota/include/tasmota_version.h | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dad9ab1c..11bcdb256 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.5] +## [12.2.0.6] +### Added + +### Breaking Changed + +### Changed + +### Fixed +- TasmotaSerial ``read(buffer, size)`` regression from v9.3.0 + +### Removed + +## [12.2.0.5] 20221129 ### Added - 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) @@ -11,9 +23,7 @@ All notable changes to this project will be documented in this file. - Command ``SetOption35 0..255`` to skip number of received messages in Serial Bridge (default 0) (#17140) - Teleinfo TEMPO (BBR) contract (#17160) - Support for HLK-LD2410 24GHz smart wave motion sensor -- Berry add module ``mdns`` - -### Breaking Changed +- Berry ``mdns`` module (#17202) ### Changed - Serial Bridge default internal serial rx buffer size from 64 to 256 (#17120) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5e456c5c2..fe955d820 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.5 +## Changelog v12.2.0.6 ### 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 @@ -131,6 +131,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Teleinfo TEMPO (BBR) contract [#17160](https://github.com/arendst/Tasmota/issues/17160) - Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892) - Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977) +- Berry ``mdns`` module [#17202](https://github.com/arendst/Tasmota/issues/17202) - 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) @@ -152,6 +153,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Zigbee improved Aqara plug support and completed cluster 0x0702 [#17073](https://github.com/arendst/Tasmota/issues/17073) ### Fixed +- TasmotaSerial ``read(buffer, size)`` regression from v9.3.0 - 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) diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 4b48759ed..f73a6a902 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 = 0x0C020005; // 12.2.0.5 +const uint32_t VERSION = 0x0C020006; // 12.2.0.6 #endif // _TASMOTA_VERSION_H_ From 7ea813c778629bf18860319c45b988858ff4a2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Koca?= Date: Wed, 30 Nov 2022 03:09:46 +0300 Subject: [PATCH 286/319] Update en_GB.h Writing mistake fixed. --- tasmota/language/en_GB.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 2e8b4af21..3357daf6a 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -358,7 +358,7 @@ #define D_PROGRAM_VERSION "Program Version" #define D_BUILD_DATE_AND_TIME "Build Date & Time" #define D_CORE_AND_SDK_VERSION "Core/SDK Version" -#define D_FLASH_WRITE_COUNT "Flash write Count" +#define D_FLASH_WRITE_COUNT "Flash Write Count" #define D_MAC_ADDRESS "MAC Address" #define D_MQTT_HOST "MQTT Host" #define D_MQTT_PORT "MQTT Port" From 35699274030ba7e05568c568fffaf8b668c14ec4 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 30 Nov 2022 09:15:34 +0100 Subject: [PATCH 287/319] Update ZeroCross Dimmer calibration on physical measurement Alligned with physical measurement of 1KW heating --- tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino index e6254b1f8..9567fdd48 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino @@ -34,12 +34,12 @@ typedef struct gamma_table_t { const gamma_table_t ac_dimmer_table[] = { // don't put in PROGMEM for performance reasons { 0, 0 }, { 10, 64 }, - { 50, 144 }, - { 100, 205 }, - { 500, 500 }, - { 900, 795 }, - { 950, 866 }, - { 990, 936 }, + { 50, 175 }, + { 100, 235 }, + { 500, 485 }, + { 900, 704 }, + { 950, 748 }, + { 990, 850 }, { 1024, 1024 }, { 0xFFFF, 0xFFFF } // fail-safe if out of range }; From d3be3dfe8fb0d864f4ef2bf744ffc405876d13a3 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 30 Nov 2022 19:40:58 +0100 Subject: [PATCH 288/319] IPv6 preview for ESP32, also working for ESP8266 --- CHANGELOG.md | 1 + .../src/{AddrList.h => AddrList46.h} | 105 +++---- .../ESP32-to-ESP8266-compat/src/ESP8266WiFi.h | 3 - .../src/IPAddress46.cpp | 270 ++++++++++++++++++ .../ESP32-to-ESP8266-compat/src/IPAddress46.h | 184 ++++++++++++ platformio.ini | 1 + tasmota/include/i18n.h | 2 + tasmota/tasmota_support/support_command.ino | 13 +- tasmota/tasmota_support/support_wifi.ino | 67 +++-- .../xdrv_01_9_webserver.ino | 6 +- .../tasmota_xdrv_driver/xdrv_02_9_mqtt.ino | 3 +- tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino | 12 +- .../xdrv_52_3_berry_tasmota.ino | 5 + 13 files changed, 575 insertions(+), 97 deletions(-) rename lib/libesp32/ESP32-to-ESP8266-compat/src/{AddrList.h => AddrList46.h} (68%) create mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp create mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 11bcdb256..616551629 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. - Teleinfo TEMPO (BBR) contract (#17160) - Support for HLK-LD2410 24GHz smart wave motion sensor - Berry ``mdns`` module (#17202) +- IPv6 preview for ESP32, also working for ESP8266 ### Changed - Serial Bridge default internal serial rx buffer size from 64 to 256 (#17120) diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h similarity index 68% rename from lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h rename to lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h index cc32ea232..bc2d07a39 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h @@ -77,6 +77,7 @@ #include #include +#include "IPAddress46.h" #if LWIP_IPV6 #define IF_NUM_ADDRESSES (1 + LWIP_IPV6_NUM_ADDRESSES) @@ -84,80 +85,63 @@ #define IF_NUM_ADDRESSES (1) #endif - namespace esp8266 { - namespace AddressListImplementation { - - struct netifWrapper { - netifWrapper (netif* netif) : _netif(netif), _num(-1) {} - netifWrapper (const netifWrapper& o) : _netif(o._netif), _num(o._num) {} + netifWrapper (netif* netif) : _netif(netif), _num(-1) {} + netifWrapper (const netifWrapper& o) : _netif(o._netif), _num(o._num) {} - netifWrapper& operator= (const netifWrapper& o) - { - _netif = o._netif; - _num = o._num; - return *this; - } + netifWrapper& operator= (const netifWrapper& o) + { + _netif = o._netif; + _num = o._num; + return *this; + } - bool equal(const netifWrapper& o) - { - return _netif == o._netif && (!_netif || _num == o._num); - } + bool equal(const netifWrapper& o) + { + return _netif == o._netif && (!_netif || _num == o._num); + } - // address properties - class IPAddress4 : public IPAddress - { - public: - bool isV6() const - { - return false; - } - bool isLocal() const - { - return false; - } - }; - IPAddress4 addr () const { return ipFromNetifNum(); } - bool isLegacy () const { return _num == 0; } - //bool isLocal () const { return addr().isLocal(); } - bool isV4 () const { return addr().isV4(); } - bool isV6 () const { return !addr().isV4(); } - String toString() const { return addr().toString(); } + IPAddress46 addr () const { return ipFromNetifNum(); } + bool isLegacy () const { return _num == 0; } + bool isLocal () const { return addr().isLocal(); } + bool isV4 () const { return addr().isV4(); } + bool isV6 () const { return !addr().isV4(); } + String toString() const { return addr().toString(); } - // related to legacy address (_num=0, ipv4) - IPAddress ipv4 () const { return _netif->ip_addr; } - IPAddress netmask () const { return _netif->netmask; } - IPAddress gw () const { return _netif->gw; } + // related to legacy address (_num=0, ipv4) + IPAddress46 ipv4 () const { return _netif->ip_addr; } + IPAddress46 netmask () const { return _netif->netmask; } + IPAddress46 gw () const { return _netif->gw; } - // common to all addresses of this interface - String ifname () const { return String(_netif->name[0]) + _netif->name[1]; } - const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); } - const char* ifmac () const { return (const char*)_netif->hwaddr; } - int ifnumber () const { return _netif->num; } - bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); } - const netif* interface () const { return _netif; } + // common to all addresses of this interface + String ifname () const { return String(_netif->name[0]) + _netif->name[1]; } + const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); } + const char* ifmac () const { return (const char*)_netif->hwaddr; } + int ifnumber () const { return _netif->num; } + bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); } + const netif* interface () const { return _netif; } - const ip_addr_t* ipFromNetifNum () const - { + const ip_addr_t* ipFromNetifNum () const + { #if LWIP_IPV6 - return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr; + return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr; #else - return &_netif->ip_addr; + return &_netif->ip_addr; #endif - } + } - // lwIP interface - netif* _netif; + // lwIP interface + netif* _netif; - // address index within interface - // 0: legacy address (IPv4) - // n>0: (_num-1) is IPv6 index for netif->ip6_addr[] - int _num; + // address index within interface + // 0: legacy address (IPv4) + // n>0: (_num-1) is IPv6 index for netif->ip6_addr[] + int _num; }; @@ -223,11 +207,10 @@ inline AddressList::const_iterator begin (const AddressList& a) { return a.begin inline AddressList::const_iterator end (const AddressList& a) { return a.end(); } -} // AddressListImplementation +} // namespace AddressListImplementation +} // namespace esp8266 -} // esp8266 - -extern AddressList addrList; +extern esp8266::AddressListImplementation::AddressList addrList; #endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h index e7a760164..f0a8476f6 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h @@ -19,9 +19,6 @@ #pragma once #include -// sorry, no -#undef LWIP_IPV6 - #define ENC_TYPE_NONE WIFI_AUTH_OPEN #define ENC_TYPE_WEP WIFI_AUTH_WEP #define ENC_TYPE_CCMP WIFI_AUTH_WPA2_PSK diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp new file mode 100644 index 000000000..b0db1a5b8 --- /dev/null +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp @@ -0,0 +1,270 @@ +/* + IPAddress46.cpp - IPv6 support for ESP32 + + This class is copied from ESP8266 Arduino framework and provides + temporary support for IPv6 on ESP32. + + 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 . +*/ + +/* + IPAddress.cpp - Base class that provides IPAddress + + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +IPAddress46::IPAddress46(const IPAddress46& from) +{ + ip_addr_copy(_ip, from._ip); +} + +IPAddress46::IPAddress46() { + _ip = *IP_ANY_TYPE; // lwIP's v4-or-v6 generic address +} + +bool IPAddress46::isSet () const { + return !ip_addr_isany(&_ip) && ((*this) != IPADDR_NONE); +} + +IPAddress46::IPAddress46(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) { + setV4(); + (*this)[0] = first_octet; + (*this)[1] = second_octet; + (*this)[2] = third_octet; + (*this)[3] = fourth_octet; +} + +void IPAddress46::ctor32(uint32_t address) { + setV4(); + v4() = address; +} + +IPAddress46::IPAddress46(const uint8_t *address) { + setV4(); + (*this)[0] = address[0]; + (*this)[1] = address[1]; + (*this)[2] = address[2]; + (*this)[3] = address[3]; +} + +bool IPAddress46::fromString(const char *address) { + if (!fromString4(address)) { +#if LWIP_IPV6 + return fromString6(address); +#else + return false; +#endif + } + return true; +} + +bool IPAddress46::fromString4(const char *address) { + // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats + + uint16_t acc = 0; // Accumulator + uint8_t dots = 0; + + while (*address) + { + char c = *address++; + if (c >= '0' && c <= '9') + { + acc = acc * 10 + (c - '0'); + if (acc > 255) { + // Value out of [0..255] range + return false; + } + } + else if (c == '.') + { + if (dots == 3) { + // Too much dots (there must be 3 dots) + return false; + } + (*this)[dots++] = acc; + acc = 0; + } + else + { + // Invalid char + return false; + } + } + + if (dots != 3) { + // Too few dots (there must be 3 dots) + return false; + } + (*this)[3] = acc; + + setV4(); + return true; +} + +IPAddress46& IPAddress46::operator=(const uint8_t *address) { + setV4(); + v4() = *reinterpret_cast(address); + return *this; +} + +IPAddress46& IPAddress46::operator=(uint32_t address) { + setV4(); + v4() = address; + return *this; +} + +bool IPAddress46::operator==(const uint8_t* addr) const { + return isV4() && v4() == *reinterpret_cast(addr); +} + +size_t IPAddress46::printTo(Print& p) const { + size_t n = 0; + + if (!isSet()) + return p.print(F("(IP unset)")); + +#if LWIP_IPV6 + if (isV6()) { + int count0 = 0; + for (int i = 0; i < 8; i++) { + uint16_t bit = PP_NTOHS(raw6()[i]); + if (bit || count0 < 0) { + n += p.printf("%x", bit); + if (count0 > 0) + // no more hiding 0 + count0 = -8; + } else + count0++; + if ((i != 7 && count0 < 2) || count0 == 7) + n += p.print(':'); + } + return n; + } +#endif + + for(int i = 0; i < 4; i++) { + n += p.print((*this)[i], DEC); + if (i != 3) + n += p.print('.'); + } + return n; +} + +String IPAddress46::toString() const +{ + StreamString sstr; +#if LWIP_IPV6 + if (isV6()) + sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm + else +#endif + sstr.reserve(16); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)' + printTo(sstr); + return sstr; +} + +bool IPAddress46::isValid(const String& arg) { + return IPAddress46().fromString(arg); +} + +bool IPAddress46::isValid(const char* arg) { + return IPAddress46().fromString(arg); +} + +const IPAddress46 INADDR46_ANY; // generic "0.0.0.0" for IPv4 & IPv6 +const IPAddress46 INADDR46_NONE(255,255,255,255); + +void IPAddress46::clear() { + (*this) = INADDR46_ANY; +} + +/**************************************/ + +#if LWIP_IPV6 + +bool IPAddress46::fromString6(const char *address) { + // TODO: test test test + + uint32_t acc = 0; // Accumulator + int dots = 0, doubledots = -1; + + while (*address) + { + char c = tolower(*address++); + if (isalnum(c)) { + if (c >= 'a') + c -= 'a' - '0' - 10; + acc = acc * 16 + (c - '0'); + if (acc > 0xffff) + // Value out of range + return false; + } + else if (c == ':') { + if (*address == ':') { + if (doubledots >= 0) + // :: allowed once + return false; + // remember location + doubledots = dots + !!acc; + address++; + } + if (dots == 7) + // too many separators + return false; + raw6()[dots++] = PP_HTONS(acc); + acc = 0; + } + else + // Invalid char + return false; + } + + if (doubledots == -1 && dots != 7) + // Too few separators + return false; + raw6()[dots++] = PP_HTONS(acc); + + if (doubledots != -1) { + for (int i = dots - doubledots - 1; i >= 0; i--) + raw6()[8 - dots + doubledots + i] = raw6()[doubledots + i]; + for (int i = doubledots; i < 8 - dots + doubledots; i++) + raw6()[i] = 0; + } + + setV6(); + return true; +} + +#endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h new file mode 100644 index 000000000..952c3ef7d --- /dev/null +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h @@ -0,0 +1,184 @@ +/* + IPAddress46.h - IPv6 support for ESP32 + + This class is copied from ESP8266 Arduino framework and provides + temporary support for IPv6 on ESP32. + + 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 . +*/ + +#ifndef __IPADDRESS46_H +#define __IPADDRESS46_H + +#include +#include +#include + +class IPAddress46: public Printable { + private: + + ip_addr_t _ip; + + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t* raw_address() { + return reinterpret_cast(&v4()); + } + const uint8_t* raw_address() const { + return reinterpret_cast(&v4()); + } + + void ctor32 (uint32_t); + + public: + // Constructors + IPAddress46(); + IPAddress46(const IPAddress46& from); + IPAddress46(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + IPAddress46(uint32_t address) { ctor32(address); } + IPAddress46(unsigned long address) { ctor32(address); } + IPAddress46(int address) { ctor32(address); } + IPAddress46(const uint8_t *address); + + bool fromString(const char *address); + bool fromString(const String &address) { return fromString(address.c_str()); } + + // Overloaded cast operator to allow IPAddress46 objects to be used where a pointer + // to a four-byte uint8_t array is expected + operator uint32_t() const { return isV4()? v4(): (uint32_t)0; } + operator uint32_t() { return isV4()? v4(): (uint32_t)0; } + + bool isSet () const; + operator bool () const { return isSet(); } // <- + operator bool () { return isSet(); } // <- both are needed + + // generic IPv4 wrapper to uint32-view like arduino loves to see it + const uint32_t& v4() const { return ip_2_ip4(&_ip)->addr; } // for raw_address(const) + uint32_t& v4() { return ip_2_ip4(&_ip)->addr; } + + bool operator==(const IPAddress46& addr) const { + return ip_addr_cmp(&_ip, &addr._ip); + } + bool operator!=(const IPAddress46& addr) const { + return !ip_addr_cmp(&_ip, &addr._ip); + } + bool operator==(uint32_t addr) const { + return isV4() && v4() == addr; + } + bool operator==(unsigned long addr) const { + return isV4() && v4() == (uint32_t)addr; + } + bool operator!=(uint32_t addr) const { + return !(isV4() && v4() == addr); + } + bool operator!=(unsigned long addr) const { + return isV4() && v4() != (uint32_t)addr; + } + bool operator==(const uint8_t* addr) const; + + int operator>>(int n) const { + return isV4()? v4() >> n: 0; + } + + // Overloaded index operator to allow getting and setting individual octets of the address + uint8_t operator[](int index) const { + return isV4()? *(raw_address() + index): 0; + } + uint8_t& operator[](int index) { + setV4(); + return *(raw_address() + index); + } + + // Overloaded copy operators to allow initialisation of IPAddress46 objects from other types + IPAddress46& operator=(const uint8_t *address); + IPAddress46& operator=(uint32_t address); + IPAddress46& operator=(const IPAddress46&) = default; + + virtual size_t printTo(Print& p) const; + String toString() const; + + void clear(); + + /* + check if input string(arg) is a valid IPV4 address or not. + return true on valid. + return false on invalid. + */ + static bool isValid(const String& arg); + static bool isValid(const char* arg); + + friend class EthernetClass; + friend class UDP; + friend class Client; + friend class Server; + friend class DhcpClass; + friend class DNSClient; + + operator ip_addr_t () const { return _ip; } + operator const ip_addr_t*() const { return &_ip; } + operator ip_addr_t*() { return &_ip; } + + bool isV4() const { return IP_IS_V4_VAL(_ip); } + void setV4() { IP_SET_TYPE_VAL(_ip, IPADDR_TYPE_V4); } + + bool isLocal () const { return ip_addr_islinklocal(&_ip); } + +#if LWIP_IPV6 + IPAddress46(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); } + IPAddress46(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); } + + IPAddress46& operator=(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); return *this; } + IPAddress46& operator=(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); return *this; } + + uint16_t* raw6() + { + setV6(); + return reinterpret_cast(ip_2_ip6(&_ip)); + } + + const uint16_t* raw6() const + { + return isV6()? reinterpret_cast(ip_2_ip6(&_ip)): nullptr; + } + + // when not IPv6, ip_addr_t == ip4_addr_t so this one would be ambiguous + // required otherwise + operator const ip4_addr_t*() const { return isV4()? ip_2_ip4(&_ip): nullptr; } + + bool isV6() const { return IP_IS_V6_VAL(_ip); } + void setV6() { IP_SET_TYPE_VAL(_ip, IPADDR_TYPE_V6); } + + protected: + bool fromString6(const char *address); + +#else + + // allow portable code when IPv6 is not enabled + + uint16_t* raw6() { return nullptr; } + const uint16_t* raw6() const { return nullptr; } + bool isV6() const { return false; } + void setV6() { } + +#endif + + protected: + bool fromString4(const char *address); +}; + +#endif // __IPADDRESS46_H diff --git a/platformio.ini b/platformio.ini index 4ac907b33..3e08f6cb2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -99,6 +99,7 @@ build_flags = ${esp_defaults.build_flags} ; NONOSDK22x_190703 = 2.2.2-dev(38a443e) -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703 -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH + ; -DPIO_FRAMEWORK_ARDUINO_LWIP2_IPV6_HIGHER_BANDWIDTH ; enables IPv6 ; VTABLES in Flash -DVTABLES_IN_FLASH ; remove the 4-bytes alignment for PSTR() diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h index b40438194..4028b33d2 100644 --- a/tasmota/include/i18n.h +++ b/tasmota/include/i18n.h @@ -110,6 +110,8 @@ #define D_JSON_IMPORT_REACTIVE "ImportReactive" #define D_JSON_INFRARED "Infrared" #define D_JSON_INVALID_FILE_TYPE "Invalid filetype or buffer" +#define D_JSON_IP6_GLOBAL "IP6Global" +#define D_JSON_IP6_LOCAL "IP6Local" #define D_JSON_UNKNOWN "Unknown" #define D_JSON_LIGHT "Light" #define D_JSON_LINK_COUNT "LinkCount" diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index aaedcf494..51f7b41ca 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -801,14 +801,23 @@ void CmndStatus(void) } if ((0 == payload) || (5 == payload)) { + // WifiDumpAddressesIPv6(); Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "1\":\"%_I\",\"" D_JSON_DNSSERVER "2\":\"%_I\",\"" - D_JSON_MAC "\":\"%s\""), + D_JSON_MAC "\":\"%s\"" +#if LWIP_IPV6 + ",\"" D_JSON_IP6_GLOBAL "\":\"%s\",\"" D_JSON_IP6_LOCAL "\":\"%s\"" +#endif // LWIP_IPV6 + ), TasmotaGlobal.hostname, (uint32_t)WiFi.localIP(), Settings->ipv4_address[1], Settings->ipv4_address[2], Settings->ipv4_address[3], Settings->ipv4_address[4], - WiFi.macAddress().c_str()); + WiFi.macAddress().c_str() +#if LWIP_IPV6 + ,WifiGetIPv6().c_str(), WifiGetIPv6LinkLocal().c_str() +#endif // LWIP_IPV6 + ); #ifdef USE_TASMESH ResponseAppend_P(PSTR(",\"SoftAPMac\":\"%s\""), WiFi.softAPmacAddress().c_str()); #endif // USE_TASMESH diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index a64d9b974..8fb65b4ed 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -42,7 +42,11 @@ const uint8_t WIFI_RETRY_OFFSET_SEC = WIFI_RETRY_SECONDS; // seconds #include // Wifi, MQTT, Ota, WifiManager #if LWIP_IPV6 -#include // IPv6 DualStack + #ifdef ESP8266 + #include // IPv6 DualStack + #else + #include // IPv6 DualStack + #endif #endif // LWIP_IPV6=1 int WifiGetRssiAsQuality(int rssi) { @@ -263,20 +267,6 @@ void WifiBegin(uint8_t flag, uint8_t channel) { if (Settings->flag5.wait_for_wifi_result) { // SetOption142 - (Wifi) Wait 1 second for wifi connection solving some FRITZ!Box modem issues (1) WiFi.waitForConnectResult(1000); // https://github.com/arendst/Tasmota/issues/14985 } - -#if LWIP_IPV6 - for (bool configured = false; !configured;) { - uint16_t cfgcnt = 0; - for (auto addr : addrList) { - if ((configured = !addr.isLocal() && addr.isV6()) || cfgcnt==30) { - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI "Got IPv6 global address %s"), addr.toString().c_str()); - break; // IPv6 is mandatory but stop after 15 seconds - } - delay(500); // Loop until real IPv6 address is aquired or too many tries failed - cfgcnt++; - } - } -#endif // LWIP_IPV6=1 } void WifiBeginAfterScan(void) @@ -473,19 +463,55 @@ void WifiSetState(uint8_t state) } #if LWIP_IPV6 +// Returns only IPv6 global address (no loopback and no link-local) String WifiGetIPv6(void) { for (auto a : addrList) { - if(!a.isLocal() && a.isV6()) return a.toString(); + if(!ip_addr_isloopback((ip_addr_t*)a.addr()) && !a.isLocal() && a.isV6()) return a.toString(); } return ""; } + +String WifiGetIPv6LinkLocal(void) +{ + for (auto a : addrList) { + if(!ip_addr_isloopback((ip_addr_t*)a.addr()) && a.isLocal() && a.isV6()) return a.toString(); + } + return ""; +} + +// add an IPv6 link-local address to all netif +void CreateLinkLocalIPv6(void) +{ +#ifdef ESP32 + for (auto intf = esp_netif_next(NULL); intf != NULL; intf = esp_netif_next(intf)) { + esp_netif_create_ip6_linklocal(intf); + } +#endif // ESP32 +} + +void WifiDumpAddressesIPv6(void) +{ + for (auto a: addrList) + AddLog(LOG_LEVEL_DEBUG, PSTR("IF='%s' index=%d legacy=%d IPv4=%d local=%d addr='%s'"), + a.ifname().c_str(), + a.ifnumber(), + a.isLegacy(), + a.addr().isV4(), + a.addr().isLocal(), + a.toString().c_str()); +} #endif // LWIP_IPV6=1 // Check to see if we have any routable IP address bool WifiHasIP(void) { -#ifdef LWIP2_IPV6 - return !a.isLocal(); +#if LWIP_IPV6 + for (auto a : addrList) { + if(!ip_addr_isloopback((ip_addr_t*)a.addr()) && !a.isLocal()) { + return true; + } + } + return false; #else return (uint32_t)WiFi.localIP() != 0; #endif @@ -504,6 +530,11 @@ void WifiCheckIp(void) { Settings->ipv4_address[2] = (uint32_t)WiFi.subnetMask(); Settings->ipv4_address[3] = (uint32_t)WiFi.dnsIP(); Settings->ipv4_address[4] = (uint32_t)WiFi.dnsIP(1); +#if LWIP_IPV6 + // create Link-local address + CreateLinkLocalIPv6(); + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI "IPv6 Link-Local %s"), WifiGetIPv6LinkLocal().c_str()); +#endif // LWIP_IPV6 // Save current AP parameters for quick reconnect Settings->wifi_channel = WiFi.channel(); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index b62176159..a681b3603 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -2362,7 +2362,11 @@ void HandleInformation(void) #if LWIP_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr != "") { - WSContentSend_P(PSTR("}1 IPv6 Address }2%s"), ipv6_addr.c_str()); + WSContentSend_P(PSTR("}1 IPv6 Global }2%s"), ipv6_addr.c_str()); + } + ipv6_addr = WifiGetIPv6LinkLocal(); + if (ipv6_addr != "") { + WSContentSend_P(PSTR("}1 IPv6 Link-Local }2%s"), ipv6_addr.c_str()); } #endif // LWIP_IPV6 = 1 if (static_cast(WiFi.localIP()) != 0) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino index 678d148f1..fdd2e3703 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino @@ -972,7 +972,8 @@ void MqttConnected(void) { ResponseAppend_P(PSTR(",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\""), TasmotaGlobal.hostname, (uint32_t)WiFi.localIP()); #if LWIP_IPV6 - ResponseAppend_P(PSTR(",\"IPv6Address\":\"%s\""), WifiGetIPv6().c_str()); + ResponseAppend_P(PSTR(",\"" D_JSON_IP6_GLOBAL "\":\"%s\""), WifiGetIPv6().c_str()); + ResponseAppend_P(PSTR(",\"" D_JSON_IP6_LOCAL "\":\"%s\""), WifiGetIPv6LinkLocal().c_str()); #endif // LWIP_IPV6 = 1 } #if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino b/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino index acf6181e3..25cbce72d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino @@ -131,12 +131,7 @@ extern "C" { if ((p->len == p->tot_len) && (p->next == nullptr)) { ip_addr_t ping_target; struct icmp_echo_hdr *iecho; -#ifdef ESP8266 - ping_target.addr = ping->ip; -#endif // ESP8266 -#ifdef ESP32 ip_addr_set_ip4_u32(&ping_target, ping->ip); -#endif // ESP32 iecho = (struct icmp_echo_hdr *) p->payload; t_ping_prepare_echo(iecho, ping_size, ping); @@ -171,12 +166,7 @@ extern "C" { // Reveived packet // static uint8_t ICACHE_FLASH_ATTR t_ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) { -#ifdef ESP8266 - Ping_t *ping = t_ping_find(addr->addr); -#endif // ESP8266 -#ifdef ESP32 - Ping_t *ping = t_ping_find(addr->u_addr.ip4.addr); -#endif // ESP32 + Ping_t *ping = t_ping_find(ip_addr_get_ip4_u32(addr)); if (nullptr == ping) { // unknown source address return 0; // don't eat the packet and ignore it 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 624bbc5d9..c6246514e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino @@ -220,6 +220,11 @@ extern "C" { be_map_insert_str(vm, "ip6", ipv6_addr.c_str()); show_rssi = true; } + ipv6_addr = WifiGetIPv6LinkLocal(); + if (ipv6_addr != "") { + be_map_insert_str(vm, "ip6local", ipv6_addr.c_str()); + show_rssi = true; + } #endif if (static_cast(WiFi.localIP()) != 0) { be_map_insert_str(vm, "mac", WiFi.macAddress().c_str()); From 816fd78fbb545ccddc85763e0837e67fafc4f989 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 1 Dec 2022 16:18:38 +0100 Subject: [PATCH 289/319] Fix LD2410 using HardwareSerial on ESP8266 --- .../TasmotaSerial-3.5.0/src/TasmotaSerial.cpp | 21 ++++--- .../TasmotaSerial-3.5.0/src/TasmotaSerial.h | 6 +- .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 57 ++++++++++++++++++- 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp index 99241a44f..ce8958169 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp @@ -54,7 +54,8 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal serial_buffer_size = buffer_size; m_rx_pin = receive_pin; m_tx_pin = transmit_pin; - m_in_pos = m_out_pos = 0; + m_in_pos = 0; + m_out_pos = 0; #ifdef ESP8266 if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) { return; @@ -293,7 +294,8 @@ void TasmotaSerial::flush(void) { while (TSerial->available()) { TSerial->read(); } #endif // ESP32 } else { - m_in_pos = m_out_pos = 0; + m_in_pos = 0; + m_out_pos = 0; } } @@ -428,13 +430,14 @@ size_t TasmotaSerial::write(uint8_t b) { } void IRAM_ATTR TasmotaSerial::rxRead(void) { + uint32_t m_out_pos_fixed = m_out_pos; if (!m_nwmode) { int32_t loop_read = m_very_high_speed ? serial_buffer_size : 1; // Advance the starting point for the samples but compensate for the // initial delay which occurs before the interrupt is delivered uint32_t wait = m_bit_start_time; uint32_t start = ESP.getCycleCount(); - while (loop_read-- > 0) { // try to receveive all consecutive bytes in a raw + while (loop_read-- > 0) { // try to receveive all consecutive bytes in a row uint32_t rec = 0; for (uint32_t i = 0; i < 8; i++) { TM_SERIAL_WAIT_RCV; @@ -442,14 +445,14 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { if (digitalRead(m_rx_pin)) rec |= 0x80; } // Store the received value in the buffer unless we have an overflow - uint32_t next = (m_in_pos+1) % serial_buffer_size; - if (next != (int)m_out_pos) { + uint32_t next = (m_in_pos + 1) % serial_buffer_size; + if (next != m_out_pos_fixed) { m_buffer[m_in_pos] = rec; m_in_pos = next; } else { - // Buffer overrun - exit and fix Hardware Watchdog in case of high speed flooding + // Buffer overrun - exit m_overflow = true; - break; + loop_read = 0; } TM_SERIAL_WAIT_RCV_LOOP; // wait for stop bit @@ -511,7 +514,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { } //stobyte(0,ssp->ss_byte>>1); uint32_t next = (m_in_pos + 1) % serial_buffer_size; - if (next != (uint32_t)m_out_pos) { + if (next != m_out_pos_fixed) { m_buffer[m_in_pos] = ss_byte >> 1; m_in_pos = next; } @@ -525,7 +528,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { // bit zero was 0, //stobyte(0,ssp->ss_byte>>1); uint32_t next = (m_in_pos + 1) % serial_buffer_size; - if (next != (uint32_t)m_out_pos) { + if (next != m_out_pos_fixed) { m_buffer[m_in_pos] = ss_byte >> 1; m_in_pos = next; } diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h index b9542699e..3e4f9a315 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h +++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h @@ -70,11 +70,12 @@ class TasmotaSerial : public Stream { private: bool isValidGPIOpin(int pin); + size_t txWrite(uint8_t byte); + void _fast_write(uint8_t b); // IRAM minimized version #ifdef ESP32 bool freeUart(void); void Esp32Begin(void); #endif - size_t txWrite(uint8_t byte); // Member variables int m_rx_pin; @@ -97,9 +98,6 @@ class TasmotaSerial : public Stream { bool m_high_speed = false; bool m_very_high_speed = false; // above 100000 bauds uint8_t *m_buffer = nullptr; - - void _fast_write(uint8_t b); // IRAM minimized version - #ifdef ESP32 uint32_t m_speed; uint32_t m_config; diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino index 474e4e825..ad4457492 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -67,6 +67,7 @@ struct { uint8_t step; uint8_t retry; uint8_t settings; + uint8_t byte_counter; bool valid_response; } LD2410; @@ -93,13 +94,13 @@ void Ld1410HandleTargetData(void) { LD2410.static_distance = LD2410.buffer[13] << 8 | LD2410.buffer[12]; LD2410.static_energy = LD2410.buffer[14]; LD2410.detect_distance = LD2410.buffer[16] << 8 | LD2410.buffer[15]; - +/* AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Type %d, State %d, Moving %d/%d%%, Static %d/%d%%, Detect %d"), LD2410.buffer[6], LD2410.buffer[8], LD2410.moving_distance, LD2410.moving_energy, LD2410.static_distance, LD2410.static_energy, LD2410.detect_distance); - +*/ if (0x01 == LD2410.buffer[6]) { // Engineering mode data // Adds 22 extra bytes of data @@ -153,6 +154,8 @@ bool Ld2410Match(const uint8_t *header, uint32_t offset) { } void Ld2410Input(void) { +/* + // Works with TasmotaSerial as SoftwareSerial but fails with HardwareSerial uint32_t size = LD2410Serial->read(LD2410.buffer, LD2410_BUFFER_SIZE); if (size) { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), size, LD2410.buffer); @@ -175,6 +178,56 @@ void Ld2410Input(void) { } } } +*/ + // Works with TasmotaSerial and HardwareSerial + while (LD2410Serial->available()) { + yield(); // Fix watchdogs + + LD2410.buffer[LD2410.byte_counter++] = LD2410Serial->read(); + if (LD2410.byte_counter < 4) { continue; } // Need first four header bytes + + uint32_t header_start = LD2410.byte_counter -4; // Fix interrupted header transmits + bool target_header = (Ld2410Match(LD2410_target_header, header_start)); // F4F3F2F1 + bool config_header = (Ld2410Match(LD2410_config_header, header_start)); // FDFCFBFA + if ((target_header || config_header) && (header_start != 0)) { + memmove(LD2410.buffer, LD2410.buffer + header_start, 4); // Sync buffer with header + LD2410.byte_counter = 4; + } + if (LD2410.byte_counter < 6) { continue; } // Need packet size bytes + + target_header = (Ld2410Match(LD2410_target_header, 0)); // F4F3F2F1 + config_header = (Ld2410Match(LD2410_config_header, 0)); // FDFCFBFA + if (target_header || config_header) { + uint32_t len = LD2410.buffer[4] +10; // Total packet size + if (len > LD2410_BUFFER_SIZE) { + LD2410.byte_counter = 0; // Invalid data + break; // Exit loop to satisfy yields + } + if (LD2410.byte_counter < len) { continue; } // Need complete packet + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); + + if (target_header) { // F4F3F2F1 + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); + + if (Ld2410Match(LD2410_target_footer, len -4)) { // F8F7F6F5 + Ld1410HandleTargetData(); + } + } + else if (config_header) { // FDFCFBFA + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); + + if (Ld2410Match(LD2410_config_footer, len -4)) { // 04030201 + Ld1410HandleConfigData(); + } + } + } + LD2410.byte_counter = 0; // Finished or bad received footer + break; // Exit loop to satisfy yields + } + // If here then LD2410.byte_counter could still be partial correct for next loop } void Ld2410SendCommand(uint32_t command, uint8_t *val = nullptr, uint32_t val_len = 0); From 6da636d685ee59679a37e8a59780ff1e5f48a977 Mon Sep 17 00:00:00 2001 From: kurkav Date: Sat, 3 Dec 2022 11:54:30 +0100 Subject: [PATCH 290/319] Invalid processing of received value. Int64 value was read from Float buffer. Also units received were Wh, struct needs kWh. --- tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino b/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino index fa25d2048..7f51053e4 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino @@ -148,15 +148,15 @@ void IEM3000Every250ms(void) break; case 10: - Energy.import_active[0] = value; + Energy.import_active[0] = value64/1000.0; break; case 11: - Energy.import_active[1] = value; + Energy.import_active[1] = value64/1000.0; break; case 12: - Energy.import_active[2] = value; + Energy.import_active[2] = value64/1000.0; break; case 13: From bbde894628832583a52648ebbe3f95bd86438b09 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 3 Dec 2022 12:33:42 +0100 Subject: [PATCH 291/319] Add serial Modbus transmit enable GPIOs Add serial Modbus transmit enable GPIOs to all modbus energy drivers and modbus bridge (#17247) --- CHANGELOG.md | 2 + RELEASENOTES.md | 2 + .../README.md | 0 .../examples/swsertest/swsertest.ino | 0 .../keywords.txt | 0 .../library.json | 2 +- .../library.properties | 2 +- .../src/TasmotaSerial.cpp | 59 +++++++++++++++---- .../src/TasmotaSerial.h | 4 ++ .../TasmotaModbus-3.6.0/src/TasmotaModbus.cpp | 17 +++--- .../TasmotaModbus-3.6.0/src/TasmotaModbus.h | 2 +- tasmota/include/tasmota_template.h | 4 ++ tasmota/language/af_AF.h | 6 +- tasmota/language/bg_BG.h | 6 +- tasmota/language/ca_AD.h | 6 +- tasmota/language/cs_CZ.h | 6 +- tasmota/language/de_DE.h | 6 +- tasmota/language/el_GR.h | 6 +- tasmota/language/en_GB.h | 6 +- tasmota/language/es_ES.h | 6 +- tasmota/language/fr_FR.h | 6 +- tasmota/language/fy_NL.h | 6 +- tasmota/language/he_HE.h | 6 +- tasmota/language/hu_HU.h | 6 +- tasmota/language/it_IT.h | 6 +- tasmota/language/ko_KO.h | 6 +- tasmota/language/nl_NL.h | 6 +- tasmota/language/pl_PL.h | 6 +- tasmota/language/pt_BR.h | 6 +- tasmota/language/pt_PT.h | 6 +- tasmota/language/ro_RO.h | 6 +- tasmota/language/ru_RU.h | 6 +- tasmota/language/sk_SK.h | 6 +- tasmota/language/sv_SE.h | 6 +- tasmota/language/tr_TR.h | 6 +- tasmota/language/uk_UA.h | 6 +- tasmota/language/vi_VN.h | 6 +- tasmota/language/zh_CN.h | 6 +- tasmota/language/zh_TW.h | 6 +- .../xdrv_63_modbus_bridge.ino | 2 +- .../tasmota_xnrg_energy/xnrg_05_pzem_ac.ino | 2 +- .../tasmota_xnrg_energy/xnrg_06_pzem_dc.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 +- .../xnrg_13_fif_le01mr.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_21_sdm230.ino | 2 +- .../tasmota_xnrg_energy/xnrg_29_modbus.ino | 2 +- 52 files changed, 191 insertions(+), 91 deletions(-) rename lib/default/{TasmotaSerial-3.5.0 => TasmotaSerial-3.6.0}/README.md (100%) rename lib/default/{TasmotaSerial-3.5.0 => TasmotaSerial-3.6.0}/examples/swsertest/swsertest.ino (100%) rename lib/default/{TasmotaSerial-3.5.0 => TasmotaSerial-3.6.0}/keywords.txt (100%) rename lib/default/{TasmotaSerial-3.5.0 => TasmotaSerial-3.6.0}/library.json (94%) rename lib/default/{TasmotaSerial-3.5.0 => TasmotaSerial-3.6.0}/library.properties (94%) rename lib/default/{TasmotaSerial-3.5.0 => TasmotaSerial-3.6.0}/src/TasmotaSerial.cpp (90%) rename lib/default/{TasmotaSerial-3.5.0 => TasmotaSerial-3.6.0}/src/TasmotaSerial.h (96%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 616551629..71a2005f0 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.6] ### Added +- Serial Modbus transmit enable GPIOs to all modbus energy drivers and modbus bridge (#17247) ### Breaking Changed ### Changed +- TasmotaSerial library from v3.5.0 to v3.6.0 ### Fixed - TasmotaSerial ``read(buffer, size)`` regression from v9.3.0 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index fe955d820..913348801 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -129,6 +129,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn [#17069](https://github.com/arendst/Tasmota/issues/17069) - WS2812 and Light ArtNet DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059) - Teleinfo TEMPO (BBR) contract [#17160](https://github.com/arendst/Tasmota/issues/17160) +- Serial Modbus transmit enable GPIOs to all modbus energy drivers and modbus bridge [#17247](https://github.com/arendst/Tasmota/issues/17247) - Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892) - Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977) - Berry ``mdns`` module [#17202](https://github.com/arendst/Tasmota/issues/17202) @@ -140,6 +141,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 +- TasmotaSerial library from v3.5.0 to v3.6.0 - 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) diff --git a/lib/default/TasmotaSerial-3.5.0/README.md b/lib/default/TasmotaSerial-3.6.0/README.md similarity index 100% rename from lib/default/TasmotaSerial-3.5.0/README.md rename to lib/default/TasmotaSerial-3.6.0/README.md diff --git a/lib/default/TasmotaSerial-3.5.0/examples/swsertest/swsertest.ino b/lib/default/TasmotaSerial-3.6.0/examples/swsertest/swsertest.ino similarity index 100% rename from lib/default/TasmotaSerial-3.5.0/examples/swsertest/swsertest.ino rename to lib/default/TasmotaSerial-3.6.0/examples/swsertest/swsertest.ino diff --git a/lib/default/TasmotaSerial-3.5.0/keywords.txt b/lib/default/TasmotaSerial-3.6.0/keywords.txt similarity index 100% rename from lib/default/TasmotaSerial-3.5.0/keywords.txt rename to lib/default/TasmotaSerial-3.6.0/keywords.txt diff --git a/lib/default/TasmotaSerial-3.5.0/library.json b/lib/default/TasmotaSerial-3.6.0/library.json similarity index 94% rename from lib/default/TasmotaSerial-3.5.0/library.json rename to lib/default/TasmotaSerial-3.6.0/library.json index 45c0c4508..aa1fda280 100644 --- a/lib/default/TasmotaSerial-3.5.0/library.json +++ b/lib/default/TasmotaSerial-3.6.0/library.json @@ -1,6 +1,6 @@ { "name": "TasmotaSerial", - "version": "3.5.0", + "version": "3.6.0", "keywords": [ "serial", "io", "TasmotaSerial" ], diff --git a/lib/default/TasmotaSerial-3.5.0/library.properties b/lib/default/TasmotaSerial-3.6.0/library.properties similarity index 94% rename from lib/default/TasmotaSerial-3.5.0/library.properties rename to lib/default/TasmotaSerial-3.6.0/library.properties index 759c7f39d..3f6d5c133 100644 --- a/lib/default/TasmotaSerial-3.5.0/library.properties +++ b/lib/default/TasmotaSerial-3.6.0/library.properties @@ -1,5 +1,5 @@ name=TasmotaSerial -version=3.5.0 +version=3.6.0 author=Theo Arends maintainer=Theo Arends sentence=Implementation of software serial with hardware serial fallback for ESP8266 and ESP32. diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp similarity index 90% rename from lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp rename to lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp index ce8958169..97c30b750 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp @@ -46,9 +46,11 @@ static uint32_t tasmota_serial_uart_bitmap = 0; // Assigned UARTs TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback, int nwmode, int buffer_size) { m_valid = false; + m_tx_enable_valid = false; m_hardserial = false; m_hardswap = false; m_overflow = false; + m_data_bits = 8; m_stop_bits = 1; m_nwmode = nwmode; serial_buffer_size = buffer_size; @@ -122,7 +124,23 @@ TasmotaSerial::~TasmotaSerial(void) { } bool TasmotaSerial::isValidGPIOpin(int pin) { +#ifdef ESP8266 return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15); +#endif +#ifdef ESP32 + return GPIO_IS_VALID_OUTPUT_GPIO(pin); +#endif +} + +void TasmotaSerial::setTransmitEnablePin(int tx_enable_pin) { + if ((tx_enable_pin > -1) && isValidGPIOpin(tx_enable_pin)) { + m_tx_enable_valid = true; + m_tx_enable_pin = tx_enable_pin; + pinMode(m_tx_enable_pin, OUTPUT); + digitalWrite(m_tx_enable_pin, LOW); + } else { + m_tx_enable_valid = false; + } } #ifdef ESP32 @@ -239,12 +257,17 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) { // Serial.printf("TSR: Using UART%d\n", m_uart); #endif // ESP32 } else { + // #define UART_NB_BIT_5 0B00000000 + // #define UART_NB_BIT_6 0B00000100 + // #define UART_NB_BIT_7 0B00001000 + // #define UART_NB_BIT_8 0B00001100 + m_data_bits = 5 + ((config &0x0C) >> 2); // Software serial fakes two stop bits if either stop bits is 2 or parity is not None // #define UART_NB_STOP_BIT_0 0B00000000 // #define UART_NB_STOP_BIT_1 0B00010000 // #define UART_NB_STOP_BIT_15 0B00100000 // #define UART_NB_STOP_BIT_2 0B00110000 - m_stop_bits = ((config &0x30) >> 5) +1; + m_stop_bits = 1 + ((config &0x30) >> 5); // #define UART_PARITY_NONE 0B00000000 // #define UART_PARITY_EVEN 0B00000010 // #define UART_PARITY_ODD 0B00000011 @@ -368,9 +391,9 @@ int TasmotaSerial::available(void) { } } -#define TM_SERIAL_WAIT_SND { while (ESP.getCycleCount() < (wait + start)) if (!m_high_speed) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts +#define TM_SERIAL_WAIT_SND { while (ESP.getCycleCount() < (wait + start)) if (!m_high_speed) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts #define TM_SERIAL_WAIT_SND_FAST { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } -#define TM_SERIAL_WAIT_RCV { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } +#define TM_SERIAL_WAIT_RCV { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } #define TM_SERIAL_WAIT_RCV_LOOP { while (ESP.getCycleCount() < (wait + start)); } void IRAM_ATTR TasmotaSerial::_fast_write(uint8_t b) { @@ -379,7 +402,7 @@ void IRAM_ATTR TasmotaSerial::_fast_write(uint8_t b) { // Start bit; digitalWrite(m_tx_pin, LOW); TM_SERIAL_WAIT_SND_FAST; - for (uint32_t i = 0; i < 8; i++) { + for (uint32_t i = 0; i < m_data_bits; i++) { digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW); TM_SERIAL_WAIT_SND_FAST; b >>= 1; @@ -392,15 +415,20 @@ void IRAM_ATTR TasmotaSerial::_fast_write(uint8_t b) { } size_t TasmotaSerial::write(uint8_t b) { + if (!m_hardserial && (-1 == m_tx_pin)) { return 0; } + + if (m_tx_enable_valid) { + digitalWrite(m_tx_enable_pin, HIGH); + } + size_t size = 0; if (m_hardserial) { #ifdef ESP8266 - return Serial.write(b); + size = Serial.write(b); #endif // ESP8266 #ifdef ESP32 - return TSerial->write(b); + size = TSerial->write(b); #endif // ESP32 } else { - if (-1 == m_tx_pin) return 0; if (m_high_speed) { cli(); // Disable interrupts in order to get a clean transmit _fast_write(b); @@ -412,7 +440,7 @@ size_t TasmotaSerial::write(uint8_t b) { // Start bit; digitalWrite(m_tx_pin, LOW); TM_SERIAL_WAIT_SND; - for (uint32_t i = 0; i < 8; i++) { + for (uint32_t i = 0; i < m_data_bits; i++) { digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW); TM_SERIAL_WAIT_SND; b >>= 1; @@ -424,25 +452,29 @@ size_t TasmotaSerial::write(uint8_t b) { TM_SERIAL_WAIT_SND; } } - - return 1; + size = 1; } + if (m_tx_enable_valid) { + digitalWrite(m_tx_enable_pin, LOW); + } + return size; } void IRAM_ATTR TasmotaSerial::rxRead(void) { uint32_t m_out_pos_fixed = m_out_pos; if (!m_nwmode) { int32_t loop_read = m_very_high_speed ? serial_buffer_size : 1; + uint32_t bit_mask = 0x01 << (m_data_bits -1); // Advance the starting point for the samples but compensate for the // initial delay which occurs before the interrupt is delivered uint32_t wait = m_bit_start_time; uint32_t start = ESP.getCycleCount(); - while (loop_read-- > 0) { // try to receveive all consecutive bytes in a row + while (loop_read-- > 0) { // try to receive all consecutive bytes in a row uint32_t rec = 0; - for (uint32_t i = 0; i < 8; i++) { + for (uint32_t i = 0; i < m_data_bits; i++) { TM_SERIAL_WAIT_RCV; rec >>= 1; - if (digitalRead(m_rx_pin)) rec |= 0x80; + if (digitalRead(m_rx_pin)) rec |= bit_mask; } // Store the received value in the buffer unless we have an overflow uint32_t next = (m_in_pos + 1) % serial_buffer_size; @@ -485,6 +517,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { // it gets set even when interrupts are disabled GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rx_pin); } else { + // Currently supports 8-bit data only uint32_t diff; uint32_t level; diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h similarity index 96% rename from lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h rename to lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h index 3e4f9a315..97fc1406c 100644 --- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h @@ -39,6 +39,7 @@ class TasmotaSerial : public Stream { public: TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback = 0, int nwmode = 0, int buffer_size = TM_SERIAL_BUFFER_SIZE); virtual ~TasmotaSerial(); + void setTransmitEnablePin(int tx_enable_pin); size_t setRxBufferSize(size_t size); size_t getRxBufferSize() { return serial_buffer_size; } @@ -80,6 +81,8 @@ class TasmotaSerial : public Stream { // Member variables int m_rx_pin; int m_tx_pin; + int m_tx_enable_pin; + uint32_t m_data_bits; uint32_t m_stop_bits; uint32_t ss_byte; uint32_t ss_bstart; @@ -91,6 +94,7 @@ class TasmotaSerial : public Stream { uint32_t m_out_pos; uint32_t serial_buffer_size = TM_SERIAL_BUFFER_SIZE; bool m_valid; + bool m_tx_enable_valid; bool m_nwmode; bool m_hardserial; bool m_hardswap; diff --git a/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.cpp b/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.cpp index 95db697f5..25ea7caaf 100644 --- a/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.cpp +++ b/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.cpp @@ -27,8 +27,9 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D //#define TASMOTAMODBUSDEBUG -TasmotaModbus::TasmotaModbus(int receive_pin, int transmit_pin) : TasmotaSerial(receive_pin, transmit_pin, 1) +TasmotaModbus::TasmotaModbus(int receive_pin, int transmit_pin, int tx_enable_pin) : TasmotaSerial(receive_pin, transmit_pin, 1) { + setTransmitEnablePin(tx_enable_pin); mb_address = 0; } @@ -91,7 +92,7 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 } else if ((function_code == 5) || (function_code == 6)) { - if (write_data == NULL) + if (write_data == NULL) { free(frame); return 13; // Register data not specified @@ -108,10 +109,10 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 { frame[framepointer++] = (uint8_t)(count >> 8); // MSB frame[framepointer++] = (uint8_t)(count); // LSB - + frame[framepointer++] = byte_count; - if (write_data == NULL) + if (write_data == NULL) { free(frame); return 13; // Register data not specified @@ -126,7 +127,7 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 frame[framepointer++] = (uint8_t)(write_data[bytepointer/2] >> (bytepointer % 2 ? 0 : 8)); // MSB, LSB, MSB .... } } - else + else { free(frame); return 1; // Wrong function code @@ -136,7 +137,7 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 frame[framepointer++] = (uint8_t)(crc); frame[framepointer++] = (uint8_t)(crc >> 8); -#ifdef TASMOTAMODBUSDEBUG +#ifdef TASMOTAMODBUSDEBUG uint8_t *buf; uint16_t bufsize=(framepointer + 1) * 3; buf = (uint8_t *)malloc(bufsize); @@ -147,7 +148,7 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: Serial Send: %s"), buf); free(buf); #endif - + flush(); write(frame, framepointer); free(frame); @@ -213,7 +214,7 @@ uint8_t TasmotaModbus::ReceiveBuffer(uint8_t *buffer, uint8_t register_count, ui // 10 = Gateway Path Unavailable // 11 = Gateway Target device failed to respond } - + if (mb_len < 6) { return 7; } // 7 = Not enough data /* diff --git a/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.h b/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.h index 520bb166d..ced5fb969 100644 --- a/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.h +++ b/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.h @@ -27,7 +27,7 @@ class TasmotaModbus : public TasmotaSerial { public: - TasmotaModbus(int receive_pin, int transmit_pin); + TasmotaModbus(int receive_pin, int transmit_pin, int tx_enable_pin = -1); virtual ~TasmotaModbus() {} int Begin(long speed = TM_MODBUS_BAUDRATE, uint32_t config = SERIAL_8N1); diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index d1ea6161d..e4e622cb8 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -202,6 +202,7 @@ enum UserSelectablePins { GPIO_BP1658CJ_CLK, GPIO_BP1658CJ_DAT,// BP1658CJ GPIO_DINGTIAN_CLK, GPIO_DINGTIAN_SDI, GPIO_DINGTIAN_Q7, GPIO_DINGTIAN_PL, GPIO_DINGTIAN_RCK, // Dingtian relay board - 595's & 165's pins GPIO_LD2410_TX, GPIO_LD2410_RX, // HLK-LD2410 + GPIO_MBR_TX_ENA, GPIO_NRG_MBS_TX_ENA, // Modbus Bridge Serial Transmit Enable GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage with max 2045 @@ -451,6 +452,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BP1658CJ_CLK "|" D_SENSOR_BP1658CJ_DAT "|" D_GPIO_DINGTIAN_CLK "|" D_GPIO_DINGTIAN_SDI "|" D_GPIO_DINGTIAN_Q7 "|" D_GPIO_DINGTIAN_PL "|" D_GPIO_DINGTIAN_RCK "|" D_SENSOR_LD2410_TX "|" D_SENSOR_LD2410_RX "|" + D_SENSOR_MBR_TX_ENA "|" D_SENSOR_NRG_MBS_TX_ENA "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -822,6 +824,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) #endif + AGPIO(GPIO_NRG_MBS_TX_ENA), // Generic Energy Modbus Transmit Enable #if defined(USE_PZEM004T) || defined(USE_PZEM_AC) || defined(USE_PZEM_DC) AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface #endif @@ -900,6 +903,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface #endif #ifdef USE_MODBUS_BRIDGE + AGPIO(GPIO_MBR_TX_ENA), // Modbus Bridge Serial interface AGPIO(GPIO_MBR_TX), // Modbus Bridge Serial interface AGPIO(GPIO_MBR_RX), // Modbus Bridge Serial interface #endif diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index fc00c5a2e..b3ff8c4b7 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index dc00fa439..3281cdc47 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index 1c36c117a..8ac3e95c7 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 80fca7baf..9707e8836 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 2d487f112..cdd50b101 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index eb60cecf9..308dc79bb 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 3357daf6a..a42565b7e 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index dd86ba6eb..b3608171e 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 6dd0eb7ab..8f0425f16 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr TX" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 TX" #define D_SENSOR_SDM72_RX "SDM72 RX" #define D_SENSOR_SDM120_TX "SDMx20 TX" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 7753d6f13..10a5a9798 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 783890999..653dba154 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 149095171..66cce299b 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 5592ac8e9..5ba644f24 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr - TX" #define D_SENSOR_MBR_TX "ModBr - TX" #define D_SENSOR_MBR_RX "ModBr - RX" +#define D_SENSOR_MBR_TX_ENA "ModBr - TX ENA" #define D_SENSOR_SR04_TRIG "SR04 Tri - TX" #define D_SENSOR_SR04_ECHO "SR04 Ech - RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus - TX" -#define D_SENSOR_NRG_MBS_RX "NrgModbus - RX" +#define D_SENSOR_NRG_MBS_TX "NrgMbs - TX" +#define D_SENSOR_NRG_MBS_RX "NrgMbs - RX" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs - TX ENA" #define D_SENSOR_SDM72_TX "SDM72 - TX" #define D_SENSOR_SDM72_RX "SDM72 - RX" #define D_SENSOR_SDM120_TX "SDMx20 - TX" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 8ff8b12d4..d397732fd 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 28e55258a..2e738f427 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 8b0735959..c4ace8791 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 25800a0b4..288d5c74b 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 1d36075ea..8e30a194a 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 2bd887f0f..30458b06f 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 4adf8ef54..22baa6b7f 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 29ad8e8f3..2c26bc49e 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 6d7d4afd5..8e0b22ed6 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 0213accba..9feaf5034 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index abe179c74..96fae7c7e 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 6eaa39736..e0a9df039 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index f603c7f55..c96261c13 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 53172c1aa..c0072dba0 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -691,10 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_MBR_TX "ModBr Tx" #define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" #define D_SENSOR_SR04_TRIG "SR04 Tri/TX" #define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgModbus Tx" -#define D_SENSOR_NRG_MBS_RX "NrgModbus Rx" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" #define D_SENSOR_SDM72_TX "SDM72 Tx" #define D_SENSOR_SDM72_RX "SDM72 Rx" #define D_SENSOR_SDM120_TX "SDMx20 Tx" diff --git a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino index 7dfa2a116..6c3c33d4e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino @@ -558,7 +558,7 @@ void ModbusBridgeInit(void) { if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX)) { - modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX)); + modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX), Pin(GPIO_MBR_TX_ENA)); ModbusBridgeBegin(); #ifdef USE_MODBUS_BRIDGE_TCP // If TCP bridge is enabled allocate a TCP receive buffer diff --git a/tasmota/tasmota_xnrg_energy/xnrg_05_pzem_ac.ino b/tasmota/tasmota_xnrg_energy/xnrg_05_pzem_ac.ino index 0648525c9..e07fcb566 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_05_pzem_ac.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_05_pzem_ac.ino @@ -114,7 +114,7 @@ void PzemAcEverySecond(void) void PzemAcSnsInit(void) { - PzemAcModbus = new TasmotaModbus(Pin(GPIO_PZEM016_RX), Pin(GPIO_PZEM0XX_TX)); + PzemAcModbus = new TasmotaModbus(Pin(GPIO_PZEM016_RX), Pin(GPIO_PZEM0XX_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = PzemAcModbus->Begin(9600); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_06_pzem_dc.ino b/tasmota/tasmota_xnrg_energy/xnrg_06_pzem_dc.ino index d1336ca08..06dcf3bb8 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_06_pzem_dc.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_06_pzem_dc.ino @@ -111,7 +111,7 @@ void PzemDcEverySecond(void) void PzemDcSnsInit(void) { - PzemDcModbus = new TasmotaModbus(Pin(GPIO_PZEM017_RX), Pin(GPIO_PZEM0XX_TX)); + PzemDcModbus = new TasmotaModbus(Pin(GPIO_PZEM017_RX), Pin(GPIO_PZEM0XX_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = PzemDcModbus->Begin(9600, SERIAL_8N2); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino b/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino index dbd2462cb..d4591aa85 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino @@ -177,7 +177,7 @@ void SDM120Every250ms(void) void Sdm120SnsInit(void) { - Sdm120Modbus = new TasmotaModbus(Pin(GPIO_SDM120_RX), Pin(GPIO_SDM120_TX)); + Sdm120Modbus = new TasmotaModbus(Pin(GPIO_SDM120_RX), Pin(GPIO_SDM120_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = Sdm120Modbus->Begin(SDM120_SPEED); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_09_dds2382.ino b/tasmota/tasmota_xnrg_energy/xnrg_09_dds2382.ino index 329c58f51..1c5e55a30 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_09_dds2382.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_09_dds2382.ino @@ -90,7 +90,7 @@ void Dds2382EverySecond(void) void Dds2382SnsInit(void) { - Dds2382Modbus = new TasmotaModbus(Pin(GPIO_DDS2382_RX), Pin(GPIO_DDS2382_TX)); + Dds2382Modbus = new TasmotaModbus(Pin(GPIO_DDS2382_RX), Pin(GPIO_DDS2382_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = Dds2382Modbus->Begin(DDS2382_SPEED); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino b/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino index dcbd2ea40..f6848707d 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino @@ -213,7 +213,7 @@ void SDM630Every250ms(void) void Sdm630SnsInit(void) { - Sdm630Modbus = new TasmotaModbus(Pin(GPIO_SDM630_RX), Pin(GPIO_SDM630_TX)); + Sdm630Modbus = new TasmotaModbus(Pin(GPIO_SDM630_RX), Pin(GPIO_SDM630_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = Sdm630Modbus->Begin(SDM630_SPEED); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_11_ddsu666.ino b/tasmota/tasmota_xnrg_energy/xnrg_11_ddsu666.ino index 59b4cb88a..ab629c106 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_11_ddsu666.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_11_ddsu666.ino @@ -132,7 +132,7 @@ void DDSU666Every250ms(void) void Ddsu666SnsInit(void) { - Ddsu666Modbus = new TasmotaModbus(Pin(GPIO_DDSU666_RX), Pin(GPIO_DDSU666_TX)); + Ddsu666Modbus = new TasmotaModbus(Pin(GPIO_DDSU666_RX), Pin(GPIO_DDSU666_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = Ddsu666Modbus->Begin(DDSU666_SPEED); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino b/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino index 8fa11f7ef..1ec4f7698 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino @@ -214,7 +214,7 @@ void FifLEEvery250ms(void) void FifLESnsInit(void) { - FifLEModbus = new TasmotaModbus(Pin(GPIO_LE01MR_RX), Pin(GPIO_LE01MR_TX)); + FifLEModbus = new TasmotaModbus(Pin(GPIO_LE01MR_RX), Pin(GPIO_LE01MR_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = FifLEModbus->Begin(LE01MR_SPEED); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino b/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino index fa25d2048..7d7c46362 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino @@ -181,7 +181,7 @@ void IEM3000Every250ms(void) void Iem3000SnsInit(void) { - Iem3000Modbus = new TasmotaModbus(Pin(GPIO_IEM3000_RX), Pin(GPIO_IEM3000_TX)); + Iem3000Modbus = new TasmotaModbus(Pin(GPIO_IEM3000_RX), Pin(GPIO_IEM3000_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = Iem3000Modbus->Begin(IEM3000_SPEED); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino b/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino index 117dab094..2a115712d 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino @@ -185,7 +185,7 @@ void WE517Every250ms(void) void We517SnsInit(void) { - We517Modbus = new TasmotaModbus(Pin(GPIO_WE517_RX), Pin(GPIO_WE517_TX)); + We517Modbus = new TasmotaModbus(Pin(GPIO_WE517_RX), Pin(GPIO_WE517_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = We517Modbus->Begin(WE517_SPEED); if (result) { if (2 == result) { diff --git a/tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino b/tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino index 61a00ee4f..bde9d90df 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino @@ -130,7 +130,7 @@ void Sdm72Every250ms(void) void Sdm72SnsInit(void) { - Sdm72Modbus = new TasmotaModbus(Pin(GPIO_SDM72_RX), Pin(GPIO_SDM72_TX)); + Sdm72Modbus = new TasmotaModbus(Pin(GPIO_SDM72_RX), Pin(GPIO_SDM72_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = Sdm72Modbus->Begin(SDM72_SPEED); if (result) { if (2 == result) { diff --git a/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino b/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino index e9607ab11..90f16f566 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino @@ -188,7 +188,7 @@ void SDM230Every250ms(void) void Sdm230SnsInit(void) { - Sdm230Modbus = new TasmotaModbus(Pin(GPIO_SDM230_RX), Pin(GPIO_SDM230_TX)); + Sdm230Modbus = new TasmotaModbus(Pin(GPIO_SDM230_RX), Pin(GPIO_SDM230_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = Sdm230Modbus->Begin(SDM230_SPEED); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino index 06e643632..7f155d7c2 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino @@ -663,7 +663,7 @@ bool EnergyModbusRegisters(void) { void EnergyModbusSnsInit(void) { if (EnergyModbusRegisters()) { - EnergyModbus = new TasmotaModbus(Pin(GPIO_NRG_MBS_RX), Pin(GPIO_NRG_MBS_TX)); + EnergyModbus = new TasmotaModbus(Pin(GPIO_NRG_MBS_RX), Pin(GPIO_NRG_MBS_TX), Pin(GPIO_NRG_MBS_TX_ENA)); uint8_t result = EnergyModbus->Begin(NrgMbsParam.serial_bps, NrgMbsParam.serial_config); if (result) { if (2 == result) { ClaimSerial(); } From 1aeee69c08860dd95c6f45db4304c532b4933182 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 4 Dec 2022 07:47:21 +0100 Subject: [PATCH 292/319] optional TRX enable --- tasmota/tasmota_xsns_sensor/xsns_53_sml.ino | 48 +++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino index 39f5b66cb..2cf934c57 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino @@ -80,6 +80,14 @@ #define DJ_VAVG "Volt_avg" #define DJ_COUNTER "Count" +typedef union { + uint8_t data; + struct { + uint8_t trxenpol : 1; // string or number + uint8_t trxen : 1; + uint8_t trxenpin : 6; + }; +} TRX_EN_TYPE; struct METER_DESC { int8_t srcpin; @@ -94,6 +102,7 @@ struct METER_DESC { uint8_t max_index; char *script_str; uint8_t sopt; + TRX_EN_TYPE trx_en; #ifdef USE_SML_SPECOPT uint32_t so_obis1; uint32_t so_obis2; @@ -1618,6 +1627,10 @@ void sml_empty_receiver(uint32_t meters) { void sml_shift_in(uint32_t meters,uint32_t shard) { uint32_t count; +#ifdef SML_OBIS_LINE + sml_options |= SML_OPTIONS_OBIS_LINE; +#endif + bool shift; if (!(sml_options & SML_OPTIONS_OBIS_LINE)) { shift = (meter_desc_p[meters].type != 'e' && meter_desc_p[meters].type != 'k' && meter_desc_p[meters].type != 'm' && meter_desc_p[meters].type != 'M' && meter_desc_p[meters].type != 'p' && meter_desc_p[meters].type != 'R' && meter_desc_p[meters].type != 'v'); @@ -2937,11 +2950,36 @@ dddef_exit: } if (*lp == ',') { lp++; + // get TRX pin script_meter_desc[index].trxpin = strtol(lp, &lp, 10); if (Gpio_used(script_meter_desc[index].trxpin)) { AddLog(LOG_LEVEL_INFO, PSTR("SML: Error: Duplicate GPIO %d defined. Not usable for TX in meter number %d"), script_meter_desc[index].trxpin, index + 1); goto dddef_exit; } + // optional transmit enable pin + if (*lp == '(') { + lp++; + if (*lp == 'i') { + lp++; + script_meter_desc[index].trx_en.trxenpol = 1; + } else { + script_meter_desc[index].trx_en.trxenpol = 0; + } + script_meter_desc[index].trx_en.trxenpin = strtol(lp, &lp, 10); + if (*lp != ')') { + goto dddef_exit; + } + lp++; + if (Gpio_used(script_meter_desc[index].trx_en.trxenpin)) { + AddLog(LOG_LEVEL_INFO, PSTR("SML: Error: Duplicate GPIO %d defined. Not usable for TX enable in meter number %d"), script_meter_desc[index].trx_en.trxenpin, index + 1); + goto dddef_exit; + } + script_meter_desc[index].trx_en.trxen = 1; + pinMode(script_meter_desc[index].trx_en.trxenpin, OUTPUT); + digitalWrite(script_meter_desc[index].trx_en.trxenpin, script_meter_desc[index].trx_en.trxenpol); + } else { + script_meter_desc[index].trx_en.trxen = 0; + } if (*lp != ',') goto next_line; lp++; script_meter_desc[index].tsecs = strtol(lp, &lp, 10); @@ -3607,8 +3645,18 @@ void SML_Send_Seq(uint32_t meter,char *seq) { slen += 6; } + if (script_meter_desc[meter].trx_en.trxen) { + digitalWrite(script_meter_desc[meter].trx_en.trxenpin, script_meter_desc[meter].trx_en.trxenpol ^ 1); + } meter_ss[meter]->flush(); meter_ss[meter]->write(sbuff, slen); + + if (script_meter_desc[meter].trx_en.trxen) { + // must wait for all data sent + meter_ss[meter]->flush(); + digitalWrite(script_meter_desc[meter].trx_en.trxenpin, script_meter_desc[meter].trx_en.trxenpol); + } + if (dump2log) { #ifdef SML_DUMP_OUT_ALL Hexdump(sbuff, slen); From 0015b5fc04a64c6754f86d2b08a991427353f800 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 4 Dec 2022 08:16:21 +0100 Subject: [PATCH 293/319] fix google chart --- tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino index f28fe2224..afa473936 100755 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino @@ -9209,7 +9209,7 @@ uint16_t cipos = 0; if (*lp == ')' || *lp == 0) break; char *lp1 = lp; float sysvar; - lp=isvar(lp, &vtype, &ind, &sysvar, 0, 0); + lp = isvar(lp, &vtype, &ind, &sysvar, 0, 0); if (vtype != VAR_NV) { SCRIPT_SKIP_SPACES uint8_t index = glob_script_mem.type[ind.index].index; @@ -9958,12 +9958,12 @@ exgc: lp++; strcpy_P(stacked,"true"); } - if (*lp=='2') { + if (*lp == '2') { lp++; nanum = 2; y2f = 1; } - if (*lp=='t') { + if (*lp == 't') { lp++; tonly = 1; } @@ -9982,6 +9982,7 @@ exgc: if (!ind.bits.constant && glob_script_mem.type[ind.index].bits.is_filter) { // is 1. array lp = slp; + max_entries = 0; } } } @@ -10009,7 +10010,7 @@ exgc: // we know how many arrays and the number of entries //Serial.printf("arrays %d\n",anum); //Serial.printf("entries %d\n",entries); - if (gs_ctype=='T') { + if (gs_ctype == 'T') { if (anum && !(entries & 1)) { WSContentSend_P(SCRIPT_MSG_GTABLEa); char label[SCRIPT_MAXSSIZE]; @@ -10017,7 +10018,7 @@ exgc: SCRIPT_SKIP_SPACES char lab2[SCRIPT_MAXSSIZE]; lab2[0] = 0; - if (*lp!=')') { + if (*lp != ')') { lp = GetStringArgument(lp, OPER_EQU, lab2, 0); WSContentSend_P(SCRIPT_MSG_GTABLEe); } else { @@ -10068,6 +10069,7 @@ exgc: //goto nextwebline; } } else { + // we need to fetch the labels now WSContentSend_P(SCRIPT_MSG_GTABLEa); lp = gc_send_labels(lp, anum); @@ -10121,7 +10123,6 @@ exgc: divflg = entries / segments; if (!divflg) divflg = 1; } - uint32_t aind = ipos; if (aind >= entries) aind = entries - 1; for (uint32_t cnt = 0; cnt < entries; cnt++) { From bb880346696e2734d2afa0c26e129b7c93752c84 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 4 Dec 2022 10:50:58 +0100 Subject: [PATCH 294/319] Fix LD2410 Hardware Watchdogs --- .../TasmotaSerial-3.6.0/src/TasmotaSerial.cpp | 29 +++++++++++++------ .../TasmotaSerial-3.6.0/src/TasmotaSerial.h | 1 + .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 9 ++++-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp index 97c30b750..7e960b05c 100644 --- a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp @@ -283,6 +283,10 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) { return m_valid; } +void TasmotaSerial::setReadChunkMode(bool mode) { + m_very_high_speed = mode; +} + bool TasmotaSerial::hardwareSerial(void) { #ifdef ESP8266 return m_hardserial; @@ -345,7 +349,9 @@ int TasmotaSerial::read(void) { return TSerial->read(); #endif // ESP32 } else { - if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1; + if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) { + return -1; + } uint32_t ch = m_buffer[m_out_pos]; m_out_pos = (m_out_pos +1) % serial_buffer_size; return ch; @@ -361,7 +367,9 @@ size_t TasmotaSerial::read(char* buffer, size_t size) { return TSerial->read(buffer, size); #endif // ESP32 } else { - if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) { return 0; } + if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) { + return 0; + } size_t count = 0; for( ; size && (m_in_pos != m_out_pos) ; --size, ++count) { *buffer++ = m_buffer[m_out_pos]; @@ -461,14 +469,17 @@ size_t TasmotaSerial::write(uint8_t b) { } void IRAM_ATTR TasmotaSerial::rxRead(void) { - uint32_t m_out_pos_fixed = m_out_pos; if (!m_nwmode) { - int32_t loop_read = m_very_high_speed ? serial_buffer_size : 1; - uint32_t bit_mask = 0x01 << (m_data_bits -1); + uint32_t start = ESP.getCycleCount(); // Advance the starting point for the samples but compensate for the // initial delay which occurs before the interrupt is delivered uint32_t wait = m_bit_start_time; - uint32_t start = ESP.getCycleCount(); + // Decide to read as much data as buffer can hold or a single byte + // The first option may keep interrupt busy too long resulting in Hardware Watchdog + // The second option may receive ocasional invalid data + // User control by function setReadChunkMode() + int32_t loop_read = m_very_high_speed ? serial_buffer_size : 1; + uint32_t bit_mask = 0x01 << (m_data_bits -1); while (loop_read-- > 0) { // try to receive all consecutive bytes in a row uint32_t rec = 0; for (uint32_t i = 0; i < m_data_bits; i++) { @@ -478,7 +489,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { } // Store the received value in the buffer unless we have an overflow uint32_t next = (m_in_pos + 1) % serial_buffer_size; - if (next != m_out_pos_fixed) { + if (next != m_out_pos) { m_buffer[m_in_pos] = rec; m_in_pos = next; } else { @@ -547,7 +558,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { } //stobyte(0,ssp->ss_byte>>1); uint32_t next = (m_in_pos + 1) % serial_buffer_size; - if (next != m_out_pos_fixed) { + if (next != m_out_pos) { m_buffer[m_in_pos] = ss_byte >> 1; m_in_pos = next; } @@ -561,7 +572,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { // bit zero was 0, //stobyte(0,ssp->ss_byte>>1); uint32_t next = (m_in_pos + 1) % serial_buffer_size; - if (next != m_out_pos_fixed) { + if (next != m_out_pos) { m_buffer[m_in_pos] = ss_byte >> 1; m_in_pos = next; } diff --git a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h index 97fc1406c..cf93f3443 100644 --- a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h @@ -55,6 +55,7 @@ class TasmotaSerial : public Stream { size_t read(uint8_t* buffer, size_t size) { return read(reinterpret_cast(buffer), size); } + void setReadChunkMode(bool mode); int available(void) override; void flush(void) override; diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino index ad4457492..7a8c008e4 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -199,13 +199,13 @@ void Ld2410Input(void) { config_header = (Ld2410Match(LD2410_config_header, 0)); // FDFCFBFA if (target_header || config_header) { uint32_t len = LD2410.buffer[4] +10; // Total packet size - if (len > LD2410_BUFFER_SIZE) { + if (len > LD2410_BUFFER_SIZE) { LD2410.byte_counter = 0; // Invalid data break; // Exit loop to satisfy yields } if (LD2410.byte_counter < len) { continue; } // Need complete packet -// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); if (target_header) { // F4F3F2F1 @@ -217,10 +217,11 @@ void Ld2410Input(void) { } else if (config_header) { // FDFCFBFA - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); if (Ld2410Match(LD2410_config_footer, len -4)) { // 04030201 Ld1410HandleConfigData(); + LD2410Serial->setReadChunkMode(0); // Disable chunk mode fixing Hardware Watchdogs } } } @@ -254,6 +255,7 @@ void Ld2410SendCommand(uint32_t command, uint8_t *val, uint32_t val_len) { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Send %*_H"), len, buffer); + LD2410Serial->setReadChunkMode(1); // Enable chunk mode introducing possible Hardware Watchdogs LD2410Serial->flush(); LD2410Serial->write(buffer, len); } @@ -401,6 +403,7 @@ void Ld2410Detect(void) { LD2410.buffer = (uint8_t*)malloc(LD2410_BUFFER_SIZE); // Default 64 if (!LD2410.buffer) { return; } LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2); +// LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2, 1); if (LD2410Serial->begin(256000)) { if (LD2410Serial->hardwareSerial()) { ClaimSerial(); } From fca19401b77cbba93ab3ba55c1bc82708dda9f47 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 4 Dec 2022 12:25:17 +0100 Subject: [PATCH 295/319] Increase user input energy max values (#15856) --- .../tasmota_xdrv_driver/xdrv_03_energy.ino | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino index 6621eee9b..065cabc5e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino @@ -972,7 +972,7 @@ void CmndEnergyConfig(void) { #ifdef USE_ENERGY_MARGIN_DETECTION void CmndPowerDelta(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= ENERGY_MAX_PHASES)) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32000)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 32000)) { Settings->energy_power_delta[XdrvMailbox.index -1] = XdrvMailbox.payload; } ResponseCmndIdxNumber(Settings->energy_power_delta[XdrvMailbox.index -1]); @@ -980,42 +980,42 @@ void CmndPowerDelta(void) { } void CmndPowerLow(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6000)) { Settings->energy_min_power = XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_min_power); } void CmndPowerHigh(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6000)) { Settings->energy_max_power = XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_max_power); } void CmndVoltageLow(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 501)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 500)) { Settings->energy_min_voltage = XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_min_voltage); } void CmndVoltageHigh(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 501)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 500)) { Settings->energy_max_voltage = XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_max_voltage); } void CmndCurrentLow(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 16001)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 25000)) { Settings->energy_min_current = XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_min_current); } void CmndCurrentHigh(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 16001)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 25000)) { Settings->energy_max_current = XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_max_current); @@ -1023,35 +1023,35 @@ void CmndCurrentHigh(void) { #ifdef USE_ENERGY_POWER_LIMIT void CmndMaxPower(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6000)) { Settings->energy_max_power_limit = XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_max_power_limit); } void CmndMaxPowerHold(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6000)) { Settings->energy_max_power_limit_hold = (1 == XdrvMailbox.payload) ? MAX_POWER_HOLD : XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_max_power_limit_hold); } void CmndMaxPowerWindow(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6000)) { Settings->energy_max_power_limit_window = (1 == XdrvMailbox.payload) ? MAX_POWER_WINDOW : XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_max_power_limit_window); } void CmndSafePower(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6000)) { Settings->energy_max_power_safe_limit = XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_max_power_safe_limit); } void CmndSafePowerHold(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6000)) { Settings->energy_max_power_safe_limit_hold = (1 == XdrvMailbox.payload) ? SAFE_POWER_HOLD : XdrvMailbox.payload; } ResponseCmndNumber(Settings->energy_max_power_safe_limit_hold); @@ -1065,7 +1065,7 @@ void CmndSafePowerWindow(void) { } void CmndMaxEnergy(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6000)) { Settings->energy_max_energy = XdrvMailbox.payload; Energy.max_energy_state = 3; } From 5f8ef0c5cb556540b8e0d67fef7403d1523c14bc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 4 Dec 2022 12:37:50 +0100 Subject: [PATCH 296/319] Fix LD2410 bad reception detection --- .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino index 7a8c008e4..b21a9b03a 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -80,37 +80,39 @@ uint32_t ToBcd(uint32_t value) { /********************************************************************************************/ void Ld1410HandleTargetData(void) { - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 - // F4 F3 F2 F1 0D 00 02 AA 00 00 00 00 00 00 37 00 00 55 00 F8 F7 F6 F5 - No target - // F4 F3 F2 F1 0D 00 02 AA 00 45 00 3E 00 00 3A 00 00 55 00 F8 F7 F6 F5 - No target - // F4 F3 F2 F1 0D 00 02 AA 03 46 00 34 00 00 3C 00 00 55 00 F8 F7 F6 F5 - Movement and Stationary target - // F4 F3 F2 F1 0D 00 02 AA 02 54 00 00 00 00 64 00 00 55 00 F8 F7 F6 F5 - Stationary target - // F4 F3 F2 F1 0D 00 02 AA 02 96 00 00 00 00 36 00 00 55 00 F8 F7 F6 F5 - Stationary target - // F4 F3 F2 F1 0D 00 02 AA 03 2A 00 64 00 00 64 00 00 55 00 F8 F7 F6 F5 - Movement and Stationary target - // header |len |dt|hd|st|movin|me|stati|se|detec|tr|ck|trailer - if (LD2410.buffer[8] != 0x00) { // Movement and/or Stationary target - LD2410.moving_distance = LD2410.buffer[10] << 8 | LD2410.buffer[9]; - LD2410.moving_energy = LD2410.buffer[11]; - LD2410.static_distance = LD2410.buffer[13] << 8 | LD2410.buffer[12]; - LD2410.static_energy = LD2410.buffer[14]; - LD2410.detect_distance = LD2410.buffer[16] << 8 | LD2410.buffer[15]; -/* - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Type %d, State %d, Moving %d/%d%%, Static %d/%d%%, Detect %d"), - LD2410.buffer[6], LD2410.buffer[8], - LD2410.moving_distance, LD2410.moving_energy, - LD2410.static_distance, LD2410.static_energy, - LD2410.detect_distance); -*/ - if (0x01 == LD2410.buffer[6]) { // Engineering mode data - // Adds 22 extra bytes of data + if ((0x0D == LD2410.buffer[4]) && (0x55 == LD2410.buffer[17])) { // Add bad reception detection + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + // F4 F3 F2 F1 0D 00 02 AA 00 00 00 00 00 00 37 00 00 55 00 F8 F7 F6 F5 - No target + // F4 F3 F2 F1 0D 00 02 AA 00 45 00 3E 00 00 3A 00 00 55 00 F8 F7 F6 F5 - No target + // F4 F3 F2 F1 0D 00 02 AA 03 46 00 34 00 00 3C 00 00 55 00 F8 F7 F6 F5 - Movement and Stationary target + // F4 F3 F2 F1 0D 00 02 AA 02 54 00 00 00 00 64 00 00 55 00 F8 F7 F6 F5 - Stationary target + // F4 F3 F2 F1 0D 00 02 AA 02 96 00 00 00 00 36 00 00 55 00 F8 F7 F6 F5 - Stationary target + // F4 F3 F2 F1 0D 00 02 AA 03 2A 00 64 00 00 64 00 00 55 00 F8 F7 F6 F5 - Movement and Stationary target + // header |len |dt|hd|st|movin|me|stati|se|detec|tr|ck|trailer + if (LD2410.buffer[8] != 0x00) { // Movement and/or Stationary target + LD2410.moving_distance = LD2410.buffer[10] << 8 | LD2410.buffer[9]; + LD2410.moving_energy = LD2410.buffer[11]; + LD2410.static_distance = LD2410.buffer[13] << 8 | LD2410.buffer[12]; + LD2410.static_energy = LD2410.buffer[14]; + LD2410.detect_distance = LD2410.buffer[16] << 8 | LD2410.buffer[15]; + /* + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Type %d, State %d, Moving %d/%d%%, Static %d/%d%%, Detect %d"), + LD2410.buffer[6], LD2410.buffer[8], + LD2410.moving_distance, LD2410.moving_energy, + LD2410.static_distance, LD2410.static_energy, + LD2410.detect_distance); + */ + if (0x01 == LD2410.buffer[6]) { // Engineering mode data + // Adds 22 extra bytes of data + } + } else { + LD2410.moving_distance = 0; + LD2410.moving_energy = 0; + LD2410.static_distance = 0; + LD2410.static_energy = 0; + LD2410.detect_distance = 0; } - } else { - LD2410.moving_distance = 0; - LD2410.moving_energy = 0; - LD2410.static_distance = 0; - LD2410.static_energy = 0; - LD2410.detect_distance = 0; } } @@ -403,7 +405,6 @@ void Ld2410Detect(void) { LD2410.buffer = (uint8_t*)malloc(LD2410_BUFFER_SIZE); // Default 64 if (!LD2410.buffer) { return; } LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2); -// LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2, 1); if (LD2410Serial->begin(256000)) { if (LD2410Serial->hardwareSerial()) { ClaimSerial(); } From 9be44131b9c0ae98a94ebe354f4f695da89dcffb Mon Sep 17 00:00:00 2001 From: stefanbode Date: Sun, 4 Dec 2022 13:25:20 +0100 Subject: [PATCH 297/319] Support Setoption13 1 on shutters to immediate feedback --- tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 733de46a0..6efc930fe 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -864,7 +864,7 @@ void ShutterButtonHandler(void) } if (NOT_PRESSED == button) { - if (Shutter[shutter_index].direction && Button.hold_timer[button_index] > 0) { + if (Shutter[shutter_index].direction && (Button.hold_timer[button_index] > 0 && (!Settings->flag.button_single || Button.hold_timer[button_index] > 20))) { XdrvMailbox.index = shutter_index +1; XdrvMailbox.payload = XdrvMailbox.index; //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d, Button %d, hold %d, dir %d, index %d, payload %d"), shutter_index+1, button_index+1, Button.hold_timer[button_index],Shutter[shutter_index].direction,XdrvMailbox.index,XdrvMailbox.payload); From 496aeeff0734861b8b744df303da1c47d253d764 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Sun, 4 Dec 2022 14:41:38 +0100 Subject: [PATCH 298/319] Fix rounding error on tiltmovement fix #17191 --- tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 6efc930fe..14797d4ce 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -690,8 +690,8 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) ShutterGlobal.start_reported = 0; Shutter[i].tilt_real_pos = tmax(tmin(Shutter[i].tilt_real_pos,Shutter[i].tilt_config[1]),Shutter[i].tilt_config[0]); Shutter[i].tilt_start_pos = Shutter[i].tilt_real_pos; - if (Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0] != 0) { - Shutter[i].venetian_delay = (direction > 0 ? Shutter[i].tilt_config[1]-Shutter[i].tilt_real_pos : Shutter[i].tilt_real_pos-Shutter[i].tilt_config[0]) * Shutter[i].tilt_config[2] / (Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0]); + if (Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0] != 0) { + Shutter[i].venetian_delay = SHT_DIV_ROUND((direction > 0 ? Shutter[i].tilt_config[1]-Shutter[i].tilt_real_pos : Shutter[i].tilt_real_pos-Shutter[i].tilt_config[0]) * Shutter[i].tilt_config[2], Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0]); //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: real %d, start %d, counter %d,freq_max %d, dir %d, freq %d"),Shutter[i].real_position, Shutter[i].start_position ,RtcSettings.pulse_counter[i],ShutterGlobal.open_velocity_max , direction ,ShutterGlobal.open_velocity_max ); AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: VenetianDelay: %d, Pos: %d, Dir: %d, Delta: %d, Dur: %d, StartP: %d, TgtP: %d"), Shutter[i].venetian_delay, Shutter[i].tilt_real_pos,direction,(Shutter[i].tilt_config[1]-Shutter[i].tilt_config[0]), Shutter[i].tilt_config[2],Shutter[i].tilt_start_pos,Shutter[i].tilt_target_pos); From e1221b924db5a67b1835f2a2f6279cb74ba97028 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 4 Dec 2022 15:09:39 +0100 Subject: [PATCH 299/319] Changed removed leading spaces on commands ``(S)SerialSend1 to 6`` Removed leading spaces on commands ``(S)SerialSend1 to 6`` but keep on duplicate commands ``(S)SerialSend11 to 16`` (#16723) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/tasmota_support/support_command.ino | 7 ++++--- tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71a2005f0..65dc09e1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. ### Changed - TasmotaSerial library from v3.5.0 to v3.6.0 +- Removed leading spaces on commands ``(S)SerialSend1 to 6`` but keep on duplicate commands ``(S)SerialSend11 to 16`` (#16723) ### Fixed - TasmotaSerial ``read(buffer, size)`` regression from v9.3.0 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 913348801..511885cba 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -153,6 +153,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds [#17055](https://github.com/arendst/Tasmota/issues/17055) - AC PWM dimmer lineair power distribution [#17177](https://github.com/arendst/Tasmota/issues/17177) - Zigbee improved Aqara plug support and completed cluster 0x0702 [#17073](https://github.com/arendst/Tasmota/issues/17073) +- Removed leading spaces on commands ``(S)SerialSend1 to 6`` but keep on duplicate commands ``(S)SerialSend11 to 16`` [#16723](https://github.com/arendst/Tasmota/issues/16723 ### Fixed - TasmotaSerial ``read(buffer, size)`` regression from v9.3.0 diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 51f7b41ca..e50167def 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -412,7 +412,8 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) bool binary_data = (index > 199); // Suppose binary data on topic index > 199 if (!binary_data) { - if (strstr_P(type, PSTR("SERIALSEND")) == nullptr) { // Do not skip leading spaces on (s)serialsend + bool keep_spaces = ((strstr_P(type, PSTR("SERIALSEND")) != nullptr) && (index > 9)); // Do not skip leading spaces on (s)serialsend10 and up + if (!keep_spaces) { while (*dataBuf && isspace(*dataBuf)) { dataBuf++; // Skip leading spaces in data data_len--; @@ -1880,8 +1881,8 @@ void CmndSerialBuffer(void) { #endif } -void CmndSerialSend(void) -{ +void CmndSerialSend(void) { + if (XdrvMailbox.index > 9) { XdrvMailbox.index -= 10; } if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { SetSeriallog(LOG_LEVEL_NONE); Settings->flag.mqtt_serial = 1; // CMND_SERIALSEND and CMND_SERIALLOG diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino index b5b626ad8..bcb38fc90 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino @@ -212,6 +212,7 @@ void SerialBridgeInit(void) { \*********************************************************************************************/ void CmndSSerialSend(void) { + if (XdrvMailbox.index > 9) { XdrvMailbox.index -= 10; } if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { serial_bridge_raw = (XdrvMailbox.index > 3); Settings->sbflag1.serbridge_console = 0; // Disable console Tee From 2a1b900775ee0aa8662dd55a9b9cb99118083503 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Sun, 4 Dec 2022 16:57:34 +0100 Subject: [PATCH 300/319] IPv6 improvements (#17268) * IPv6 improvements * Fix esp8266 compilation * grrr * Fix compilation issue * Fix declaration * Fix esp32c3 --- .../ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp | 10 + .../ESP32-to-ESP8266-compat/src/ESP8266WiFi.h | 2 + .../src/IPAddress46.cpp | 69 +++- .../ESP32-to-ESP8266-compat/src/IPAddress46.h | 16 +- .../ESP32-to-ESP8266-compat/src/Udp46.h | 93 +++++ .../ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp | 335 ++++++++++++++++++ .../ESP32-to-ESP8266-compat/src/WiFiUdp46.h | 77 ++++ lib/libesp32/berry_tasmota/src/be_udp_lib.cpp | 51 +-- tasmota/tasmota.ino | 2 + tasmota/tasmota_support/support_command.ino | 4 +- tasmota/tasmota_support/support_wifi.ino | 78 +++- 11 files changed, 704 insertions(+), 33 deletions(-) create mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h create mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp create mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp index b700f2955..43ec90479 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp @@ -91,6 +91,16 @@ bool WiFiClass32::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int3 return WiFi.getNetworkInfo(i, ssid, encType, rssi, bssid, channel); } +// from https://github.com/espressif/arduino-esp32/pull/7520 +static const int WIFI_WANT_IP6_BIT_ALT = BIT15; +bool WiFiClass32::IPv6(bool state) { + if (state) + WiFiGenericClass::setStatusBits(WIFI_WANT_IP6_BIT_ALT); + else + WiFiGenericClass::clearStatusBits(WIFI_WANT_IP6_BIT_ALT); + return true; +} + void wifi_station_disconnect() { // erase ap: empty ssid, ... WiFi.disconnect(true, true); diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h index f0a8476f6..1c1630b4c 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h @@ -50,6 +50,8 @@ public: static void forceSleepBegin(); static void forceSleepWake(); static bool getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &hidden_scan); + + bool IPv6(bool state); // make sure it always exists even with older Arduino framework }; void wifi_station_disconnect(); diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp index b0db1a5b8..365ab5801 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp @@ -45,17 +45,27 @@ #include #include +// Tasmota Logging +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); +enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; + IPAddress46::IPAddress46(const IPAddress46& from) { ip_addr_copy(_ip, from._ip); } IPAddress46::IPAddress46() { - _ip = *IP_ANY_TYPE; // lwIP's v4-or-v6 generic address +#if LWIP_IPV6 + _ip = *IP6_ADDR_ANY; +#else + _ip = *IP_ADDR_ANY; +#endif + // _ip = *IP_ANY_TYPE; // lwIP's v4-or-v6 generic address } bool IPAddress46::isSet () const { - return !ip_addr_isany(&_ip) && ((*this) != IPADDR_NONE); + return !IP_IS_ANY_TYPE_VAL(_ip); + // return !ip_addr_isany(&_ip) && ((*this) != IPADDR_NONE); } IPAddress46::IPAddress46(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) { @@ -152,8 +162,8 @@ bool IPAddress46::operator==(const uint8_t* addr) const { size_t IPAddress46::printTo(Print& p) const { size_t n = 0; - if (!isSet()) - return p.print(F("(IP unset)")); + // if (!isSet()) + // return p.print(F("(IP unset)")); #if LWIP_IPV6 if (isV6()) { @@ -267,4 +277,55 @@ bool IPAddress46::fromString6(const char *address) { return true; } +// -------------------------------------------------- +// Get host by name working for IPv6 +// -------------------------------------------------- +#include "lwip/dns.h" + +/** + * DNS callback + * @param name + * @param ipaddr + * @param callback_arg + */ +static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg) +{ + if(ipaddr) { + (*reinterpret_cast(callback_arg)) = IPAddress46(ipaddr); + } + WiFiGeneric46::DnsDone(); + // xEventGroupSetBits(_arduino_event_group, WIFI_DNS_DONE_BIT); +} + +int WiFiGeneric46::hostByName(const char* aHostname, IPAddress46& aResult) { + ip_addr_t addr; + aResult = static_cast(INADDR_NONE); + waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); + clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); + err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult, LWIP_DNS_ADDRTYPE_DEFAULT); + AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiGeneric46::hostByName err=%i", err); + + if(err == ERR_OK) { + aResult = IPAddress46(&addr); + + if (!aResult.isSet()) { +#if LWIP_IPV6 + aResult.setV6(); +#else + aResult.setV4(); +#endif + } + } else if(err == ERR_INPROGRESS) { + waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] + clearStatusBits(WIFI_DNS_DONE_BIT); + } + setStatusBits(WIFI_DNS_IDLE_BIT); + + if(err == ERR_OK) { + AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiGeneric46::hostByName Host: %s IP: %s", aHostname ? aHostname : "", aResult.toString().c_str()); + return 1; + } + return 0; +} + #endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h index 952c3ef7d..8aeff2015 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h @@ -123,7 +123,7 @@ class IPAddress46: public Printable { static bool isValid(const char* arg); friend class EthernetClass; - friend class UDP; + friend class UDP46; friend class Client; friend class Server; friend class DhcpClass; @@ -181,4 +181,18 @@ class IPAddress46: public Printable { bool fromString4(const char *address); }; +// -------------------------------------------------------------------------------- +// We need to create a subclass of WiFiGenericClass to access protected methods +// -------------------------------------------------------------------------------- +#include "WiFiGeneric.h" + +class WiFiGeneric46 : public WiFiGenericClass +{ + public: + WiFiGeneric46() {}; + + static int hostByName(const char *aHostname, IPAddress46 &aResult); + static void DnsDone(void) { setStatusBits(WIFI_DNS_DONE_BIT); }; +}; + #endif // __IPADDRESS46_H diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h new file mode 100644 index 000000000..85e891797 --- /dev/null +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h @@ -0,0 +1,93 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef udp46_h +#define udp46_h + +#include +#include + +class UDP46: public Stream +{ + +public: + virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t beginMulticast(IPAddress46, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure + virtual void stop() =0; // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress46 ip, uint16_t port) =0; + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port) =0; + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket() =0; + // Write a single byte into the packet + virtual size_t write(uint8_t) =0; + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size) =0; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket() =0; + // Number of bytes remaining in the current packet + virtual int available() =0; + // Read a single byte from the current packet + virtual int read() =0; + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len) =0; + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) =0; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek() =0; + virtual void flush() =0; // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress46 remoteIP() =0; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() =0; +protected: + uint8_t* rawIPAddress(IPAddress46& addr) + { + return addr.raw_address(); + } +}; + +#endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp new file mode 100644 index 000000000..79c34f94f --- /dev/null +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp @@ -0,0 +1,335 @@ +/* + Udp.cpp - UDP class for Raspberry Pi + Copyright (c) 2016 Hristo Gochkov All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "WiFiUdp46.h" +#include +#include +#include + +#undef write +#undef read + +// Tasmota Logging +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); +enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; + +WiFiUDP46::WiFiUDP46() +: udp_server(-1) +, server_port(0) +, remote_port(0) +, tx_buffer(0) +, tx_buffer_len(0) +, rx_buffer(0) +{} + +WiFiUDP46::~WiFiUDP46(){ + stop(); +} + +uint8_t WiFiUDP46::begin(IPAddress46 address, uint16_t port){ + stop(); + server_port = port; + + tx_buffer = new char[1460]; + if(!tx_buffer){ + log_e("could not create tx buffer: %d", errno); + return 0; + } + +#if LWIP_IPV6 + if ((udp_server=socket(AF_INET6, SOCK_DGRAM, 0)) == -1){ +#else + if ((udp_server=socket(AF_INET, SOCK_DGRAM, 0)) == -1){ +#endif + log_e("could not create socket: %d", errno); + return 0; + } + + // AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin socket called"); + int yes = 1; + if (setsockopt(udp_server,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) { + log_e("could not set socket option: %d", errno); + stop(); + return 0; + } + + //AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin setsockopt called"); + + struct sockaddr* sock_addr = NULL; + size_t sock_size = 0; + struct sockaddr_in addr; +#if LWIP_IPV6 + struct sockaddr_in6 addr6; + if (address.isV6()) { + // AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin set IPv6"); + memset((char *) &addr6, 0, sizeof(sockaddr_in6)); + addr6.sin6_len = sizeof(sockaddr_in6); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = htons(server_port); + addr6.sin6_addr = *(in6_addr*)(ip_addr_t*)address; + addr6.sin6_addr = in6addr_any; + addr6.sin6_flowinfo = 0; + sock_addr = (struct sockaddr*)&addr6; + sock_size = sizeof(sockaddr_in6); + + // AddLog(LOG_LEVEL_DEBUG, "SOCK_ADDR_TYPE_MATCH(name, sock)=%i", SOCK_ADDR_TYPE_MATCH(sock_addr, sock_size)); + } else +#endif + if (1) { + memset((char *) &addr, 0, sizeof(sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(server_port); + addr.sin_addr.s_addr = (in_addr_t)address; + sock_addr = (struct sockaddr*)&addr; + sock_size = sizeof(sockaddr_in); + } + //AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin udp_server=%p sock_addr=%p sock_size=%i", udp_server, sock_addr, sock_size); + if(bind(udp_server , sock_addr, sock_size) == -1){ + AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiUDP46::begin bind error=%o", errno); + log_e("could not bind socket: %d", errno); + stop(); + return 0; + } + fcntl(udp_server, F_SETFL, O_NONBLOCK); + return 1; +} + +uint8_t WiFiUDP46::begin(uint16_t p){ + return begin(IPAddress46(), p); +} + +uint8_t WiFiUDP46::beginMulticast(IPAddress46 a, uint16_t p){ + if(begin(IPAddress46(), p)){ + if(!ip_addr_isany((ip_addr_t*)a)){ + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = (in_addr_t)a; + mreq.imr_interface.s_addr = INADDR_ANY; + if (setsockopt(udp_server, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { + log_e("could not join igmp: %d", errno); + stop(); + return 0; + } + multicast_ip = a; + } + return 1; + } + return 0; +} + +void WiFiUDP46::stop(){ + if(tx_buffer){ + delete[] tx_buffer; + tx_buffer = NULL; + } + tx_buffer_len = 0; + if(rx_buffer){ + cbuf *b = rx_buffer; + rx_buffer = NULL; + delete b; + } + if(udp_server == -1) + return; + if(!ip_addr_isany((ip_addr_t*)multicast_ip)){ + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = (in_addr_t)multicast_ip; + mreq.imr_interface.s_addr = (in_addr_t)0; +#if LWIP_IPV6 + setsockopt(udp_server, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); +#else + setsockopt(udp_server, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); +#endif + multicast_ip = IPAddress46(INADDR_ANY); + } + close(udp_server); + udp_server = -1; +} + +int WiFiUDP46::beginMulticastPacket(){ + if(!server_port || multicast_ip == IPAddress46(INADDR_ANY)) + return 0; + remote_ip = multicast_ip; + remote_port = server_port; + return beginPacket(); +} + +int WiFiUDP46::beginPacket(){ + if(!remote_port) + return 0; + + // allocate tx_buffer if is necessary + if(!tx_buffer){ + tx_buffer = new char[1460]; + if(!tx_buffer){ + log_e("could not create tx buffer: %d", errno); + return 0; + } + } + + tx_buffer_len = 0; + + // check whereas socket is already open + if (udp_server != -1) + return 1; + + if ((udp_server=socket(AF_INET, SOCK_DGRAM, 0)) == -1){ + log_e("could not create socket: %d", errno); + return 0; + } + + fcntl(udp_server, F_SETFL, O_NONBLOCK); + + return 1; +} + +int WiFiUDP46::beginPacket(IPAddress46 ip, uint16_t port){ + remote_ip = ip; + remote_port = port; + return beginPacket(); +} + +int WiFiUDP46::beginPacket(const char *host, uint16_t port){ + struct hostent *server; + server = gethostbyname(host); + if (server == NULL){ + log_e("could not get host from dns: %d", errno); + return 0; + } + return beginPacket(IPAddress46((const uint8_t *)(server->h_addr_list[0])), port); +} + +int WiFiUDP46::endPacket(){ + if (remote_ip.isV4()) { + struct sockaddr_in recipient; + recipient.sin_len = sizeof(sockaddr_in); + recipient.sin_addr.s_addr = (uint32_t)remote_ip; + recipient.sin_family = AF_INET; + recipient.sin_port = htons(remote_port); + int sent = sendto(udp_server, tx_buffer, tx_buffer_len, 0, (struct sockaddr*) &recipient, sizeof(recipient)); + if(sent < 0){ + log_e("could not send data: %d", errno); + return 0; + } + } else { + struct sockaddr_in6 recipient; + recipient.sin6_len = sizeof(sockaddr_in6); + recipient.sin6_flowinfo = 0; + recipient.sin6_addr = *(in6_addr*)(ip_addr_t*)remote_ip; + // recipient.sin6_family = AF_INET6; + recipient.sin6_port = htons(remote_port); + int sent = sendto(udp_server, tx_buffer, tx_buffer_len, 0, (struct sockaddr*) &recipient, sizeof(recipient)); + if(sent < 0){ + log_e("could not send data: %d", errno); + return 0; + } + } + return 1; +} + +size_t WiFiUDP46::write(uint8_t data){ + if(tx_buffer_len == 1460){ + endPacket(); + tx_buffer_len = 0; + } + tx_buffer[tx_buffer_len++] = data; + return 1; +} + +size_t WiFiUDP46::write(const uint8_t *buffer, size_t size){ + size_t i; + for(i=0;i 0) { + rx_buffer = new cbuf(len); + rx_buffer->write(buf, len); + } + delete[] buf; + return len; +} + +int WiFiUDP46::available(){ + if(!rx_buffer) return 0; + return rx_buffer->available(); +} + +int WiFiUDP46::read(){ + if(!rx_buffer) return -1; + int out = rx_buffer->read(); + if(!rx_buffer->available()){ + cbuf *b = rx_buffer; + rx_buffer = 0; + delete b; + } + return out; +} + +int WiFiUDP46::read(unsigned char* buffer, size_t len){ + return read((char *)buffer, len); +} + +int WiFiUDP46::read(char* buffer, size_t len){ + if(!rx_buffer) return 0; + int out = rx_buffer->read(buffer, len); + if(!rx_buffer->available()){ + cbuf *b = rx_buffer; + rx_buffer = 0; + delete b; + } + return out; +} + +int WiFiUDP46::peek(){ + if(!rx_buffer) return -1; + return rx_buffer->peek(); +} + +void WiFiUDP46::flush(){ + if(!rx_buffer) return; + cbuf *b = rx_buffer; + rx_buffer = 0; + delete b; +} + +IPAddress46 WiFiUDP46::remoteIP(){ + return remote_ip; +} + +uint16_t WiFiUDP46::remotePort(){ + return remote_port; +} diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h new file mode 100644 index 000000000..d0436c51e --- /dev/null +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h @@ -0,0 +1,77 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef _WIFIUDP46_H_ +#define _WIFIUDP46_H_ + +#include +#include +#include + +class WiFiUDP46 : public UDP46 { +private: + int udp_server; + IPAddress46 multicast_ip; + IPAddress46 remote_ip; + uint16_t server_port; + uint16_t remote_port; + char * tx_buffer; + size_t tx_buffer_len; + cbuf * rx_buffer; +public: + WiFiUDP46(); + ~WiFiUDP46(); + uint8_t begin(IPAddress46 a, uint16_t p); + uint8_t begin(uint16_t p); + uint8_t beginMulticast(IPAddress46 a, uint16_t p); + void stop(); + int beginMulticastPacket(); + int beginPacket(); + int beginPacket(IPAddress46 ip, uint16_t port); + int beginPacket(const char *host, uint16_t port); + int endPacket(); + size_t write(uint8_t); + size_t write(const uint8_t *buffer, size_t size); + int parsePacket(); + int available(); + int read(); + int read(unsigned char* buffer, size_t len); + int read(char* buffer, size_t len); + int peek(); + void flush(); + IPAddress46 remoteIP(); + uint16_t remotePort(); +}; + +#endif /* _WIFIUDP46_H_ */ diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp index 27a97189f..9110be68c 100644 --- a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp +++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp @@ -15,21 +15,25 @@ #include #include -#include +#include #include "be_mapping.h" +// Tasmota Logging +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); +enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; + extern "C" { // init() - WiFiUDP *be_udp_init_ntv(void) { - return new WiFiUDP(); + WiFiUDP46 *be_udp_init_ntv(void) { + return new WiFiUDP46(); } int32_t be_udp_init(struct bvm *vm) { return be_call_c_func(vm, (void*) &be_udp_init_ntv, "+.p", ""); } // deinit() - void *be_udp_deinit_ntv(WiFiUDP *udp) { + void *be_udp_deinit_ntv(WiFiUDP46 *udp) { if (udp != nullptr) { delete udp; } return nullptr; } @@ -38,20 +42,22 @@ extern "C" { } // 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) - if(host && (*host != 0) && !WiFiGenericClass::hostByName(host, addr)){ - return 0; - } + int32_t be_udp_begin_ntv(WiFiUDP46 *udp, int32_t port) { + IPAddress46 addr; + // AddLog(LOG_LEVEL_DEBUG, "BRY: udp.begin listening to '%s'", addr.toString().c_str()); return udp->begin(addr, port); } int32_t be_udp_begin(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_udp_begin_ntv, "b", ".si"); + if (be_top(vm) >= 3 && be_isstring(vm, 2)) { + // legacy string parameter, now ignored + return be_call_c_func(vm, (void*) &be_udp_begin_ntv, "b", ".-i"); + } else { + return be_call_c_func(vm, (void*) &be_udp_begin_ntv, "b", ".i"); + } } // udp.stop() -> nil - void be_udp_stop_ntv(WiFiUDP *udp) { + void be_udp_stop_ntv(WiFiUDP46 *udp) { udp->stop(); } int32_t be_udp_stop(struct bvm *vm) { @@ -59,23 +65,24 @@ extern "C" { } // 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); - if(!WiFiGenericClass::hostByName(host, addr)){ + int32_t be_udp_begin_mcast_ntv(WiFiUDP46 *udp, const char *host, int32_t port) { + IPAddress46 addr; + if(!WiFiGeneric46::hostByName(host, addr)){ return 0; } - return udp->WiFiUDP::beginMulticast(addr, port); + return udp->WiFiUDP46::beginMulticast(addr, port); } int32_t be_udp_begin_mcast(struct bvm *vm) { return be_call_c_func(vm, (void*) &be_udp_begin_mcast_ntv, "b", ".si"); } // udp.send(address:string, port:int, payload:bytes) -> bool - int32_t be_udp_send_ntv(WiFiUDP *udp, const char *host, int32_t port, const uint8_t* buf, int32_t len) { - IPAddress addr((uint32_t)0); - if (!WiFiGenericClass::hostByName(host, addr)){ + int32_t be_udp_send_ntv(WiFiUDP46 *udp, const char *host, int32_t port, const uint8_t* buf, int32_t len) { + IPAddress46 addr; + if (!WiFiGeneric46::hostByName(host, addr)){ return 0; } + // AddLog(LOG_LEVEL_DEBUG, "BRY: udp.begin got host '%s'", addr.toString().c_str()); if (!udp->beginPacket(addr, port)) { return 0; } int bw = udp->write(buf, len); if (!bw) { return 0; } @@ -87,7 +94,7 @@ extern "C" { } // udp.send_multicast(payload:bytes) -> bool - int32_t be_udp_send_mcast_ntv(WiFiUDP *udp, const uint8_t* buf, int32_t len) { + int32_t be_udp_send_mcast_ntv(WiFiUDP46 *udp, const uint8_t* buf, int32_t len) { if (!udp->beginMulticastPacket()) { return 0; } int bw = udp->write(buf, len); if (!bw) { return 0; } @@ -100,7 +107,7 @@ extern "C" { // udp.read() -> bytes or nil int32_t be_udp_read(struct bvm *vm) { - WiFiUDP *udp = (WiFiUDP*) be_convert_single_elt(vm, 1, NULL, NULL); + WiFiUDP46 *udp = (WiFiUDP46*) be_convert_single_elt(vm, 1, NULL, NULL); if (udp->parsePacket()) { int btr = udp->available(); // btr contains the size of bytes_to_read @@ -128,7 +135,7 @@ extern "C" { int32_t btr2 = udp->read(buf, btr); // set remotet ip - IPAddress remote_ip = udp->remoteIP(); + IPAddress46 remote_ip = udp->remoteIP(); be_pushstring(vm, remote_ip.toString().c_str()); be_setmember(vm, 1, "remote_ip"); be_pop(vm, 1); diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index a90a1c069..b5e98c07d 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -118,6 +118,8 @@ struct WIFI { bool wifi_test_AP_TIMEOUT = false; bool wifi_Test_Restart = false; bool wifi_Test_Save_SSID2 = false; + // IPv6 support, not guarded with #if LWIP_IPV6 to avoid bloating code with ifdefs + bool ipv6_local_link_called = false; // did we already enable IPv6 Local-Link address, needs to be redone at each reconnect } Wifi; typedef struct { diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index e50167def..ce66bffe1 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -802,7 +802,9 @@ void CmndStatus(void) } if ((0 == payload) || (5 == payload)) { - // WifiDumpAddressesIPv6(); +#if LWIP_IPV6 + if (5 == payload) { WifiDumpAddressesIPv6(); } +#endif // LWIP_IPV6 Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "1\":\"%_I\",\"" D_JSON_DNSSERVER "2\":\"%_I\",\"" diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index 8fb65b4ed..439eb752e 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -213,6 +213,9 @@ 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 LWIP_IPV6 && defined(ESP32) + WiFi.IPv6(true); +#endif #ifdef USE_WIFI_RANGE_EXTENDER if (WiFi.getMode() != WIFI_AP_STA || !RgxApUp()) { // Preserve range extender connections (#17103) @@ -518,6 +521,17 @@ bool WifiHasIP(void) { } void WifiCheckIp(void) { +#if LWIP_IPV6 + if (WL_CONNECTED == WiFi.status()) { + if (!Wifi.ipv6_local_link_called) { + WiFi.enableIpV6(); + Wifi.ipv6_local_link_called = true; + // AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: calling enableIpV6")); + } + + } +#endif + if ((WL_CONNECTED == WiFi.status()) && WifiHasIP()) { WifiSetState(1); Wifi.counter = WIFI_CHECK_SEC; @@ -530,11 +544,6 @@ void WifiCheckIp(void) { Settings->ipv4_address[2] = (uint32_t)WiFi.subnetMask(); Settings->ipv4_address[3] = (uint32_t)WiFi.dnsIP(); Settings->ipv4_address[4] = (uint32_t)WiFi.dnsIP(1); -#if LWIP_IPV6 - // create Link-local address - CreateLinkLocalIPv6(); - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI "IPv6 Link-Local %s"), WifiGetIPv6LinkLocal().c_str()); -#endif // LWIP_IPV6 // Save current AP parameters for quick reconnect Settings->wifi_channel = WiFi.channel(); @@ -721,10 +730,21 @@ void WifiEnable(void) { //#include // sntp_servermode_dhcp() //#endif // ESP8266 +#ifdef ESP32 +void WifiEvents(arduino_event_t *event); +#endif + void WifiConnect(void) { if (!Settings->flag4.network_wifi) { return; } +#ifdef ESP32 + static bool wifi_event_registered = false; + if (!wifi_event_registered) { + WiFi.onEvent(WifiEvents); // register event listener only once + wifi_event_registered = true; + } +#endif // ESP32 WifiSetState(0); WifiSetOutputPower(); @@ -1039,3 +1059,51 @@ uint64_t WifiGetNtp(void) { ntp_server_id++; // Next server next time return 0; } + +// -------------------------------------------------------------------------------- +// Respond to some Arduino/esp-idf events for better IPv6 support +// -------------------------------------------------------------------------------- +#ifdef ESP32 +#include "IPAddress46.h" +// typedef void (*WiFiEventSysCb)(arduino_event_t *event); +void WifiEvents(arduino_event_t *event) { + switch (event->event_id) { + +#if LWIP_IPV6 + case ARDUINO_EVENT_WIFI_STA_GOT_IP6: + case ARDUINO_EVENT_ETH_GOT_IP6: + { + ip_addr_t ip_addr6; + ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); + IPAddress46 addr(ip_addr6); + AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: IPv6 %s %s"), addr.isLocal() ? PSTR("Link-Local") : PSTR("Global"), addr.toString().c_str()); + } + break; +#endif // LWIP_IPV6 + case ARDUINO_EVENT_ETH_GOT_IP: + case ARDUINO_EVENT_WIFI_STA_GOT_IP: + { + ip_addr_t ip_addr4; + ip_addr_copy_from_ip4(ip_addr4, event->event_info.got_ip.ip_info.ip); + AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: IPv4 %_I, mask %_I, gateway %_I"), + event->event_info.got_ip.ip_info.ip.addr, + event->event_info.got_ip.ip_info.netmask.addr, + event->event_info.got_ip.ip_info.gw.addr); + + } + break; + + case ARDUINO_EVENT_WIFI_STA_CONNECTED: + // AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: Received ARDUINO_EVENT_WIFI_STA_CONNECTED")); + Wifi.ipv6_local_link_called = false; // not sure if this is needed, make sure link-local is restored at each reconnect + break; + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: + case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE: + Wifi.ipv6_local_link_called = false; + break; + + default: + break; + } +} +#endif // ESP32 From 70f73edf9e8cb1c30bbf7bb29b23f88da7851b3e Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 4 Dec 2022 19:15:42 +0100 Subject: [PATCH 301/319] Fix type for BinaryInValue --- tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1b775935c..96216c02c 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 @@ -732,7 +732,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zstring, Cx000F, 0x002E, Z_(BinaryInInactiveText),Cm1, 0 }, { Zbool, Cx000F, 0x0051, Z_(BinaryInOutOfService),Cm1, 0 }, { Zenum8, Cx000F, 0x0054, Z_(BinaryInPolarity), Cm1, 0 }, - { Zstring, Cx000F, 0x0055, Z_(BinaryInValue), Cm1, 0 }, + { Zbool, Cx000F, 0x0055, Z_(BinaryInValue), Cm1, 0 }, // { 0xFF, Cx000F, 0x0057, (BinaryInPriorityArray),Cm1, 0 }, { Zenum8, Cx000F, 0x0067, Z_(BinaryInReliability), Cm1, 0 }, { Zmap8, Cx000F, 0x006F, Z_(BinaryInStatusFlags), Cm1, 0 }, From ec174406629563c9ff45372349554c149d523d60 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 4 Dec 2022 19:20:11 +0100 Subject: [PATCH 302/319] Berry crypto module, with AES_GCM by default and EC_CC25519 optional --- CHANGELOG.md | 1 + lib/libesp32/berry/default/be_modtab.c | 2 -- .../berry_tasmota/src/be_crypto_lib.c | 10 ++----- tasmota/my_user_config.h | 5 +++- .../xdrv_52_3_berry_crypto.ino | 30 +++++++++++++++++-- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65dc09e1c..22ed71f35 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.6] ### Added - Serial Modbus transmit enable GPIOs to all modbus energy drivers and modbus bridge (#17247) +- Berry crypto module, with AES_GCM by default and EC_CC25519 optional ### Breaking Changed diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c index 62c38ab0c..ad1844d0a 100644 --- a/lib/libesp32/berry/default/be_modtab.c +++ b/lib/libesp32/berry/default/be_modtab.c @@ -164,9 +164,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = { &be_native_module(flash), &be_native_module(partition_core), &be_native_module(crc), -#ifdef USE_ALEXA_AVS &be_native_module(crypto), -#endif #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 diff --git a/lib/libesp32/berry_tasmota/src/be_crypto_lib.c b/lib/libesp32/berry_tasmota/src/be_crypto_lib.c index 4108fd16a..5e6818a00 100644 --- a/lib/libesp32/berry_tasmota/src/be_crypto_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_crypto_lib.c @@ -7,8 +7,6 @@ *******************************************************************/ #include "be_constobj.h" -#ifdef USE_ALEXA_AVS - extern int m_aes_gcm_init(bvm *vm); extern int m_aes_gcm_encryt(bvm *vm); extern int m_aes_gcm_decryt(bvm *vm); @@ -23,7 +21,7 @@ extern int m_ec_c25519_sharedkey(bvm *vm); /* @const_object_info_begin -class be_class_aes_gcm (scope: global, name: AES_GCM, strings: weak) { +class be_class_aes_gcm (scope: global, name: AES_GCM) { .p1, var .p2, var @@ -33,16 +31,14 @@ class be_class_aes_gcm (scope: global, name: AES_GCM, strings: weak) { tag, func(m_aes_gcm_tag) } -class be_class_ec_c25519 (scope: global, name: EC_C25519, strings: weak) { +class be_class_ec_c25519 (scope: global, name: EC_C25519) { public_key, func(m_ec_c25519_pubkey) shared_key, func(m_ec_c25519_sharedkey) } -module crypto (scope: global, strings: weak) { +module crypto (scope: global) { AES_GCM, class(be_class_aes_gcm) EC_C25519, class(be_class_ec_c25519) } @const_object_info_end */ - -#endif // USE_ALEXA_AVS diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 9cd29bb80..e89a34b93 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -1096,6 +1096,9 @@ #define USE_BERRY_WEBCLIENT_TIMEOUT 2000 // Default timeout in milliseconds #define USE_BERRY_TCPSERVER // Enable TCP socket server (+0.6k) // #define USE_BERRY_ULP // Enable ULP (Ultra Low Power) support (+4.9k) + // Berry crypto extensions below: + #define USE_BERRY_CRYPTO_AES_GCM // enable AES GCM 256 bits + // #define USE_BERRY_CRYPTO_EC_C25519 // enable Elliptic Curve C C25519 #define USE_CSE7761 // Add support for CSE7761 Energy monitor as used in Sonoff Dual R3 // -- LVGL Graphics Library --------------------------------- @@ -1232,7 +1235,7 @@ #endif #endif -#if defined(USE_MQTT_TLS) || defined(USE_TELEGRAM) || defined(USE_WEBCLIENT_HTTPS) || defined(USE_ALEXA_AVS) +#if defined(USE_MQTT_TLS) || defined(USE_TELEGRAM) || defined(USE_WEBCLIENT_HTTPS) #define USE_TLS // flag indicates we need to include TLS code #endif diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino index f89ed23c6..2c89fb30a 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino @@ -19,7 +19,6 @@ #ifdef USE_BERRY -#ifdef USE_ALEXA_AVS #include #include "be_mem.h" @@ -34,6 +33,7 @@ extern "C" { // `AES_GCM.init(secret_key:bytes(32), iv:bytes(12)) -> instance` int32_t m_aes_gcm_init(struct bvm *vm); int32_t m_aes_gcm_init(struct bvm *vm) { +#ifdef USE_BERRY_CRYPTO_AES_GCM int32_t argc = be_top(vm); // Get the number of arguments if (argc >= 3 && be_isinstance(vm, 2) && be_isinstance(vm, 3)) { do { @@ -77,11 +77,15 @@ extern "C" { } while (0); } be_raise(vm, kTypeError, nullptr); +#else // USE_BERRY_CRYPTO_AES_GCM + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_AES_GCM } int32_t m_aes_gcm_encryt(bvm *vm); int32_t m_aes_gcm_decryt(bvm *vm); int32_t m_aes_gcm_encrypt_or_decryt(bvm *vm, int encrypt) { +#ifdef USE_BERRY_CRYPTO_AES_GCM int32_t argc = be_top(vm); // Get the number of arguments if (argc >= 2 && be_isinstance(vm, 2)) { do { @@ -111,15 +115,27 @@ extern "C" { } while (0); } be_raise(vm, kTypeError, nullptr); +#else // USE_BERRY_CRYPTO_AES_GCM + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_AES_GCM } int32_t m_aes_gcm_encryt(bvm *vm) { +#ifdef USE_BERRY_CRYPTO_AES_GCM return m_aes_gcm_encrypt_or_decryt(vm, 1); +#else // USE_BERRY_CRYPTO_AES_GCM + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_AES_GCM } int32_t m_aes_gcm_decryt(bvm *vm) { +#ifdef USE_BERRY_CRYPTO_AES_GCM return m_aes_gcm_encrypt_or_decryt(vm, 0); +#else // USE_BERRY_CRYPTO_AES_GCM + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_AES_GCM } int32_t m_aes_gcm_tag(bvm *vm) { +#ifdef USE_BERRY_CRYPTO_AES_GCM do { be_getglobal(vm, "bytes"); /* get the bytes class */ /* TODO eventually replace with be_getbuiltin */ @@ -137,6 +153,9 @@ extern "C" { // success } while (0); be_raise(vm, kTypeError, nullptr); +#else // USE_BERRY_CRYPTO_AES_GCM + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_AES_GCM } } @@ -151,6 +170,7 @@ extern "C" { // Computes the public key from a completely random private key of 32 bytes int32_t m_ec_c25519_pubkey(bvm *vm); int32_t m_ec_c25519_pubkey(bvm *vm) { +#ifdef USE_BERRY_CRYPTO_EC_C25519 int32_t argc = be_top(vm); // Get the number of arguments if (argc >= 2 && be_isbytes(vm, 2)) { size_t buf_len = 0; @@ -173,12 +193,16 @@ extern "C" { be_raise(vm, "value_error", "invalid input"); } be_raise(vm, kTypeError, nullptr); +#else // USE_BERRY_CRYPTO_EC_C25519 + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_EC_C25519 } // crypto.EC_C25519().shared_key(my_private_key:bytes(32), their_public_key:bytes(32)) -> bytes(32) // Computes the shared pre-key. Normally this shared pre-key is hashed with another algorithm. int32_t m_ec_c25519_sharedkey(bvm *vm); int32_t m_ec_c25519_sharedkey(bvm *vm) { +#ifdef USE_BERRY_CRYPTO_EC_C25519 int32_t argc = be_top(vm); // Get the number of arguments if (argc >= 3 && be_isbytes(vm, 2) && be_isbytes(vm, 3)) { size_t sk_len = 0; @@ -204,8 +228,10 @@ extern "C" { be_raise(vm, "value_error", "invalid input"); } be_raise(vm, kTypeError, nullptr); +#else // USE_BERRY_CRYPTO_EC_C25519 + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_EC_C25519 } } -#endif // USE_ALEXA_AVS #endif // USE_BERRY From 687e38f6b5d20656b1f9d2251f9849f19318df30 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Tue, 6 Dec 2022 09:27:51 +0100 Subject: [PATCH 303/319] Fix #17282 fix reboot on "shutter" command --- tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 14797d4ce..030f0927c 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -67,7 +67,7 @@ const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|" D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_SETOPEN "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|" D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS "|" D_CMND_SHUTTER_STOPOPEN "|" D_CMND_SHUTTER_STOPCLOSE "|" D_CMND_SHUTTER_STOPTOGGLE "|" D_CMND_SHUTTER_STOPTOGGLEDIR "|" D_CMND_SHUTTER_STOPPOSITION "|" D_CMND_SHUTTER_INCDEC "|" - D_CMND_SHUTTER_UNITTEST "|" D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|" D_CMND_SHUTTER_TILTINCDEC "|"; + D_CMND_SHUTTER_UNITTEST "|" D_CMND_SHUTTER_TILTCONFIG "|" D_CMND_SHUTTER_SETTILT "|" D_CMND_SHUTTER_TILTINCDEC; void (* const ShutterCommand[])(void) PROGMEM = { &CmndShutterOpen, &CmndShutterClose, &CmndShutterToggle, &CmndShutterToggleDir, &CmndShutterStop, &CmndShutterPosition, From 35475d9353930f251a32bc89b01d3ce944920082 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Tue, 6 Dec 2022 16:27:34 +0100 Subject: [PATCH 304/319] Avoid ghost switching in position 0 and 100 confirming the position and setting the tilt in 0 and 100% causes ghost switching of the relays. #16435 --- tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino index 030f0927c..20971efe0 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino @@ -1212,8 +1212,8 @@ void CmndShutterPosition(void) } // if position is either 0 or 100 reset the tilt to avoid tilt moving at the end - if (XdrvMailbox.payload == 0) {Shutter[index].tilt_target_pos = Shutter[index].tilt_config[4];} - if (XdrvMailbox.payload == 100) {Shutter[index].tilt_target_pos = Shutter[index].tilt_config[3];} + if (XdrvMailbox.payload == 0 && ShutterRealToPercentPosition(Shutter[index].real_position, index) > 0 ) {Shutter[index].tilt_target_pos = Shutter[index].tilt_config[4];} + if (XdrvMailbox.payload == 100 && ShutterRealToPercentPosition(Shutter[index].real_position, index) < 100) {Shutter[index].tilt_target_pos = Shutter[index].tilt_config[3];} int8_t target_pos_percent = (XdrvMailbox.payload < 0) ? (XdrvMailbox.payload == -99 ? ShutterRealToPercentPosition(Shutter[index].real_position, index) : 0) : ((XdrvMailbox.payload > 100) ? 100 : XdrvMailbox.payload); // webgui still send also on inverted shutter the native position. From 513d6239b30a8ccf8912f52cfee39680ea458093 Mon Sep 17 00:00:00 2001 From: Barbudor Date: Tue, 6 Dec 2022 20:07:18 +0100 Subject: [PATCH 305/319] Fix HMC5883 sensor json Fix https://github.com/arendst/Tasmota/issues/17295 --- tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino index a800a8998..d75a54773 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino @@ -173,7 +173,7 @@ const char HTTP_SNS_HMC5883L[] PROGMEM = 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,\""), + 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 { From 237695de229a65f632ad6b87d5265b92b177b91b Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Wed, 7 Dec 2022 08:52:13 +0100 Subject: [PATCH 306/319] fix recursion --- tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino index afa473936..17fd9b79b 100755 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino @@ -6025,7 +6025,9 @@ int16_t retval; if (!glob_script_mem.scriptptr) { return -99; } - if (tasm_cmd_activ && tlen > 0) return 0; + //if (tasm_cmd_activ && tlen > 0) return 0; + if (tasm_cmd_activ) return 0; + struct GVARS gv; gv.jo = 0; retval = Run_script_sub(type, tlen, &gv); @@ -6040,7 +6042,8 @@ int16_t retval; return -99; } - if (tasm_cmd_activ && tlen>0) return 0; + //if (tasm_cmd_activ && tlen>0) return 0; + if (tasm_cmd_activ) return 0; struct GVARS gv; @@ -7712,14 +7715,14 @@ else light_status += "true"; light_status += ","; break; */ - +String GetHueDeviceId(uint16_t id, uint8_t ep); void Script_HueStatus(String *response, uint16_t hue_devs) { if (hue_script[hue_devs].type=='p') { *response += FPSTR(SCRIPT_HUE_LIGHTS_STATUS_JSON2); response->replace("{j1", hue_script[hue_devs].name); - response->replace("{j2", GetHueDeviceId(hue_devs)); + response->replace("{j2", GetHueDeviceId(hue_devs, 0)); uint8_t pwr = glob_script_mem.fvars[hue_script[hue_devs].index[0] - 1]; response->replace("{state}", (pwr ? "true" : "false")); return; @@ -7793,7 +7796,7 @@ void Script_HueStatus(String *response, uint16_t hue_devs) { response->replace("{light_status}", light_status); response->replace("{j1", hue_script[hue_devs].name); - response->replace("{j2", GetHueDeviceId(hue_devs)); + response->replace("{j2", GetHueDeviceId(hue_devs, 0)); } From aa19bbf9706a449e46a0c5d68725b88ca3d0ffb9 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Wed, 7 Dec 2022 09:20:25 +0100 Subject: [PATCH 307/319] Update italian language Please check and merge, Thanks. --- tasmota/language/it_IT.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 5ba644f24..f595ca2ec 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 27.11.2022 + * Updated until v9.4.0.1 - Last update 07.12.2022 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -691,12 +691,12 @@ #define D_SENSOR_SBR_TX "SerBr - TX" #define D_SENSOR_MBR_TX "ModBr - TX" #define D_SENSOR_MBR_RX "ModBr - RX" -#define D_SENSOR_MBR_TX_ENA "ModBr - TX ENA" +#define D_SENSOR_MBR_TX_ENA "ModBr - TX ON" #define D_SENSOR_SR04_TRIG "SR04 Tri - TX" #define D_SENSOR_SR04_ECHO "SR04 Ech - RX" #define D_SENSOR_NRG_MBS_TX "NrgMbs - TX" #define D_SENSOR_NRG_MBS_RX "NrgMbs - RX" -#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs - TX ENA" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs - TX ON" #define D_SENSOR_SDM72_TX "SDM72 - TX" #define D_SENSOR_SDM72_RX "SDM72 - RX" #define D_SENSOR_SDM120_TX "SDMx20 - TX" From 5916d72598d450ee7c3ea8b0ef50155bf54ec4fc Mon Sep 17 00:00:00 2001 From: barbudor Date: Wed, 7 Dec 2022 19:01:17 +0100 Subject: [PATCH 308/319] add missing closing brace --- tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino index d75a54773..f460b9ba4 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino @@ -173,7 +173,7 @@ const char HTTP_SNS_HMC5883L[] PROGMEM = 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"), + 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 { From a83c45e3ad89949fcc7a2434b285fca8f675c478 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Thu, 8 Dec 2022 06:43:26 +0100 Subject: [PATCH 309/319] fix regression from latest commit --- tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino index 17fd9b79b..1f8596ec3 100755 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino @@ -469,6 +469,7 @@ struct SCRIPT_MEM { char *fast_script = 0; char *event_script = 0; char *html_script = 0; + char *teleperiod = 0; char *web_pages[10]; uint32_t script_lastmillis; bool event_handeled = false; @@ -6025,8 +6026,7 @@ int16_t retval; if (!glob_script_mem.scriptptr) { return -99; } - //if (tasm_cmd_activ && tlen > 0) return 0; - if (tasm_cmd_activ) return 0; + if (tasm_cmd_activ && tlen >= 0) return 0; struct GVARS gv; gv.jo = 0; @@ -6042,8 +6042,7 @@ int16_t retval; return -99; } - //if (tasm_cmd_activ && tlen>0) return 0; - if (tasm_cmd_activ) return 0; + if (tasm_cmd_activ && tlen >= 0) return 0; struct GVARS gv; @@ -7065,7 +7064,8 @@ void ScripterEvery100ms(void) { if (ResponseLength()) { ResponseJsonStart(); ResponseJsonEnd(); - Run_Scripter(">T", 2, ResponseData()); + //Run_Scripter(">T", 2, ResponseData()); + if (glob_script_mem.teleperiod) Run_Scripter(glob_script_mem.teleperiod, 0, ResponseData()); } } if (bitRead(Settings->rule_enabled, 0)) { @@ -7557,6 +7557,7 @@ void set_callbacks() { if (Run_Scripter1(">F", -2, 0) == 99) {glob_script_mem.fast_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.fast_script = 0;} if (Run_Scripter1(">E", -2, 0) == 99) {glob_script_mem.event_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.event_script = 0;} if (Run_Scripter1(">C", -2, 0) == 99) {glob_script_mem.html_script = glob_script_mem.section_ptr + 2;} else {glob_script_mem.html_script = 0;} + if (Run_Scripter1(">T", -2, 0) == 99) {glob_script_mem.teleperiod = glob_script_mem.section_ptr + 2;} else {glob_script_mem.teleperiod = 0;} } void set_wpages(char *id, uint16_t index) { @@ -11477,7 +11478,8 @@ bool Xdrv10(uint32_t function) case FUNC_TELEPERIOD_RULES_PROCESS: if (bitRead(Settings->rule_enabled, 0)) { if (ResponseLength()) { - Run_Scripter(">T", 2, ResponseData()); + //Run_Scripter(">T", 2, ResponseData()); + if (glob_script_mem.teleperiod) Run_Scripter(glob_script_mem.teleperiod, 0, ResponseData()); } } break; From 2f1b2ec5fd62a5ede5802318b5a18e0a50f85e11 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 8 Dec 2022 19:06:51 +0100 Subject: [PATCH 310/319] IPv6 support for Ethernet (ESP32) --- CHANGELOG.md | 1 + tasmota/include/i18n.h | 1 + tasmota/tasmota_support/support_command.ino | 13 +++- tasmota/tasmota_support/support_wifi.ino | 60 ++++++++++++------- .../xdrv_01_9_webserver.ino | 14 ++++- .../xdrv_52_3_berry_tasmota.ino | 14 ++++- .../xdrv_82_esp32_ethernet.ino | 45 ++++++++++---- 7 files changed, 111 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22ed71f35..5a019f47e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - Serial Modbus transmit enable GPIOs to all modbus energy drivers and modbus bridge (#17247) - Berry crypto module, with AES_GCM by default and EC_CC25519 optional +- IPv6 support for Ethernet (ESP32) ### Breaking Changed diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h index 4028b33d2..4294c3297 100644 --- a/tasmota/include/i18n.h +++ b/tasmota/include/i18n.h @@ -808,6 +808,7 @@ #define D_LOG_UPLOAD "UPL: " // Upload #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +#define D_LOG_ETH "ETH: " // Ethernet #define D_LOG_ZIGBEE "ZIG: " // Zigbee #define D_LOG_TCP "TCP: " // TCP bridge #define D_LOG_BERRY "BRY: " // Berry scripting language diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index ce66bffe1..7144351ed 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -828,11 +828,20 @@ void CmndStatus(void) ResponseAppend_P(PSTR(",\"Ethernet\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "1\":\"%_I\",\"" D_JSON_DNSSERVER "2\":\"%_I\",\"" - D_JSON_MAC "\":\"%s\"}"), + D_JSON_MAC "\":\"%s\"" + +#if LWIP_IPV6 + ",\"" D_JSON_IP6_GLOBAL "\":\"%s\",\"" D_JSON_IP6_LOCAL "\":\"%s\"" +#endif // LWIP_IPV6 + "}"), EthernetHostname(), (uint32_t)EthernetLocalIP(), Settings->eth_ipv4_address[1], Settings->eth_ipv4_address[2], Settings->eth_ipv4_address[3], Settings->eth_ipv4_address[4], - EthernetMacAddress().c_str()); + EthernetMacAddress().c_str() +#if LWIP_IPV6 + ,EthernetGetIPv6().c_str(), EthernetGetIPv6LinkLocal().c_str() +#endif // LWIP_IPV6 + ); #endif // USE_ETHERNET ResponseAppend_P(PSTR(",\"" D_CMND_WEBSERVER "\":%d,\"HTTP_API\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"), Settings->webserver, Settings->flag5.disable_referer_chk, Settings->sta_config, WifiGetOutputPower().c_str()); diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index 439eb752e..6c2914d8a 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -466,21 +466,34 @@ void WifiSetState(uint8_t state) } #if LWIP_IPV6 +// +// Scan through all interfaces to find a global or local IPv6 address +// Arg: +// is_local: is the address Link-Local (true) or Global (false) +// if_type: possible values are "st" for Wifi STA, "en" for Ethernet, "lo" for localhost (not useful) +static String WifiFindIPv6(bool is_local, const char * if_type = "st") { + for (netif* intf = netif_list; intf != nullptr; intf = intf->next) { + if (intf->name[0] == if_type[0] && intf->name[1] == if_type[1]) { + for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + ip_addr_t *ipv6 = &intf->ip6_addr[i]; + if (IP_IS_V6_VAL(*ipv6) && !ip_addr_isloopback(ipv6) && ((bool)ip_addr_islinklocal(ipv6) == is_local)) { + return IPAddress46(ipv6).toString(); + } + } + } + } + return String(); +} + // Returns only IPv6 global address (no loopback and no link-local) String WifiGetIPv6(void) { - for (auto a : addrList) { - if(!ip_addr_isloopback((ip_addr_t*)a.addr()) && !a.isLocal() && a.isV6()) return a.toString(); - } - return ""; + return WifiFindIPv6(false, "st"); } String WifiGetIPv6LinkLocal(void) { - for (auto a : addrList) { - if(!ip_addr_isloopback((ip_addr_t*)a.addr()) && a.isLocal() && a.isV6()) return a.toString(); - } - return ""; + return WifiFindIPv6(true, "st"); } // add an IPv6 link-local address to all netif @@ -493,16 +506,18 @@ void CreateLinkLocalIPv6(void) #endif // ESP32 } +// void WifiDumpAddressesIPv6(void) { - for (auto a: addrList) - AddLog(LOG_LEVEL_DEBUG, PSTR("IF='%s' index=%d legacy=%d IPv4=%d local=%d addr='%s'"), - a.ifname().c_str(), - a.ifnumber(), - a.isLegacy(), - a.addr().isV4(), - a.addr().isLocal(), - a.toString().c_str()); + for (netif* intf = netif_list; intf != nullptr; intf = intf->next) { + if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c' IPv4 %s", intf->name[0], intf->name[1], IPAddress46(intf->ip_addr).toString().c_str()); + for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (!ip_addr_isany_val(intf->ip6_addr[i])) + AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c' IPv6 %s %s", intf->name[0], intf->name[1], + IPAddress46(intf->ip6_addr[i]).toString().c_str(), + ip_addr_islinklocal(&intf->ip6_addr[i]) ? "local" : ""); + } + } } #endif // LWIP_IPV6=1 @@ -738,7 +753,7 @@ void WifiConnect(void) { if (!Settings->flag4.network_wifi) { return; } -#ifdef ESP32 +#if defined(ESP32) && !defined(FIRMWARE_MINIMAL) static bool wifi_event_registered = false; if (!wifi_event_registered) { WiFi.onEvent(WifiEvents); // register event listener only once @@ -895,6 +910,7 @@ bool WifiHostByName(const char* aHostname, IPAddress& aResult) { if (WiFi.hostByName(aHostname, aResult)) { // Host name resolved if (0xFFFFFFFF != (uint32_t)aResult) { + AddLog(LOG_LEVEL_DEBUG, "WIF: Resolving '%s' (%s)", aHostname, aResult.toString().c_str()); return true; } } @@ -903,6 +919,7 @@ bool WifiHostByName(const char* aHostname, IPAddress& aResult) { uint32_t dns_address = (!TasmotaGlobal.global_state.eth_down) ? Settings->eth_ipv4_address[3] : Settings->ipv4_address[3]; DnsClient.begin((IPAddress)dns_address); if (1 == DnsClient.getHostByName(aHostname, aResult)) { + AddLog(LOG_LEVEL_DEBUG, "WIF: Resolving '%s' (%s)", aHostname, aResult.toString().c_str()); return true; } } @@ -1076,16 +1093,19 @@ void WifiEvents(arduino_event_t *event) { ip_addr_t ip_addr6; ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); IPAddress46 addr(ip_addr6); - AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: IPv6 %s %s"), addr.isLocal() ? PSTR("Link-Local") : PSTR("Global"), addr.toString().c_str()); + AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"), + event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", + addr.isLocal() ? PSTR("Local") : PSTR("Global"), addr.toString().c_str()); } break; #endif // LWIP_IPV6 - case ARDUINO_EVENT_ETH_GOT_IP: case ARDUINO_EVENT_WIFI_STA_GOT_IP: + case ARDUINO_EVENT_ETH_GOT_IP: { ip_addr_t ip_addr4; ip_addr_copy_from_ip4(ip_addr4, event->event_info.got_ip.ip_info.ip); - AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: IPv4 %_I, mask %_I, gateway %_I"), + AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv4 %_I, mask %_I, gateway %_I"), + event->event_id == ARDUINO_EVENT_ETH_GOT_IP ? "ETH" : "WIF", event->event_info.got_ip.ip_info.ip.addr, event->event_info.got_ip.ip_info.netmask.addr, event->event_info.got_ip.ip_info.gw.addr); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index a681b3603..ffc691eca 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -2362,11 +2362,11 @@ void HandleInformation(void) #if LWIP_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr != "") { - WSContentSend_P(PSTR("}1 IPv6 Global }2%s"), ipv6_addr.c_str()); + WSContentSend_P(PSTR("}1 IPv6 Global (wifi)}2%s"), ipv6_addr.c_str()); } ipv6_addr = WifiGetIPv6LinkLocal(); if (ipv6_addr != "") { - WSContentSend_P(PSTR("}1 IPv6 Link-Local }2%s"), ipv6_addr.c_str()); + WSContentSend_P(PSTR("}1 IPv6 Local (wifi)}2%s"), ipv6_addr.c_str()); } #endif // LWIP_IPV6 = 1 if (static_cast(WiFi.localIP()) != 0) { @@ -2387,6 +2387,16 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1
}2
")); } WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? PSTR(".local") : ""); +#if LWIP_IPV6 + String ipv6_eth_addr = EthernetGetIPv6(); + if (ipv6_eth_addr != "") { + WSContentSend_P(PSTR("}1 IPv6 Global (eth)}2%s"), ipv6_eth_addr.c_str()); + } + ipv6_eth_addr = EthernetGetIPv6LinkLocal(); + if (ipv6_eth_addr != "") { + WSContentSend_P(PSTR("}1 IPv6 Local (eth)}2%s"), ipv6_eth_addr.c_str()); + } +#endif // LWIP_IPV6 = 1 WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%_I"), (uint32_t)EthernetLocalIP()); } 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 c6246514e..c2327b73f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino @@ -228,7 +228,7 @@ extern "C" { #endif if (static_cast(WiFi.localIP()) != 0) { be_map_insert_str(vm, "mac", WiFi.macAddress().c_str()); - be_map_insert_str(vm, "ip", WiFi.localIP().toString().c_str()); + be_map_insert_str(vm, "ip", IPAddress46((uint32_t)WiFi.localIP()).toString().c_str()); // quick fix for IPAddress bug show_rssi = true; } if (show_rssi) { @@ -252,8 +252,18 @@ extern "C" { #ifdef USE_ETHERNET if (static_cast(EthernetLocalIP()) != 0) { be_map_insert_str(vm, "mac", EthernetMacAddress().c_str()); - be_map_insert_str(vm, "ip", EthernetLocalIP().toString().c_str()); + be_map_insert_str(vm, "ip", IPAddress46((uint32_t)EthernetLocalIP()).toString().c_str()); // quick fix for IPAddress bug } +#if LWIP_IPV6 + String ipv6_addr = EthernetGetIPv6(); + if (ipv6_addr != "") { + be_map_insert_str(vm, "ip6", ipv6_addr.c_str()); + } + ipv6_addr = EthernetGetIPv6LinkLocal(); + if (ipv6_addr != "") { + be_map_insert_str(vm, "ip6local", ipv6_addr.c_str()); + } +#endif #endif be_pop(vm, 1); be_return(vm); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index 922d44abc..4b6b142be 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -85,19 +85,28 @@ char eth_hostname[sizeof(TasmotaGlobal.hostname)]; uint8_t eth_config_change; -void EthernetEvent(WiFiEvent_t event) { - switch (event) { +void EthernetEvent(arduino_event_t *event) { + switch (event->event_id) { case ARDUINO_EVENT_ETH_START: - AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: " D_ATTEMPTING_CONNECTION)); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH D_ATTEMPTING_CONNECTION)); ETH.setHostname(eth_hostname); break; + case ARDUINO_EVENT_ETH_CONNECTED: - AddLog(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED " at %dMbps%s"), - ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : ""); +#if LWIP_IPV6 + ETH.enableIpV6(); // enable Link-Local +#endif + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"), + ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "", + ETH.macAddress().c_str(), eth_hostname + ); + + // AddLog(LOG_LEVEL_DEBUG, D_LOG_ETH "ETH.enableIpV6() -> %i", ETH.enableIpV6()); break; + case ARDUINO_EVENT_ETH_GOT_IP: - AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %_I, Hostname %s"), - ETH.macAddress().c_str(), (uint32_t)ETH.localIP(), eth_hostname); + // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Mac %s, IPAddress %_I, Hostname %s"), + // ETH.macAddress().c_str(), (uint32_t)ETH.localIP(), eth_hostname); Settings->eth_ipv4_address[1] = (uint32_t)ETH.gatewayIP(); Settings->eth_ipv4_address[2] = (uint32_t)ETH.subnetMask(); if (0 == Settings->eth_ipv4_address[0]) { // At this point ETH.dnsIP() are NOT correct unless DHCP @@ -107,15 +116,18 @@ void EthernetEvent(WiFiEvent_t event) { TasmotaGlobal.rules_flag.eth_connected = 1; TasmotaGlobal.global_state.eth_down = 0; break; + case ARDUINO_EVENT_ETH_DISCONNECTED: - AddLog(LOG_LEVEL_INFO, PSTR("ETH: Disconnected")); + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH "Disconnected")); TasmotaGlobal.rules_flag.eth_disconnected = 1; TasmotaGlobal.global_state.eth_down = 1; break; + case ARDUINO_EVENT_ETH_STOP: - AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Stopped")); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Stopped")); TasmotaGlobal.global_state.eth_down = 1; break; + default: break; } @@ -130,10 +142,21 @@ void EthernetSetIp(void) { Settings->eth_ipv4_address[4]); // IPAddress dns2 } +// Returns only IPv6 global address (no loopback and no link-local) +String EthernetGetIPv6(void) +{ + return WifiFindIPv6(false, "en"); +} + +String EthernetGetIPv6LinkLocal(void) +{ + return WifiFindIPv6(true, "en"); +} + void EthernetInit(void) { if (!Settings->flag4.network_ethernet) { return; } if (!PinUsed(GPIO_ETH_PHY_MDC) && !PinUsed(GPIO_ETH_PHY_MDIO)) { - AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: No ETH MDC and/or ETH MDIO GPIO defined")); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "No ETH MDC and/or ETH MDIO GPIO defined")); return; } @@ -180,7 +203,7 @@ void EthernetInit(void) { delay(1); #endif // CONFIG_IDF_TARGET_ESP32 if (!ETH.begin(Settings->eth_address, eth_power, eth_mdc, eth_mdio, (eth_phy_type_t)Settings->eth_type, (eth_clock_mode_t)Settings->eth_clk_mode)) { - AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Bad PHY type or init error")); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Bad PHY type or init error")); return; }; From 20c8348654acee62604341520286e824ad63b77f Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 8 Dec 2022 19:42:04 +0100 Subject: [PATCH 311/319] Fix compilation --- tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index 4b6b142be..8e962d22c 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -85,6 +85,7 @@ char eth_hostname[sizeof(TasmotaGlobal.hostname)]; uint8_t eth_config_change; +void EthernetEvent(arduino_event_t *event); void EthernetEvent(arduino_event_t *event) { switch (event->event_id) { case ARDUINO_EVENT_ETH_START: From eee86f01a7b5288da45c095fd5f0d014043a7bb6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 8 Dec 2022 20:24:48 +0100 Subject: [PATCH 312/319] CI: Delay start of Linux builds (#17316) --- .github/workflows/build_all_the_things.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build_all_the_things.yml b/.github/workflows/build_all_the_things.yml index 15b07ba1b..a91217bac 100644 --- a/.github/workflows/build_all_the_things.yml +++ b/.github/workflows/build_all_the_things.yml @@ -113,6 +113,10 @@ jobs: - tasmota32s3-safeboot - tasmota32s3cdc-safeboot steps: + - name: Sleep a while, try to start MacOS / Windows CI env first + uses: jakejarvis/wait-action@master + with: + time: '1m' - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 From 561f6fd480cb881cfed824e3ea7cc02f0e3dfc5e Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Fri, 9 Dec 2022 09:32:14 +0100 Subject: [PATCH 313/319] fix text escape --- .../tasmota_xdrv_driver/xdrv_13_display.ino | 180 +++++++++++++----- 1 file changed, 136 insertions(+), 44 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino index f7cb20fc1..547fdde95 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino @@ -477,6 +477,7 @@ void DisplayText(void) escape = 1; cp++; // if string in buffer print it + dp -= decode_te(linebuf); if ((uint32_t)dp - (uint32_t)linebuf) { if (!fill) { *dp = 0; } if (col > 0 && lin > 0) { @@ -585,12 +586,17 @@ void DisplayText(void) break; #ifdef USE_UFILESYS case 'P': - { char *ep=strchr(cp,':'); + { char *ep = strchr(cp,':'); if (ep) { - *ep=0; + *ep = 0; ep++; - Draw_RGB_Bitmap(cp,disp_xpos,disp_ypos, false); - cp=ep; + int16_t scale = 0; + if (isdigit(*ep)) { + var = atoiv(ep, &scale); + ep += var; + } + Draw_RGB_Bitmap(cp,disp_xpos,disp_ypos, scale, false); + cp = ep; } } break; @@ -862,7 +868,7 @@ void DisplayText(void) cp = get_string(bbuff, sizeof(bbuff), cp); char unit[4]; cp = get_string(unit, sizeof(unit), cp); - decode_te(unit); + decode_te(unit); define_dt_var(num, gxp, gyp, textbcol, textfcol, font, textsize, txlen, time, dp, bbuff, unit); } } @@ -2271,7 +2277,7 @@ char ppath[16]; } else { strcat(ppath, ".jpg"); } - Draw_RGB_Bitmap(ppath, xp, yp, inverted); + Draw_RGB_Bitmap(ppath, xp, yp, 0, inverted); } #endif // USE_TOUCH_BUTTONS @@ -2281,51 +2287,62 @@ char ppath[16]; #include "img_converters.h" #include "esp_jpg_decode.h" bool jpg2rgb888(const uint8_t *src, size_t src_len, uint8_t * out, jpg_scale_t scale); +bool jpg2rgb565(const uint8_t *src, size_t src_len, uint8_t * out, jpg_scale_t scale); char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height); #endif // JPEG_PICTS #endif // ESP32 +//#define SLOW_RGB16 + #ifdef USE_UFILESYS extern FS *ufsp; #define XBUFF_LEN 128 -void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp, bool inverted ) { +void Draw_RGB_Bitmap(char *file, uint16_t xp, uint16_t yp, uint8_t scale, bool inverted ) { if (!renderer) return; File fp; - char *ending = strrchr(file,'.'); - if (!ending) return; - ending++; - char estr[8]; - memset(estr,0,sizeof(estr)); - for (uint32_t cnt=0; cnt= 0; cnt--) { + if (file[cnt] == '.') { + ending = &file[cnt + 1]; + break; + } } + if (!ending) return; + char estr[8]; + memset(estr, 0, sizeof(estr)); + for (uint32_t cnt = 0; cnt < strlen(ending); cnt++) { + estr[cnt] = tolower(ending[cnt]); + } + estr[3] = 0; if (!strcmp(estr,"rgb")) { // special rgb format - fp=ufsp->open(file,FS_FILE_READ); + fp = ufsp->open(file, FS_FILE_READ); if (!fp) return; uint16_t xsize; - fp.read((uint8_t*)&xsize,2); + fp.read((uint8_t*)&xsize, 2); uint16_t ysize; - fp.read((uint8_t*)&ysize,2); -#if 1 - renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize); - uint16_t rgb[xsize]; - for (int16_t j=0; jpushColors(rgb,xsize,true); - // } - OsWatchLoop(); + fp.read((uint8_t*)&ysize, 2); +#ifndef SLOW_RGB16 + renderer->setAddrWindow(xp, yp, xp + xsize, yp + ysize); + uint16_t *rgb = (uint16_t *)special_malloc(xsize * 2); + if (rgb) { + //uint16_t rgb[xsize]; + for (int16_t j = 0; j < ysize; j++) { + fp.read((uint8_t*)rgb, xsize * 2); + renderer->pushColors(rgb, xsize, true); + OsWatchLoop(); + } + free(rgb); } - renderer->setAddrWindow(0,0,0,0); + renderer->setAddrWindow(0, 0, 0, 0); #else - for(int16_t j=0; jwritePixel(xp+i,yp,rgb); + renderer->writePixel(xp + i, yp, rgb); } delay(0); OsWatchLoop(); @@ -2337,37 +2354,41 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp, bool inverted ) { // jpeg files on ESP32 with more memory #ifdef ESP32 #ifdef JPEG_PICTS - fp=ufsp->open(file,FS_FILE_READ); - if (!fp) return; + fp = ufsp->open(file, FS_FILE_READ); + if (!fp) { + // try url + Draw_JPG_from_URL(file, xp, yp, scale); + return; + } uint32_t size = fp.size(); - uint8_t *mem = (uint8_t *)special_malloc(size+4); + uint8_t *mem = (uint8_t *)special_malloc(size + 4); if (mem) { - uint8_t res=fp.read(mem, size); + uint8_t res = fp.read(mem, size); if (res) { uint16_t xsize; uint16_t ysize; - if (mem[0]==0xff && mem[1]==0xd8) { + if (mem[0] == 0xff && mem[1] == 0xd8) { get_jpeg_size(mem, size, &xsize, &ysize); //Serial.printf(" x,y,fs %d - %d - %d\n",xsize, ysize, size ); if (xsize && ysize) { - uint8_t *out_buf = (uint8_t *)special_malloc((xsize*ysize*3)+4); + uint8_t *out_buf = (uint8_t *)special_malloc((xsize * ysize * 3) + 4); if (out_buf) { - uint16_t *pixb = (uint16_t *)special_malloc((xsize*2)+4); + uint16_t *pixb = (uint16_t *)special_malloc((xsize * 2) + 4); if (pixb) { - uint8_t *ob=out_buf; + uint8_t *ob = out_buf; if (jpg2rgb888(mem, size, out_buf, (jpg_scale_t)JPG_SCALE_NONE)) { - renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize); - for(int32_t j=0; jsetAddrWindow(xp, yp, xp + xsize, yp + ysize); + for (int32_t j = 0; j < ysize; j++) { + if (inverted == false) { rgb888_to_565(ob, pixb, xsize); } else { rgb888_to_565i(ob, pixb, xsize); } - ob+=xsize*3; + ob += xsize * 3; renderer->pushColors(pixb, xsize, true); OsWatchLoop(); } - renderer->setAddrWindow(0,0,0,0); + renderer->setAddrWindow(0, 0, 0, 0); } free(out_buf); free(pixb); @@ -2385,6 +2406,77 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp, bool inverted ) { #endif // ESP32 } } + +#ifdef ESP32 +#ifdef JPEG_PICTS +#define JPG_DEFSIZE 150000 +void Draw_JPG_from_URL(char *url, uint16_t xp, uint16_t yp, uint8_t scale) { + uint8_t *mem = 0; + WiFiClient http_client; + HTTPClient http; + int32_t httpCode = 0; + String weburl = "http://" + UrlEncode(url); + http.begin(http_client, weburl); + httpCode = http.GET(); + //AddLog(LOG_LEVEL_INFO, PSTR("HTTP RESULT %d %s"), httpCode , weburl.c_str()); + uint32_t jpgsize = 0; + if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { + mem = (uint8_t *)special_malloc(JPG_DEFSIZE); + if (!mem) return; + uint8_t *jpgp = mem; + WiFiClient *stream = http.getStreamPtr(); + int32_t len = http.getSize(); + if (len < 0) len = 99999999; + while (http.connected() && (len > 0)) { + size_t size = stream->available(); + if (size) { + if (size > JPG_DEFSIZE) { + size = JPG_DEFSIZE; + } + uint32_t read = stream->readBytes(jpgp, size); + len -= read; + jpgp += read; + jpgsize += read; + //AddLog(LOG_LEVEL_INFO,PSTR("HTTP read %d - %d"), read, jpgsize); + } + delayMicroseconds(1); + } + } else { + AddLog(LOG_LEVEL_INFO, PSTR("HTTP ERROR %s"), http.getString().c_str()); + } + http.end(); + http_client.stop(); + + if (jpgsize) { + Draw_jpeg(mem, jpgsize, xp, yp, scale); + } + if (mem) free(mem); +} + +void Draw_jpeg(uint8_t *mem, uint16_t jpgsize, uint16_t xp, uint16_t yp, uint8_t scale) { + if (mem[0] == 0xff && mem[1] == 0xd8) { + uint16_t xsize; + uint16_t ysize; + get_jpeg_size(mem, jpgsize, &xsize, &ysize); + //AddLog(LOG_LEVEL_INFO, PSTR("Pict size %d - %d - %d"), xsize, ysize, jpgsize); + scale &= 3; + uint8_t fac = 1 << scale; + xsize /= fac; + ysize /= fac; + renderer->setAddrWindow(xp, yp, xp + xsize, yp + ysize); + uint8_t *rgbmem = (uint8_t *)special_malloc(xsize * ysize * 2); + if (rgbmem) { + //jpg2rgb565(mem, jpgsize, rgbmem, JPG_SCALE_NONE); + jpg2rgb565(mem, jpgsize, rgbmem, (jpg_scale_t)scale); + renderer->pushColors((uint16_t*)rgbmem, xsize * ysize, true); + free(rgbmem); + } + renderer->setAddrWindow(0, 0, 0, 0); + } +} +#endif // JPEG_PICTS +#endif // ESP32 + #endif // USE_UFILESYS /*********************************************************************************************\ From 423945233ca58da0fc0618e9c13118f99e10ee66 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 9 Dec 2022 17:35:57 +0100 Subject: [PATCH 314/319] Fix RFrecv exceptions 0 and/or 6 (#17285) --- lib/lib_rf/rc-switch/src/RCSwitch.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/lib_rf/rc-switch/src/RCSwitch.cpp b/lib/lib_rf/rc-switch/src/RCSwitch.cpp index c4e891f1b..05d2a8313 100644 --- a/lib/lib_rf/rc-switch/src/RCSwitch.cpp +++ b/lib/lib_rf/rc-switch/src/RCSwitch.cpp @@ -57,21 +57,21 @@ /* Protocol description format * * { - * Pulse length, - * + * Pulse length, + * * PreambleFactor, * Preamble {high,low}, - * + * * HeaderFactor, * Header {high,low}, - * + * * "0" bit {high,low}, * "1" bit {high,low}, - * + * * Inverted Signal, * Guard time * } - * + * * Pulse length: pulse duration (Te) in microseconds, * for example 350 * PreambleFactor: Number of high and low states to send @@ -80,7 +80,7 @@ * Preamble: Pulse shape which defines a preamble bit. * Sent ceil(PreambleFactor/2) times. * For example, {1, 2} with factor 3 would send - * _ _ + * _ _ * | |__| |__ (each horizontal bar has a duration of Te, * vertical bars are ignored) * HeaderFactor: Number of times to send the header pulse. @@ -88,22 +88,22 @@ * {1, 31} means one pulse of duration 1 Te high and 31 Te low * _ * | |_______________________________ (don't count the vertical bars) - * + * * "0" bit: pulse shape defining a data bit, which is a logical "0" * {1, 3} means 1 pulse duration Te high level and 3 low * _ * | |___ - * + * * "1" bit: pulse shape that defines the data bit, which is a logical "1" * {3, 1} means 3 pulses with a duration of Te high level and 1 low * ___ * | |_ * * (note: to form the state bit Z (Tri-State bit), two codes are combined) - * + * * Inverted Signal: Signal inversion - if true the signal is inverted * replacing high to low in a transmitted / received packet - * Guard time: Separation time between two retries. It will be followed by the + * Guard time: Separation time between two retries. It will be followed by the * next preamble of the next packet. In number of Te. * e.g. 39 pulses of duration Te low level */ @@ -758,7 +758,7 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun unsigned int sdelay = 0; if (syncLengthInPulses > 0) { sdelay = RCSwitch::timings[FirstTiming] / syncLengthInPulses; - } else { + } else if (pro.PreambleFactor > 0) { sdelay = RCSwitch::timings[FirstTiming-2] / pro.PreambleFactor; } const unsigned int delay = sdelay; From 742302c53f32f716b8a05a44b8375befdfdca8fc Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 10 Dec 2022 07:20:37 +0100 Subject: [PATCH 315/319] Makerfabs esp32-s3 p16 ili9488 --- lib/lib_display/UDisplay/uDisplay.cpp | 99 +++++++------------ .../displaydesc/MF_ILI9488_p16_display.ini | 30 ++++++ 2 files changed, 68 insertions(+), 61 deletions(-) create mode 100644 tasmota/displaydesc/MF_ILI9488_p16_display.ini diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp index af5835e3f..d3b55316e 100755 --- a/lib/lib_display/UDisplay/uDisplay.cpp +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -670,10 +670,10 @@ Renderer *uDisplay::Init(void) { } } else { for (uint32_t cnt = 0; cnt < 8; cnt ++) { - bus_config.data_gpio_nums[cnt] = par_dbh[cnt]; + bus_config.data_gpio_nums[cnt] = par_dbl[cnt]; } for (uint32_t cnt = 0; cnt < 8; cnt ++) { - bus_config.data_gpio_nums[cnt + 8] = par_dbl[cnt]; + bus_config.data_gpio_nums[cnt + 8] = par_dbh[cnt]; } } @@ -2490,6 +2490,8 @@ void uDisplay::_setup_dma_desc_links(const uint8_t *data, int32_t len) { */ } +#define WAIT_LCD_NOT_BUSY while (*reg_lcd_user & LCD_CAM_LCD_START) {} + void uDisplay::pb_beginTransaction(void) { auto dev = _dev; @@ -2533,84 +2535,60 @@ bool uDisplay::pb_busy(void) { } bool uDisplay::pb_writeCommand(uint32_t data, uint_fast8_t bit_length) { - if (interface == _UDSP_PAR8) { + auto dev = _dev; + auto reg_lcd_user = &(dev->lcd_user.val); + dev->lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE | LCD_CAM_LCD_CD_CMD_SET; + + if (interface == _UDSP_PAR8) { // 8bit bus auto bytes = bit_length >> 3; - auto dev = _dev; - auto reg_lcd_user = &(dev->lcd_user.val); - dev->lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE | LCD_CAM_LCD_CD_CMD_SET; do { dev->lcd_cmd_val.lcd_cmd_value = data; data >>= 8; - while (*reg_lcd_user & LCD_CAM_LCD_START) {} + WAIT_LCD_NOT_BUSY *reg_lcd_user = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; } while (--bytes); return true; - } else { - // 16 bit bus - if (_has_align_data) { _send_align_data(); } - auto dev = _dev; - auto reg_lcd_user = &(dev->lcd_user.val); - dev->lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE | LCD_CAM_LCD_CD_CMD_SET; + } else { dev->lcd_cmd_val.val = data; - - if (bit_length <= 16) { - while (*reg_lcd_user & LCD_CAM_LCD_START) {} - *reg_lcd_user = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; - return true; - } - - while (*reg_lcd_user & LCD_CAM_LCD_START) {} - *reg_lcd_user = LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; + WAIT_LCD_NOT_BUSY + *reg_lcd_user = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; return true; - } - } - + } +} void uDisplay::pb_writeData(uint32_t data, uint_fast8_t bit_length) { - if (interface == _UDSP_PAR8) { - auto bytes = bit_length >> 3; - auto dev = _dev; - auto reg_lcd_user = &(dev->lcd_user.val); - dev->lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE; + auto dev = _dev; + auto reg_lcd_user = &(dev->lcd_user.val); + dev->lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE; + auto bytes = bit_length >> 3; + if (interface == _UDSP_PAR8) { uint8_t shift = (bytes - 1) * 8; for (uint32_t cnt = 0; cnt < bytes; cnt++) { dev->lcd_cmd_val.lcd_cmd_value = (data >> shift) & 0xff; shift -= 8; - while (*reg_lcd_user & LCD_CAM_LCD_START) {} + WAIT_LCD_NOT_BUSY *reg_lcd_user = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; } return; } else { - auto bytes = bit_length >> 3; - auto dev = _dev; - auto reg_lcd_user = &(dev->lcd_user.val); - dev->lcd_misc.val = LCD_CAM_LCD_CD_IDLE_EDGE; - if (_has_align_data) { - _has_align_data = false; - dev->lcd_cmd_val.val = _align_data | (data << 8); - while (*reg_lcd_user & LCD_CAM_LCD_START) {} - *reg_lcd_user = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; - if (--bytes == 0) { return; } - data >>= 8; + if (bytes == 1 || bytes == 4) { + uint8_t shift = (bytes - 1) * 8; + for (uint32_t cnt = 0; cnt < bytes; cnt++) { + dev->lcd_cmd_val.lcd_cmd_value = (data >> shift) & 0xff; + shift -= 8; + WAIT_LCD_NOT_BUSY + *reg_lcd_user = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; + } + return; } - if (bytes > 1) { - dev->lcd_cmd_val.val = data; - if (bytes == 4) { - while (*reg_lcd_user & LCD_CAM_LCD_START) {} - *reg_lcd_user = LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; - return; - } - while (*reg_lcd_user & LCD_CAM_LCD_START) {} - *reg_lcd_user = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; - if (bytes == 2) { return; } - data >>= 16; - } - _has_align_data = true; - _align_data = data; + dev->lcd_cmd_val.val = data; + WAIT_LCD_NOT_BUSY + *reg_lcd_user = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; + return; } } @@ -2626,7 +2604,7 @@ void uDisplay::pb_pushPixels(uint16_t* data, uint32_t length, bool swap_bytes, b while (*reg_lcd_user & LCD_CAM_LCD_START) {} *reg_lcd_user = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; dev->lcd_cmd_val.lcd_cmd_value = *data >> 8; - while (*reg_lcd_user & LCD_CAM_LCD_START) {} + WAIT_LCD_NOT_BUSY *reg_lcd_user = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; data++; } @@ -2636,7 +2614,7 @@ void uDisplay::pb_pushPixels(uint16_t* data, uint32_t length, bool swap_bytes, b while (*reg_lcd_user & LCD_CAM_LCD_START) {} *reg_lcd_user = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; dev->lcd_cmd_val.lcd_cmd_value = *data; - while (*reg_lcd_user & LCD_CAM_LCD_START) {} + WAIT_LCD_NOT_BUSY *reg_lcd_user = LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; data++; } @@ -2648,14 +2626,13 @@ void uDisplay::pb_pushPixels(uint16_t* data, uint32_t length, bool swap_bytes, b iob = *data++; iob = (iob << 8) | (iob >> 8); dev->lcd_cmd_val.lcd_cmd_value = iob; - while (*reg_lcd_user & LCD_CAM_LCD_START) {} + WAIT_LCD_NOT_BUSY *reg_lcd_user = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; - data++; } } else { for (uint32_t cnt = 0; cnt < length; cnt++) { dev->lcd_cmd_val.lcd_cmd_value = *data++; - while (*reg_lcd_user & LCD_CAM_LCD_START) {} + WAIT_LCD_NOT_BUSY *reg_lcd_user = LCD_CAM_LCD_2BYTE_EN | LCD_CAM_LCD_CMD | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; } } diff --git a/tasmota/displaydesc/MF_ILI9488_p16_display.ini b/tasmota/displaydesc/MF_ILI9488_p16_display.ini new file mode 100644 index 000000000..e73eae9f0 --- /dev/null +++ b/tasmota/displaydesc/MF_ILI9488_p16_display.ini @@ -0,0 +1,30 @@ +:H,ILI9488,480,320,16,PAR,16,-1,37,36,35,48,45,47,21,14,13,12,11,10,9,3,8,16,15,7,6,5,4,20 +:S,2,1,1,0,40,20 +:I +E0,0F,00,03,09,08,16,0A,3F,78,4C,09,0A,08,16,1A,0F +E1,0F,00,16,19,03,0F,05,32,45,46,04,0E,0D,35,37,0F +C0,2,17,15 +C1,1,41 +C5,3,00,12,80 +36,1,48 +3A,1,55 +B0,1,80 +B1,1,A0 +B4,1,02 +B6,2,02,02 +E9,1,00 +F7,4,A9,51,2C,82 +11,80 +29,0 +:o,28 +:O,29 +:A,2A,2B,2C,16 +:R,36 +:0,28,00,00,85 +:1,88,00,00,02 +:2,E8,00,00,84 +:3,48,00,00,00 +:i,20,21 +:TI1,38,*,* +:B,20,0 +# From 4a32623a5130b8fbd2769f53b437799805926bb3 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 10 Dec 2022 13:44:16 +0100 Subject: [PATCH 316/319] IPv6 improvements --- .../ESP32-to-ESP8266-compat/src/AddrList46.h | 216 ----------- .../src/IPAddress46.cpp | 331 ----------------- .../ESP32-to-ESP8266-compat/src/IPAddress46.h | 198 ----------- .../ESP32-to-ESP8266-compat/src/Udp46.h | 93 ----- .../ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp | 335 ------------------ .../ESP32-to-ESP8266-compat/src/WiFiUdp46.h | 77 ---- .../src/esp8266toEsp32.h | 2 - lib/libesp32/berry_tasmota/src/be_udp_lib.cpp | 34 +- tasmota/my_user_config.h | 6 + tasmota/tasmota.ino | 9 +- tasmota/tasmota_support/support_command.ino | 20 +- tasmota/tasmota_support/support_wifi.ino | 43 +-- .../xdrv_01_9_webserver.ino | 12 +- .../tasmota_xdrv_driver/xdrv_02_9_mqtt.ino | 4 +- .../xdrv_52_3_berry_tasmota.ino | 14 +- .../xdrv_82_esp32_ethernet.ino | 6 +- 16 files changed, 75 insertions(+), 1325 deletions(-) delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h deleted file mode 100644 index bc2d07a39..000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - AddrList.h - cycle through lwIP netif's ip addresses like a c++ list - Copyright (c) 2018 david gauchard. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - This class allows to explore all configured IP addresses - in lwIP netifs, with that kind of c++ loop: - - for (auto a: addrList) - out.printf("IF='%s' index=%d legacy=%d IPv4=%d local=%d hostname='%s' addr= %s\n", - a.iface().c_str(), - a.ifnumber(), - a.addr().isLegacy(), - a.addr().isV4(), - a.addr().isLocal(), - a.hostname().c_str(), - a.addr().toString().c_str()); - - This loop: - - while (WiFi.status() != WL_CONNECTED()) { - Serial.print('.'); - delay(500); - } - - can be replaced by: - - for (bool configured = false; !configured; ) { - for (auto iface: addrList) - if ((configured = !iface.addr().isLocal()) - break; - Serial.print('.'); - delay(500); - } - - waiting for an IPv6 global address: - - for (bool configured = false; !configured; ) { - for (auto iface: addrList) - if ((configured = ( !iface.addr().isV4() - && !iface.addr().isLocal()))) - break; - Serial.print('.'); - delay(500); - } - - waiting for an IPv6 global address, on a specific interface: - - for (bool configured = false; !configured; ) { - for (auto iface: addrList) - if ((configured = ( !iface.addr().isV4() - && !iface.addr().isLocal() - && iface.ifnumber() == STATION_IF))) - break; - Serial.print('.'); - delay(500); - } -*/ - -#ifndef __ADDRLIST_H -#define __ADDRLIST_H - -#include -#include -#include "IPAddress46.h" - -#if LWIP_IPV6 -#define IF_NUM_ADDRESSES (1 + LWIP_IPV6_NUM_ADDRESSES) -#else -#define IF_NUM_ADDRESSES (1) -#endif - -namespace esp8266 -{ -namespace AddressListImplementation -{ -struct netifWrapper -{ - netifWrapper (netif* netif) : _netif(netif), _num(-1) {} - netifWrapper (const netifWrapper& o) : _netif(o._netif), _num(o._num) {} - - netifWrapper& operator= (const netifWrapper& o) - { - _netif = o._netif; - _num = o._num; - return *this; - } - - bool equal(const netifWrapper& o) - { - return _netif == o._netif && (!_netif || _num == o._num); - } - - IPAddress46 addr () const { return ipFromNetifNum(); } - bool isLegacy () const { return _num == 0; } - bool isLocal () const { return addr().isLocal(); } - bool isV4 () const { return addr().isV4(); } - bool isV6 () const { return !addr().isV4(); } - String toString() const { return addr().toString(); } - - // related to legacy address (_num=0, ipv4) - IPAddress46 ipv4 () const { return _netif->ip_addr; } - IPAddress46 netmask () const { return _netif->netmask; } - IPAddress46 gw () const { return _netif->gw; } - - // common to all addresses of this interface - String ifname () const { return String(_netif->name[0]) + _netif->name[1]; } - const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); } - const char* ifmac () const { return (const char*)_netif->hwaddr; } - int ifnumber () const { return _netif->num; } - bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); } - const netif* interface () const { return _netif; } - - const ip_addr_t* ipFromNetifNum () const - { -#if LWIP_IPV6 - return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr; -#else - return &_netif->ip_addr; -#endif - } - - // lwIP interface - netif* _netif; - - // address index within interface - // 0: legacy address (IPv4) - // n>0: (_num-1) is IPv6 index for netif->ip6_addr[] - int _num; -}; - - -class AddressListIterator -{ -public: - AddressListIterator (const netifWrapper& o) : netIf(o) {} - AddressListIterator (netif* netif) : netIf(netif) - { - // This constructor is called with lwIP's global netif_list, or - // nullptr. operator++() is designed to loop through _configured_ - // addresses. That's why netIf's _num is initialized to -1 to allow - // returning the first usable address to AddressList::begin(). - (void)operator++(); - } - - const netifWrapper& operator* () const { return netIf; } - const netifWrapper* operator-> () const { return &netIf; } - - bool operator== (AddressListIterator& o) { return netIf.equal(*o); } - bool operator!= (AddressListIterator& o) { return !netIf.equal(*o); } - - AddressListIterator operator++ (int) - { - AddressListIterator ret = *this; - (void)operator++(); - return ret; - } - - AddressListIterator& operator++ () - { - while (netIf._netif) - { - if (++netIf._num == IF_NUM_ADDRESSES) - { - // all addresses from current interface were iterated, - // switching to next interface - netIf = netifWrapper(netIf._netif->next); - continue; - } - if (!ip_addr_isany(netIf.ipFromNetifNum())) - // found an initialized address - break; - } - return *this; - } - - netifWrapper netIf; -}; - - -class AddressList -{ -public: - using const_iterator = const AddressListIterator; - - const_iterator begin () const { return const_iterator(netif_list); } - const_iterator end () const { return const_iterator(nullptr); } - -}; - -inline AddressList::const_iterator begin (const AddressList& a) { return a.begin(); } -inline AddressList::const_iterator end (const AddressList& a) { return a.end(); } - - -} // namespace AddressListImplementation -} // namespace esp8266 - -extern esp8266::AddressListImplementation::AddressList addrList; - - -#endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp deleted file mode 100644 index 365ab5801..000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* - IPAddress46.cpp - IPv6 support for ESP32 - - This class is copied from ESP8266 Arduino framework and provides - temporary support for IPv6 on ESP32. - - 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 . -*/ - -/* - IPAddress.cpp - Base class that provides IPAddress - - Copyright (c) 2011 Adrian McEwen. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -// Tasmota Logging -extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); -enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; - -IPAddress46::IPAddress46(const IPAddress46& from) -{ - ip_addr_copy(_ip, from._ip); -} - -IPAddress46::IPAddress46() { -#if LWIP_IPV6 - _ip = *IP6_ADDR_ANY; -#else - _ip = *IP_ADDR_ANY; -#endif - // _ip = *IP_ANY_TYPE; // lwIP's v4-or-v6 generic address -} - -bool IPAddress46::isSet () const { - return !IP_IS_ANY_TYPE_VAL(_ip); - // return !ip_addr_isany(&_ip) && ((*this) != IPADDR_NONE); -} - -IPAddress46::IPAddress46(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) { - setV4(); - (*this)[0] = first_octet; - (*this)[1] = second_octet; - (*this)[2] = third_octet; - (*this)[3] = fourth_octet; -} - -void IPAddress46::ctor32(uint32_t address) { - setV4(); - v4() = address; -} - -IPAddress46::IPAddress46(const uint8_t *address) { - setV4(); - (*this)[0] = address[0]; - (*this)[1] = address[1]; - (*this)[2] = address[2]; - (*this)[3] = address[3]; -} - -bool IPAddress46::fromString(const char *address) { - if (!fromString4(address)) { -#if LWIP_IPV6 - return fromString6(address); -#else - return false; -#endif - } - return true; -} - -bool IPAddress46::fromString4(const char *address) { - // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats - - uint16_t acc = 0; // Accumulator - uint8_t dots = 0; - - while (*address) - { - char c = *address++; - if (c >= '0' && c <= '9') - { - acc = acc * 10 + (c - '0'); - if (acc > 255) { - // Value out of [0..255] range - return false; - } - } - else if (c == '.') - { - if (dots == 3) { - // Too much dots (there must be 3 dots) - return false; - } - (*this)[dots++] = acc; - acc = 0; - } - else - { - // Invalid char - return false; - } - } - - if (dots != 3) { - // Too few dots (there must be 3 dots) - return false; - } - (*this)[3] = acc; - - setV4(); - return true; -} - -IPAddress46& IPAddress46::operator=(const uint8_t *address) { - setV4(); - v4() = *reinterpret_cast(address); - return *this; -} - -IPAddress46& IPAddress46::operator=(uint32_t address) { - setV4(); - v4() = address; - return *this; -} - -bool IPAddress46::operator==(const uint8_t* addr) const { - return isV4() && v4() == *reinterpret_cast(addr); -} - -size_t IPAddress46::printTo(Print& p) const { - size_t n = 0; - - // if (!isSet()) - // return p.print(F("(IP unset)")); - -#if LWIP_IPV6 - if (isV6()) { - int count0 = 0; - for (int i = 0; i < 8; i++) { - uint16_t bit = PP_NTOHS(raw6()[i]); - if (bit || count0 < 0) { - n += p.printf("%x", bit); - if (count0 > 0) - // no more hiding 0 - count0 = -8; - } else - count0++; - if ((i != 7 && count0 < 2) || count0 == 7) - n += p.print(':'); - } - return n; - } -#endif - - for(int i = 0; i < 4; i++) { - n += p.print((*this)[i], DEC); - if (i != 3) - n += p.print('.'); - } - return n; -} - -String IPAddress46::toString() const -{ - StreamString sstr; -#if LWIP_IPV6 - if (isV6()) - sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm - else -#endif - sstr.reserve(16); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)' - printTo(sstr); - return sstr; -} - -bool IPAddress46::isValid(const String& arg) { - return IPAddress46().fromString(arg); -} - -bool IPAddress46::isValid(const char* arg) { - return IPAddress46().fromString(arg); -} - -const IPAddress46 INADDR46_ANY; // generic "0.0.0.0" for IPv4 & IPv6 -const IPAddress46 INADDR46_NONE(255,255,255,255); - -void IPAddress46::clear() { - (*this) = INADDR46_ANY; -} - -/**************************************/ - -#if LWIP_IPV6 - -bool IPAddress46::fromString6(const char *address) { - // TODO: test test test - - uint32_t acc = 0; // Accumulator - int dots = 0, doubledots = -1; - - while (*address) - { - char c = tolower(*address++); - if (isalnum(c)) { - if (c >= 'a') - c -= 'a' - '0' - 10; - acc = acc * 16 + (c - '0'); - if (acc > 0xffff) - // Value out of range - return false; - } - else if (c == ':') { - if (*address == ':') { - if (doubledots >= 0) - // :: allowed once - return false; - // remember location - doubledots = dots + !!acc; - address++; - } - if (dots == 7) - // too many separators - return false; - raw6()[dots++] = PP_HTONS(acc); - acc = 0; - } - else - // Invalid char - return false; - } - - if (doubledots == -1 && dots != 7) - // Too few separators - return false; - raw6()[dots++] = PP_HTONS(acc); - - if (doubledots != -1) { - for (int i = dots - doubledots - 1; i >= 0; i--) - raw6()[8 - dots + doubledots + i] = raw6()[doubledots + i]; - for (int i = doubledots; i < 8 - dots + doubledots; i++) - raw6()[i] = 0; - } - - setV6(); - return true; -} - -// -------------------------------------------------- -// Get host by name working for IPv6 -// -------------------------------------------------- -#include "lwip/dns.h" - -/** - * DNS callback - * @param name - * @param ipaddr - * @param callback_arg - */ -static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg) -{ - if(ipaddr) { - (*reinterpret_cast(callback_arg)) = IPAddress46(ipaddr); - } - WiFiGeneric46::DnsDone(); - // xEventGroupSetBits(_arduino_event_group, WIFI_DNS_DONE_BIT); -} - -int WiFiGeneric46::hostByName(const char* aHostname, IPAddress46& aResult) { - ip_addr_t addr; - aResult = static_cast(INADDR_NONE); - waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); - clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); - err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult, LWIP_DNS_ADDRTYPE_DEFAULT); - AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiGeneric46::hostByName err=%i", err); - - if(err == ERR_OK) { - aResult = IPAddress46(&addr); - - if (!aResult.isSet()) { -#if LWIP_IPV6 - aResult.setV6(); -#else - aResult.setV4(); -#endif - } - } else if(err == ERR_INPROGRESS) { - waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] - clearStatusBits(WIFI_DNS_DONE_BIT); - } - setStatusBits(WIFI_DNS_IDLE_BIT); - - if(err == ERR_OK) { - AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiGeneric46::hostByName Host: %s IP: %s", aHostname ? aHostname : "", aResult.toString().c_str()); - return 1; - } - return 0; -} - -#endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h deleted file mode 100644 index 8aeff2015..000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - IPAddress46.h - IPv6 support for ESP32 - - This class is copied from ESP8266 Arduino framework and provides - temporary support for IPv6 on ESP32. - - 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 . -*/ - -#ifndef __IPADDRESS46_H -#define __IPADDRESS46_H - -#include -#include -#include - -class IPAddress46: public Printable { - private: - - ip_addr_t _ip; - - // Access the raw byte array containing the address. Because this returns a pointer - // to the internal structure rather than a copy of the address this function should only - // be used when you know that the usage of the returned uint8_t* will be transient and not - // stored. - uint8_t* raw_address() { - return reinterpret_cast(&v4()); - } - const uint8_t* raw_address() const { - return reinterpret_cast(&v4()); - } - - void ctor32 (uint32_t); - - public: - // Constructors - IPAddress46(); - IPAddress46(const IPAddress46& from); - IPAddress46(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); - IPAddress46(uint32_t address) { ctor32(address); } - IPAddress46(unsigned long address) { ctor32(address); } - IPAddress46(int address) { ctor32(address); } - IPAddress46(const uint8_t *address); - - bool fromString(const char *address); - bool fromString(const String &address) { return fromString(address.c_str()); } - - // Overloaded cast operator to allow IPAddress46 objects to be used where a pointer - // to a four-byte uint8_t array is expected - operator uint32_t() const { return isV4()? v4(): (uint32_t)0; } - operator uint32_t() { return isV4()? v4(): (uint32_t)0; } - - bool isSet () const; - operator bool () const { return isSet(); } // <- - operator bool () { return isSet(); } // <- both are needed - - // generic IPv4 wrapper to uint32-view like arduino loves to see it - const uint32_t& v4() const { return ip_2_ip4(&_ip)->addr; } // for raw_address(const) - uint32_t& v4() { return ip_2_ip4(&_ip)->addr; } - - bool operator==(const IPAddress46& addr) const { - return ip_addr_cmp(&_ip, &addr._ip); - } - bool operator!=(const IPAddress46& addr) const { - return !ip_addr_cmp(&_ip, &addr._ip); - } - bool operator==(uint32_t addr) const { - return isV4() && v4() == addr; - } - bool operator==(unsigned long addr) const { - return isV4() && v4() == (uint32_t)addr; - } - bool operator!=(uint32_t addr) const { - return !(isV4() && v4() == addr); - } - bool operator!=(unsigned long addr) const { - return isV4() && v4() != (uint32_t)addr; - } - bool operator==(const uint8_t* addr) const; - - int operator>>(int n) const { - return isV4()? v4() >> n: 0; - } - - // Overloaded index operator to allow getting and setting individual octets of the address - uint8_t operator[](int index) const { - return isV4()? *(raw_address() + index): 0; - } - uint8_t& operator[](int index) { - setV4(); - return *(raw_address() + index); - } - - // Overloaded copy operators to allow initialisation of IPAddress46 objects from other types - IPAddress46& operator=(const uint8_t *address); - IPAddress46& operator=(uint32_t address); - IPAddress46& operator=(const IPAddress46&) = default; - - virtual size_t printTo(Print& p) const; - String toString() const; - - void clear(); - - /* - check if input string(arg) is a valid IPV4 address or not. - return true on valid. - return false on invalid. - */ - static bool isValid(const String& arg); - static bool isValid(const char* arg); - - friend class EthernetClass; - friend class UDP46; - friend class Client; - friend class Server; - friend class DhcpClass; - friend class DNSClient; - - operator ip_addr_t () const { return _ip; } - operator const ip_addr_t*() const { return &_ip; } - operator ip_addr_t*() { return &_ip; } - - bool isV4() const { return IP_IS_V4_VAL(_ip); } - void setV4() { IP_SET_TYPE_VAL(_ip, IPADDR_TYPE_V4); } - - bool isLocal () const { return ip_addr_islinklocal(&_ip); } - -#if LWIP_IPV6 - IPAddress46(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); } - IPAddress46(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); } - - IPAddress46& operator=(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); return *this; } - IPAddress46& operator=(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); return *this; } - - uint16_t* raw6() - { - setV6(); - return reinterpret_cast(ip_2_ip6(&_ip)); - } - - const uint16_t* raw6() const - { - return isV6()? reinterpret_cast(ip_2_ip6(&_ip)): nullptr; - } - - // when not IPv6, ip_addr_t == ip4_addr_t so this one would be ambiguous - // required otherwise - operator const ip4_addr_t*() const { return isV4()? ip_2_ip4(&_ip): nullptr; } - - bool isV6() const { return IP_IS_V6_VAL(_ip); } - void setV6() { IP_SET_TYPE_VAL(_ip, IPADDR_TYPE_V6); } - - protected: - bool fromString6(const char *address); - -#else - - // allow portable code when IPv6 is not enabled - - uint16_t* raw6() { return nullptr; } - const uint16_t* raw6() const { return nullptr; } - bool isV6() const { return false; } - void setV6() { } - -#endif - - protected: - bool fromString4(const char *address); -}; - -// -------------------------------------------------------------------------------- -// We need to create a subclass of WiFiGenericClass to access protected methods -// -------------------------------------------------------------------------------- -#include "WiFiGeneric.h" - -class WiFiGeneric46 : public WiFiGenericClass -{ - public: - WiFiGeneric46() {}; - - static int hostByName(const char *aHostname, IPAddress46 &aResult); - static void DnsDone(void) { setStatusBits(WIFI_DNS_DONE_BIT); }; -}; - -#endif // __IPADDRESS46_H diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h deleted file mode 100644 index 85e891797..000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Udp.cpp: Library to send/receive UDP packets. - * - * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) - * 1) UDP does not guarantee the order in which assembled UDP packets are received. This - * might not happen often in practice, but in larger network topologies, a UDP - * packet can be received out of sequence. - * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being - * aware of it. Again, this may not be a concern in practice on small local networks. - * For more information, see http://www.cafeaulait.org/course/week12/35.html - * - * MIT License: - * Copyright (c) 2008 Bjoern Hartmann - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * bjoern@cs.stanford.edu 12/30/2008 - */ - -#ifndef udp46_h -#define udp46_h - -#include -#include - -class UDP46: public Stream -{ - -public: - virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use - virtual uint8_t beginMulticast(IPAddress46, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure - virtual void stop() =0; // Finish with the UDP socket - - // Sending UDP packets - - // Start building up a packet to send to the remote host specific in ip and port - // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port - virtual int beginPacket(IPAddress46 ip, uint16_t port) =0; - // Start building up a packet to send to the remote host specific in host and port - // Returns 1 if successful, 0 if there was a problem resolving the hostname or port - virtual int beginPacket(const char *host, uint16_t port) =0; - // Finish off this packet and send it - // Returns 1 if the packet was sent successfully, 0 if there was an error - virtual int endPacket() =0; - // Write a single byte into the packet - virtual size_t write(uint8_t) =0; - // Write size bytes from buffer into the packet - virtual size_t write(const uint8_t *buffer, size_t size) =0; - - // Start processing the next available incoming packet - // Returns the size of the packet in bytes, or 0 if no packets are available - virtual int parsePacket() =0; - // Number of bytes remaining in the current packet - virtual int available() =0; - // Read a single byte from the current packet - virtual int read() =0; - // Read up to len bytes from the current packet and place them into buffer - // Returns the number of bytes read, or 0 if none are available - virtual int read(unsigned char* buffer, size_t len) =0; - // Read up to len characters from the current packet and place them into buffer - // Returns the number of characters read, or 0 if none are available - virtual int read(char* buffer, size_t len) =0; - // Return the next byte from the current packet without moving on to the next byte - virtual int peek() =0; - virtual void flush() =0; // Finish reading the current packet - - // Return the IP address of the host who sent the current incoming packet - virtual IPAddress46 remoteIP() =0; - // Return the port of the host who sent the current incoming packet - virtual uint16_t remotePort() =0; -protected: - uint8_t* rawIPAddress(IPAddress46& addr) - { - return addr.raw_address(); - } -}; - -#endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp deleted file mode 100644 index 79c34f94f..000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - Udp.cpp - UDP class for Raspberry Pi - Copyright (c) 2016 Hristo Gochkov All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include "WiFiUdp46.h" -#include -#include -#include - -#undef write -#undef read - -// Tasmota Logging -extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); -enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; - -WiFiUDP46::WiFiUDP46() -: udp_server(-1) -, server_port(0) -, remote_port(0) -, tx_buffer(0) -, tx_buffer_len(0) -, rx_buffer(0) -{} - -WiFiUDP46::~WiFiUDP46(){ - stop(); -} - -uint8_t WiFiUDP46::begin(IPAddress46 address, uint16_t port){ - stop(); - server_port = port; - - tx_buffer = new char[1460]; - if(!tx_buffer){ - log_e("could not create tx buffer: %d", errno); - return 0; - } - -#if LWIP_IPV6 - if ((udp_server=socket(AF_INET6, SOCK_DGRAM, 0)) == -1){ -#else - if ((udp_server=socket(AF_INET, SOCK_DGRAM, 0)) == -1){ -#endif - log_e("could not create socket: %d", errno); - return 0; - } - - // AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin socket called"); - int yes = 1; - if (setsockopt(udp_server,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) { - log_e("could not set socket option: %d", errno); - stop(); - return 0; - } - - //AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin setsockopt called"); - - struct sockaddr* sock_addr = NULL; - size_t sock_size = 0; - struct sockaddr_in addr; -#if LWIP_IPV6 - struct sockaddr_in6 addr6; - if (address.isV6()) { - // AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin set IPv6"); - memset((char *) &addr6, 0, sizeof(sockaddr_in6)); - addr6.sin6_len = sizeof(sockaddr_in6); - addr6.sin6_family = AF_INET6; - addr6.sin6_port = htons(server_port); - addr6.sin6_addr = *(in6_addr*)(ip_addr_t*)address; - addr6.sin6_addr = in6addr_any; - addr6.sin6_flowinfo = 0; - sock_addr = (struct sockaddr*)&addr6; - sock_size = sizeof(sockaddr_in6); - - // AddLog(LOG_LEVEL_DEBUG, "SOCK_ADDR_TYPE_MATCH(name, sock)=%i", SOCK_ADDR_TYPE_MATCH(sock_addr, sock_size)); - } else -#endif - if (1) { - memset((char *) &addr, 0, sizeof(sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(server_port); - addr.sin_addr.s_addr = (in_addr_t)address; - sock_addr = (struct sockaddr*)&addr; - sock_size = sizeof(sockaddr_in); - } - //AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin udp_server=%p sock_addr=%p sock_size=%i", udp_server, sock_addr, sock_size); - if(bind(udp_server , sock_addr, sock_size) == -1){ - AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiUDP46::begin bind error=%o", errno); - log_e("could not bind socket: %d", errno); - stop(); - return 0; - } - fcntl(udp_server, F_SETFL, O_NONBLOCK); - return 1; -} - -uint8_t WiFiUDP46::begin(uint16_t p){ - return begin(IPAddress46(), p); -} - -uint8_t WiFiUDP46::beginMulticast(IPAddress46 a, uint16_t p){ - if(begin(IPAddress46(), p)){ - if(!ip_addr_isany((ip_addr_t*)a)){ - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = (in_addr_t)a; - mreq.imr_interface.s_addr = INADDR_ANY; - if (setsockopt(udp_server, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { - log_e("could not join igmp: %d", errno); - stop(); - return 0; - } - multicast_ip = a; - } - return 1; - } - return 0; -} - -void WiFiUDP46::stop(){ - if(tx_buffer){ - delete[] tx_buffer; - tx_buffer = NULL; - } - tx_buffer_len = 0; - if(rx_buffer){ - cbuf *b = rx_buffer; - rx_buffer = NULL; - delete b; - } - if(udp_server == -1) - return; - if(!ip_addr_isany((ip_addr_t*)multicast_ip)){ - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = (in_addr_t)multicast_ip; - mreq.imr_interface.s_addr = (in_addr_t)0; -#if LWIP_IPV6 - setsockopt(udp_server, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); -#else - setsockopt(udp_server, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); -#endif - multicast_ip = IPAddress46(INADDR_ANY); - } - close(udp_server); - udp_server = -1; -} - -int WiFiUDP46::beginMulticastPacket(){ - if(!server_port || multicast_ip == IPAddress46(INADDR_ANY)) - return 0; - remote_ip = multicast_ip; - remote_port = server_port; - return beginPacket(); -} - -int WiFiUDP46::beginPacket(){ - if(!remote_port) - return 0; - - // allocate tx_buffer if is necessary - if(!tx_buffer){ - tx_buffer = new char[1460]; - if(!tx_buffer){ - log_e("could not create tx buffer: %d", errno); - return 0; - } - } - - tx_buffer_len = 0; - - // check whereas socket is already open - if (udp_server != -1) - return 1; - - if ((udp_server=socket(AF_INET, SOCK_DGRAM, 0)) == -1){ - log_e("could not create socket: %d", errno); - return 0; - } - - fcntl(udp_server, F_SETFL, O_NONBLOCK); - - return 1; -} - -int WiFiUDP46::beginPacket(IPAddress46 ip, uint16_t port){ - remote_ip = ip; - remote_port = port; - return beginPacket(); -} - -int WiFiUDP46::beginPacket(const char *host, uint16_t port){ - struct hostent *server; - server = gethostbyname(host); - if (server == NULL){ - log_e("could not get host from dns: %d", errno); - return 0; - } - return beginPacket(IPAddress46((const uint8_t *)(server->h_addr_list[0])), port); -} - -int WiFiUDP46::endPacket(){ - if (remote_ip.isV4()) { - struct sockaddr_in recipient; - recipient.sin_len = sizeof(sockaddr_in); - recipient.sin_addr.s_addr = (uint32_t)remote_ip; - recipient.sin_family = AF_INET; - recipient.sin_port = htons(remote_port); - int sent = sendto(udp_server, tx_buffer, tx_buffer_len, 0, (struct sockaddr*) &recipient, sizeof(recipient)); - if(sent < 0){ - log_e("could not send data: %d", errno); - return 0; - } - } else { - struct sockaddr_in6 recipient; - recipient.sin6_len = sizeof(sockaddr_in6); - recipient.sin6_flowinfo = 0; - recipient.sin6_addr = *(in6_addr*)(ip_addr_t*)remote_ip; - // recipient.sin6_family = AF_INET6; - recipient.sin6_port = htons(remote_port); - int sent = sendto(udp_server, tx_buffer, tx_buffer_len, 0, (struct sockaddr*) &recipient, sizeof(recipient)); - if(sent < 0){ - log_e("could not send data: %d", errno); - return 0; - } - } - return 1; -} - -size_t WiFiUDP46::write(uint8_t data){ - if(tx_buffer_len == 1460){ - endPacket(); - tx_buffer_len = 0; - } - tx_buffer[tx_buffer_len++] = data; - return 1; -} - -size_t WiFiUDP46::write(const uint8_t *buffer, size_t size){ - size_t i; - for(i=0;i 0) { - rx_buffer = new cbuf(len); - rx_buffer->write(buf, len); - } - delete[] buf; - return len; -} - -int WiFiUDP46::available(){ - if(!rx_buffer) return 0; - return rx_buffer->available(); -} - -int WiFiUDP46::read(){ - if(!rx_buffer) return -1; - int out = rx_buffer->read(); - if(!rx_buffer->available()){ - cbuf *b = rx_buffer; - rx_buffer = 0; - delete b; - } - return out; -} - -int WiFiUDP46::read(unsigned char* buffer, size_t len){ - return read((char *)buffer, len); -} - -int WiFiUDP46::read(char* buffer, size_t len){ - if(!rx_buffer) return 0; - int out = rx_buffer->read(buffer, len); - if(!rx_buffer->available()){ - cbuf *b = rx_buffer; - rx_buffer = 0; - delete b; - } - return out; -} - -int WiFiUDP46::peek(){ - if(!rx_buffer) return -1; - return rx_buffer->peek(); -} - -void WiFiUDP46::flush(){ - if(!rx_buffer) return; - cbuf *b = rx_buffer; - rx_buffer = 0; - delete b; -} - -IPAddress46 WiFiUDP46::remoteIP(){ - return remote_ip; -} - -uint16_t WiFiUDP46::remotePort(){ - return remote_port; -} diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h deleted file mode 100644 index d0436c51e..000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Udp.cpp: Library to send/receive UDP packets. - * - * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) - * 1) UDP does not guarantee the order in which assembled UDP packets are received. This - * might not happen often in practice, but in larger network topologies, a UDP - * packet can be received out of sequence. - * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being - * aware of it. Again, this may not be a concern in practice on small local networks. - * For more information, see http://www.cafeaulait.org/course/week12/35.html - * - * MIT License: - * Copyright (c) 2008 Bjoern Hartmann - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * bjoern@cs.stanford.edu 12/30/2008 - */ - -#ifndef _WIFIUDP46_H_ -#define _WIFIUDP46_H_ - -#include -#include -#include - -class WiFiUDP46 : public UDP46 { -private: - int udp_server; - IPAddress46 multicast_ip; - IPAddress46 remote_ip; - uint16_t server_port; - uint16_t remote_port; - char * tx_buffer; - size_t tx_buffer_len; - cbuf * rx_buffer; -public: - WiFiUDP46(); - ~WiFiUDP46(); - uint8_t begin(IPAddress46 a, uint16_t p); - uint8_t begin(uint16_t p); - uint8_t beginMulticast(IPAddress46 a, uint16_t p); - void stop(); - int beginMulticastPacket(); - int beginPacket(); - int beginPacket(IPAddress46 ip, uint16_t port); - int beginPacket(const char *host, uint16_t port); - int endPacket(); - size_t write(uint8_t); - size_t write(const uint8_t *buffer, size_t size); - int parsePacket(); - int available(); - int read(); - int read(unsigned char* buffer, size_t len); - int read(char* buffer, size_t len); - int peek(); - void flush(); - IPAddress46 remoteIP(); - uint16_t remotePort(); -}; - -#endif /* _WIFIUDP46_H_ */ diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index f6a6338c6..23ed7f1b4 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -137,8 +137,6 @@ typedef int SerialConfig; //#define PortUdp_writestr(log_data) PortUdp.write((const uint8_t *)(log_data), strlen(log_data)) #define PortUdp_write(log_data, n) PortUdp.write((const uint8_t *)(log_data), n) -#undef LWIP_IPV6 - #define REASON_DEFAULT_RST 0 // "Power on" normal startup by power on #define REASON_WDT_RST 1 // "Hardware Watchdog" hardware watch dog reset #define REASON_EXCEPTION_RST 2 // "Exception" exception reset, GPIO status won’t change diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp index 9110be68c..f6084b049 100644 --- a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp +++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include "be_mapping.h" // Tasmota Logging @@ -25,15 +25,15 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D extern "C" { // init() - WiFiUDP46 *be_udp_init_ntv(void) { - return new WiFiUDP46(); + WiFiUDP *be_udp_init_ntv(void) { + return new WiFiUDP(); } int32_t be_udp_init(struct bvm *vm) { return be_call_c_func(vm, (void*) &be_udp_init_ntv, "+.p", ""); } // deinit() - void *be_udp_deinit_ntv(WiFiUDP46 *udp) { + void *be_udp_deinit_ntv(WiFiUDP *udp) { if (udp != nullptr) { delete udp; } return nullptr; } @@ -42,8 +42,8 @@ extern "C" { } // udp.begin(address:string, port:int) -> bool - int32_t be_udp_begin_ntv(WiFiUDP46 *udp, int32_t port) { - IPAddress46 addr; + int32_t be_udp_begin_ntv(WiFiUDP *udp, int32_t port) { + IPAddress addr; // AddLog(LOG_LEVEL_DEBUG, "BRY: udp.begin listening to '%s'", addr.toString().c_str()); return udp->begin(addr, port); } @@ -57,7 +57,7 @@ extern "C" { } // udp.stop() -> nil - void be_udp_stop_ntv(WiFiUDP46 *udp) { + void be_udp_stop_ntv(WiFiUDP *udp) { udp->stop(); } int32_t be_udp_stop(struct bvm *vm) { @@ -65,21 +65,21 @@ extern "C" { } // udp.begin_multicast(address:string, port:int) -> nil - int32_t be_udp_begin_mcast_ntv(WiFiUDP46 *udp, const char *host, int32_t port) { - IPAddress46 addr; - if(!WiFiGeneric46::hostByName(host, addr)){ + int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) { + IPAddress addr; + if(!WiFiGenericClass::hostByName(host, addr)){ return 0; } - return udp->WiFiUDP46::beginMulticast(addr, port); + return udp->WiFiUDP::beginMulticast(addr, port); } int32_t be_udp_begin_mcast(struct bvm *vm) { return be_call_c_func(vm, (void*) &be_udp_begin_mcast_ntv, "b", ".si"); } // udp.send(address:string, port:int, payload:bytes) -> bool - int32_t be_udp_send_ntv(WiFiUDP46 *udp, const char *host, int32_t port, const uint8_t* buf, int32_t len) { - IPAddress46 addr; - if (!WiFiGeneric46::hostByName(host, addr)){ + int32_t be_udp_send_ntv(WiFiUDP *udp, const char *host, int32_t port, const uint8_t* buf, int32_t len) { + IPAddress addr; + if (!WiFiGenericClass::hostByName(host, addr)){ return 0; } // AddLog(LOG_LEVEL_DEBUG, "BRY: udp.begin got host '%s'", addr.toString().c_str()); @@ -94,7 +94,7 @@ extern "C" { } // udp.send_multicast(payload:bytes) -> bool - int32_t be_udp_send_mcast_ntv(WiFiUDP46 *udp, const uint8_t* buf, int32_t len) { + int32_t be_udp_send_mcast_ntv(WiFiUDP *udp, const uint8_t* buf, int32_t len) { if (!udp->beginMulticastPacket()) { return 0; } int bw = udp->write(buf, len); if (!bw) { return 0; } @@ -107,7 +107,7 @@ extern "C" { // udp.read() -> bytes or nil int32_t be_udp_read(struct bvm *vm) { - WiFiUDP46 *udp = (WiFiUDP46*) be_convert_single_elt(vm, 1, NULL, NULL); + WiFiUDP *udp = (WiFiUDP*) be_convert_single_elt(vm, 1, NULL, NULL); if (udp->parsePacket()) { int btr = udp->available(); // btr contains the size of bytes_to_read @@ -135,7 +135,7 @@ extern "C" { int32_t btr2 = udp->read(buf, btr); // set remotet ip - IPAddress46 remote_ip = udp->remoteIP(); + IPAddress remote_ip = udp->remoteIP(); be_pushstring(vm, remote_ip.toString().c_str()); be_setmember(vm, 1, "remote_ip"); be_pop(vm, 1); diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e89a34b93..b73e0ff80 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -405,6 +405,12 @@ #define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 13 as used by Wi-Fi Manager web GUI #define USE_IMPROV // Add support for IMPROV serial protocol as used by esp-web-tools (+2k code) +// -- IPv6 support ------------------------------- +// #define USE_IPV6 // Enable IPv6 support (if the underlying esp-idf is also configured to support it) + // Code size increase: + // ESP8266: tbd + // ESP32: tbd + // -- ESP-NOW ------------------------------------- //#define USE_TASMESH // Enable Tasmota Mesh using ESP-NOW (+11k code) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index b5e98c07d..479dce33a 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -32,6 +32,13 @@ #include "include/i18n.h" // Language support configured by my_user_config.h #include "include/tasmota_template.h" // Hardware configuration +// ------------------------------------------------------------------------------------------ +// If IPv6 is not support by the underlying esp-idf, disable it +// ------------------------------------------------------------------------------------------ +#if !LWIP_IPV6 + #undef USE_IPV6 +#endif + // Libraries #include // Ota #include // Ota @@ -494,7 +501,7 @@ void setup(void) { #ifdef ESP32 AddLog(LOG_LEVEL_INFO, PSTR("HDW: %s %s"), GetDeviceHardware().c_str(), FoundPSRAM() ? (CanUsePSRAM() ? "(PSRAM)" : "(PSRAM disabled)") : "" ); - AddLog(LOG_LEVEL_DEBUG, PSTR("HDW: FoundPSRAM=%i CanUsePSRAM=%i"), FoundPSRAM(), CanUsePSRAM()); + // AddLog(LOG_LEVEL_DEBUG, PSTR("HDW: FoundPSRAM=%i CanUsePSRAM=%i"), FoundPSRAM(), CanUsePSRAM()); #if !defined(HAS_PSRAM_FIX) if (FoundPSRAM() && !CanUsePSRAM()) { AddLog(LOG_LEVEL_INFO, PSTR("HDW: PSRAM is disabled, requires specific compilation on this hardware (see doc)")); diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 7144351ed..07fba6fe4 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -802,24 +802,24 @@ void CmndStatus(void) } if ((0 == payload) || (5 == payload)) { -#if LWIP_IPV6 +#ifdef USE_IPV6 if (5 == payload) { WifiDumpAddressesIPv6(); } -#endif // LWIP_IPV6 +#endif // USE_IPV6 Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "1\":\"%_I\",\"" D_JSON_DNSSERVER "2\":\"%_I\",\"" D_JSON_MAC "\":\"%s\"" -#if LWIP_IPV6 +#ifdef USE_IPV6 ",\"" D_JSON_IP6_GLOBAL "\":\"%s\",\"" D_JSON_IP6_LOCAL "\":\"%s\"" -#endif // LWIP_IPV6 +#endif // USE_IPV6 ), TasmotaGlobal.hostname, (uint32_t)WiFi.localIP(), Settings->ipv4_address[1], Settings->ipv4_address[2], Settings->ipv4_address[3], Settings->ipv4_address[4], WiFi.macAddress().c_str() -#if LWIP_IPV6 +#ifdef USE_IPV6 ,WifiGetIPv6().c_str(), WifiGetIPv6LinkLocal().c_str() -#endif // LWIP_IPV6 +#endif // USE_IPV6 ); #ifdef USE_TASMESH ResponseAppend_P(PSTR(",\"SoftAPMac\":\"%s\""), WiFi.softAPmacAddress().c_str()); @@ -830,17 +830,17 @@ void CmndStatus(void) D_JSON_DNSSERVER "1\":\"%_I\",\"" D_JSON_DNSSERVER "2\":\"%_I\",\"" D_JSON_MAC "\":\"%s\"" -#if LWIP_IPV6 +#ifdef USE_IPV6 ",\"" D_JSON_IP6_GLOBAL "\":\"%s\",\"" D_JSON_IP6_LOCAL "\":\"%s\"" -#endif // LWIP_IPV6 +#endif // USE_IPV6 "}"), EthernetHostname(), (uint32_t)EthernetLocalIP(), Settings->eth_ipv4_address[1], Settings->eth_ipv4_address[2], Settings->eth_ipv4_address[3], Settings->eth_ipv4_address[4], EthernetMacAddress().c_str() -#if LWIP_IPV6 +#ifdef USE_IPV6 ,EthernetGetIPv6().c_str(), EthernetGetIPv6LinkLocal().c_str() -#endif // LWIP_IPV6 +#endif // USE_IPV6 ); #endif // USE_ETHERNET ResponseAppend_P(PSTR(",\"" D_CMND_WEBSERVER "\":%d,\"HTTP_API\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"), diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index 6c2914d8a..b72c309cd 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -41,13 +41,6 @@ const uint8_t WIFI_CHECK_SEC = 20; // seconds const uint8_t WIFI_RETRY_OFFSET_SEC = WIFI_RETRY_SECONDS; // seconds #include // Wifi, MQTT, Ota, WifiManager -#if LWIP_IPV6 - #ifdef ESP8266 - #include // IPv6 DualStack - #else - #include // IPv6 DualStack - #endif -#endif // LWIP_IPV6=1 int WifiGetRssiAsQuality(int rssi) { int quality = 0; @@ -213,7 +206,7 @@ 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 LWIP_IPV6 && defined(ESP32) +#if defined(USE_IPV6) && defined(ESP32) WiFi.IPv6(true); #endif @@ -465,7 +458,7 @@ void WifiSetState(uint8_t state) } } -#if LWIP_IPV6 +#ifdef USE_IPV6 // // Scan through all interfaces to find a global or local IPv6 address // Arg: @@ -476,8 +469,8 @@ static String WifiFindIPv6(bool is_local, const char * if_type = "st") { if (intf->name[0] == if_type[0] && intf->name[1] == if_type[1]) { for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { ip_addr_t *ipv6 = &intf->ip6_addr[i]; - if (IP_IS_V6_VAL(*ipv6) && !ip_addr_isloopback(ipv6) && ((bool)ip_addr_islinklocal(ipv6) == is_local)) { - return IPAddress46(ipv6).toString(); + if (IP_IS_V6_VAL(*ipv6) && !ip_addr_isloopback(ipv6) && !ip_addr_isany(ipv6) && ((bool)ip_addr_islinklocal(ipv6) == is_local)) { + return IPAddress(ipv6).toString(); } } } @@ -510,33 +503,28 @@ void CreateLinkLocalIPv6(void) void WifiDumpAddressesIPv6(void) { for (netif* intf = netif_list; intf != nullptr; intf = intf->next) { - if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c' IPv4 %s", intf->name[0], intf->name[1], IPAddress46(intf->ip_addr).toString().c_str()); + if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c' IPv4 %s", intf->name[0], intf->name[1], IPAddress(intf->ip_addr).toString().c_str()); for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (!ip_addr_isany_val(intf->ip6_addr[i])) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c' IPv6 %s %s", intf->name[0], intf->name[1], - IPAddress46(intf->ip6_addr[i]).toString().c_str(), + IPAddress(intf->ip6_addr[i]).toString().c_str(), ip_addr_islinklocal(&intf->ip6_addr[i]) ? "local" : ""); } } } -#endif // LWIP_IPV6=1 +#endif // USE_IPV6 // Check to see if we have any routable IP address bool WifiHasIP(void) { -#if LWIP_IPV6 - for (auto a : addrList) { - if(!ip_addr_isloopback((ip_addr_t*)a.addr()) && !a.isLocal()) { - return true; - } - } - return false; +#ifdef USE_IPV6 + return !WiFi.localIP().isAny(); #else return (uint32_t)WiFi.localIP() != 0; -#endif +#endif // USE_IPV6 } void WifiCheckIp(void) { -#if LWIP_IPV6 +#ifdef USE_IPV6 if (WL_CONNECTED == WiFi.status()) { if (!Wifi.ipv6_local_link_called) { WiFi.enableIpV6(); @@ -545,7 +533,7 @@ void WifiCheckIp(void) { } } -#endif +#endif // USE_IPV6 if ((WL_CONNECTED == WiFi.status()) && WifiHasIP()) { WifiSetState(1); @@ -1081,24 +1069,23 @@ uint64_t WifiGetNtp(void) { // Respond to some Arduino/esp-idf events for better IPv6 support // -------------------------------------------------------------------------------- #ifdef ESP32 -#include "IPAddress46.h" // typedef void (*WiFiEventSysCb)(arduino_event_t *event); void WifiEvents(arduino_event_t *event) { switch (event->event_id) { -#if LWIP_IPV6 +#ifdef USE_IPV6 case ARDUINO_EVENT_WIFI_STA_GOT_IP6: case ARDUINO_EVENT_ETH_GOT_IP6: { ip_addr_t ip_addr6; ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); - IPAddress46 addr(ip_addr6); + IPAddress addr(ip_addr6); AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"), event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", addr.isLocal() ? PSTR("Local") : PSTR("Global"), addr.toString().c_str()); } break; -#endif // LWIP_IPV6 +#endif // USE_IPV6 case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_ETH_GOT_IP: { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index ffc691eca..94eaf5d27 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -610,7 +610,7 @@ void StartWebserver(int type, IPAddress ipweb) Webserver->begin(); // Web server start } if (Web.state != type) { -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr!="") { AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %_I and IPv6 global address %s "), @@ -622,7 +622,7 @@ void StartWebserver(int type, IPAddress ipweb) #else AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %_I"), NetworkHostname(), (Mdns.begun) ? PSTR(".local") : "", (uint32_t)ipweb); -#endif // LWIP_IPV6 = 1 +#endif // USE_IPV6 TasmotaGlobal.rules_flag.http_init = 1; Web.state = type; } @@ -2359,7 +2359,7 @@ void HandleInformation(void) int32_t rssi = WiFi.RSSI(); WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm) 11%c"), Settings->sta_active +1, HtmlEscape(SettingsText(SET_STASSID1 + Settings->sta_active)).c_str(), WifiGetRssiAsQuality(rssi), rssi, pgm_read_byte(&kWifiPhyMode[WiFi.getPhyMode() & 0x3]) ); WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), TasmotaGlobal.hostname, (Mdns.begun) ? PSTR(".local") : ""); -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Global (wifi)}2%s"), ipv6_addr.c_str()); @@ -2368,7 +2368,7 @@ void HandleInformation(void) if (ipv6_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Local (wifi)}2%s"), ipv6_addr.c_str()); } -#endif // LWIP_IPV6 = 1 +#endif // USE_IPV6 if (static_cast(WiFi.localIP()) != 0) { WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (wifi)}2%_I"), (uint32_t)WiFi.localIP()); @@ -2387,7 +2387,7 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1
}2
")); } WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? PSTR(".local") : ""); -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_eth_addr = EthernetGetIPv6(); if (ipv6_eth_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Global (eth)}2%s"), ipv6_eth_addr.c_str()); @@ -2396,7 +2396,7 @@ void HandleInformation(void) if (ipv6_eth_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Local (eth)}2%s"), ipv6_eth_addr.c_str()); } -#endif // LWIP_IPV6 = 1 +#endif // USE_IPV6 WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%_I"), (uint32_t)EthernetLocalIP()); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino index fdd2e3703..950085016 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino @@ -971,10 +971,10 @@ void MqttConnected(void) { if (static_cast(WiFi.localIP()) != 0) { ResponseAppend_P(PSTR(",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\""), TasmotaGlobal.hostname, (uint32_t)WiFi.localIP()); -#if LWIP_IPV6 +#ifdef USE_IPV6 ResponseAppend_P(PSTR(",\"" D_JSON_IP6_GLOBAL "\":\"%s\""), WifiGetIPv6().c_str()); ResponseAppend_P(PSTR(",\"" D_JSON_IP6_LOCAL "\":\"%s\""), WifiGetIPv6LinkLocal().c_str()); -#endif // LWIP_IPV6 = 1 +#endif // USE_IPV6 } #if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET) if (static_cast(EthernetLocalIP()) != 0) { 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 c2327b73f..c42f6e003 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino @@ -214,7 +214,7 @@ extern "C" { if (Settings->flag4.network_wifi) { int32_t rssi = WiFi.RSSI(); bool show_rssi = false; -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr != "") { be_map_insert_str(vm, "ip6", ipv6_addr.c_str()); @@ -225,10 +225,10 @@ extern "C" { be_map_insert_str(vm, "ip6local", ipv6_addr.c_str()); show_rssi = true; } -#endif +#endif // USE_IPV6 if (static_cast(WiFi.localIP()) != 0) { be_map_insert_str(vm, "mac", WiFi.macAddress().c_str()); - be_map_insert_str(vm, "ip", IPAddress46((uint32_t)WiFi.localIP()).toString().c_str()); // quick fix for IPAddress bug + be_map_insert_str(vm, "ip", IPAddress((uint32_t)WiFi.localIP()).toString().c_str()); // quick fix for IPAddress bug show_rssi = true; } if (show_rssi) { @@ -252,9 +252,9 @@ extern "C" { #ifdef USE_ETHERNET if (static_cast(EthernetLocalIP()) != 0) { be_map_insert_str(vm, "mac", EthernetMacAddress().c_str()); - be_map_insert_str(vm, "ip", IPAddress46((uint32_t)EthernetLocalIP()).toString().c_str()); // quick fix for IPAddress bug + be_map_insert_str(vm, "ip", IPAddress((uint32_t)EthernetLocalIP()).toString().c_str()); // quick fix for IPAddress bug } -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_addr = EthernetGetIPv6(); if (ipv6_addr != "") { be_map_insert_str(vm, "ip6", ipv6_addr.c_str()); @@ -263,8 +263,8 @@ extern "C" { if (ipv6_addr != "") { be_map_insert_str(vm, "ip6local", ipv6_addr.c_str()); } -#endif -#endif +#endif // USE_IPV6 +#endif // USE_ETHERNET be_pop(vm, 1); be_return(vm); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index 8e962d22c..406d3f94f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -94,9 +94,9 @@ void EthernetEvent(arduino_event_t *event) { break; case ARDUINO_EVENT_ETH_CONNECTED: -#if LWIP_IPV6 +#ifdef USE_IPV6 ETH.enableIpV6(); // enable Link-Local -#endif +#endif // USE_IPV6 AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"), ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "", ETH.macAddress().c_str(), eth_hostname @@ -143,6 +143,7 @@ void EthernetSetIp(void) { Settings->eth_ipv4_address[4]); // IPAddress dns2 } +#ifdef USE_IPV6 // Returns only IPv6 global address (no loopback and no link-local) String EthernetGetIPv6(void) { @@ -153,6 +154,7 @@ String EthernetGetIPv6LinkLocal(void) { return WifiFindIPv6(true, "en"); } +#endif // USE_IPV6 void EthernetInit(void) { if (!Settings->flag4.network_ethernet) { return; } From 5e23d78bf28b963bfac3ad6e18e242a062cbfc26 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 10 Dec 2022 16:55:04 +0100 Subject: [PATCH 317/319] Update credits --- CODE_OWNERS.md | 112 ++++++++++ MODULES.md | 2 +- TEMPLATES.md | 166 ++++++++++---- ...mo.ino => xdrv_122_file_settings_demo.ino} | 2 +- .../xdrv_90_esp32_dingtian_relay.ino | 210 ++++++++++++++++++ .../tasmota_xsns_sensor/xsns_11_veml6070.ino | 2 +- .../tasmota_xsns_sensor/xsns_12_ads1115.ino | 4 +- .../tasmota_xsns_sensor/xsns_20_novasds.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino | 2 +- .../tasmota_xsns_sensor/xsns_38_az7798.ino | 2 +- .../tasmota_xsns_sensor/xsns_41_max44009.ino | 2 +- .../tasmota_xsns_sensor/xsns_47_max31865.ino | 2 +- tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino | 1 - .../tasmota_xsns_sensor/xsns_73_hp303b.ino | 2 +- .../xsns_75_prometheus.ino | 2 +- .../tasmota_xsns_sensor/xsns_77_vl53l1x.ino | 2 +- .../tasmota_xsns_sensor/xsns_85_mpu6886.ino | 2 +- .../tasmota_xsns_sensor/xsns_95_cm110x.ino | 18 +- tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino | 2 +- 19 files changed, 466 insertions(+), 71 deletions(-) rename tasmota/tasmota_xdrv_driver/{xdrv_98_file_settings_demo.ino => xdrv_122_file_settings_demo.ino} (99%) create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_90_esp32_dingtian_relay.ino diff --git a/CODE_OWNERS.md b/CODE_OWNERS.md index 49a268bb7..0df3e4a1f 100644 --- a/CODE_OWNERS.md +++ b/CODE_OWNERS.md @@ -71,17 +71,129 @@ In addition to @arendst the following code is mainly owned by: | xdrv_60_shift595 | Jacek Ziółkowski | xdrv_61_ds3502 | f-reiling | xdrv_62_improv | @arendst +| xdrv_63_modbus_bridge | @jeroenst +| | | xdrv_79_esp32_ble | @staars, @btsimonh | xdrv_81_esp32_webcam | @gemu, @philrich | xdrv_82_esp32_ethernet | @arendst | xdrv_83_esp32_watch | @gemu | xdrv_85_esp32_ble_eq3_trv | @btsimonh | xdrv_86_esp32_sonoff_spm | @arendst +| xdrv_87_esp32_sonoff_tm1621 | @arendst +| xdrv_88_esp32_shelly_pro | @arendst +| xdrv_89_esp32_dali | @eeak +| xdrv_90_esp32_dingtian_relay | @barbudor +| | +| xdrv_122_file_settings_demo | @arendst +| xdrv_127_debug | @arendst | | | Tasmota Sensors | | | | xsns_01_counter | @arendst, @stefanbode +| xsns_02_analog | @arendst, @barbudor +| xsns_03_energy | @arendst +| xsns_04_snfsc | @arendst +| xsns_05_ds18x20 | @arendst +| xsns_06_dht | @arendst +| xsns_07_sht1x | @arendst +| xsns_08_htu | Heiko Krupp +| xsns_09_bmp | @arendst +| xsns_10_bh1750 | @arendst +| xsns_11_veml6070 | @mike2nl +| xsns_12_ads1115 | @syssi, @stefanbode +| xsns_13_ina219 | @stefanbode +| xsns_14_sht3x | Stefan Tibus +| xsns_15_mhz19 | @arendst +| xsns_16_tsl2561 | Joachim Banzhaf +| xsns_17_senseair | @arendst +| xsns_18_pms5003 | @arendst +| xsns_19_mgs | @palich2000 +| xsns_20_novasds | Norbert Richter +| xsns_21_sgp30 | Gerhard Mutz +| xsns_22_sr04 | Nuno Ferreira, @arendst +| xsns_23 | +| xsns_24_si1145 | +| xsns_25 | +| xsns_26_lm75ad | Andre Thomas +| xsns_27_apds9960 | Shawn Hymel +| xsns_28_tm1638 | @arendst +| xsns_29_mcp230xx | Andre Thomas +| xsns_30_mpr121 | Rene 'Renne' Bartsch +| xsns_31_ccs811 | Gerhard Mutz +| xsns_32_mpu6050 | Oliver Welter +| xsns_33_qmc5883l | Helge Scheunemann +| xsns_34_hx711 | @arendst +| xsns_35_tx20 | Thomas Eckerstorfer, Norbert Richter +| xsns_36_mgc3130 | Christian Baars +| xsns_37_rfsensor | @arendst +| xsns_38_az7798 | @adebeun +| xsns_39_max31855 | Markus Past +| xsns_40_pn532 | Andre Thomas, @md5sum-as +| xsns_41_max44009 | @llagendijk +| xsns_42_scd30 | @frogmore42 +| xsns_43_hre | Jon Little +| xsns_44_sps30 | Gerhard Mutz +| xsns_45_vl53l0x | Gerhard Mutz, Adrian Scillato +| xsns_46_mlx90614 | Gerhard Mutz +| xsns_47_max31865 | Alberto Lopez Siemens +| xsns_48_chirp | Christian Baars +| xsns_49 | +| xsns_50_paj7620 | Christian Baars +| xsns_51_rdm6300 | Gerhard Mutz +| xsns_52_esp32_ibeacon | Gerhard Mutz, @btsimonh +| xsns_52_ibeacon | Gerhard Mutz +| xsns_53_sml | Gerhard Mutz +| xsns_54_ina226 | Stephen Rodgers +| xsns_55_hih_series | +| xsns_56_hpma | David Hunt +| xsns_57_tsl2591 | Markus Bösling +| xsns_58_dht12 | Stefan Oskam +| xsns_59_ds1624 | Leonid Myravje +| xsns_60_gps | Christian Baars, Adrian Scillato +| xsns_61_mi_nrf24 | Christian Baars +| xsns_62_mi_hm10 | Christian Baars +| xsns_62_esp32_mi | Christian Baars +| xsns_63_aht1x | Martin Wagner +| xsns_64_hrxl | Jon Little +| xsns_65_hdc1080 | Luis Teixeira +| xsns_66_iaq | Christian Baars +| xsns_67_as3935 | Martin Wagner +| xsns_68_windmeter | Matteo Albinola +| xsns_69_opentherm | Yuriy Sannikov +| xsns_70_veml6075 | Martin Wagner +| xsns_71_veml7700 | Martin Wagner +| xsns_72_mcp9808 | Martin Wagner +| xsns_73_hp303b | @rjaakke +| xsns_74_lmt01 | @justifiably +| xsns_75_prometheus | @marius, @mhansen, @hansmi +| xsns_76_dyp | Janusz Kostorz +| xsns_77_vl53l1x | Rui Marinho, @Jason2866 | xsns_78_ezo | Christopher Tremblay +| xsns_79_as608 | @boaschti +| xsns_80_mfrc522 | @arendst +| xsns_81_seesaw_soil | Wayne Ross, Peter Franck +| xsns_82_wiegand | Sigurd Leuther +| xsns_83_neopool | Norbert Richter +| xsns_84_tof10120 | Cyril Pawelko +| xsns_85_mpu6886 | @s-hadinger +| xsns_86_tfminiplus | Raphael Breiting +| xsns_87_can_sniffer | @kwiatek6324, Marius Bezuidenhout +| xsns_87_mcp2515 | Marius Bezuidenhout +| xsns_88_am2320 | Lars Wessels +| xsns_89_t67xx | Alexander Savchenko +| xsns_90_hrg15 | Wouter Breukink +| xsns_91_vindriktning | Marcel Ritter +| xsns_92_scd40 | @frogmore42, @arnold-n +| xsns_93_hm330x | @barbudor +| xsns_94_hdc2010 | Luc Boudreau +| xsns_95_cm1107 | @maksim +| xsns_96_flowratemeter | Norbert Richter +| xsns_97_hyt | Thomas Schnittcher, Adjan Kretz +| xsns_98_sgp40 | Jean-Pierre Deschamps +| xsns_99_luxv30b | Marius Bezuidenhout +| xsns_100_ina3221 | @barbudor +| xsns_101_hmc5883l | Andreas Achtzehn +| xsns_102_ld2410 | @arendst | | | Libraries | | | diff --git a/MODULES.md b/MODULES.md index 6058c385d..f82f7b465 100644 --- a/MODULES.md +++ b/MODULES.md @@ -94,4 +94,4 @@ Module | LCode | Description 06 TTGO Watch | x | TTGO Watch 07 M5Stack Core2 | x | M5Stack Core2 -Over 2400 additional devices are supported using [templates](TEMPLATES.md). +Over 2500 additional devices are supported using [templates](TEMPLATES.md). diff --git a/TEMPLATES.md b/TEMPLATES.md index f5b23c7a6..7d2b90617 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -2,17 +2,13 @@ # Templates -Find below the available templates as of October 2022. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) +Find below the available templates as of December 2022. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) -## Addressable LED +## Adapter Board ``` -Athom 2812b {"NAME":"LS2812B-TAS","GPIO":[32,0,1376,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Athom High Power 16A {"NAME":"LS_4PIN_TAS","GPIO":[32,1376,0,0,0,0,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"Rule1 on Power1#State do power2 2 endon|Rule1 1"} -BlitzWolf IC Smart RGB Magic {"NAME":"BW-LT31","GPIO":[0,0,32,1376,0,0,0,0,0,1088,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO37 24"} -cod.m WLAN Pixel Controller v0.8 {"NAME":"cod.m Pixel Controller V0.8","GPIO":[0,0,0,0,0,544,0,0,0,0,0,32,1376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} -ESP01 NeoPixel Ring {"NAME":"ESP-01S-RGB-LED-v1.0","GPIO":[1,1,1376,1,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -IOTMCU {"NAME":"IOTMCU_ESP-12S-RGB-LED-v1","GPIO":[1,1,1,1,0,1376,0,0,1,1088,32,0,0,0],"FLAG":0,"BASE":18} -SP501E WS2812B {"NAME":"SP501E","GPIO":[0,32,0,1376,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +3DStar ESP-OpenTherm v1.1 {"NAME":"3DS_OpenTherm","GPIO":[0,0,0,0,0,0,0,0,4960,0,4928,0,0,0],"FLAG":0,"BASE":18} +WifInfo - Teleinfo Server {"NAME":"WifInfo","GPIO":[1376,1,1,5152,640,608,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18} +ZiGate-Ethernet {"NAME":"ZIGATE-ETH","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0],"FLAG":0,"BASE":18,"CMND":"EthClockMode 3 | EthAddress 1"} ``` ## Air Purifier @@ -51,7 +47,7 @@ GL.iNet POE Ethernet {"NAME":"GL-S10 v1.0","GPIO":[32,0,0,0,0,0,0,0,321, ## CCT ``` AICase 800lm {"NAME":"AICase Smart L","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} -AiYaTo 12W {"NAME":"AiYaTo CW","GPIO":[0,0,0,0,416,0,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} +AiYaTo 12W {"NAME":"AiYaTo-CW","GPIO":[0,0,0,0,416,0,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} Ajax Online 380lm {"NAME":"AjaxOnline","GPIO":[32,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":38} Ajax Online 7W Vintage {"NAME":"AjaxOnline-7W","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} Anoopsyche 9W 800lm {"NAME":"Anoop-CW-WW","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} @@ -59,6 +55,7 @@ Arlec Smart 1350lm PAR38 {"NAME":"Arlec GLD302HA","GPIO":[0,0,0,0,0,0,0,0,41 Arlec Smart 9.5W 806lm {"NAME":"Arlec GLD110HA","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":48} Arlec Smart 9.5W 806lm {"NAME":"Arlec CCT","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":48} Arlec Smart R80 9.5W 806lm {"NAME":"Arlec R80","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":48} +AZzardo Led Vintage {"NAME":"Azzardo AZ3210 LightBulb Vintage","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} BlitzWolf A70 9W 900lm {"NAME":"BW-LT29","GPIO":[0,0,0,0,0,0,0,0,0,449,0,416,0,0],"FLAG":0,"BASE":18} BrilliantSmart 20696 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} BrilliantSmart 20697 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} @@ -128,6 +125,7 @@ Nedis G125 5.5W 350lm Twisted Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0 Nedis PAR16 330lm {"NAME":"Nedis WIFILW30","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18} Nedis PAR16 4,5W 380lm {"NAME":"Nedis WIFILW10WTGU10","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18} Nedis PAR16 4.5W 330lm 110 {"NAME":"WIFILW30","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18} +Nous P2 {"NAME":"NOUS-P2","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":37} Philips Zhirui Candle 250lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,417,0,0,416,0,0],"FLAG":0,"BASE":48} Phillips Zhirui 450lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,417,0,0,416,0,0],"FLAG":0,"BASE":48} Polux ST64 5.5W 470lm {"NAME":"basic","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} @@ -141,7 +139,9 @@ Spectrum Smart 5W 410lm Candle {"NAME":"lightbulb","GPIO":[0,0,0,0,0,0,0,0,417, Status 9W 806lm {"NAME":"Status Smart","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} Sulion Dante G100 10W 1055lm {"NAME":"Sulion Bombilla G100","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} Sulion Edisson Filament ST64 8W 600lm {"NAME":"Sulion Bombilla ST64","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} +Sulion Morgan C37 5W 470lm {"NAME":"Sulion Bombilla C37","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} Swisstone 806lm {"NAME":"SwisstoneSH330","GPIO":[0,0,0,0,2912,416,0,0,417,2976,2944,0,0,0],"FLAG":0,"BASE":18} +Swisstone SH 310 {"NAME":"Swisstone SH 310","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} Treatlife A19 9W 800lm {"NAME":"Treatlife SL20","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} V-Tac PAR16 4.5W 300lm 110 {"NAME":"V-TAC VT-5174","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} Vestaiot BR30 800lm {"NAME":"Vesta BR30 CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} @@ -171,7 +171,10 @@ Fcmila 48W RGBCCT {"NAME":"XDD-48W","GPIO":[0,0,0,0,416,419,0,0,417,4 Globe Electric Brushed Nickel 11" Flush Mount {"NAME":"Globe 60839","GPIO":[0,0,0,0,0,0,0,0,4064,0,4032,0,0,0],"FLAG":0,"BASE":18} Hama Glitter Effect, 27cm Square {"NAME":"Hama LED Ceiling Light","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,1],"FLAG":0,"BASE":18} HeyLight Plafoniera 30W CCT {"NAME":"HeyLight Ceiling Light","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18} +Hykolity 13" RGBCCT Flush Mount {"NAME":"Hykolity","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} +Lamptan 3 Lights in 1 36W {"NAME":"Lamptan Smart Wi-Fi Ceiling Lamp LUMINA 36W","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":54} LE lampUX 15W RGBCCT {"NAME":"LE lampUX 15W","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} +LightZone MeLiTec {"NAME":"LightZone MeLiTec D114 Light ","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,20 | TuyaMCU 21,22 | TuyaMCU 23,23 | DimmerRange 25,1000"} Lohas ZN026CL10 RGBCCT {"NAME":"Lohas LED Lamp","GPIO":[0,0,0,0,417,416,0,0,419,418,420,0,0,0],"FLAG":0,"BASE":18} LOLAsmart Uranus White 70 cm {"NAME":"lola smart","GPIO":[0,0,0,1088,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} LSC 20W 1400lm White Ambiance {"NAME":"LSC RGBCW LED","GPIO":[0,0,0,0,0,0,0,0,4064,0,4032,0,0,0],"FLAG":0,"BASE":18} @@ -248,6 +251,10 @@ Hoch Circuit Breaker 1P {"NAME":"HOCH ZJSB9","GPIO":[32,0,0,0,0,0,0,0,224,3 Ketotek Single Phase Energy Monitor {"NAME":"Ketotek KTEM06","GPIO":[0,2272,0,2304,0,0,0,0,0,0,320,0,32,0],"FLAG":0,"BASE":54} OpenEnergyMonitor WiFi MQTT Thermostat {"NAME":"MQTT-RELAY","GPIO":[32,0,1,0,0,224,0,0,0,0,0,0,320,0],"FLAG":0,"BASE":18} RocketController ASTRA Controller {"NAME":"ASTRA R4A4","GPIO":[1,1,1,1,576,1,1,1,480,1,1,1,3232,3200,1,1,0,640,608,1,0,224,225,1152,0,0,0,0,227,226,160,161,162,0,0,163],"FLAG":0,"BASE":1} +Shelly Pro 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"} +Shelly Pro 1PM {"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"} +Shelly Pro 2 {"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"} +Shelly Pro 2PM {"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"} Sinotimer {"NAME":"TM608","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18} Sinotimer {"NAME":"Sinotimer TM60","GPIO":[0,0,0,0,0,288,0,0,224,160,0,0,0,0],"FLAG":0,"BASE":18} SMTONOFF 63A {"NAME":"SMTONOFF","GPIO":[32,0,0,3104,0,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":43} @@ -262,6 +269,7 @@ Tongou 2P 63A Circuit Breaker {"NAME":"RCD_CONTACTOR","GPIO":[32,224,0,0,0,0,0, ## Dehumidifier ``` +Duux Bora {"NAME":"Duux Bora","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 73,3 | TuyaMCU 74,4 | TuyaMCU 12,5 | TuyaMCU 13,7 | TuyaMCU 81,13 | TuyaMCU 14,101 | HumRes 0"} electriQ 12L Portable {"NAME":"electriQ CD12PW","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Vacplus 50 Pint {"NAME":"VacPlus Dehumidifier","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54} ``` @@ -274,7 +282,8 @@ Adafruit HUZZAH32 ESP32 Feather {"NAME":"HUZZAH32","GPIO":[0,0,0,0,4709,0,1,1,1 Adafruit QT Py ESP32 Pico {"NAME":"QTPy ESP32 Pico","GPIO":[32,3200,0,3232,1,1376,0,0,1,1,1,1,0,0,0,608,0,0,640,0,0,1,1,1,0,1,3840,0,1,1,0,0,0,0,0,0],"FLAG":0,"BASE":1} AZ-Envy Environmental Sensor {"NAME":"AZ Envy","GPIO":[32,0,320,0,640,608,0,0,0,0,0,0,0,4704],"FLAG":0,"BASE":18} Coiaca Tasmota {"NAME":"AWR01t","GPIO":[576,1,1,128,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -ESP32 Lite V1.0.0 {"NAME":"ESP32 Lite V1.0.0","GPIO":[1,0,1,0,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0],"FLAG":0,"BASE":1} +Coiaca Tasmota Development Board AWR12 {"NAME":"AWR12t","GPIO":[320,1,1,1,1,1,0,0,1,1,1,1,1,1],"FLAG":0,"BASE":18} +Espoir Rev 1.0.0 PoE+ {"NAME":"Espoir","GPIO":[0,0,1,0,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,5568,5600,1,7968,1,1,1,1],"FLAG":0,"BASE":1} LC Technology MicroPython Maker {"NAME":"LC-ESP-Python","GPIO":[1,1,544,1,1,1,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18} LilyGO RGB LED Ring Encoder {"NAME":"T-Encoder","GPIO":[0,0,1,0,1,0,0,0,1,1,1,1,0,0,0,480,6212,0,0,0,0,449,450,448,0,0,0,0,0,0,0,0,3296,3264,32,0],"FLAG":0,"BASE":1,"CMND":"BuzzerPwm 1"} LilyGO T7 v1.5 {"NAME":"LilyGO T7 V1.5","GPIO":[1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,544,0,0,0,1,0,1,1,1,0,0,0,0,0,1,1,4704,1,0,0,1],"FLAG":0,"BASE":1} @@ -286,11 +295,11 @@ Olimex ESP32-POE Ethernet {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0, QuinLED 2 Channel {"NAME":"QuinLED 2 channel","GPIO":[416,0,417,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Silicognition wESP32 {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} TZT ESP8266 Weather Station Kit {"NAME":"TZT Weather Station","GPIO":[32,0,640,0,1,1184,0,0,1,1,608,1,1,1],"FLAG":0,"BASE":18} -WifInfo - Teleinfo Server {"NAME":"WifInfo","GPIO":[1376,1,1,5152,640,608,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18} +Wemos D1 Mini ESP32 {"NAME":"Wemos D1 Mini ESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0],"FLAG":0,"BASE":1} +Wemos LOLIN32 Lite V1.0.0 (ESP32) {"NAME":"Wemos LOLIN32 Lite V1.0.0","GPIO":[1,0,1,0,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0],"FLAG":0,"BASE":1} Wireless Tag ESP32 Ethernet {"NAME":"WT32-ETH01","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1],"FLAG":0,"BASE":1} Witty Cloud {"NAME":"Witty Cloud","GPIO":[1,1,320,1,32,1,0,0,417,418,1,416,1,4704],"FLAG":0,"BASE":32} Yison ESP-01/ESP-202 {"NAME":"Yison Dev Board","GPIO":[259,544,258,1,260,261,1,1,416,418,257,417,256,1],"FLAG":0,"BASE":18} -ZiGate-Ethernet {"NAME":"ZIGATE-ETH","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0],"FLAG":0,"BASE":18,"CMND":"EthClockMode 3 | EthAddress 1"} ``` ## Dimmable @@ -391,12 +400,13 @@ Globe 3 Way {"NAME":"Globe Dimmer","GPIO":[0,2272,0,2304,0,0,0, Gosund SW2 {"NAME":"Gosund Dimmer","GPIO":[1,3200,1,3232,32,0,1,1,320,576,416,1,1,0],"FLAG":0,"BASE":18} iLintek / Lumary {"NAME":"L-DS100","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} iSwitch Touch Switch {"NAME":"iSwitchOZ Dimmer","GPIO":[0,0,0,0,0,0,0,0,0,0,290,0,0,0],"FLAG":0,"BASE":54} -Martin Jerry SD01 {"NAME":"MJ-SD01 Dimmer","GPIO":[34,33,0,323,576,322,0,0,321,416,320,96,256],"FLAG":0,"BASE":73} -Martin Jerry Single Pole {"NAME":"SD01 Dimmer","GPIO":[34,33,0,323,576,322,0,0,321,416,320,96,256],"FLAG":0,"BASE":73} +Martin Jerry SD01 {"NAME":"MJ-SD01 Dimmer","GPIO":[34,33,0,323,576,322,0,0,321,416,320,96,256,0],"FLAG":0,"BASE":73} +Martin Jerry Single Pole {"NAME":"SD01 Dimmer","GPIO":[34,33,0,323,576,322,0,0,321,416,320,96,256,0],"FLAG":0,"BASE":73} Martin Jerry Single Pole {"NAME":"MJ-KN01 Dimmer","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Maxcio Rotary {"NAME":"EDM-1WAA-EU","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} Minoston 3-Way {"NAME":"MS10W","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} Moes {"NAME":"MOES DS01","GPIO":[1,1,1,1,1,1,0,0,1,2304,1,2272,1,0],"FLAG":0,"BASE":54} +Moes 3 Way Smart Light {"NAME":"EDM-1WAA-US","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} PS-16-DZ {"NAME":"PS-16-DZ","GPIO":[1,3200,1,3232,1,1,0,0,1,288,1,1,1,0],"FLAG":0,"BASE":58} Stitch {"NAME":"Stitch 35558","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 21,3|DimmerRange 21,255"} Teekar UIW001-1 {"NAME":"Teekar UIW001-","GPIO":[0,3232,416,3200,640,608,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18} @@ -422,7 +432,7 @@ BrilliantSmart Jupiter {"NAME":"BrSm Jupiter","GPIO":[0,2272,0,2304,0,0,0, EX-Store 2 Kanal RS232 V4 {"NAME":"EXS Dimmer","GPIO":[0,3200,0,3232,0,0,0,0,0,4128,0,0,0,0],"FLAG":0,"BASE":72} Moes 2 Gang {"NAME":"WM-105","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 21,2 | TuyaMCU 12,7 | TuyaMCU 22,8 | DimmerRange 0,1003"} Moes MS-105-1 v2 {"NAME":"MS-105","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} -QS-WiFi-D01-TRIAC 150W {"NAME":"QS-WiFi-D01-TRIAC","GPIO":[0,3200,0,3232,0,0,0,0,0,352,416,0,0],"FLAG":0,"BASE":18} +QS-WiFi-D01-TRIAC 150W {"NAME":"QS-WiFi-D01-TRIAC","GPIO":[0,3200,0,3232,0,0,0,0,0,352,416,0,0,0],"FLAG":0,"BASE":18} RJWF-02A {"NAME":"RJWF-02A","GPIO":[32,2272,0,2304,0,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":54} Shelly Dimmer {"NAME":"Shelly Dimmer 1","GPIO":[0,3200,0,3232,5568,5600,0,0,192,0,193,288,0,4736],"FLAG":0,"BASE":18} Shelly Dimmer 2 {"NAME":"Shelly Dimmer 2","GPIO":[0,3200,0,3232,5568,5600,0,0,193,0,192,0,320,4736],"FLAG":0,"BASE":18} @@ -453,7 +463,7 @@ Wireless Tag 3.5" Touch {"NAME":"WT32-SC01","GPIO":[6210,1,1,1,1,1,0,0,1,70 ## Display Switch ``` Lanbon L8 5 in 1 LCD Touch {"NAME":"Lanbon L8","GPIO":[0,0,0,0,0,992,0,0,224,0,225,0,0,0,1024,896,0,6624,6592,864,0,832,416,226,0,0,0,0,417,418,0,352,0,0,0,4736],"FLAG":0,"BASE":1} -Sonoff NSPanel Touch {"NAME":"NSPanel","GPIO":[0,0,0,0,3872,0,0,0,0,0,32,0,0,0,0,225,0,480,224,1,0,0,0,33,0,0,0,0,0,0,0,0,0,0,4736,0],"FLAG":0,"BASE":1,"CMND":"ADCParam 2,11200,10000,3950 | Sleep 0 | BuzzerPWM 1"} +Sonoff NSPanel Touch {"NAME":"NSPanel","GPIO":[0,0,0,0,3872,0,0,0,0,0,32,0,0,0,0,225,0,480,224,1,0,0,0,33,0,0,0,0,0,0,0,0,0,0,4736,0],"FLAG":0,"BASE":1,"CMND":"ADCParam1 2,11200,10000,3950 | Sleep 0 | BuzzerPWM 1"} ``` ## Downlight @@ -538,6 +548,7 @@ Sonoff iFan04-L 110V Light and Ceiling {"NAME":"iFan04-L","GPIO":[32,3200,0,323 Avatto Light and {"NAME":"AVATTO SYS-FL01","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Deta Light and {"NAME":"Deta Fan Speed and Light Controller","GPIO":[33,0,0,576,226,34,0,0,0,225,224,227,32,0],"FLAG":0,"BASE":18} iSwitch Light and {"NAME":"iSwitchOZ Light Fan","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +Martin Jerry Fan Controller {"NAME":"US-FC-01","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} Treatlife 1.5A 4 Speed Ceiling {"NAME":"DS02F","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1|SO97 1|SO68 0"} ``` @@ -564,12 +575,14 @@ SmartMi Electric Air {"NAME":"ZNNFJ07ZM","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0 ## Humidifier ``` -Duux Beam {"NAME":"Duux Beam","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 12,5 | TuyaMCU 13,21 | TuyaMCU 71,14 | TuyaMCU 74,15 | TuyaMCU 73,16"} +Duux Beam Ultrasonic {"NAME":"Duux Beam","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 12,5 | TuyaMCU 13,21 | TuyaMCU 71,14 | TuyaMCU 74,15 | TuyaMCU 73,16"} Proscenic {"NAME":"Generic","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} ``` ## IR Controller ``` +3DStar ESP IR Blaster 8L {"NAME":"3DS_IRblaster_xL","GPIO":[0,0,0,0,0,0,0,0,0,0,0,1056,0,0],"FLAG":0,"BASE":18} +3DStar ESP IR Blaster xLR {"NAME":"3DS_IR Blaster_xLR","GPIO":[0,0,0,0,0,0,0,0,0,1088,0,1056,0,0],"FLAG":0,"BASE":18} A1 Universal Remote Control {"NAME":"A1 IR Controller","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} AI Universal Remote {"NAME":"YTF IR Controller","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} Alfawise KS1 {"NAME":"KS1","GPIO":[1,1792,32,1824,32,1088,0,0,320,0,1056,0,0,4704],"FLAG":0,"BASE":62} @@ -598,6 +611,7 @@ Orvibo Magic Cube {"NAME":"Orvibo CT10W","GPIO":[0,0,0,0,32,1088,0,0, Phlipton Universal Remote {"NAME":"Phliptron IR","GPIO":[1,3200,1,3232,576,1088,0,0,320,32,1056,0,0,0],"FLAG":0,"BASE":62} Remote Control {"NAME":"DC-QRA2","GPIO":[0,0,0,0,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} RM mini {"NAME":"RM mini","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} +Smart Remote {"NAME":"IRC","GPIO":[0,0,544,0,0,288,0,0,1088,32,1056,0,0,0],"FLAG":0,"BASE":18} Smartpoint Smart Remote {"NAME":"Smartpoint SPCNTRL-WM","GPIO":[0,0,0,0,288,1088,0,0,0,0,1056,0,0,0],"FLAG":0,"BASE":18} STITCH {"NAME":"Stitch 35753","GPIO":[0,0,0,0,288,1088,0,0,0,64,1056,0,0,0],"FLAG":0,"BASE":62} SZMDLX IR Remote Controller {"NAME":"SZMDLX WiFi IR","GPIO":[0,0,0,0,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} @@ -640,6 +654,7 @@ DD001-MINI(G)-IR-V03 {"NAME":"WIFI-RGB","GPIO":[32,0,0,0,0,0,0,0,417,418 DD001-MINI(G)-IR-V08 {"NAME":"WIFI-RGB","GPIO":[0,0,0,0,416,0,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} Electrodragon ESP LED Strip Board, Mosfet Drive {"NAME":"LEDBoard RGBW","GPIO":[0,0,0,0,0,0,0,0,418,417,419,416,288,0],"FLAG":0,"BASE":18} H801 {"NAME":"H801","GPIO":[1,288,1,1,420,321,0,0,418,417,419,416,0,0],"FLAG":0,"BASE":20} +Hama Adapter and RGB {"NAME":"HAMA LED-Strip WLAN-Controller","GPIO":[0,0,0,0,417,419,0,0,0,416,418,0,0,0],"FLAG":0,"BASE":18} Holman Garden Light RGB {"NAME":"Holman RGB","GPIO":[0,0,0,0,0,0,0,0,417,416,418,0,0,0],"FLAG":0,"BASE":18} Jinvoo SM-WA104 RGB {"NAME":"Jinvoo LED Controller","GPIO":[0,0,0,0,256,418,0,0,416,32,417,0,257,0],"FLAG":0,"BASE":18} Konesky 12V RGB {"NAME":"RGBwifi","GPIO":[0,0,0,0,416,0,0,0,417,320,418,0,0,0],"FLAG":0,"BASE":18} @@ -697,13 +712,14 @@ HitLights L1012V-MC1 {"NAME":"HitLights RBG","GPIO":[32,0,0,0,416,419,0, HomeMate 10m RGB {"NAME":"Homemate Strip","GPIO":[0,0,0,0,0,416,0,0,418,32,417,0,0,0],"FLAG":0,"BASE":18} Hykker 3m RGB {"NAME":"HYKKER Strip","GPIO":[0,0,0,0,0,416,0,0,418,32,417,0,0,0],"FLAG":0,"BASE":18} INDARUN RGB String Lights {"NAME":"STAR301","GPIO":[0,0,0,0,1088,416,0,0,417,418,0,0,0,0],"FLAG":0,"BASE":34} -Kogan RGB + Cool & Warm White 2m {"NAME":"RGB+W+C Strip","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} +Kogan RGB + Cool & Warm White 2m {"NAME":"RGB+W+C Strip","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} LE LampUX 16.4ft RGB {"NAME":"LampUX","GPIO":[0,33,32,0,0,417,0,0,418,1088,0,416,0,0],"FLAG":0,"BASE":18} LE LampUX 2m RGB TV Backlight {"NAME":"LE 904102","GPIO":[0,32,33,0,0,417,0,0,418,34,0,416,0,0],"FLAG":0,"BASE":18} LE LampUX 5m RGB {"NAME":"LampUX","GPIO":[32,0,0,0,0,417,0,0,418,0,0,416,0,0],"FLAG":0,"BASE":18} LE LampUX 5m RGB {"NAME":"LE LampUx","GPIO":[0,0,0,0,0,417,0,0,418,0,0,416,0,0],"FLAG":0,"BASE":34} LE lampUX 5m RGBW {"NAME":"LampUX","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} Lednify WiZ Connected 5m RGB+W {"NAME":"Lednify 429336","GPIO":[0,0,420,0,419,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,416,417,418,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} +Lenovo 2m RGB {"NAME":"Lenovo LED Strip 2m","GPIO":[32,0,0,0,416,0,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} Lenovo 5m RGBW {"NAME":"Lenovo LED Strip 5m","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} LePower 32.8ft RGB {"NAME":"LePower","GPIO":[0,0,0,0,0,417,0,0,418,0,0,416,0,0],"FLAG":0,"BASE":18} Lohas ZN022 5m RGBW {"NAME":"LOHAS M5-022","GPIO":[0,0,0,0,417,416,0,0,32,418,0,0,0,0],"FLAG":0,"BASE":18} @@ -712,6 +728,7 @@ Lumary RGBCCT {"NAME":"Lumary LED","GPIO":[32,0,0,0,416,419,0,0,4 Lumary RGBCCT {"NAME":"Lumary LED","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Maxonar Lightstrip Pro XS-SLD001 {"NAME":"Maxonar LED","GPIO":[0,0,0,0,0,416,0,0,418,32,417,0,0,0],"FLAG":0,"BASE":18} MegaLight Smart RGB {"NAME":"MegaLight Smart LED-Stripe","GPIO":[0,0,0,0,417,1088,0,0,418,416,0,0,32,0],"FLAG":0,"BASE":18} +Merkury 6-1/2 ft {"NAME":"Mercury RGBWWCW String","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Merkury Innovations MI-EW003-999W {"NAME":"MI-EW003-999W ","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Mirabella Genio RGB+CW {"NAME":"MirabellaStrip","GPIO":[32,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} Monster Smart IlluminEssence {"NAME":"MI-EW003-999W ","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} @@ -781,7 +798,7 @@ Sonoff {"NAME":"Sonoff BN-SZ","GPIO":[0,0,0,0,0,0,0,0,416, Spotlight 9cm RGB+W 7W {"NAME":"Spotlight RGBW","GPIO":[0,0,0,0,0,0,0,0,0,3008,0,3040,0,0],"FLAG":0,"BASE":27} TCP WPAN Square 600X600mm 36W CCT Panel {"NAME":"TCPsmart LED Panel","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO92 1|DimmerRange 30,100"} Teckin FL41 {"NAME":"Teckin FL41","GPIO":[0,0,0,0,0,32,0,0,0,0,416,0,0,0],"FLAG":0,"BASE":18} -Wipro 20W LED RGB Batten {"NAME":"Wipro RGBW Tubelight","GPIO":[0,0,0,0,416,420,0,0,417,419,418,0,0,1],"FLAG":0,"BASE":18} +Wipro 20W LED RGB Batten {"NAME":"Wipro RGBW Tubelight","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,1],"FLAG":0,"BASE":18} Wipro Next Smart Batten 20W CCT {"NAME":"WIPROBatten","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":18} Xiaomi Mi Computer Monitor Light Bar 1S {"NAME":"Mijia Desk Lamp 1S (MJGJD02YL)","GPIO":[0,0,0,0,3840,0,1,1,0,0,0,0,0,0,0,416,0,417,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"DimmerRange 45,255"} Xiaomi Mi Desk Lamp Pro {"NAME":"Mi Desk Lamp Pro","GPIO":[6212,0,416,0,417,0,0,0,3840,0,0,0,160,640,608,0,0,0,0,0,0,0,3296,3264,0,0,0,0,0,32,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"DimmerRange 30,100"} @@ -809,6 +826,7 @@ Liectroux C30B Robot Vacuum {"NAME":"Liectroux C30B","GPIO":[1,1,1,1,1,1,0,0,1, Mosquito Killer Lamp {"NAME":"MosquitoKiller","GPIO":[32,0,0,0,0,0,0,0,416,320,0,0,0,0],"FLAG":0,"BASE":18} NEO Coolcam Mouse Trap {"NAME":"Neo Mouse Trap","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} PCI-e Desktop PC Remote Control {"NAME":"PC-Switch-01","GPIO":[32,0,0,0,0,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":18} +Petoneer Smart Dot Cat Toy {"NAME":"Petoneer Smart Dot","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Proscenic T21 Air Fryer {"NAME":"Proscenic T21","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} RainPoint Indoor Water Pump {"NAME":"RainPoint","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 81,107|TuyaMCU 12,109|TuyaMCU 11,1|TuyaMCU 82,104"} Sinilink PCIe Computer Remote {"NAME":"XY-WPCE","GPIO":[1,1,320,1,32,224,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO114 1 | SwitchMode1 2"} @@ -835,6 +853,11 @@ Sinilink MODBUS Interface {"NAME":"XY-WFPOW","GPIO":[0,8768,544,8800,32,0,0,0 TYWE2S Replacement {"NAME":"ESP-02S","GPIO":[1,1,1,1,1,1,0,0,1,1,1,0,0,1],"FLAG":0,"BASE":18} ``` +## Module Switch +``` +Moes Mini 3 Gang 1/2 Way {"NAME":"Moes MS-104C","GPIO":[0,0,0,34,32,33,0,0,224,225,226,0,0,0],"FLAG":0,"BASE":18} +``` + ## Motion Sensor ``` DP-WP001 PIR {"NAME":"TUYA PIR","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} @@ -847,7 +870,7 @@ Tuya Alarm PIR {"NAME":"CT61W","GPIO":[0,0,0,0,0,0,0,0,0,160,480,2 ``` Steren Curtain {"NAME":"Steren_SHOME-155","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"SO54 1|SO20 1|TuyaMCU 61,1|TuyaMCU 21,2|TuyaMCU 27,3|TuyaMCU 97,5|TuyaMCU 11,6|TuyaMCU 62,7|TuyaMCU 63,8|TuyaMCU 81,9|TuyaMCU 98,10|TuyaMCU 82,11"} Zemismart BCM300D-TY {"NAME":"Zemistart_Curt","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54} -Zemismart Blinds Controller {"NAME":"Zemismart Blind","GPIO":[1,1,1,1,1,1,0,0,1,2304,1,2272,1],"FLAG":0,"BASE":54} +Zemismart Blinds Controller {"NAME":"Zemismart Blind","GPIO":[1,1,1,1,1,1,0,0,1,2304,1,2272,1,0],"FLAG":0,"BASE":54} Zemismart Curtain {"NAME":"Zemismart_Curt","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54} Zemismart Rechargeable Roller Shade {"NAME":"Zemismart Remote","GPIO":[544,0,288,33,225,32,0,0,34,226,289,224,290,0],"FLAG":0,"BASE":18} Zemismart Roller Shade {"NAME":"M2805EIGB","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} @@ -936,6 +959,7 @@ Wyze {"NAME":"Wyze Plug Outdoor","GPIO":[0,0,0,0,0,576,0 ## Plug ``` +16A {"NAME":"AWP16L","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45} 1AC 2USB {"NAME":"BSD31","GPIO":[0,0,0,0,0,225,0,0,224,32,320,0,0,0],"FLAG":0,"BASE":18} 2nice {"NAME":"2NICE SP111","GPIO":[320,0,321,0,0,0,0,0,0,32,0,224,0,4736],"FLAG":0,"BASE":18} 3Stone Mini {"NAME":"3Stone Smart Plug","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} @@ -949,6 +973,7 @@ Aisirer AWP07L {"NAME":"AISIRER AWP07L","GPIO":[320,0,321,0,0,2688 Aisirer JH-G018 {"NAME":"AISIRER JH-G01","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Aisirer SWA11 {"NAME":"SWA11","GPIO":[0,0,0,0,288,224,0,0,0,32,0,0,0,0],"FLAG":0,"BASE":18} Aisirer UK-1 {"NAME":"AISIRER","GPIO":[0,32,0,0,0,0,0,0,0,288,224,0,0,4704],"FLAG":0,"BASE":18} +AiYaTo 12W {"NAME":"AiYaTo-SWITCH","GPIO":[0,0,0,0,32,544,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18} Alecto SMART-PLUG20 {"NAME":"Alecto SP20","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18} Alexfirst TV-ASP801EU {"NAME":"Alexfirst","GPIO":[32,0,0,0,290,320,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18} Alfawise {"NAME":"PE1606","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} @@ -1026,7 +1051,7 @@ Bardi 16A {"NAME":"BARDI","GPIO":[320,0,0,0,0,2720,0,0,224,32 Bauhn ASPU-1019 {"NAME":"Bauhn Smart Pl","GPIO":[0,0,0,0,224,225,0,0,0,320,32,0,0,0],"FLAG":0,"BASE":18} BAW {"NAME":"BAW TPSWIFI-10","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Bawoo {"NAME":"Bawoo S120","GPIO":[0,0,0,0,288,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} -Be HiTech 16A {"NAME":"Be HiTech","GPIO":[0,0,0,288,0,2720,0,0,2624,32,2656,224,0],"FLAG":0,"BASE":18} +Be HiTech 16A {"NAME":"Be HiTech","GPIO":[0,0,0,288,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} Bearware 303492 3AC+2USB {"NAME":"Bearware 30349","GPIO":[0,320,0,32,225,226,0,0,227,224,544,0,0,0],"FLAG":0,"BASE":18} Bestek MRJ1011 {"NAME":"BestekMRJ1011","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":1} BlitzWolf 1200W Dual {"NAME":"BlitzWolf SHP3","GPIO":[320,0,321,0,225,2720,0,0,2624,33,2656,224,32,0],"FLAG":0,"BASE":45} @@ -1112,10 +1137,9 @@ ednet 84334 {"NAME":"84334","GPIO":[0,0,0,0,320,321,0,0,224,32, eFamilyCloud ASDFEE174 {"NAME":"eFamily Plug","GPIO":[0,0,0,0,288,224,0,0,0,32,0,0,0,0],"FLAG":0,"BASE":18} EFUN SH330W {"NAME":"EFUNPlug","GPIO":[320,1,1,1,1,1,1,1,1,32,1,224,1,1],"FLAG":0,"BASE":18} EFUN SH331W {"NAME":"Efun-Plug","GPIO":[320,0,576,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} -Elehot 16A {"NAME":"ELEHOT AWP16L","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45} EleLight {"NAME":"EleLight PE1004T","GPIO":[0,0,0,0,288,289,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} EletecPro 2 {"NAME":"EletecPro-2","GPIO":[1,1,1,1,32,1,0,0,289,288,224,1,1,4704],"FLAG":0,"BASE":18} -Emil Lux Wifi-Stecker IP20 {"NAME":"Emil Lux Wifi-Steckdose","GPIO":[0,0,0,0,321,0,0,0,224,320,32,0,0,0],"FLAG":0,"BASE":18} +Emil Lux Wifi-Stecker IP20 {"NAME":"Obi CH Plug","GPIO":[0,0,0,0,320,0,0,0,224,576,32,0,0,0],"FLAG":0,"BASE":18} Emporia {"NAME":"Emporia EMS01","GPIO":[0,0,0,289,224,2720,0,0,2624,32,2656,288,0,0],"FLAG":0,"BASE":18} Emporia 15A {"NAME":"Emporia EMS02","GPIO":[320,0,321,0,224,2720,0,0,2624,32,2656,0,0,0],"FLAG":0,"BASE":18} Ener-J {"NAME":"ENER-J SHA5264","GPIO":[32,0,0,0,2720,2656,0,0,2624,288,224,0,0,0],"FLAG":0,"BASE":18} @@ -1195,10 +1219,10 @@ HBN 13A {"NAME":"BNC-50/E75T","GPIO":[0,0,0,0,576,320,0,0,2 HBN BNC-60/U152T {"NAME":"BNC-60/U152T","GPIO":[0,0,0,0,320,0,1,1,224,32,0,0,0,0],"FLAG":0,"BASE":18} HerePow {"NAME":"HerePow ZHX-ZNOC","GPIO":[0,544,0,2624,2720,2656,0,0,224,32,320,0,0,0],"FLAG":0,"BASE":68} Heygo 02 {"NAME":"Heygo 02","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} -HiHome WPP-10S1 {"NAME":"HIhome WPP-10S","GPIO":[320,0,576,1,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":49} -HiHome WPP-10S2 {"NAME":"HiHome WPP-10S","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} -HiHome WPP-16S {"NAME":"HIhome WPP-16S","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} -HiHome WPP-16T {"NAME":"HiHome WPP-16T","GPIO":[32,320,1,1,2720,2656,0,0,33,1,225,2592,224,4704],"FLAG":0,"BASE":18} +HiHome {"NAME":"HIhome WPP-16S","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} +HiHome {"NAME":"HiHome WPP-10S","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} +HiHome {"NAME":"HIhome WPP-10S","GPIO":[320,0,576,1,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":49} +HiHome {"NAME":"HiHome WPP-16T","GPIO":[32,320,1,1,2720,2656,0,0,33,1,225,2592,224,4704],"FLAG":0,"BASE":18} HIPER IoT P01 {"NAME":"HIPER IoT P01","GPIO":[0,0,0,0,0,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} hiwild W-US002 {"NAME":"W-US002","GPIO":[0,32,0,0,0,0,0,0,0,288,224,0,576,0],"FLAG":0,"BASE":18} HLT-309 {"NAME":"HLT-309","GPIO":[0,0,0,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} @@ -1273,7 +1297,7 @@ Ledvance Smart+ {"NAME":"Ledvance Plug","GPIO":[0,0,0,320,2688,2656 Ledvance Smart+ CH {"NAME":"Ledvance Plug CH","GPIO":[0,0,0,288,32,0,0,0,2656,224,2720,0,0,0],"FLAG":0,"BASE":18} Lenovo SE-341A {"NAME":"Lenovo SE-341A","GPIO":[0,0,0,0,32,224,0,0,576,0,320,0,0,0],"FLAG":0,"BASE":18} Lenovo SE-341AA {"NAME":"Lenovo SE-341AC","GPIO":[0,0,0,0,32,224,0,0,576,0,320,0,0,0],"FLAG":0,"BASE":18} -Lenovo SE-341AC {"NAME":"Lenovo SE-341AC","GPIO":[0,0,0,32,0,0,0,0,320,224,0,0,0,0],"FLAG":0,"BASE":18} +Lenovo SE-341AC {"NAME":"Lenovo SE-341AC","GPIO":[0,321,0,32,2720,2656,0,0,320,224,2624,0,0,0],"FLAG":0,"BASE":18} LESHP KS-501 {"NAME":"LESHP KS-501","GPIO":[32,0,0,0,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":1} Lighting Arena {"NAME":"Lighting Arena Smart Plug","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} Lloyd's {"NAME":"Lloyds LC-1193","GPIO":[0,0,0,0,320,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18} @@ -1284,7 +1308,7 @@ Lohas Nightlight + USB {"NAME":"Lohas LED Mini Plug","GPIO":[0,321,0,288,3 Lombex Actis Pro {"NAME":"U11-Socket","GPIO":[0,0,0,0,289,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Lonsonho 10A Type E {"NAME":"Lonsonho10ALed","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} LoraTap SP400W-IT {"NAME":"LoraTap SP400W","GPIO":[0,0,0,0,544,320,0,0,224,32,0,0,0,1],"FLAG":0,"BASE":18} -LSC Power {"NAME":"LSC Smart Plug","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} +LSC Power {"NAME":"LSC Smart Plug (CB2S)","GPIO":[0,0,0,0,32,224,0,0,0,288,289,0,0,0],"FLAG":0,"BASE":18} LSC Smart Connect {"NAME":"LSC Smart Plug FR","GPIO":[0,0,0,0,320,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18} Lumiman LM650 {"NAME":"Lumiman LM650","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Luminea {"NAME":"CH-1556","GPIO":[0,0,0,32,2720,2656,1,1,2624,320,224,0,0,0],"FLAG":0,"BASE":18} @@ -1296,6 +1320,7 @@ Lunvon 2000W {"NAME":"Lunvon Smart Plug","GPIO":[32,0,0,0,0,0,28 Lunvon 3000W {"NAME":"Lunvon Smart Plug","GPIO":[32,0,0,0,0,0,288,224,0,0,0,0,0,0],"FLAG":0,"BASE":18} Martin Jerry V01 {"NAME":"MJ V01","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Martin Jerry XS-SSA01 {"NAME":"MJ_XS-SSA01","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} +Maxcio 16A Mini {"NAME":"MAXCIO RMC021","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":1} Maxcio W-UK007S {"NAME":"Maxcio","GPIO":[320,0,1,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45} Maxcio W-US002S {"NAME":"W-US002S","GPIO":[321,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45} Maxcio W-US003 {"NAME":"W-US003","GPIO":[1,32,1,1,1,1,0,0,1,225,224,1,1,0],"FLAG":0,"BASE":18} @@ -1341,13 +1366,14 @@ NGS Loop Track 16A {"NAME":"LOOP","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224 Nightlight and AC Outlet {"NAME":"SWN03","GPIO":[32,0,0,0,0,0,1,1,416,0,0,224,0,0],"FLAG":0,"BASE":18} Nishica SM-PW701I {"NAME":"SM-PW701I","GPIO":[1,1,1,1,1,1,1,1,224,288,32,1,1,1],"FLAG":0,"BASE":18} Nivian {"NAME":"Nivian Smart Socket","GPIO":[0,0,320,0,0,2688,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} -Nous 16A {"NAME":"NOUS A1T","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0],"FLAG":0,"BASE":49} +Nous 16A {"NAME":"NOUS A1T","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} Nous A1 {"NAME":"NOUS A1","GPIO":[320,0,576,0,2656,2720,0,0,2624,32,0,224,0,0],"FLAG":0,"BASE":45} NX-SM112 {"NAME":"NX-SM112v3","GPIO":[0,0,0,0,2720,2656,0,0,576,32,2592,224,0,0],"FLAG":0,"BASE":45} NX-SM200 {"NAME":"NX-SM200","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,321,2624,0],"FLAG":0,"BASE":18} NX-SM210 {"NAME":"NX-SM210","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} NX-SM223 {"NAME":"Smart Thurmm","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} Oakter Oak Plug Plus 16A {"NAME":"Oakter OakPlug Plus","GPIO":[0,0,0,0,224,0,0,0,544,320,0,0,0,0],"FLAG":0,"BASE":18} +Oakter OakPlug Mini 10A {"NAME":"Oakter OakPlug Mini","GPIO":[0,0,0,0,224,0,0,0,544,320,0,0,0,0],"FLAG":0,"BASE":18} Oakter OakPlug Plus (old) {"NAME":"Oakter OakPlug Plus (old)","GPIO":[0,0,0,0,224,0,0,0,0,320,0,0,544,0],"FLAG":0,"BASE":18} Obi Stecker {"NAME":"OBI Socket","GPIO":[1,1,0,1,288,224,0,0,290,1,32,0,1,4704],"FLAG":0,"BASE":51} Obi Stecker 2 {"NAME":"OBI Socket 2","GPIO":[0,0,0,0,224,32,0,0,320,289,0,0,0,0],"FLAG":0,"BASE":61} @@ -1559,7 +1585,7 @@ ZSP-001 {"NAME":"ZSP-001","GPIO":[32,1,1,1,2688,2656,0,0,25 ## Power Strip ``` 3AC 4USB {"NAME":"C723","GPIO":[0,0,320,0,0,224,0,0,226,320,32,227,225,0],"FLAG":0,"BASE":18} -4 AC Outlets 10A and 4 USB Ports {"NAME":"SA-P802 Power Strip","GPIO":[544,0,0,0,227,228,0,0,225,224,226,0,35,1],"FLAG":0,"BASE":18} +4 AC Outlets 10A and 4 USB Ports {"NAME":"SA-P802 Power Strip","GPIO":[544,0,0,0,227,228,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18} A0F0 ZLD-44EU-W {"NAME":"AOFO-4AC-4USB","GPIO":[0,320,0,32,225,224,0,0,226,227,260,0,0,4704],"FLAG":0,"BASE":18} Acenx 3AC+3USB {"NAME":"ACENX 3-Outlet","GPIO":[320,291,290,289,0,224,0,0,226,227,225,0,32,0],"FLAG":0,"BASE":18} AHRise 4+4AC+4USB {"NAME":"AHRise-083","GPIO":[0,0,0,0,320,32,0,0,225,224,226,227,0,0],"FLAG":0,"BASE":18} @@ -1585,6 +1611,7 @@ Brennenstuhl Connect Eco-Line {"NAME":"WS EL01 DE","GPIO":[34,33,0,32,224,225,0 Brennenstuhl Connect Premium-Line {"NAME":"WS PL01 DE","GPIO":[34,33,0,32,224,225,0,0,288,0,35,289,576,0],"FLAG":0,"BASE":18} BrilliantSmart Powerboard with USB Chargers {"NAME":"B_WiFi-4","GPIO":[320,0,0,321,256,32,0,0,258,257,259,0,228,4704],"FLAG":0,"BASE":18} Calex 4AC 2USB {"NAME":"Calex Power Strip 429228","GPIO":[0,320,0,36,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18} +Calex 4AC 4USB {"NAME":"Calex Power Strip 429228","GPIO":[0,0,0,288,224,226,0,0,0,228,227,225,32,0],"FLAG":0,"BASE":18} CE Smart Home {"NAME":"CE Power Strip","GPIO":[288,0,0,0,227,228,0,0,225,226,224,0,32,0],"FLAG":0,"BASE":18} CE Smart Home Garden Stake {"NAME":"CE Power Stake","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} CRST LTS-4G-W {"NAME":"CRST LTS-4G-W","GPIO":[0,0,0,0,227,0,0,0,225,226,224,0,0,0],"FLAG":0,"BASE":18} @@ -1653,6 +1680,7 @@ Surge Protector 3AC 2USB {"NAME":"C158","GPIO":[260,0,0,0,261,230,0,0,224,0, SWB1 {"NAME":"SWB1","GPIO":[288,0,0,0,0,227,0,0,224,32,225,226,0,0],"FLAG":0,"BASE":18} SWB2 3AC + 2USB {"NAME":"SWB2","GPIO":[576,1,0,1,0,226,0,0,224,32,225,227,0,0],"FLAG":0,"BASE":18} Swisstone 4AC 4USB {"NAME":"Swisstone SH140","GPIO":[0,576,0,32,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18} +Sygonix 4AC {"NAME":"Sygonix SY-4538254","GPIO":[576,32,0,231,229,230,0,0,225,224,226,228,259,0],"FLAG":0,"BASE":18} TCP Smart 4AC+USB {"NAME":"TCP WPS4WUK","GPIO":[1,320,0,32,226,227,0,0,225,224,228,0,0,1],"FLAG":0,"BASE":18} Teckin SS30 {"NAME":"Teckin SS30","GPIO":[288,1,1,321,256,32,0,0,258,257,259,1,228,0],"FLAG":0,"BASE":18} Tellur 3AC 4USB {"NAME":"Tellur","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,4704],"FLAG":0,"BASE":18} @@ -1687,10 +1715,15 @@ ZLD-44USA-W {"NAME":"ZLD-44USA-W","GPIO":[0,320,0,32,225,224,0, ZLD64-EU-W {"NAME":"ZLD64-EU-W","GPIO":[0,320,0,32,225,224,0,0,0,0,226,0,0,0],"FLAG":0,"BASE":18} ``` +## Presence Sensor +``` +Tuya mmWave {"NAME":"ZY-M100","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"SO97 1 | TuyaMCU 99,1 | TuyaMCU 75,104"} +``` + ## RF Gateway ``` Sonoff RF Bridge 433 {"NAME":"Sonoff Bridge","GPIO":[32,3200,1,3232,1,1,0,0,1,320,1,0,0,0],"FLAG":0,"BASE":25} -Virage Labs VirageBridge 433MHz {"NAME":"VirageBridge","GPIO":[32,3200,1,3232,1,1,0,0,1,320,1,0,0],"FLAG":0,"BASE":25} +Virage Labs VirageBridge 433MHz {"NAME":"VirageBridge","GPIO":[32,3200,1,3232,1,1,0,0,1,320,1,0,0,0],"FLAG":0,"BASE":25} ``` ## RGB @@ -1714,6 +1747,7 @@ Wipro Garnet NS7001 480lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,416,419,0, Aigital LE13 800lm {"NAME":"Aigital 9W RGB","GPIO":[0,0,0,0,420,417,0,0,418,0,419,416,0,0],"FLAG":0,"BASE":18} Aisirer 10W 1000lm {"NAME":"Aisirer RGBCW","GPIO":[160,0,0,0,0,0,0,0,0,4032,4064,0,0,0],"FLAG":0,"BASE":18} AiYaTo 12W {"NAME":"AiYaTo RGBCW","GPIO":[0,0,0,0,419,418,0,0,416,420,417,0,0,0],"FLAG":0,"BASE":18} +AiYaTo 12W {"NAME":"AiYaTo RGBCW","GPIO":[0,0,0,0,419,418,0,0,416,420,417,0,0,0],"FLAG":0,"BASE":18} Alfawise LE12 9W 900LM {"NAME":"Alfawise LE12 ","GPIO":[0,0,0,0,420,417,0,0,418,0,419,416,0,0],"FLAG":0,"BASE":18} Aoycocr JL81 5W 400lm {"NAME":"AoycocrJLB1","GPIO":[0,0,0,0,418,0,0,0,417,420,416,419,0,0],"FLAG":0,"BASE":18} Aoycocr Q10CWM BR30 9W 720lm {"NAME":"AoycocrBR30","GPIO":[0,0,0,0,0,418,0,0,417,0,416,419,0,0],"FLAG":0,"BASE":18} @@ -1729,6 +1763,7 @@ Aunics 7W 600lm {"NAME":"Aunics RGBW","GPIO":[0,0,0,0,416,419,0,0,4 Avatar 8W 800lm {"NAME":"Avatar 8W RGBCW","GPIO":[1,1,1,1,416,419,1,1,417,420,418,1,1,1],"FLAG":0,"BASE":18} Avatar ALB201W 720lm {"NAME":"AVATAR ALB201W","GPIO":[0,0,0,0,0,418,0,0,417,0,416,419,0,0],"FLAG":0,"BASE":18} Avatar ALS18L A60 800lm {"NAME":"Avatar E14 7W","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":20} +AZzardo 10W {"NAME":"Azzardo AZ3213","GPIO":[0,0,0,0,4032,0,0,0,0,0,4064,0,0,0],"FLAG":0,"BASE":18,"CMND":"SetOption37 6"} B.K. Licht 5.5W 350lm {"NAME":"BKL1262","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18} B.K. Licht 9W 806lm {"NAME":"BKL1253","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18} Bakibo TB95 9W 1000lm {"NAME":"Bakibo A19 9W","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} @@ -1806,6 +1841,7 @@ Legelite A60 7W {"NAME":"Legelite A60 7","GPIO":[0,0,0,0,416,419,0, Legelite A60 7W 600lm {"NAME":"Legelite E26","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Lenovo 800lm {"NAME":"Lenovo SE-241EB","GPIO":[0,0,0,0,416,419,0,0,417,452,418,0,0,0],"FLAG":0,"BASE":18} Lloyd's 5W 400Lm {"NAME":"LLOYDS LC-1271","GPIO":[160,0,0,0,0,0,0,0,4064,0,4032,0,0,0],"FLAG":0,"BASE":18} +Local Bytes 9W 900lm {"NAME":"localbytes bulb","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Lohas ZN004 8W 680lm {"NAME":"Lohas B22 R63","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18} Lohas ZN011 5W 420lm {"NAME":"LohasZN011","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18} Lohas ZN014-2 5W 380lm {"NAME":"Lohas ZN014-2","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18} @@ -1859,7 +1895,7 @@ Ruihai 9W 800lm {"NAME":"Ruihai SB50","GPIO":[0,0,0,0,416,419,0,0,4 RYE 5W 450LM Candle {"NAME":"RYE Candlebra","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Saudio A19 7W 700lm {"NAME":"X002BU0DOL","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Sealight A19 9W 810lm {"NAME":"DGO/SEASTAR","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18} -Slitinto 5W Candle {"NAME":"Slitinto RGBWW","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0,0],"FLAG":0,"BASE":18} +Slitinto 5W Candle {"NAME":"Slitinto RGBWW","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} Slitinto TB95 9W 1000lm {"NAME":"Slitinto 9W","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Smart 9W 800lm {"NAME":"SmartLED ","GPIO":[0,0,0,0,420,417,0,0,418,0,419,416,0,0],"FLAG":0,"BASE":18} SmartLED 9W 400lm {"NAME":"SmartLED","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} @@ -1893,6 +1929,19 @@ ZunPulse 9W {"NAME":"ZunPulse B22 9W","GPIO":[0,0,0,0,416,419,0 ZZHXON 600lm {"NAME":"E27_RGB_Bulb","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} ``` +## RGBIC LED +``` +Athom 2812b Controller for {"NAME":"LS2812B-TAS","GPIO":[32,0,1376,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Athom ESP32 Music Controller for {"NAME":"Athom LS8P","GPIO":[32,1,224,1,1,1,1,1,1,1,1,7904,1,1377,1376,1,0,1,1,1,0,1088,1,1,0,0,0,0,7872,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +Athom High Power 16A Controller for {"NAME":"LS_4PIN_TAS","GPIO":[32,1376,0,0,0,0,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"Rule1 on Power1#State do power2 2 endon|Rule1 1"} +BlitzWolf IC Smart RGB Controller for {"NAME":"BW-LT31","GPIO":[0,0,32,1376,0,0,0,0,0,1088,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO37 24"} +cod.m WLAN Pixel Controller v0.8 {"NAME":"cod.m Pixel Controller V0.8","GPIO":[0,0,0,0,0,544,0,0,0,0,0,32,1376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} +ESP01 NeoPixel Ring {"NAME":"ESP-01S-RGB-LED-v1.0","GPIO":[1,1,1376,1,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +H803WF 2048 Pixel 5V-24V {"NAME":"H803WF","GPIO":[0,0,0,0,3840,3840,0,0,3872,1376,0,3872,0,0],"FLAG":0,"BASE":18} +IOTMCU {"NAME":"IOTMCU_ESP-12S-RGB-LED-v1","GPIO":[1,1,1,1,0,1376,0,0,1,1088,32,0,0,0],"FLAG":0,"BASE":18} +SP501E WS2812B {"NAME":"SP501E","GPIO":[0,32,0,1376,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +``` + ## RGBW ``` 3Stone EBE-QPW36 1050lm {"NAME":"3STONE","GPIO":[0,0,0,0,2944,2912,0,0,416,2976,0,0,0,1],"FLAG":0,"BASE":18} @@ -2031,7 +2080,7 @@ REPSN G45 5W 500lm {"NAME":"REPSN RGBW E14","GPIO":[0,0,0,0,0,0,0,0,40 Riversong Juno 10W {"NAME":"Juno10","GPIO":[0,0,0,0,2912,416,0,0,0,2976,2944,0,0,0],"FLAG":0,"BASE":18} Rogoei EBE-QPZ04 6.5W 450lm {"NAME":"EBE-QPZ04","GPIO":[0,0,0,0,4032,0,0,0,0,0,4064,0,0,0],"FLAG":0,"BASE":18} Saudio 7W 700lm {"NAME":"X002BU0DOL","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} -Shelly Duo RGBW 5W {"NAME":"Shelly Duo RGBW","GPIO":[0,0,0,0,0,419,0,0,417,416,418,0,0,0],"FLAG":0,"BASE":18} +Shelly Duo RGBW 5W 400lm {"NAME":"Shelly Duo RGBW","GPIO":[0,0,0,0,0,419,0,0,417,416,418,0,0,0],"FLAG":0,"BASE":18} Shelly Duo RGBW 9W 800lm {"NAME":"Shelly Duo RGBW","GPIO":[0,0,0,0,0,419,0,0,417,416,418,0,0,0],"FLAG":0,"BASE":18} Smart 810lm {"NAME":"OOOLED 60W RGB","GPIO":[0,0,0,0,418,419,0,0,416,0,417,0,0,4704],"FLAG":0,"BASE":18} SmartLED 9W 400lm {"NAME":"SmartLED RGBWW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} @@ -2046,6 +2095,7 @@ Swisstone 806lm {"NAME":"SH 340","GPIO":[0,0,0,0,2912,416,0,0,0,297 Syska 7W 480lm {"NAME":"Syska","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Syska 8W {"NAME":"Syska SMW-8W-C","GPIO":[0,0,0,0,420,419,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} Syska 9W 720lm {"NAME":"SyskaSmartBulb","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} +TCP Smart 5W {"NAME":"TAOLGU42OWW25RGBW","GPIO":[0,0,0,0,417,416,0,0,419,418,420,0,0,0],"FLAG":0,"BASE":18} TCP Smart 9W 806lm {"NAME":"TCP Smart RGBW","GPIO":[0,0,0,0,2912,416,0,0,417,2976,2944,0,0,0],"FLAG":0,"BASE":18} Teckin 7.5W 800lm {"NAME":"Teckin SB60","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} Teckin SB50 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} @@ -2072,6 +2122,11 @@ Zemismart A19 10W {"NAME":"Zemism_E27_A19","GPIO":[0,0,0,0,0,0,0,0,0, Zilotek A19 800lm {"NAME":"Zilotek RGBW","GPIO":[0,0,0,0,2912,416,0,0,417,2976,2944,0,0,0],"FLAG":0,"BASE":18} ``` +## Relay +``` +LilyGo T-Relay 8 {"NAME":"LilyGo ESP32 Relay 8","GPIO":[1,1,1,1,1,231,1,1,227,226,1,1,1,1,230,229,0,228,1,1,0,544,1,1,0,0,0,0,225,224,1,1,1,0,0,1],"FLAG":0,"BASE":1} +``` + ## Relay Board ``` 2 Channel Tuya {"NAME":"TY-DIY-S02","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 12,2 | TuyaMCU 13,13 | TuyaMCU 1,101"} @@ -2089,7 +2144,7 @@ Eachen ST-UDC1 {"NAME":"ST-UDC1","GPIO":[160,0,0,0,0,0,0,0,224,320 Electrodragon Board SPDT {"NAME":"ED Relay Board","GPIO":[1,1,1,1,1,1,0,0,224,225,1,1,288,4704],"FLAG":0,"BASE":18} Electrodragon ESP8266 {"NAME":"ElectroDragon","GPIO":[33,1,32,1,1,1,0,0,225,224,1,1,288,4704],"FLAG":0,"BASE":15} Electrodragon Inductive Load {"NAME":"ED RelayBoard IL","GPIO":[0,0,1,0,1,1,0,0,224,225,1,1,288,0],"FLAG":0,"BASE":18} -ESP-01 Relay V4.0 {"NAME":"ESP01v4","GPIO":[256,320,0,32,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +ESP-01 Relay V4.0 {"NAME":"ESP01v4","GPIO":[256,320,0,32,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} ESP-01S 5V Relay Module V1.0 {"NAME":"ESP-01S Relay","GPIO":[256,288,1,1,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} ESP-12F 5V/7-28V 1 Channel 30A {"NAME":"Aideepen","GPIO":[0,0,0,0,0,288,0,0,0,0,0,0,224,0],"FLAG":0,"BASE":18} ESP-12F 5V/7-28V 4 Channel 30A {"NAME":"ESP12F_Relay_30A_X4","GPIO":[1,1,1,1,32,1,1,1,226,227,225,1,224,1],"FLAG":0,"BASE":18} @@ -2111,6 +2166,7 @@ KRIDA 8 Channel 10A Electromagnetic {"NAME":"8CH Relay","GPIO":[230,1,231,229,1 LC Technology 12V 4 Channel {"NAME":"LC Technology 4CH Relay","GPIO":[224,0,225,0,226,227,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} LC Technology 5V 2 Channel {"NAME":"LC-ESP01-2R-5V","GPIO":[0,3200,0,3232,0,0,0,0,224,225,0,0,0,0],"FLAG":0,"BASE":18} LC Technology 5V 4 Channel {"NAME":"LC-Tech_4CH ","GPIO":[288,1,32,1,0,0,0,0,224,225,226,227,0,0],"FLAG":0,"BASE":18} +LC Technology 5V/7-30V 8 Channel {"NAME":"ESP32_Relay_X8","GPIO":[0,0,0,0,0,0,0,0,225,224,226,0,0,0,0,0,0,0,0,0,0,229,228,227,0,0,0,0,231,230,0,0,0,0,0,0],"FLAG":0,"BASE":1} LC Technology 5V/8-80V 1 Channel {"NAME":"LC-Relay-ESP12-1R-MV","GPIO":[1,1,544,1,1,224,1,1,1,1,1,1,321,1],"FLAG":0,"BASE":18} LC Technology 5V/8-80V 1 Channel {"NAME":"LC-Relay-ESP12-1R-D8","GPIO":[1,1,544,1,1,224,1,1,1,1,1,1,321,1],"FLAG":0,"BASE":18} LC Technology AC90V-250V 1 Channel {"NAME":"ESP32_Relay_AC_X1","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,224,1,1,1,0,1,1,544,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} @@ -2140,12 +2196,14 @@ Yunshan 7-30V 10A {"NAME":"Yunshan 10A","GPIO":[32,1,288,1,224,161,0, ``` 2 CH Smart Switch {"NAME":"Generic","GPIO":[32,1,1,1,1,225,33,1,224,288,1,1,1,1],"FLAG":0,"BASE":18} Aubess Power Monitor Switch 16A {"NAME":"Aubess with (BL0942)","GPIO":[0,3200,0,7520,0,0,0,0,0,0,224,0,0,0],"FLAG":0,"BASE":18} +Mini Smart Switch {"NAME":"SmartSwitch-MK601","GPIO":[0,0,0,160,32,224,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} Moes 10A {"NAME":"Moes MS-101","GPIO":[0,0,0,0,0,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Smarsecur Smart Switch {"NAME":"ESP-02S","GPIO":[0,0,0,32,0,0,0,0,0,0,224,0,0,0],"FLAG":0,"BASE":18} ``` ## Sensor ``` +Bresser 7-Kanal Thermo-/Hygrometer with Outdoor {"NAME":"Bresser","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"SO97 1 | TuyaMCU 73,2 | TuyaMCU 71,102"} Genesense IoT Controller {"NAME":"GNS24","GPIO":[32,1,1312,1,256,320,1,1,256,1216,160,3840,1,4704],"FLAG":0,"BASE":18} Shelly 3EM Power Monitoring Module {"NAME":"Shelly 3EM","GPIO":[1,1,288,1,32,8065,0,0,640,8064,608,224,8096,0],"FLAG":0,"BASE":18} ``` @@ -2171,6 +2229,11 @@ Slampher {"NAME":"Slampher","GPIO":[32,1,0,1,0,0,0,0,224,320 SmartBase E0260 {"NAME":"SmartBaseE0260","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} ``` +## Soil Sensor +``` +DIY MORE ESP32 DHT11 {"NAME":"DIYMORESOILDHT11","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,544,1,1,1,0,1,1184,1,0,1,1,1,0,0,0,0,4864,288,4865,1,1,0,0,1],"FLAG":0,"BASE":1} +``` + ## Switch ``` 3 Way Smart Light {"NAME":"KS-602F","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} @@ -2179,6 +2242,7 @@ AGL 2 Gang {"NAME":"AGL WiFi 02","GPIO":[0,0,544,0,0,33,0,0,22 AGL 3 Gang {"NAME":"AGL WiFi 03","GPIO":[0,0,544,0,34,33,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18} Aoycocr SW1 {"NAME":"Aoycocr SW1","GPIO":[576,1,321,1,1,1,1,1,320,32,1,224,1,1],"FLAG":0,"BASE":18} APPIO 1 Gang Switch {"NAME":"Appio-9608","GPIO":[0,0,0,0,0,32,0,0,0,0,0,224,288,0],"FLAG":0,"BASE":18} +Appio 3 Gang Touch {"NAME":"Appio 9611","GPIO":[0,0,0,0,226,33,0,0,32,224,34,225,288,0],"FLAG":0,"BASE":18} Athom 1 Gang {"NAME":"Athom SW011EU","GPIO":[576,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1} Athom 1 Gang {"NAME":"Athom SW031US","GPIO":[576,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1} Athom 1 Gang No Neutral {"NAME":"Athom SW111EU","GPIO":[576,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1} @@ -2225,7 +2289,7 @@ Dierya Touch Panel 2 Gang {"NAME":"CD302","GPIO":[544,0,0,33,225,0,0,0,32,224 Dierya Touch Panel 3 Gang {"NAME":"CD303","GPIO":[576,289,0,34,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18} Digoo DG-S811 3 Gang {"NAME":"DIGOO Switch","GPIO":[0,0,0,0,34,33,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18} DS-101 1 Gang {"NAME":"Smart Life Switch","GPIO":[0,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":18} -DS-101 2 Gang {"NAME":"Smart Life Switch","GPIO":[576,289,0,32,225,33,0,0,0,224,288,0,0],"FLAG":0,"BASE":18} +DS-101 2 Gang {"NAME":"Smart Life Switch","GPIO":[576,289,0,32,225,33,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":18} DS-101 3 Gang {"NAME":"DS-101 3 gang","GPIO":[576,322,0,33,226,34,0,0,32,225,321,224,320,0],"FLAG":0,"BASE":18} DS-101 4 Gang Switch {"NAME":"DS-101 4 Gang","GPIO":[544,0,0,33,225,34,0,0,32,224,227,226,35,0],"FLAG":0,"BASE":18} DS-102 1 Gang {"NAME":"DS-102 1 Gang","GPIO":[576,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":18} @@ -2269,6 +2333,7 @@ Innens RF433 2 Gang 1 Way {"NAME":"Innens Light Switch 2G","GPIO":[0,0,289,0, Jinvoo SM-SW101-1 {"NAME":"SM-SW101-1","GPIO":[288,0,0,33,0,0,0,0,32,224,0,0,0,4704],"FLAG":0,"BASE":18} Jinvoo SM-SW101-2 {"NAME":"SM-SW101-2","GPIO":[288,0,0,33,225,0,0,0,32,224,0,0,0,4704],"FLAG":0,"BASE":18} Jinvoo SM-SW101-3 {"NAME":"Jinvoo Wall Sw","GPIO":[288,0,0,33,225,34,0,0,32,224,0,226,0,4704],"FLAG":0,"BASE":18} +KaBuM! 15A 3 Gang Touch {"NAME":"Kabum Switch 3","GPIO":[0,0,0,0,226,33,0,0,32,224,34,225,576,0],"FLAG":0,"BASE":18} Kauf RGB Wall {"NAME":"Kauf SRF10","GPIO":[448,1,450,1,450,449,1,1,449,32,448,224,1,1],"FLAG":0,"BASE":18} KingArt 1 Gang {"NAME":"KING-L1","GPIO":[0,0,0,0,0,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} KingArt 3 Gang {"NAME":"KING-L3","GPIO":[0,0,0,0,226,225,0,0,224,164,165,0,167,0],"FLAG":0,"BASE":18} @@ -2292,6 +2357,7 @@ LerLink 2 Gang No Neutral {"NAME":"Lonsonho 2gang","GPIO":[0,0,0,33,32,0,0,0, Lerlink 3 Gang {"NAME":"X803A","GPIO":[0,0,0,33,32,34,0,0,224,259,225,226,288,0],"FLAG":0,"BASE":18} Lerlink 3 Gang {"NAME":"X803A","GPIO":[0,0,0,33,32,34,0,0,224,288,225,226,0,0],"FLAG":0,"BASE":18} Lerlink 3 Gang No Neutral {"NAME":"X803K-L 3 Gang","GPIO":[0,0,320,0,32,34,33,0,224,0,225,226,0,0],"FLAG":0,"BASE":18} +Lidl Silvercrest {"NAME":"Lidl Silvercrest HG06337","GPIO":[0,0,0,0,0,0,0,0,32,320,224,0,0,0],"FLAG":0,"BASE":18} Lightstory WT02S {"NAME":"WT02S","GPIO":[0,0,0,0,321,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":50} Linkind 2-Way {"NAME":"Linkind WS240010008","GPIO":[0,0,0,0,0,224,0,0,0,0,288,0,0,0,0,0,0,0,0,0,0,576,321,0,0,0,0,0,33,32,0,0,0,0,0,0],"FLAG":0,"BASE":1} Linkind Dimmer {"NAME":"Linkind Dimmer WS240010108","GPIO":[6213,8448,0,0,640,0,0,0,0,0,288,0,0,0,0,0,0,0,608,0,0,0,544,0,0,0,0,0,33,32,0,0,0,0,0,0],"FLAG":0,"BASE":1} @@ -2308,7 +2374,7 @@ LX-WIFI-00M 4 Gang {"NAME":"LX-WIFI-00M","GPIO":[32,228,1,1,226,225,33 MakeGood 2 Gang {"NAME":"MakeGood 2 Gang","GPIO":[0,0,0,0,0,0,0,0,0,0,290,0,0,0],"FLAG":0,"BASE":54} MakeGood 4 Gang {"NAME":"MakeGood 4 Gang","GPIO":[0,0,0,0,0,0,0,0,0,0,290,0,0,0],"FLAG":0,"BASE":54} Markevina KS-602S {"NAME":"Markevina KS-6","GPIO":[32,1,0,1,0,0,0,0,224,288,0,0,0,0],"FLAG":0,"BASE":18} -Martin Jerry S01 15A {"NAME":"MJ-S01 Switch","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0],"FLAG":0,"BASE":18} +Martin Jerry S01 15A {"NAME":"MJ-S01 Switch","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Martin Jerry ST01 3 Way {"NAME":"MJ 3Way Switch","GPIO":[1,1,1,1,288,289,0,0,224,160,544,1,0,0],"FLAG":0,"BASE":18} Maxcio IT Wall 3 Gang Light {"NAME":"Maxcio 3 Gang Switch","GPIO":[544,0,0,0,32,33,0,0,225,226,224,0,34,0],"FLAG":0,"BASE":18} Merkury MI-WW107-199W {"NAME":"MI-WW107-199W","GPIO":[288,0,0,0,0,0,0,0,32,224,0,0,0,0],"FLAG":0,"BASE":18} @@ -2336,6 +2402,7 @@ Moes 3 Gang {"NAME":"Moes WS-EU3-W","GPIO":[544,0,290,33,225,34 Moes 3-Way {"NAME":"Moes 3-Way","GPIO":[1,1,1,1,224,321,0,0,257,161,160,1,1,0],"FLAG":0,"BASE":18} Moes BS-US-W Boiler {"NAME":"BS-US-W","GPIO":[290,0,0,32,224,0,0,0,0,0,288,0,291,0],"FLAG":0,"BASE":18} Moes Light and Fan {"NAME":"Moes WF-FL01","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +Moes Push Button 3 Way Light {"NAME":"Moes ESW-1WAA-US","GPIO":[32,0,0,0,288,0,0,0,0,224,161,0,0,0],"FLAG":0,"BASE":18} Moes RF433 2 Gang Switch {"NAME":"WS-EUB2-WR","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Moes RF433 3 Gang {"NAME":"WS-EUB3-WR","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Moes RF433 3 Gang Touch {"NAME":"WS-EU-RF","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 12,2 | TuyaMCU 13,3"} @@ -2357,11 +2424,13 @@ NaamaSmart KS602 {"NAME":"KS-602","GPIO":[32,0,0,0,0,0,0,0,224,576,0 Nedis Dual {"NAME":"SM-SW102U-2","GPIO":[576,0,0,33,225,0,0,0,32,224,0,0,0,4704],"FLAG":0,"BASE":18} Nexete DS-123 {"NAME":"DS-123","GPIO":[544,321,1,32,224,33,0,0,1,225,320,1,1,0],"FLAG":0,"BASE":18} Nexete DS-123 Single {"NAME":"DS-123","GPIO":[544,0,1,33,0,32,0,0,1,224,320,1,1,0],"FLAG":0,"BASE":18} -Novadigital Interruptor Touch Led 1 Botno {"NAME":"Nova Digital Switch 1 Gang","GPIO":[544,0,0,32,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} +Novadigital Interruptor Touch Led 1 Boto {"NAME":"Nova Digital Switch 1 Gang","GPIO":[544,0,0,32,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} Prosto {"NAME":"Prosto WFS-T10","GPIO":[0,0,0,0,0,224,0,0,320,0,64,0,0,0],"FLAG":0,"BASE":18} Push Button 1/2/3/4 Gang {"NAME":"DS-122","GPIO":[321,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":18} Q-touch 1 Gang {"NAME":"Qtouch","GPIO":[289,0,0,32,0,0,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":1} Q-touch 433MHz 1 Gang {"NAME":"Qtouch 1G","GPIO":[32,0,0,0,0,0,0,0,224,288,0,0,0,0],"FLAG":0,"BASE":18} +Q-touch 433MHz 1 Gang No Neutral {"NAME":"QWP_W1_WIFI-TOUCH","GPIO":[32,1,1,1,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":28} +Q-touch 433MHz 2 Gang No Neutral {"NAME":"QWP_W2_WIFI-TOUCH","GPIO":[32,1,1,1,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":29} Qualitel 1 Gang {"NAME":"Qualitel 1 Gang","GPIO":[544,0,0,160,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} Qualitel 2-Gang {"NAME":"Qualitel 2 Gang","GPIO":[544,0,289,0,0,161,0,0,160,224,0,225,288,0],"FLAG":0,"BASE":18} Qualitel 3 Gang {"NAME":"Qualitel 3 Gang","GPIO":[544,0,290,161,225,162,0,0,160,224,289,226,288,0],"FLAG":0,"BASE":18} @@ -2488,7 +2557,7 @@ ZUCZUG 3 Gang {"NAME":"2ph105626a x3","GPIO":[0,288,0,32,34,33,0, ``` AGL Modulo Relay 01 Canal {"NAME":"AGL-Basic","GPIO":[0,1,0,0,224,32,0,0,0,0,320,0,0,0],"FLAG":0,"BASE":18} Albohes 2 Channel {"NAME":"Albohes SH-08","GPIO":[0,3200,33,3232,321,320,0,0,224,544,32,0,225,1],"FLAG":0,"BASE":18} -Athom 10A {"NAME":"CB01-TAS-1","GPIO":[0,0,0,32,576,0,0,0,0,224,0,0,0,1],"FLAG":0,"BASE":18} +Athom 10A {"NAME":"CB01-TAS-1","GPIO":[0,0,0,32,320,0,0,0,0,224,0,0,0,1],"FLAG":0,"BASE":18} Athom 2Ch Inching/Self-locking {"NAME":"Athom R02","GPIO":[1,1,1,1,225,224,1,1,1,1,1,1,576,0],"FLAG":0,"BASE":18} Athom 3-Way Mini Relay {"NAME":"RS01-TAS-1","GPIO":[0,0,0,32,576,0,0,0,0,224,160,0,0,0],"FLAG":0,"BASE":18} Athom 4Ch Inching/Self-locking 10A {"NAME":"Athom R04","GPIO":[1,1,1,1,32,576,1,1,226,227,225,1,224,0],"FLAG":0,"BASE":18} @@ -2522,7 +2591,7 @@ LoveAnna AC85-250V 10A {"NAME":"2xSwitch No RF LoveAnna","GPIO":[32,0,0,0, Luani HVIO {"NAME":"Luani HVIO","GPIO":[0,1,1,1,224,225,0,0,160,161,1,288,0,4704],"FLAG":0,"BASE":35} Milfra Smart {"NAME":"Milfra Smart Module TB41","GPIO":[576,0,0,225,2688,2656,0,0,2592,193,480,224,192,0],"FLAG":0,"BASE":18} Moes {"NAME":"Moes MS-104B","GPIO":[0,0,32,0,480,0,0,0,161,160,224,225,0,0],"FLAG":0,"BASE":18} -Nedis 10A {"NAME":"Nedis WIFIPS10WT","GPIO":[0,0,0,0,21,0,0,0,17,57,0,52,0,0],"FLAG":0,"BASE":18} +Nedis 10A {"NAME":"Nedis WIFIPS10WT","GPIO":[0,0,0,0,224,0,0,0,32,321,0,288,0,0],"FLAG":0,"BASE":18} Nova Digital Basic 1 MS101 {"NAME":"NovaDigBasic1","GPIO":[0,1,0,1,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} PPA Contatto Wi-Fi {"NAME":"PPA Contatto","GPIO":[0,0,32,0,224,162,0,0,288,225,0,0,0,0],"FLAG":0,"BASE":18} PS-1604 16A {"NAME":"PS-1604 16A","GPIO":[32,1,1,1,1,0,0,0,224,320,1,0,0,0],"FLAG":0,"BASE":1} @@ -2534,10 +2603,10 @@ Shelly 1L No Neutral {"NAME":"Shelly 1L","GPIO":[320,0,0,0,192,224,0,0,0 Shelly 1PM {"NAME":"Shelly 1PM","GPIO":[320,0,0,0,192,2720,0,0,0,0,0,224,0,4736],"FLAG":0,"BASE":18} Shelly 2 {"NAME":"Shelly 2","GPIO":[0,2752,0,2784,224,225,0,0,160,0,161,2816,0,0],"FLAG":0,"BASE":47} Shelly 2.5 {"NAME":"Shelly 2.5","GPIO":[320,0,0,0,224,193,0,0,640,192,608,225,3456,4736],"FLAG":0,"BASE":18} -Shelly EM {"NAME":"Shelly EM","GPIO":[0,0,0,0,0,0,0,0,640,3456,608,224,0,1],"FLAG":0,"BASE":18} +Shelly EM {"NAME":"Shelly EM","GPIO":[0,0,0,0,0,0,0,0,640,3457,608,224,8832,1],"FLAG":0,"BASE":18} Shelly i3 Action and Scenes Activation Device {"NAME":"Shelly i3","GPIO":[0,0,0,0,0,320,0,0,193,194,192,0,0,4736],"FLAG":0,"BASE":18} Shelly Plus 1 {"NAME":"Shelly Plus 1 ","GPIO":[0,0,0,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} -Shelly Plus 1PM {"NAME":"Shelly Plus 1PM","GPIO":[0,0,0,0,192,2720,0,0,0,0,0,0,0,0,2656,0,0,0,0,2624,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} +Shelly Plus 1PM {"NAME":"Shelly Plus 1PM","GPIO":[0,0,0,0,192,2720,0,0,0,0,0,0,0,0,2656,0,0,0,0,2624,0,32,224,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} Shelly Plus 2PM {"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,3456,0,0,0,0,0,0,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"} Shelly Plus i4 {"NAME":"Shelly Plus i4","GPIO":[0,0,0,0,0,0,0,0,192,0,193,0,0,0,0,0,0,0,0,0,0,0,195,194,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"SwitchMode1 1 | SwitchMode2 1 | SwitchMode3 1 | SwitchMode4 1 | SwitchTopic 0 | SetOption114 1"} Sinilink USB {"NAME":"XY-WFUSB","GPIO":[1,1,0,1,32,224,0,0,0,0,320,0,544,0],"FLAG":0,"BASE":18} @@ -2594,7 +2663,8 @@ Shelly Add-on {"NAME":"Shelly 1 Temp ","GPIO":[1344,0,0,1312,224, ## Thermostat ``` Floor Heating or Water/Gas Boiler {"NAME":"ME81H Thermostat","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} -Moes Floor Heating or Water/Gas Boiler Wall {"NAME":"WHT-HY609-GB-WH-MS","GPIO":[0,2304,0,2272,0,0,0,0,0,0,896,928,0,0],"FLAG":0,"BASE":54} +Lytko 101 {"NAME":"Lytko 101","GPIO":[1,7584,1312,1,1792,1824,0,0,1,1,1,224,1,4736],"FLAG":0,"BASE":18} +Moes Floor Heating or Water/Gas Boiler Wall {"NAME":"WHT-HY609-GB-WH-MS","GPIO":[0,2304,0,2272,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Mysa V1 Electric Baseboard Heater {"NAME":"Mysa Thermostat","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,640,608,0,0,0,0,0,0],"FLAG":0,"BASE":1} ``` @@ -2613,8 +2683,9 @@ Tuya Gas/Water {"NAME":"Valve FM101","GPIO":[320,0,0,0,224,0,0,0,0 ## Wall Outlet ``` 2AC 1USB {"NAME":"SM-SW801U","GPIO":[0,0,0,0,288,32,0,0,224,0,225,0,226,0],"FLAG":0,"BASE":18} +Aigostar P40 {"NAME":"Aigostar 8433325212278","GPIO":[0,0,0,0,544,288,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Aseer THWFS01 {"NAME":"ASEER-THWFS01","GPIO":[320,33,544,323,2720,2656,0,0,2624,225,321,224,32,0],"FLAG":0,"BASE":18} -Athom {"NAME":"Athom SK01","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18} +Athom {"NAME":"Athom SK01","GPIO":[0,0,0,3104,0,32,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18} Bestten LO-2-W {"NAME":"BESTTEN LO-2-W","GPIO":[0,0,0,0,576,32,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18} BingoElec 16A {"NAME":"BingoElecPower","GPIO":[0,0,0,0,288,289,1,1,224,32,0,0,1,1],"FLAG":0,"BASE":18} BlitzWolf SHP8 {"NAME":"SHP8","GPIO":[0,320,0,32,2720,2656,0,0,2624,289,224,0,0,0],"FLAG":0,"BASE":64} @@ -2632,6 +2703,7 @@ Kapok T16 {"NAME":"tiltech-t16","GPIO":[0,320,0,32,192,0,0,0, Kesen KS-604 {"NAME":"KS-604","GPIO":[1,1,288,1,1,33,0,0,225,224,1,1,32,0],"FLAG":0,"BASE":18} Kesen KS-604S {"NAME":"KS-604S","GPIO":[1,1,258,1,1,33,0,0,225,224,1,1,32,4704],"FLAG":0,"BASE":18} Keygma KS-15TW {"NAME":"Keygma KS-15T","GPIO":[0,0,0,0,0,320,0,0,224,160,0,0,0,0],"FLAG":0,"BASE":18} +Knightsbridge Dual Waterproof {"NAME":"Knightsbridge Dual Socket","GPIO":[321,544,320,544,225,0,0,0,0,33,0,224,32,0],"FLAG":0,"BASE":18} KS-621 {"NAME":"KS-621","GPIO":[32,0,0,0,2688,2656,0,0,2592,288,0,224,65,1],"FLAG":0,"BASE":18} Makegood MG-AUWF01 {"NAME":"MG-AUWF01","GPIO":[320,161,544,323,2720,2656,0,0,2624,225,321,224,160,0],"FLAG":0,"BASE":18} Makegood MG-UKWSG01 {"NAME":"Aseer 2-Gang","GPIO":[321,160,544,323,2720,2656,0,0,2624,224,320,225,161,0],"FLAG":0,"BASE":18} @@ -2649,8 +2721,8 @@ Steren Dual Plug and USB Charger {"NAME":"Steren_SHOME-118","GPIO":[0,576,0,32, T16E Dual USB 10A {"NAME":"T16E 10A","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18} TCP Smart Dual {"NAME":"TCP TAUWIS2GUK","GPIO":[33,0,0,0,0,224,32,0,225,544,0,0,0,0],"FLAG":0,"BASE":18} Teckin SR40 {"NAME":"RF-SR40-US","GPIO":[576,0,0,32,320,33,0,0,225,224,321,226,0,0],"FLAG":0,"BASE":18} +TopGreener {"NAME":"TGWF15RM","GPIO":[0,320,0,32,2720,2656,0,0,2624,321,224,0,0,0],"FLAG":0,"BASE":55} TopGreener Dual USB {"NAME":"TGWF215U2A","GPIO":[0,320,0,32,2720,2656,0,0,2624,225,224,321,0,0],"FLAG":0,"BASE":18} -TopGreener TGWF15RM {"NAME":"TGWF15RM","GPIO":[0,320,0,32,2720,2656,0,0,2624,321,224,0,0,0],"FLAG":0,"BASE":55} Vigica VGSPK00815 {"NAME":"VIGICA outlet","GPIO":[32,1,1,1,1,225,33,1,224,1,1,1,1,4704],"FLAG":0,"BASE":18} Virage Labs ViragePlug {"NAME":"ViragePlug","GPIO":[544,0,0,32,320,33,0,0,225,224,320,226,0,0],"FLAG":0,"BASE":18} Woox Dual {"NAME":"Woox R4053","GPIO":[33,0,0,0,0,224,32,0,225,320,0,0,0,0],"FLAG":0,"BASE":18} @@ -2659,12 +2731,14 @@ Xenon 2AC 1USB {"NAME":"Xenon SM-PW801-U1","GPIO":[0,0,0,0,288,32, ## Water Sensor ``` +Nedis SmartLife Water Detector {"NAME":"Nedis WIFIDW10WT","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 51,21"} W06 {"NAME":"W06 Water Sensor","GPIO":[0,3200,0,3232,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Y09 {"NAME":"Y09","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} ``` ## Zigbee Gateway ``` +Athom ESP32 Ethernet {"NAME":"Athom ZG01","GPIO":[32,0,0,0,0,0,0,0,5472,0,5504,544,0,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,1,5792,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} Eachen eWeLink ZbBridge Pro Ethernet {"NAME":"ZB-GW03-V1.2","GPIO":[0,0,3552,0,3584,0,0,0,5793,5792,320,544,5536,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,608,640,32,0,0,0,0,0],"FLAG":0,"BASE":1} Sonoff ZBBridge {"NAME":"Sonoff ZbBridge","GPIO":[320,3552,0,3584,5312,0,0,0,640,576,608,0,32,0],"FLAG":0,"BASE":75} Sonoff ZBBridge Pro {"NAME":"Sonoff Zigbee Pro","GPIO":[0,0,576,0,480,0,0,0,0,1,1,5792,0,0,0,3552,0,320,5793,3584,0,640,608,32,0,0,0,0,0,1,0,0,0,0,0,0],"FLAG":0,"BASE":1} diff --git a/tasmota/tasmota_xdrv_driver/xdrv_98_file_settings_demo.ino b/tasmota/tasmota_xdrv_driver/xdrv_122_file_settings_demo.ino similarity index 99% rename from tasmota/tasmota_xdrv_driver/xdrv_98_file_settings_demo.ino rename to tasmota/tasmota_xdrv_driver/xdrv_122_file_settings_demo.ino index f53fd65e0..8be544611 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_98_file_settings_demo.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_122_file_settings_demo.ino @@ -1,5 +1,5 @@ /* - xdrv_98_file_settings_demo.ino - Demo for Tasmota + xdrv_122_file_settings_demo.ino - Demo for Tasmota Copyright (C) 2021 Theo Arends diff --git a/tasmota/tasmota_xdrv_driver/xdrv_90_esp32_dingtian_relay.ino b/tasmota/tasmota_xdrv_driver/xdrv_90_esp32_dingtian_relay.ino new file mode 100644 index 000000000..5ef54642b --- /dev/null +++ b/tasmota/tasmota_xdrv_driver/xdrv_90_esp32_dingtian_relay.ino @@ -0,0 +1,210 @@ +/* + xdrv_90_esp32_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; + 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); + } + } +} + +/******************************************************************************************************** + * 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(STAT, PSTR("DINGTIAN_CHG")); + } + } +} + +void DingtianSetPower(void) +{ + // store relay status in structure + Dingtian->outputs = (XdrvMailbox.index >> Dingtian->first) & ~(0xFFFFFFFF << 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(uint32_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 diff --git a/tasmota/tasmota_xsns_sensor/xsns_11_veml6070.ino b/tasmota/tasmota_xsns_sensor/xsns_11_veml6070.ino index 59547b037..343ff4852 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_11_veml6070.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_11_veml6070.ino @@ -1,7 +1,7 @@ /* xsns_11_veml6070.ino - VEML6070 ultra violet light sensor support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2021 Mike2Nl 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 diff --git a/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino b/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino index 98397babe..0610ca9d0 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino @@ -1,7 +1,7 @@ /* xsns_12_ads1115_ada.ino - ADS1115 A/D Converter support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2021 Syssi, stefanbode 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 @@ -176,7 +176,7 @@ void Ads1115Detect(void) // Set default mode and range Ads1115.channels = ADS1115_SINGLE_CHANNELS; Ads1115.range = ADS1115_REG_CONFIG_PGA_6_144V; - + for (uint32_t i = 0; i < sizeof(Ads1115.addresses); i++) { if (!Ads1115.found[i]) { Ads1115.address = Ads1115.addresses[i]; diff --git a/tasmota/tasmota_xsns_sensor/xsns_20_novasds.ino b/tasmota/tasmota_xsns_sensor/xsns_20_novasds.ino index faa3cd3f9..a0c773923 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_20_novasds.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_20_novasds.ino @@ -1,7 +1,7 @@ /* xsns_20_novasds.ino - Nova SDS011/SDS021 particle concentration sensor support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2021 Norbert Richter 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 diff --git a/tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino b/tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino index 7c4217da3..54a7a77b5 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino @@ -1,7 +1,7 @@ /* xsns_21_sgp30.ino - SGP30 gas and air quality sensor support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2021 Gerhard Mutz 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 diff --git a/tasmota/tasmota_xsns_sensor/xsns_38_az7798.ino b/tasmota/tasmota_xsns_sensor/xsns_38_az7798.ino index ad6cf6f66..1869ed76f 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_38_az7798.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_38_az7798.ino @@ -1,7 +1,7 @@ /* xsns_38_az7798.ino - AZ_Instrument 7798 CO2/temperature/humidity meter support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2021 adebeun 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 diff --git a/tasmota/tasmota_xsns_sensor/xsns_41_max44009.ino b/tasmota/tasmota_xsns_sensor/xsns_41_max44009.ino index 2d13c6275..a4a001f41 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_41_max44009.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_41_max44009.ino @@ -1,7 +1,7 @@ /* xsns_41_max44009.ino - MAX44009 ambient light sensor support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2021 llagendijk 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 diff --git a/tasmota/tasmota_xsns_sensor/xsns_47_max31865.ino b/tasmota/tasmota_xsns_sensor/xsns_47_max31865.ino index 9a8bc0b03..6388f311c 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_47_max31865.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_47_max31865.ino @@ -1,5 +1,5 @@ /* - xsns_39_MAX31865.ino - MAX31865 thermocouple sensor support for Tasmota + xsns_47_max31865.ino - MAX31865 thermocouple sensor support for Tasmota Copyright (C) 2021 Alberto Lopez Siemens diff --git a/tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino b/tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino index 0c1918b49..65b1fe6b9 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino @@ -1,7 +1,6 @@ /* xsns_56_hpma.ino - Honeywell HPMA115S0 particle concentration sensor support for Tasmota - Copyright (C) 2021 Theo Arends Copyright (C) 2021 David Hunt This program is free software: you can redistribute it and/or modify diff --git a/tasmota/tasmota_xsns_sensor/xsns_73_hp303b.ino b/tasmota/tasmota_xsns_sensor/xsns_73_hp303b.ino index a4310397f..2df3d1f91 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_73_hp303b.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_73_hp303b.ino @@ -1,7 +1,7 @@ /* xsns_72_hp303b.ino - HP303B digital barometric air pressure sensor support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2021 @rjaakke 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 diff --git a/tasmota/tasmota_xsns_sensor/xsns_75_prometheus.ino b/tasmota/tasmota_xsns_sensor/xsns_75_prometheus.ino index 1914881e3..56b507c61 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_75_prometheus.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_75_prometheus.ino @@ -1,7 +1,7 @@ /* xsns_75_prometheus.ino - Web based information for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2021 @marius, @mhansen, @hansmi 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 diff --git a/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino b/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino index b6a88538a..9138875b0 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino @@ -1,5 +1,5 @@ /* - xsns_77_vl53l1x_device[0].ino - VL53L1X sensor support for Tasmota + xsns_77_vl53l1x.ino - VL53L1X sensor support for Tasmota Copyright (C) 2021 Theo Arends, Rui Marinho and Johann Obermeier diff --git a/tasmota/tasmota_xsns_sensor/xsns_85_mpu6886.ino b/tasmota/tasmota_xsns_sensor/xsns_85_mpu6886.ino index c80820180..a3c64b360 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_85_mpu6886.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_85_mpu6886.ino @@ -1,5 +1,5 @@ /* - xsns_84_tof10120.ino -MPU6886/MPU9250 accelerometer support for Tasmota + xsns_85_mpu6886.ino - MPU6886/MPU9250 accelerometer support for Tasmota Copyright (C) 2021 Stephan Hadinger and Theo Arends diff --git a/tasmota/tasmota_xsns_sensor/xsns_95_cm110x.ino b/tasmota/tasmota_xsns_sensor/xsns_95_cm110x.ino index 931b83c4c..c71a91093 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_95_cm110x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_95_cm110x.ino @@ -1,7 +1,7 @@ /* XSNS_95_cm1107.ino - CM1107(B) CO2 sensor support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2022 Maksim 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 @@ -28,7 +28,7 @@ * Filter usage * * Select filter usage on low stability readings - * + * * ******************************************************************************************* * Some CM11 models has manual or continuos modes - this logic not implemented. \*********************************************************************************************/ @@ -42,8 +42,8 @@ enum CM11FilterOptions {CM1107_FILTER_OFF, CM1107_FILTER_FAST, CM1107_FILTER_MED #endif /*********************************************************************************************\ * Source: https://en.gassensor.com.cn/CO2Sensor/list.html (pdf for 1106/1107/1109 sensors) - * - * + * + * * Automatic Baseline Correction (ABC logic function) is enabled by default but may be disabled with command * Sensor95 0 * and enabled again with command @@ -137,7 +137,7 @@ size_t CM11SendCmd(uint8_t command_id) memcpy_P(&cm11_send[1], kCM11Commands[command_id], (len+1) * sizeof(uint8_t)); cm11_send[len+2] = CM11CalculateChecksum(cm11_send,0, len+2); - + #ifdef DEBUG_TASMOTA_SENSOR char cmdFull[len+30];// = {0}; memset( cmdFull, 0, (len+3)*sizeof(char) ); @@ -175,7 +175,7 @@ bool CM11CheckAndApplyFilter(uint16_t ppm, uint8_t drift) }else { difference >>=cm11_filter; } - + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "CM11 diff: %d"),difference); cm11_last_ppm = static_cast(cm11_last_ppm + difference); return true; @@ -243,7 +243,7 @@ void CM11EverySecond(void) if (cm11_response[2]==cmd_read[1]){ //0x01 - read command uint16_t ppm = (cm11_response[3] << 8) | cm11_response[4]; AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "CM11 PPM: %u"),ppm); - if (ppm ==550) { // Preheating mode, fixed value. + if (ppm ==550) { // Preheating mode, fixed value. //DOCs says that preheating is cm11_response[5] & (1 << 0)) ==1 (first bit ==1), but mine sensor (CM1107, sw V1.07.0.02 ) // set first bit 0 when preheating at switch to 1 then finished. AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "CM11 preheating")); @@ -294,7 +294,7 @@ void CM11EverySecond(void) sprintf_P(cm11_serial_number+i*2,"%04u", v); //print int value to result str } AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_DEBUG "Serial number: %s"),cm11_serial_number); - } + } } } @@ -328,7 +328,7 @@ bool CM11CommandSensor(void) Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_95, CM11_ABC_ENABLED); break; case 2: - CM11SendCmd(CM11_CMND_ZEROPOINT); + CM11SendCmd(CM11_CMND_ZEROPOINT); Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_95, D_JSON_ZERO_POINT_CALIBRATION); break; case 3: diff --git a/tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino b/tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino index b25555bba..e40df3f07 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino @@ -1,7 +1,7 @@ /* xsns_98_sgp40.ino - SGP40 gas and air quality sensor support for Tasmota - Copyright (C) 2021 Theo Arends + Copyright (C) 2022 Jean-Pierre Deschamps 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 41d79183f389205197dfef41b75198e8f7a56d4f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 10 Dec 2022 16:56:12 +0100 Subject: [PATCH 318/319] Delete xdrv_90_dingtian_relay.ino --- .../xdrv_90_dingtian_relay.ino | 210 ------------------ 1 file changed, 210 deletions(-) delete mode 100644 tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino diff --git a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino deleted file mode 100644 index 16ae49dda..000000000 --- a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino +++ /dev/null @@ -1,210 +0,0 @@ -/* - 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; - 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); - } - } -} - -/******************************************************************************************************** - * 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(STAT, PSTR("DINGTIAN_CHG")); - } - } -} - -void DingtianSetPower(void) -{ - // store relay status in structure - Dingtian->outputs = (XdrvMailbox.index >> Dingtian->first) & ~(0xFFFFFFFF << 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(uint32_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 e018b61a9d90f6f2ca247b4eb01ee3538b53192a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 10 Dec 2022 17:16:42 +0100 Subject: [PATCH 319/319] Update changelogs --- BUILDS.md | 9 +++++++++ CHANGELOG.md | 1 + RELEASENOTES.md | 1 + 3 files changed, 11 insertions(+) diff --git a/BUILDS.md b/BUILDS.md index f10d3359a..f3dbeadab 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -68,6 +68,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up | USE_SM2135 | - | x / - | x | x | - | x | | USE_SM2335 | - | x / - | x | x | - | x | | USE_BP5758D | - | x / - | x | x | - | x | +| USE_BP1658CJ | - | x / - | x | x | - | x | | USE_SONOFF_L1 | - | x / - | x | x | - | x | | USE_ELECTRIQ_MOODL | - | x / - | x | x | - | x | | | | | | | | | @@ -177,10 +178,13 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up | USE_DS3502 | - | - / - | - | - | - | - | | USE_HYT | - | - / - | - | - | - | - | | USE_LUXV30B | - | - / - | - | - | - | - | +| USE_HMC5883L | - | - / - | - | - | - | - | +| USE_QMC5883L | - | - / - | - | - | - | - | | | | | | | | | | Feature or Sensor | l | t | k | s | i | d | Remarks | USE_SPI | - | - / - | - | - | - | x | | USE_RC522 | - | - / - | - | - | - | - | +| USE_CANSNIFFER | - | - / - | - | - | - | - | | USE_MHZ19 | - | - / x | - | x | - | - | | USE_SENSEAIR | - | - / x | - | x | - | - | | USE_PMS5003 | - | - / x | - | x | - | - | @@ -201,6 +205,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up | USE_MIEL_HVAC | - | - / - | - | - | - | - | | USE_PROJECTOR_CTRL | - | - / - | - | - | - | - | | USE_AS608 | - | - / - | - | - | - | - | +| USE_LD2410 | - | - / - | - | - | - | - | | USE_TCP_BRIDGE | - | - / - | - | - | - | - | zbbridge / zbbrdgpro | | | | | | | | | USE_NRF24 | - | - / - | - | - | - | - | @@ -254,5 +259,9 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up | USE_I2S_AUDIO | | / - | | | | | | USE_TTGO_WATCH | | / - | | | | | | USE_SONOFF_SPM | | / x | | | | | +| USE_DISPLAY_TM1621_SONOFF | | / x | | | | | +| USE_SHELLY_PRO | | / x | | | | | +| USE_DALI | | / - | | | | | +| USE_DINGTIAN_RELAY | | / - | | | | | * USE_MQTT_TLS is enabled by default in every ESP32 variants diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a019f47e..9998818fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file. ### Fixed - TasmotaSerial ``read(buffer, size)`` regression from v9.3.0 +- RCSwitch exception 0/6 on some protocols (#17285) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 511885cba..9d5ff4e29 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -164,6 +164,7 @@ 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) - 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) +- RCSwitch exception 0/6 on some protocols [#17285](https://github.com/arendst/Tasmota/issues/17285) ### Removed - Define ``USE_PN532_DATA_RAW`` from NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)