Date: Sat, 27 Aug 2022 09:27:09 +0200
Subject: [PATCH 092/366] Rework flowmeter
---
.../xsns_96_flowratemeter.ino | 250 +++++++++++++-----
1 file changed, 183 insertions(+), 67 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino b/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
index 4e43bd6b8..2cbe54947 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
@@ -29,30 +29,34 @@
#define FLOWRATEMETER_WEIGHT_AVG_SAMPLE 20 // number of samples for smooth weigted average
#define FLOWRATEMETER_MIN_FREQ 1 // Hz
-#define D_JSON_FLOWRATEMETER_RATE "Rate"
-#define D_JSON_FLOWRATEMETER_VALUE "Value"
-#define D_JSON_FLOWRATEMETER_UNIT "Unit"
-#define D_JSON_FLOWRATEMETER_VALUE_AVG "average"
-#define D_JSON_FLOWRATEMETER_VALUE_RAW "raw"
+#define D_UNIT_CUBIC_METER "m³"
+
+#define D_JSON_FLOWRATEMETER_RATE "Rate"
+#define D_JSON_FLOWRATEMETER_VALUE "Source"
+#define D_JSON_FLOWRATEMETER_UNIT "Unit"
+#define D_JSON_FLOWRATEMETER_AMOUNT_TODAY "AmountToday"
+#define D_JSON_FLOWRATEMETER_AMOUNT_UNIT "AmountUnit"
+#define D_JSON_FLOWRATEMETER_DURATION_TODAY "DurationToday"
+#define D_JSON_FLOWRATEMETER_VALUE_AVG "average"
+#define D_JSON_FLOWRATEMETER_VALUE_RAW "raw"
-
-#ifdef USE_WEBSERVER
-const char HTTP_SNS_FLOWRATEMETER[] PROGMEM =
- "{s}" D_FLOWRATEMETER_NAME "-%d{m}%*_f %s{e}"
- ;
-#endif // USE_WEBSERVER
-
+#define FLOWRATEMETER_INVALID (uint32_t)-1
int32_t flowratemeter_period[MAX_FLOWRATEMETER] = {0};
float flowratemeter_period_avg[MAX_FLOWRATEMETER] = {0};
uint32_t flowratemeter_count[MAX_FLOWRATEMETER] = {0};
-volatile uint32_t flowratemeter_last_irq[MAX_FLOWRATEMETER] = {0};
+volatile uint32_t flowratemeter_last_irq[MAX_FLOWRATEMETER] = {FLOWRATEMETER_INVALID};
+
+int32_t flowratemeter_period_sum[MAX_FLOWRATEMETER];
+int32_t flowratemeter_period_sum_dT[MAX_FLOWRATEMETER];
+int32_t flowratemeter_period_duration[MAX_FLOWRATEMETER];
+
-bool flowratemeter_valuesread = false;
bool flowratemeter_raw_value = false;
+#define FlowRateMeterIsValid(time, meter) flowratemeter_last_irq[meter] != FLOWRATEMETER_INVALID && flowratemeter_last_irq[meter] < time
void IRAM_ATTR FlowRateMeterIR(uint16_t irq)
{
@@ -62,12 +66,16 @@ void IRAM_ATTR FlowRateMeterIR(uint16_t irq)
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
#endif
if (irq < MAX_FLOWRATEMETER) {
- if ((time - flowratemeter_last_irq[irq]) < (1000000 / FLOWRATEMETER_MIN_FREQ)) {
- flowratemeter_period[irq] = time - flowratemeter_last_irq[irq];
- } else {
- flowratemeter_period[irq] = 0;
+ if (FlowRateMeterIsValid(time, irq)) {
+ if ((time - flowratemeter_last_irq[irq]) < (1000000 / FLOWRATEMETER_MIN_FREQ)) {
+ flowratemeter_period_sum_dT[irq] = millis();
+ flowratemeter_period_sum[irq]++;
+ flowratemeter_period[irq] = time - flowratemeter_last_irq[irq];
+ flowratemeter_period_duration[irq] += flowratemeter_period[irq] / 100;
+ } else {
+ flowratemeter_period[irq] = 0;
+ }
}
- flowratemeter_valuesread = true;
flowratemeter_last_irq[irq] = time;
}
}
@@ -81,20 +89,36 @@ void IRAM_ATTR FlowRateMeter2IR(void)
FlowRateMeterIR(1);
}
+void FlowRateMeterMidnightReset(void)
+{
+ uint32_t t = millis();
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ flowratemeter_period_sum[i] = 0;
+ flowratemeter_period_duration[i] = 0;
+ flowratemeter_period_sum_dT[i] = t;
+ }
+}
+
void FlowRateMeterRead(void)
{
for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
- if ((micros() - flowratemeter_last_irq[i]) >= (1000000 / FLOWRATEMETER_MIN_FREQ)) {
- flowratemeter_period[i] = 0;
- flowratemeter_period_avg[i] = 0;
- }
+ uint32_t time = micros();
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i) && FlowRateMeterIsValid(time, i)) {
+ if ((time - flowratemeter_last_irq[i]) >= (1000000 / FLOWRATEMETER_MIN_FREQ)) {
+ // invalid in case of pulse outage
+ flowratemeter_period[i] = 0;
+ flowratemeter_period_avg[i] = 0;
+ flowratemeter_count[i] = 0;
+ flowratemeter_last_irq[i] = FLOWRATEMETER_INVALID;
+ }
- // exponentially weighted average
- if (flowratemeter_count[i] <= FLOWRATEMETER_WEIGHT_AVG_SAMPLE) {
- flowratemeter_count[i]++;
+ // exponentially weighted average
+ if (flowratemeter_count[i] <= FLOWRATEMETER_WEIGHT_AVG_SAMPLE) {
+ flowratemeter_count[i]++;
+ }
+ flowratemeter_period_avg[i] -= flowratemeter_period_avg[i] / flowratemeter_count[i];
+ flowratemeter_period_avg[i] += float(flowratemeter_period[i]) / flowratemeter_count[i];
}
- flowratemeter_period_avg[i] -= flowratemeter_period_avg[i] / flowratemeter_count[i];
- flowratemeter_period_avg[i] += float(flowratemeter_period[i]) / flowratemeter_count[i];
}
}
@@ -102,7 +126,7 @@ void FlowRateMeterInit(void)
{
void (* irq_service[MAX_FLOWRATEMETER])(void)= {FlowRateMeter1IR, FlowRateMeter2IR};
- flowratemeter_valuesread = false;
+ FlowRateMeterMidnightReset();
for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
pinMode(Pin(GPIO_FLOWRATEMETER_IN, i), INPUT);
@@ -111,50 +135,139 @@ void FlowRateMeterInit(void)
}
}
-void FlowRateMeterShow(bool json)
+void FlowRateMeterGetValue(uint32_t meter, float *rate_float, float *amount_today)
{
- if (json) {
- ResponseAppend_P(PSTR(",\"" D_FLOWRATEMETER_NAME "\":{\"" D_JSON_FLOWRATEMETER_RATE "\":["));
- }
-
- for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
- float flowratemeter_rate_avg_float = 0;
-
- if (flowratemeter_period[i]) {
- flowratemeter_rate_avg_float =
- ((Settings->SensorBits1.flowratemeter_unit ? (1000000.0 / 1000.0) : (1000000 / 60.0)) / 2.0)
- / (flowratemeter_raw_value ? flowratemeter_period[i] : flowratemeter_period_avg[i])
- * (Settings->flowratemeter_calibration[i] ? (float)Settings->flowratemeter_calibration[i] : 1000.0);
- }
-
- if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
- if (json) {
- ResponseAppend_P(PSTR("%s%*_f"),
- i ? PSTR(",") : PSTR(""),
- Settings->flag2.frequency_resolution, &flowratemeter_rate_avg_float
- );
-
-#ifdef USE_WEBSERVER
- } else {
- WSContentSend_PD(HTTP_SNS_FLOWRATEMETER,
- i+1,
- Settings->flag2.frequency_resolution, &flowratemeter_rate_avg_float,
- Settings->SensorBits1.flowratemeter_unit ? D_UNIT_CUBICMETER_PER_HOUR : D_UNIT_LITER_PER_MINUTE
- );
-#endif // USE_WEBSERVER
- }
+ if (nullptr != rate_float) {
+ *rate_float = 0;
+ if (meter < MAX_FLOWRATEMETER && flowratemeter_period[meter]) {
+ *rate_float =
+ (1000000.0 / 60.0 / 2.0)
+ / (flowratemeter_raw_value ? flowratemeter_period[meter] : flowratemeter_period_avg[meter])
+ * (Settings->flowratemeter_calibration[meter] ? (float)Settings->flowratemeter_calibration[meter] : 1000.0);
}
}
- if (json) {
- ResponseAppend_P(PSTR("],\"" D_JSON_FLOWRATEMETER_VALUE "\":\"%s\""),
- flowratemeter_raw_value ? PSTR(D_JSON_FLOWRATEMETER_VALUE_RAW) : PSTR(D_JSON_FLOWRATEMETER_VALUE_AVG)
- );
- ResponseAppend_P(PSTR(",\"" D_JSON_FLOWRATEMETER_UNIT "\":\"%s\"}"),
- Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBICMETER_PER_HOUR) : PSTR(D_UNIT_LITER_PER_MINUTE)
- );
+
+ if (nullptr != amount_today) {
+ *amount_today = 0;
+ if (meter < MAX_FLOWRATEMETER && flowratemeter_period_sum[meter]) {
+ uint32_t _flowratemeter_period = (uint32_t)((float)flowratemeter_period_sum_dT[meter] / (float)flowratemeter_period_sum[meter] * 1000.0);
+ float lmin = (((1000000.0 / 60.0) / 2.0) / _flowratemeter_period * (Settings->flowratemeter_calibration[meter] ? (float)Settings->flowratemeter_calibration[meter] : 1000.0));
+ *amount_today = (lmin / 60000) * flowratemeter_period_sum_dT[meter];
+ }
}
}
+void FlowRateMeterShow(bool json)
+{
+ uint16_t flowmeter_count = 0;
+ const char* open_square_bracket;
+ const char* close_square_bracket;
+ float flowratemeter_rate_float[MAX_FLOWRATEMETER];
+ float floatrate_amount_today[MAX_FLOWRATEMETER];
+
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ FlowRateMeterGetValue(i, &flowratemeter_rate_float[i], &floatrate_amount_today[i]);
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
+ flowmeter_count++;
+ }
+ }
+ if (flowmeter_count > 1) {
+ open_square_bracket = PSTR("[");
+ close_square_bracket = PSTR("]");
+ } else {
+ open_square_bracket = PSTR("");
+ close_square_bracket = PSTR("");
+ }
+
+ if (json) {
+ ResponseAppend_P(PSTR(",\"" D_FLOWRATEMETER_NAME "\":{\"" D_JSON_FLOWRATEMETER_RATE "\":%s"), open_square_bracket);
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
+ float rate = Settings->SensorBits1.flowratemeter_unit ? flowratemeter_rate_float[i] * 60 / 1000 : flowratemeter_rate_float[i];
+ ResponseAppend_P(PSTR("%s%*_f"), i ? PSTR(",") : PSTR(""), Settings->flag2.frequency_resolution, &rate);
+ }
+ }
+ ResponseAppend_P(PSTR("%s,\"" D_JSON_FLOWRATEMETER_AMOUNT_TODAY "\":%s"), close_square_bracket, open_square_bracket);
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
+ float amount_today = Settings->SensorBits1.flowratemeter_unit ? floatrate_amount_today[i] / 1000 : floatrate_amount_today[i];
+ ResponseAppend_P(PSTR("%s%*_f"), i ? PSTR(",") : PSTR(""), Settings->flag2.frequency_resolution, &amount_today);
+ }
+ }
+ ResponseAppend_P(PSTR("%s,\"" D_JSON_FLOWRATEMETER_DURATION_TODAY "\":%s"), close_square_bracket, open_square_bracket);
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
+ ResponseAppend_P(PSTR("%s%ld"), i ? PSTR(",") : PSTR(""), flowratemeter_period_duration[i] / 10000);
+ }
+ }
+ ResponseAppend_P(PSTR("%s,\"" D_JSON_FLOWRATEMETER_VALUE "\":\"%s\""),
+ close_square_bracket,
+ flowratemeter_raw_value ? PSTR(D_JSON_FLOWRATEMETER_VALUE_RAW) : PSTR(D_JSON_FLOWRATEMETER_VALUE_AVG)
+ );
+ ResponseAppend_P(PSTR(",\"" D_JSON_FLOWRATEMETER_AMOUNT_UNIT "\":\"%s\""),
+ Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBIC_METER) : PSTR(D_UNIT_LITERS));
+ ResponseAppend_P(PSTR(",\"" D_JSON_FLOWRATEMETER_UNIT "\":\"%s\"}"),
+ Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBICMETER_PER_HOUR) : PSTR(D_UNIT_LITER_PER_MINUTE));
+#ifdef USE_WEBSERVER
+ } else {
+ // {s} = , {m} = | , {e} = |
+ if (flowmeter_count > 1) {
+ // head
+ WSContentSend_PD(PSTR("{s} | "));
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
+ WSContentSend_PD(PSTR("%d | | "),
+ Settings->flag5.gui_table_align ? PSTR("right") : PSTR("center"),
+ i+1
+ );
+ }
+ }
+ WSContentSend_PD(PSTR(" | "));
+ }
+
+ // Flowrate
+ WSContentSend_PD(PSTR("{s}" D_FLOWRATEMETER_NAME "{m} "));
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
+ float rate = Settings->SensorBits1.flowratemeter_unit ? flowratemeter_rate_float[i] * 60 / 1000 : flowratemeter_rate_float[i];
+ WSContentSend_PD(PSTR("%*_f | | "),
+ Settings->flag5.gui_table_align ? PSTR("right") : PSTR("center"),
+ Settings->flag2.frequency_resolution, &rate
+ );
+ }
+ }
+ WSContentSend_PD(PSTR("%s{e}"), Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBICMETER_PER_HOUR) : PSTR(D_UNIT_LITER_PER_MINUTE));
+
+ // Amount today
+ WSContentSend_PD(PSTR("{s}" D_FLOWRATEMETER_NAME " Amount Today" "{m} | "));
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
+ float amount_today = Settings->SensorBits1.flowratemeter_unit ? floatrate_amount_today[i] / 1000 : floatrate_amount_today[i];
+ WSContentSend_PD(PSTR("%*_f | | "),
+ Settings->flag5.gui_table_align ? PSTR("right") : PSTR("center"),
+ Settings->flag2.frequency_resolution, &amount_today
+ );
+ }
+ }
+ WSContentSend_PD(PSTR("%s{e}"), Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBIC_METER) : PSTR(D_UNIT_LITERS));
+
+ // Duration today
+ WSContentSend_PD(PSTR("{s}" D_FLOWRATEMETER_NAME " Duration Today" "{m} | "));
+ for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
+ if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
+ float amount_today = Settings->SensorBits1.flowratemeter_unit ? floatrate_amount_today[i] / 1000 : floatrate_amount_today[i];
+ WSContentSend_PD(PSTR("%s | | "),
+ (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("center"),
+ GetDuration(flowratemeter_period_duration[i] / 10000).c_str()
+ );
+ }
+ }
+ WSContentSend_PD(PSTR("{e}"));
+#endif // USE_WEBSERVER
+ }
+}
+
+
/*********************************************************************************************\
* Supported commands for Sensor96:
*
@@ -246,6 +359,9 @@ bool Xsns96(uint8_t function)
case FUNC_INIT:
FlowRateMeterInit();
break;
+ case FUNC_SAVE_AT_MIDNIGHT:
+ FlowRateMeterMidnightReset();
+ break;
case FUNC_EVERY_250_MSECOND:
FlowRateMeterRead();
break;
From 2b163ad4ea7f9d80e0c91d727bee77fad6f5e31c Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Tue, 30 Aug 2022 11:46:19 +0200
Subject: [PATCH 093/366] Flowrate meter add flow amount/duration
---
CHANGELOG.md | 1 +
tasmota/language/af_AF.h | 5 ++++-
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/tasmota_xsns_sensor/xsns_96_flowratemeter.ino | 7 ++-----
29 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c2ce50ee4..1e679b257 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
- TasmotaModbus library from v3.5.0 to v3.6.0 (#16351)
- Button debouncing V3 by adopting switch debounce code (#16339)
- Thermostat max allowed temperature from 100 to 200C (#16363)
+- Flowrate meter add flow amount/duration, show values in table format
### Fixed
- Removed whitespace from JSON values with no decimals (#16365)
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index a02170f37..72fe31896 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1076,7 +1077,9 @@
#define D_FP_UNKNOWNERROR "Fout" // Any other error
// xsns_96_flowratemeter.ino
-#define D_FLOWRATEMETER_NAME "Flowmeter"
+#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 581d0b6fc..949dbdb16 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index 6dfeec7e9..bbdb4eee1 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Posant l'adreça a"
#define D_OUT_OF_RANGE "Fora de rang"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Cabal"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index 8cc9a3255..71d42ddfc 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index 44c63ba50..e9a9f6609 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Neue Adresse"
#define D_OUT_OF_RANGE "Außerhalb Bereich"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Durchflussmesser"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Menge heute"
+#define D_FLOWRATEMETER_DURATION_TODAY "Dauer heute"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index ab3479641..028c9a49d 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index 25d605ab3..60b9e8942 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index c0209fe37..e9a5c46fe 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Cambiando dirección a"
#define D_OUT_OF_RANGE "Fuera de Rango"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 21dcf9060..b94af9891 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Positionner l'adresse à"
#define D_OUT_OF_RANGE "Hors limites"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 0212d2f2c..fbe031e89 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 9f0a2df84..6c5cbb225 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index b748b0dbc..d31d0957d 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 560cb299f..e54d71f59 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/ora"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Imposta indirizzo a"
#define D_OUT_OF_RANGE "Fuori intervallo"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Portata"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 40ebaec62..92400dfe5 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 2b69901e2..729aa5e0e 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Nieuw adres"
#define D_OUT_OF_RANGE "Buiten beriek"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index 992419ee1..fa9c391c2 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Ustawiam adres na"
#define D_OUT_OF_RANGE "Poza zakresem"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index 763efdea3..b845055a4 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Mudança de endereço para"
#define D_OUT_OF_RANGE "Fora de Alcance"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index 2d216a4a6..4b03eb70b 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Mudança de endereço para"
#define D_OUT_OF_RANGE "Fora de Alcance"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index 8d2d409e2..93f2381b1 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index e5f0a0e81..81e66fa2c 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "Вт/м²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index c24ab53cb..f1a60f325 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index c36612aed..fa52fe7fe 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index 319791d99..90337d4cb 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index ea736ffea..8258e3a0a 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "Вт/м²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index 26de9f0a7..3422ab65d 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index e74e51008..2a8158b8c 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 2fe003a1c..00b247f74 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -934,6 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/h"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Setting address to"
#define D_OUT_OF_RANGE "Out of Range"
@@ -1077,6 +1078,8 @@
// xsns_96_flowratemeter.ino
#define D_FLOWRATEMETER_NAME "Flowrate"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
+#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
diff --git a/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino b/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
index 2cbe54947..16a635e9e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
@@ -25,12 +25,9 @@
#define XSNS_96 96
-
#define FLOWRATEMETER_WEIGHT_AVG_SAMPLE 20 // number of samples for smooth weigted average
#define FLOWRATEMETER_MIN_FREQ 1 // Hz
-#define D_UNIT_CUBIC_METER "m³"
-
#define D_JSON_FLOWRATEMETER_RATE "Rate"
#define D_JSON_FLOWRATEMETER_VALUE "Source"
#define D_JSON_FLOWRATEMETER_UNIT "Unit"
@@ -239,7 +236,7 @@ void FlowRateMeterShow(bool json)
WSContentSend_PD(PSTR("%s{e}"), Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBICMETER_PER_HOUR) : PSTR(D_UNIT_LITER_PER_MINUTE));
// Amount today
- WSContentSend_PD(PSTR("{s}" D_FLOWRATEMETER_NAME " Amount Today" "{m} | "));
+ WSContentSend_PD(PSTR("{s}" D_FLOWRATEMETER_NAME " " D_FLOWRATEMETER_AMOUNT_TODAY "{m} | "));
for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
float amount_today = Settings->SensorBits1.flowratemeter_unit ? floatrate_amount_today[i] / 1000 : floatrate_amount_today[i];
@@ -252,7 +249,7 @@ void FlowRateMeterShow(bool json)
WSContentSend_PD(PSTR("%s{e}"), Settings->SensorBits1.flowratemeter_unit ? PSTR(D_UNIT_CUBIC_METER) : PSTR(D_UNIT_LITERS));
// Duration today
- WSContentSend_PD(PSTR("{s}" D_FLOWRATEMETER_NAME " Duration Today" "{m} | "));
+ WSContentSend_PD(PSTR("{s}" D_FLOWRATEMETER_NAME " " D_FLOWRATEMETER_DURATION_TODAY "{m} "));
for (uint32_t i = 0; i < MAX_FLOWRATEMETER; i++) {
if (PinUsed(GPIO_FLOWRATEMETER_IN, i)) {
float amount_today = Settings->SensorBits1.flowratemeter_unit ? floatrate_amount_today[i] / 1000 : floatrate_amount_today[i];
From cb4a5ed736b706434e691a75bec94e75be2785f9 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 30 Aug 2022 18:11:04 +0200
Subject: [PATCH 094/366] Berry extend max bytes size to 512Kb when PSRAM is
available
---
lib/libesp32/berry/default/berry_conf.h | 8 ++++++++
lib/libesp32/berry/src/be_byteslib.c | 3 +--
lib/libesp32/berry/src/be_vm.c | 1 +
lib/libesp32/berry/src/be_vm.h | 1 +
tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino | 4 ++++
5 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/lib/libesp32/berry/default/berry_conf.h b/lib/libesp32/berry/default/berry_conf.h
index c70af7945..4d46eb3df 100644
--- a/lib/libesp32/berry/default/berry_conf.h
+++ b/lib/libesp32/berry/default/berry_conf.h
@@ -41,6 +41,14 @@
**/
#define BE_USE_SINGLE_FLOAT 1 // use `float` not `double`
+/* Macro: BE_BYTES_MAX_SIZE
+ * Maximum size in bytes of a `bytes()` object.
+ * Putting too much pressure on the memory allocator can do
+ * harm, so we limit the maximum size.
+ * Default: 32kb
+ **/
+#define BE_BYTES_MAX_SIZE (32*1024) /* 32 kb default value */
+
/* Macro: BE_USE_PRECOMPILED_OBJECT
* Use precompiled objects to avoid creating these objects at
* runtime. Enable this macro can greatly optimize RAM usage.
diff --git a/lib/libesp32/berry/src/be_byteslib.c b/lib/libesp32/berry/src/be_byteslib.c
index 11857963a..299cc2fcd 100644
--- a/lib/libesp32/berry/src/be_byteslib.c
+++ b/lib/libesp32/berry/src/be_byteslib.c
@@ -18,7 +18,6 @@
#include
#define BYTES_DEFAULT_SIZE 28 // default pre-reserved size for buffer (keep 4 bytes for len/size)
-#define BYTES_MAX_SIZE (32*1024) // max 32Kb
#define BYTES_OVERHEAD 4 // bytes overhead to be added when allocating (used to store len and size)
#define BYTES_HEADROOM 8 // keep a natural headroom of 8 bytes when resizing
@@ -506,7 +505,7 @@ void m_write_attributes(bvm *vm, int rel_idx, const buf_impl * attr)
void bytes_realloc(bvm *vm, buf_impl * attr, int32_t size)
{
if (!attr->fixed && size < 4) { size = 4; }
- if (size > BYTES_MAX_SIZE) { size = BYTES_MAX_SIZE; }
+ if (size > vm->bytesmaxsize) { size = vm->bytesmaxsize; }
size_t oldsize = attr->bufptr ? attr->size : 0;
attr->bufptr = (uint8_t*) be_realloc(vm, attr->bufptr, oldsize, size); /* malloc */
attr->size = size;
diff --git a/lib/libesp32/berry/src/be_vm.c b/lib/libesp32/berry/src/be_vm.c
index de738fb4d..ffc55977a 100644
--- a/lib/libesp32/berry/src/be_vm.c
+++ b/lib/libesp32/berry/src/be_vm.c
@@ -477,6 +477,7 @@ BERRY_API bvm* be_vm_new(void)
be_gc_setpause(vm, 1);
be_loadlibs(vm);
vm->compopt = 0;
+ vm->bytesmaxsize = BE_BYTES_MAX_SIZE;
vm->obshook = NULL;
vm->ctypefunc = NULL;
#if BE_USE_PERF_COUNTERS
diff --git a/lib/libesp32/berry/src/be_vm.h b/lib/libesp32/berry/src/be_vm.h
index 816d10cd1..474e74a7d 100644
--- a/lib/libesp32/berry/src/be_vm.h
+++ b/lib/libesp32/berry/src/be_vm.h
@@ -105,6 +105,7 @@ struct bvm {
struct bgc gc;
bctypefunc ctypefunc; /* handler to ctype_func */
bbyte compopt; /* compilation options */
+ uint32_t bytesmaxsize; /* max allowed size for bytes() object, default 32kb but can be increased */
bobshook obshook;
bmicrosfnct microsfnct; /* fucntion to get time as a microsecond resolution */
#if BE_USE_PERF_COUNTERS
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
index 51d18abad..36ac8b4e0 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
@@ -316,6 +316,10 @@ void BerryInit(void) {
comp_set_strict(berry.vm); /* Enable strict mode in Berry compiler, equivalent of `import strict` */
be_set_ctype_func_hanlder(berry.vm, be_call_ctype_func);
+ if (UsePSRAM()) { // if PSRAM is available, raise the max size to 512kb
+ berry.vm->bytesmaxsize = 512 * 1024;
+ }
+
be_load_custom_libs(berry.vm); // load classes and modules
// Set the GC threshold to 3584 bytes to avoid the first useless GC
From 3791ecd2a0dab5cfb9952f9b747fe4f8c420c2b2 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 30 Aug 2022 18:46:22 +0200
Subject: [PATCH 095/366] Support for Ethernet in ESP32 safeboot firmware
---
CHANGELOG.md | 1 +
tasmota/include/tasmota_configurations_ESP32.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c2ce50ee4..e80cd862f 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 SGP40 gas and air quality sensor (#16341)
- Support for Modbus writing using ModbusBridge by JeroenSt (#16351)
+- Support for Ethernet in ESP32 safeboot firmware
### Changed
- TasmotaModbus library from v3.5.0 to v3.6.0 (#16351)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index 9f33d3544..4544f7da6 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -182,6 +182,7 @@
#define USE_WEBCLIENT
#define USE_WEBCLIENT_HTTPS
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge console Tee (+0k8 code)
+#define USE_ETHERNET
#endif // FIRMWARE_SAFEBOOT
From b3552317214467fbd31e0262b4e4bf7d2e7a123b Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 31 Aug 2022 10:09:22 +0200
Subject: [PATCH 096/366] Fix unstable ETH on Olimex POE
---
.../xdrv_82_esp32_ethernet.ino | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
index b7cfada24..264cd8f3c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
@@ -154,6 +154,31 @@ void EthernetInit(void) {
int eth_power = Pin(GPIO_ETH_PHY_POWER);
int eth_mdc = Pin(GPIO_ETH_PHY_MDC);
int eth_mdio = Pin(GPIO_ETH_PHY_MDIO);
+#ifdef ESP32
+ // fix an disconnection issue after rebooting Olimex POE - this forces a clean state for all GPIO involved in RMII
+ gpio_reset_pin((gpio_num_t)GPIO_ETH_PHY_POWER);
+ gpio_reset_pin((gpio_num_t)GPIO_ETH_PHY_MDC);
+ gpio_reset_pin((gpio_num_t)GPIO_ETH_PHY_MDIO);
+ gpio_reset_pin(GPIO_NUM_19); // EMAC_TXD0 - hardcoded
+ gpio_reset_pin(GPIO_NUM_21); // EMAC_TX_EN - hardcoded
+ gpio_reset_pin(GPIO_NUM_22); // EMAC_TXD1 - hardcoded
+ gpio_reset_pin(GPIO_NUM_25); // EMAC_RXD0 - hardcoded
+ gpio_reset_pin(GPIO_NUM_26); // EMAC_RXD1 - hardcoded
+ gpio_reset_pin(GPIO_NUM_27); // EMAC_RX_CRS_DV - hardcoded
+ switch (Settings->eth_clk_mode) {
+ case 0: // ETH_CLOCK_GPIO0_IN
+ case 1: // ETH_CLOCK_GPIO0_OUT
+ gpio_reset_pin(GPIO_NUM_0);
+ break;
+ case 2: // ETH_CLOCK_GPIO16_OUT
+ gpio_reset_pin(GPIO_NUM_16);
+ break;
+ case 3: // ETH_CLOCK_GPIO17_OUT
+ gpio_reset_pin(GPIO_NUM_17);
+ break;
+ }
+ delay(1);
+#endif
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"));
return;
From 74cbc47614f7fd5d0b6287ad480a76322803bd64 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 31 Aug 2022 10:12:25 +0200
Subject: [PATCH 097/366] Be more specific to target ESP32
---
tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
index 264cd8f3c..525e878cc 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
@@ -154,7 +154,7 @@ void EthernetInit(void) {
int eth_power = Pin(GPIO_ETH_PHY_POWER);
int eth_mdc = Pin(GPIO_ETH_PHY_MDC);
int eth_mdio = Pin(GPIO_ETH_PHY_MDIO);
-#ifdef ESP32
+#if CONFIG_IDF_TARGET_ESP32
// fix an disconnection issue after rebooting Olimex POE - this forces a clean state for all GPIO involved in RMII
gpio_reset_pin((gpio_num_t)GPIO_ETH_PHY_POWER);
gpio_reset_pin((gpio_num_t)GPIO_ETH_PHY_MDC);
@@ -178,7 +178,7 @@ void EthernetInit(void) {
break;
}
delay(1);
-#endif
+#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"));
return;
From 0e59ddc4673d0fa8700a30e4b42fef9473e56d6c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 31 Aug 2022 11:08:45 +0200
Subject: [PATCH 098/366] Update changelogs
---
CHANGELOG.md | 5 +++--
RELEASENOTES.md | 4 +++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 70ec56618..8b2c6a528 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,13 +7,14 @@ All notable changes to this project will be documented in this file.
### Added
- Support for SGP40 gas and air quality sensor (#16341)
- Support for Modbus writing using ModbusBridge by JeroenSt (#16351)
-- Support for Ethernet in ESP32 safeboot firmware
+- Support for Ethernet in ESP32 safeboot firmware (#16388)
+- Flowrate meter flow amount/duration, show values in table format (#16385)
### Changed
- TasmotaModbus library from v3.5.0 to v3.6.0 (#16351)
- Button debouncing V3 by adopting switch debounce code (#16339)
- Thermostat max allowed temperature from 100 to 200C (#16363)
-- Flowrate meter add flow amount/duration, show values in table format
+- Using command ``SerialBuffer`` raise max allowed buffer size to 2048 characters (#16374)
### Fixed
- Removed whitespace from JSON values with no decimals (#16365)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index ff53be16d..048e367ef 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -113,6 +113,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- 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)
- Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` [#16252](https://github.com/arendst/Tasmota/issues/16252)
+- Flowrate meter flow amount/duration, show values in table format [#16385](https://github.com/arendst/Tasmota/issues/16385)
+- Support for Ethernet in ESP32 safeboot firmware [#16388](https://github.com/arendst/Tasmota/issues/16388)
- ESP32-S3 support for internal temperature sensor
### Breaking Changed
@@ -122,6 +124,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- TasmotaModbus library from v3.5.0 to v3.6.0 [#16351](https://github.com/arendst/Tasmota/issues/16351)
- 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)
+- Using command ``SerialBuffer`` raise max allowed buffer size to 2048 characters [#16374](https://github.com/arendst/Tasmota/issues/16374)
### Fixed
- RTC not detected when lights are present [#16242](https://github.com/arendst/Tasmota/issues/16242)
@@ -130,5 +133,4 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- 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)
-
### Removed
From e23dd638e06adc757767f8373804c70d79820bde Mon Sep 17 00:00:00 2001
From: bovirus <1262554+bovirus@users.noreply.github.com>
Date: Wed, 31 Aug 2022 14:32:43 +0200
Subject: [PATCH 099/366] Update italian language
Please check and merge
---
tasmota/language/it_IT.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index e54d71f59..ba49afae4 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 19.07.2022
+ * Updated until v9.4.0.1 - Last update 31.08.2022
\*********************************************************************/
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@@ -934,7 +934,7 @@
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
#define D_UNIT_LITER_PER_MINUTE "l/min"
#define D_UNIT_CUBICMETER_PER_HOUR "m³/ora"
-#define D_UNIT_CUBIC_METER "m³"
+#define D_UNIT_CUBIC_METER "m³"
#define D_NEW_ADDRESS "Imposta indirizzo a"
#define D_OUT_OF_RANGE "Fuori intervallo"
@@ -1077,9 +1077,9 @@
#define D_FP_UNKNOWNERROR "Errore" // Any other error
// xsns_96_flowratemeter.ino
-#define D_FLOWRATEMETER_NAME "Portata"
-#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today"
-#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today"
+#define D_FLOWRATEMETER_NAME "Portata"
+#define D_FLOWRATEMETER_AMOUNT_TODAY "Valore odierno"
+#define D_FLOWRATEMETER_DURATION_TODAY "Durata odierna"
// xsns_83_neopool.ino
#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names
From 71c3b98b35ec03926203c9f5ce30cc3d40ba4735 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 31 Aug 2022 15:51:21 +0200
Subject: [PATCH 100/366] Add download link for v5.14.0
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 048e367ef..f4912f2dc 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -14,7 +14,7 @@ Pay attention to the following version breaks due to dynamic settings updates:
1. Migrate to **Sonoff-Tasmota 3.9.x**
2. Migrate to **Sonoff-Tasmota 4.x**
-3. Migrate to **Sonoff-Tasmota 5.14**
+3. Migrate to **Sonoff-Tasmota 5.14** (http://ota.tasmota.com/tasmota/release_5.14.0/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions
4. Migrate to **Sonoff-Tasmota 6.7.1** (http://ota.tasmota.com/tasmota/release_6.7.1/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions
5. Migrate to **Tasmota 7.2.0** (http://ota.tasmota.com/tasmota/release-7.2.0/tasmota.bin)
From a1e5f53ddd775d041f0017cec6824adddfc43009 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 31 Aug 2022 19:21:00 +0200
Subject: [PATCH 101/366] Berry fix json crash
---
lib/libesp32/berry/src/be_strlib.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/libesp32/berry/src/be_strlib.c b/lib/libesp32/berry/src/be_strlib.c
index 23fdf978f..2c5424634 100644
--- a/lib/libesp32/berry/src/be_strlib.c
+++ b/lib/libesp32/berry/src/be_strlib.c
@@ -263,6 +263,9 @@ BERRY_API bint be_str2int(const char *str, const char **endstr)
while ((c = be_char2hex(*str++)) >= 0) {
sum = sum * 16 + c;
}
+ if (endstr) {
+ *endstr = str - 1;
+ }
return sum;
} else {
/* decimal literal */
From d0f5c80ae1e11e791d0d9c0a09944947e2896ebf Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 31 Aug 2022 21:04:35 +0200
Subject: [PATCH 102/366] Zigbee fix regression when reporting a command
---
.../xdrv_23_zigbee_1z_libs.ino | 42 +++++++++++--------
1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_1z_libs.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_1z_libs.ino
index 34dfd2e57..335431b53 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_1z_libs.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_1z_libs.ino
@@ -317,6 +317,7 @@ public:
// if suffix == 0, we don't care and find the first match
Z_attribute & findOrCreateAttribute(uint16_t cluster, uint16_t attr_id, uint8_t suffix = 0);
Z_attribute & findOrCreateAttribute(const char * name, uint8_t suffix = 0);
+ Z_attribute & findOrCreateCmd(uint16_t cluster, uint8_t cmd_id, bool direction, uint8_t suffix = 0);
// always care about suffix
Z_attribute & findOrCreateAttribute(const Z_attribute &attr);
// replace attribute with new value, suffix does care
@@ -558,27 +559,25 @@ bool Z_attribute::equalsKey(const Z_attribute & attr2, bool ignore_key_suffix) c
}
bool Z_attribute::equalsId(uint16_t _cluster, uint16_t _attr_id, uint8_t suffix) const {
- if (!key_is_str) {
- if ((this->cluster == _cluster) && (this->attr_id == _attr_id) && (!this->key_is_cmd)) {
- if (suffix) {
- if (key_suffix == suffix) { return true; }
- } else {
- return true;
- }
+ if (key_is_cmd || key_is_str) { return false; }
+ if ((this->cluster == _cluster) && (this->attr_id == _attr_id) && (!this->key_is_cmd)) {
+ if (suffix) {
+ if (key_suffix == suffix) { return true; }
+ } else {
+ return true;
}
}
return false;
}
bool Z_attribute::equalsCmd(uint16_t _cluster, uint8_t _cmd_id, bool _direction, uint8_t suffix) const {
- if (!key_is_str) {
- uint16_t _attr_id = _cmd_id | (_direction ? 0x100 : 0x000);
- if ((this->cluster == _cluster) && (this->attr_id == _attr_id) && (!this->key_is_cmd)) {
- if (suffix) {
- if (key_suffix == suffix) { return true; }
- } else {
- return true;
- }
+ if (!key_is_cmd ||key_is_str) { return false; }
+ uint16_t _attr_id = _cmd_id | (_direction ? 0x100 : 0x000);
+ if ((this->cluster == _cluster) && (this->attr_id == _attr_id) && (!this->key_is_cmd)) {
+ if (suffix) {
+ if (key_suffix == suffix) { return true; }
+ } else {
+ return true;
}
}
return false;
@@ -813,7 +812,7 @@ Z_attribute & Z_attribute_list::addAttributeCmd(uint16_t cluster, uint8_t cmd_id
Z_attribute & attr = addToLast();
attr.cluster = cluster;
attr.attr_id = cmd_id | (direction ? 0x100 : 0);
- attr.key_is_str = true;
+ attr.key_is_cmd = true;
if (!suffix) { attr.key_suffix = countAttribute(attr.cluster, attr.attr_id); }
else { attr.key_suffix = suffix; }
return attr;
@@ -891,7 +890,7 @@ const Z_attribute * Z_attribute_list::findAttribute(const Z_attribute &attr) con
const Z_attribute * Z_attribute_list::findAttribute(uint16_t cluster, uint16_t attr_id, uint8_t suffix) const {
for (const auto & attr : *this) {
- if (attr.equalsId(cluster, attr_id, suffix)) { return &attr; }
+ if (attr.equalsId(cluster, attr_id, suffix) && !attr.key_is_cmd) { return &attr; }
}
return nullptr;
}
@@ -916,6 +915,11 @@ Z_attribute & Z_attribute_list::findOrCreateAttribute(uint16_t cluster, uint16_t
return found ? *found : addAttribute(cluster, attr_id, suffix);
}
+Z_attribute & Z_attribute_list::findOrCreateCmd(uint16_t cluster, uint8_t cmd_id, bool direction, uint8_t suffix) {
+ Z_attribute * found = findAttributeCmd(cluster, cmd_id, direction, suffix);
+ return found ? *found : addAttributeCmd(cluster, cmd_id, direction, suffix);
+}
+
const Z_attribute * Z_attribute_list::findAttribute(const char * name, uint8_t suffix) const {
for (const auto & attr : *this) {
if (attr.equalsKey(name, suffix)) { return &attr; }
@@ -938,7 +942,9 @@ Z_attribute & Z_attribute_list::findOrCreateAttribute(const char * name, uint8_t
// same but passing a Z_attribute as key
Z_attribute & Z_attribute_list::findOrCreateAttribute(const Z_attribute &attr) {
Z_attribute & ret = attr.key_is_str ? findOrCreateAttribute(attr.key, attr.key_suffix)
- : findOrCreateAttribute(attr.cluster, attr.attr_id, attr.key_suffix);
+ : attr.key_is_cmd ?
+ findOrCreateCmd(attr.cluster, attr.attr_id & 0xFF, attr.attr_id & 0x100 ? true : false, attr.key_suffix)
+ : findOrCreateAttribute(attr.cluster, attr.attr_id, attr.key_suffix);
ret.key_suffix = attr.key_suffix;
return ret;
}
From c2cfc973d70ee56cee6a9f67c20659895bfedf1d Mon Sep 17 00:00:00 2001
From: renzhe
Date: Thu, 1 Sep 2022 12:20:58 +0800
Subject: [PATCH 103/366] translate some chinese
---
tasmota/language/zh_CN.h | 66 ++++++++++++++++++++--------------------
1 file changed, 33 insertions(+), 33 deletions(-)
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index e74e51008..7e6e2da7e 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -130,7 +130,7 @@
#define D_MULTI_PRESS "多次按键"
#define D_NOISE "嘈杂"
#define D_NONE "无"
-#define D_O2 "Oxygen"
+#define D_O2 "氧"
#define D_OFF "关"
#define D_OFFLINE "离线"
#define D_OK "好"
@@ -140,7 +140,7 @@
#define D_PASSWORD "密码"
#define D_PH "pH"
#define D_MQ "MQ"
-#define D_PARTITION "Partition" // As in flash and firmware partition
+#define D_PARTITION "分区" // As in flash and firmware partition
#define D_PORT "端口"
#define D_POWER_FACTOR "功率因数"
#define D_POWERUSAGE "功率"
@@ -177,14 +177,14 @@
#define D_TO "to"
#define D_TOGGLE "切换"
#define D_TOPIC "主题"
-#define D_TOTAL_USAGE "Total Usage"
+#define D_TOTAL_USAGE "总共使用"
#define D_TRANSMIT "发送"
#define D_TRUE "True"
#define D_TVOC "TVOC"
#define D_UPGRADE "升级"
#define D_UPLOAD "上传"
#define D_UPTIME "运行时间"
-#define D_USED "used"
+#define D_USED "已使用"
#define D_USER "用户名"
#define D_UTC_TIME "UTC"
#define D_UV_INDEX "紫外线指数"
@@ -202,9 +202,9 @@
#define D_VOLUME "Volume"
#define D_WEIGHT "重量"
#define D_WARMLIGHT "暖"
-#define D_WEB_SERVER "Web Server"
-#define D_SOC "State of Charge"
-#define D_SOH "State of Health"
+#define D_WEB_SERVER "Web服务器"
+#define D_SOC "充电状态"
+#define D_SOH "充电健康"
// tasmota.ino
#define D_WARNING_MINIMAL_VERSION "警告:精简固件不支持持久保存设置"
@@ -216,7 +216,7 @@
#define D_SET_BAUDRATE_TO "设置波特率为:"
#define D_RECEIVED_TOPIC "接收到的主题:"
#define D_DATA_SIZE "数据大小:"
-#define D_ANALOG_INPUT "Analog"
+#define D_ANALOG_INPUT "模拟"
// support.ino
#define D_OSWATCH "osWatch"
@@ -300,18 +300,18 @@
#define D_WPA_PSK "WPA PSK"
#define D_WPA2_PSK "WPA2 PSK"
#define D_AP1_SSID "WiFi 名称"
-#define D_AP1_SSID_HELP "Type or Select your WiFi Network"
+#define D_AP1_SSID_HELP "输入或选择您的WiFi网络"
#define D_AP2_SSID "WiFi 名称 2"
-#define D_AP2_SSID_HELP "Type your Alternative WiFi Network"
+#define D_AP2_SSID_HELP "输入您的备用WiFi网络"
#define D_AP_PASSWORD "WiFi 密码"
-#define D_AP_PASSWORD_HELP "Enter your WiFi Password"
-#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network"
-#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks"
-#define D_SHOW_MORE_OPTIONS "More Options"
-#define D_CHECK_CREDENTIALS "Please, check your credentials"
-#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection"
-#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window"
-#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address"
+#define D_AP_PASSWORD_HELP "输入您的WiFi密码"
+#define D_SELECT_YOUR_WIFI_NETWORK "选择你的Wifi网络"
+#define D_SHOW_MORE_WIFI_NETWORKS "扫描所有WiFi网络"
+#define D_SHOW_MORE_OPTIONS "更多选项"
+#define D_CHECK_CREDENTIALS "请检查您的密码"
+#define D_SUCCESSFUL_WIFI_CONNECTION "WiFi连接成功"
+#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "您现在可以关闭这个窗口"
+#define D_REDIRECTING_TO_NEW_IP "重定向到新设备的 IP 地址"
#define D_MQTT_PARAMETERS "MQTT 设置"
#define D_CLIENT "客户端"
@@ -319,7 +319,7 @@
#define D_LOGGING_PARAMETERS "日志设置"
#define D_SERIAL_LOG_LEVEL "串口日志级别"
-#define D_MQTT_LOG_LEVEL "Mqtt log level"
+#define D_MQTT_LOG_LEVEL "Mqtt 日志级别"
#define D_WEB_LOG_LEVEL "Web 日志级别"
#define D_SYS_LOG_LEVEL "Syslog 日志级别"
#define D_MORE_DEBUG "全部调试"
@@ -330,7 +330,7 @@
#define D_OTHER_PARAMETERS "其他设置"
#define D_TEMPLATE "模板"
#define D_ACTIVATE "启用"
-#define D_DEVICE_NAME "Device Name"
+#define D_DEVICE_NAME "设备名称"
#define D_WEB_ADMIN_PASSWORD "WEB 管理密码"
#define D_MQTT_ENABLE "启用 MQTT"
#define D_MQTT_TLS_ENABLE "MQTT TLS"
@@ -376,15 +376,15 @@
#define D_OTA_URL "OTA 地址"
#define D_START_UPGRADE "开始升级"
#define D_UPGRADE_BY_FILE_UPLOAD "通过文件升级"
-#define D_UPLOAD_FACTORY "Switching to safeboot partition"
+#define D_UPLOAD_FACTORY "切换到安全启动分区"
#define D_UPLOAD_STARTED "开始上传"
#define D_UPGRADE_STARTED "开始升级"
#define D_UPLOAD_DONE "上传完成"
-#define D_UPLOAD_TRANSFER "Upload transfer"
-#define D_TRANSFER_STARTED "Transfer started"
+#define D_UPLOAD_TRANSFER "上传中"
+#define D_TRANSFER_STARTED "传输开始"
#define D_UPLOAD_ERR_1 "没有选择任何文件"
#define D_UPLOAD_ERR_2 "没有足够空间"
-#define D_UPLOAD_ERR_3 "Invalid file signature"
+#define D_UPLOAD_ERR_3 "无效的文件签名"
#define D_UPLOAD_ERR_4 "固件大小超过 flash 容量"
#define D_UPLOAD_ERR_5 "上传缓冲区不足,请先刷入精简固件再升级"
#define D_UPLOAD_ERR_6 "上传失败。 启用日志级别 3 调试"
@@ -395,7 +395,7 @@
#define D_UPLOAD_ERR_11 "擦除 RF 芯片失败"
#define D_UPLOAD_ERR_12 "写入 RF 芯片失败"
#define D_UPLOAD_ERR_13 "解码 RF 固件失败"
-#define D_UPLOAD_ERR_14 "Not compatible"
+#define D_UPLOAD_ERR_14 "不兼容"
#define D_UPLOAD_ERROR_CODE "上传错误代码"
#define D_ENTER_COMMAND "输入命令"
@@ -485,12 +485,12 @@
// xdrv_23_zigbee
#define D_ZIGBEE_PERMITJOIN_ACTIVE "允许设备连入"
-#define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee Mapping"
+#define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee 映射"
#define D_ZIGBEE_NOT_STARTED "Zigbee 未启动"
-#define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "Mapping in progress (%d s. remaining)"
-#define D_ZIGBEE_MAPPING_NOT_PRESENT "No mapping"
-#define D_ZIGBEE_MAP_REFRESH "Zigbee Map Refresh"
-#define D_ZIGBEE_MAP "Zigbee Map"
+#define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "正在处理中 (等待 %d s.)"
+#define D_ZIGBEE_MAPPING_NOT_PRESENT "无映射"
+#define D_ZIGBEE_MAP_REFRESH "Zigbee 映射刷新"
+#define D_ZIGBEE_MAP "Zigbee 映射"
#define D_ZIGBEE_PERMITJOIN "Zigbee 允许连入"
#define D_ZIGBEE_GENERATE_KEY "正在生成 Zigbee 网络随机秘钥"
#define D_ZIGBEE_UNKNOWN_DEVICE "未知设备"
@@ -940,8 +940,8 @@
#define D_SENSOR_DETECTED "detected"
//SDM220, SDM120, SDM72, LE01MR, SDM230
-#define D_EXPORT_POWER "Export Power"
-#define D_IMPORT_POWER "Import Power"
+#define D_EXPORT_POWER "输出功率"
+#define D_IMPORT_POWER "输入功率"
#define D_PHASE_ANGLE "相位角"
#define D_IMPORT_ACTIVE "有功输入"
#define D_EXPORT_ACTIVE "有功输出"
@@ -950,7 +950,7 @@
#define D_TOTAL_REACTIVE "总无功功率"
#define D_UNIT_KWARH "千乏时"
#define D_UNIT_ANGLE "度"
-#define D_TOTAL_ACTIVE "Total Active"
+#define D_TOTAL_ACTIVE "总功率"
#define D_RESETTABLE_TOTAL_ACTIVE "Total Active (RST)"
//SOLAXX1
From 7fb00daa52f9ee7edaa3bed5b8eae4d0a64475c8 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 1 Sep 2022 08:14:37 +0200
Subject: [PATCH 104/366] Zigbee prepare for Green Power support
---
CHANGELOG.md | 1 +
.../xdrv_23_zigbee_0_constants.ino | 2 +
.../xdrv_23_zigbee_5_0_constants.ino | 1064 +++++++++--------
.../xdrv_23_zigbee_5_1_attributes.ino | 29 +-
.../xdrv_23_zigbee_5_2_converters.ino | 52 +-
.../xdrv_23_zigbee_7_0_statemachine.ino | 16 +-
.../xdrv_23_zigbee_8_parsers.ino | 4 +-
.../xdrv_23_zigbee_9_serial.ino | 11 +-
.../xdrv_23_zigbee_A_impl.ino | 34 +-
9 files changed, 666 insertions(+), 547 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8b2c6a528..cfe3871bb 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 Modbus writing using ModbusBridge by JeroenSt (#16351)
- Support for Ethernet in ESP32 safeboot firmware (#16388)
- Flowrate meter flow amount/duration, show values in table format (#16385)
+- Zigbee prepare for Green Power support
### Changed
- TasmotaModbus library from v3.5.0 to v3.6.0 (#16351)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_0_constants.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_0_constants.ino
index ac2aae6ed..cffd37e59 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_0_constants.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_0_constants.ino
@@ -923,6 +923,8 @@ enum Z_App_Profiles {
Z_PROF_TA = 0x0107, // Telecom Applications
Z_PROF_PHHC = 0x0108, // Personal Home & Hospital Care
Z_PROF_AMI = 0x0109, // Advanced Metering Initiative
+ // Green Power
+ Z_PROF_GP = 0xa1e0, // Green Power profile
};
enum Z_Device_Ids {
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 9e476650c..d244032fe 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
@@ -240,12 +240,16 @@ const char Z_strings[] PROGMEM =
"BinaryRelinquishDefault" "\x00"
"BinaryStatusFlags" "\x00"
"BinaryValue" "\x00"
+ "BlockedGPDID" "\x00"
"CIE" "\x00"
"CO" "\x00"
"CT" "\x00"
"CalculationPeriod" "\x00"
+ "CcommissioningExitMode" "\x00"
"CheckinInterval" "\x00"
"CheckinIntervalMin" "\x00"
+ "ClientActiveFunctionality" "\x00"
+ "ClientFunctionality" "\x00"
"ClosedLimit" "\x00"
"Color" "\x00"
"ColorCapabilities" "\x00"
@@ -275,6 +279,8 @@ const char Z_strings[] PROGMEM =
"ColorTempStep" "\x00"
"ColorTempStepDown" "\x00"
"ColorTempStepUp" "\x00"
+ "CommissioningWindow" "\x00"
+ "CommunicationMode" "\x00"
"CompanyName" "\x00"
"CompensationText" "\x00"
"ConfigStatus" "\x00"
@@ -415,6 +421,7 @@ const char Z_strings[] PROGMEM =
"LineCurrent" "\x00"
"LineCurrentPhB" "\x00"
"LineCurrentPhC" "\x00"
+ "LinkKey" "\x00"
"LocalTemperature" "\x00"
"LocalTemperatureCalibration" "\x00"
"LocalTime" "\x00"
@@ -458,7 +465,10 @@ const char Z_strings[] PROGMEM =
"MaxCoolSetpointLimit" "\x00"
"MaxHeatSetpointLimit" "\x00"
"MaxPINCodeLength" "\x00"
+ "MaxProxyTableEntries" "\x00"
"MaxRFIDCodeLength" "\x00"
+ "MaxSearchCounter" "\x00"
+ "MaxSinkTableEntries" "\x00"
"MaxTempExperienced" "\x00"
"Measured11thHarmonicCurrent" "\x00"
"Measured1stHarmonicCurrent" "\x00"
@@ -510,6 +520,8 @@ const char Z_strings[] PROGMEM =
"MultiValue" "\x00"
"MultipleScheduling" "\x00"
"NeutralCurrent" "\x00"
+ "NotificationRetryNumber" "\x00"
+ "NotificationRetryTimer" "\x00"
"NumberOfDevices" "\x00"
"NumberOfHolidaySchedulesSupported" "\x00"
"NumberOfLogRecordsSupported" "\x00"
@@ -596,6 +608,7 @@ const char Z_strings[] PROGMEM =
"ProductCode" "\x00"
"ProductRevision" "\x00"
"ProductURL" "\x00"
+ "ProxyTable" "\x00"
"QualityMeasure" "\x00"
"RGB" "\x00"
"RHDehumidificationSetpoint" "\x00"
@@ -661,6 +674,11 @@ const char Z_strings[] PROGMEM =
"SceneValid" "\x00"
"ScheduleMode" "\x00"
"SeaPressure" "\x00"
+ "SecurityLevel" "\x00"
+ "ServerActiveFunctionality" "\x00"
+ "ServerFunctionality" "\x00"
+ "SharedSecurityKey" "\x00"
+ "SharedSecurityKeyType" "\x00"
"ShortPollInterval" "\x00"
"Shutter" "\x00"
"ShutterClose" "\x00"
@@ -668,6 +686,7 @@ const char Z_strings[] PROGMEM =
"ShutterOpen" "\x00"
"ShutterStop" "\x00"
"ShutterTilt" "\x00"
+ "SinkTable" "\x00"
"SoftwareRevision" "\x00"
"StackVersion" "\x00"
"StandardTime" "\x00"
@@ -921,519 +940,538 @@ enum Z_offsets {
Zo_BinaryRelinquishDefault = 3108,
Zo_BinaryStatusFlags = 3132,
Zo_BinaryValue = 3150,
- Zo_CIE = 3162,
- Zo_CO = 3166,
- Zo_CT = 3169,
- Zo_CalculationPeriod = 3172,
- Zo_CheckinInterval = 3190,
- Zo_CheckinIntervalMin = 3206,
- Zo_ClosedLimit = 3225,
- Zo_Color = 3237,
- Zo_ColorCapabilities = 3243,
- Zo_ColorLoopActive = 3261,
- Zo_ColorLoopDirection = 3277,
- Zo_ColorLoopStartEnhancedHue = 3296,
- Zo_ColorLoopStoredEnhancedHue = 3322,
- Zo_ColorLoopTime = 3349,
- Zo_ColorMode = 3363,
- Zo_ColorMove = 3373,
- Zo_ColorPointBIntensity = 3383,
- Zo_ColorPointBX = 3404,
- Zo_ColorPointBY = 3417,
- Zo_ColorPointGIntensity = 3430,
- Zo_ColorPointGX = 3451,
- Zo_ColorPointGY = 3464,
- Zo_ColorPointRIntensity = 3477,
- Zo_ColorPointRX = 3498,
- Zo_ColorPointRY = 3511,
- Zo_ColorStep = 3524,
- Zo_ColorTempMove = 3534,
- Zo_ColorTempMoveDown = 3548,
- Zo_ColorTempMoveStop = 3566,
- Zo_ColorTempMoveUp = 3584,
- Zo_ColorTempPhysicalMaxMireds = 3600,
- Zo_ColorTempPhysicalMinMireds = 3627,
- Zo_ColorTempStep = 3654,
- Zo_ColorTempStepDown = 3668,
- Zo_ColorTempStepUp = 3686,
- Zo_CompanyName = 3702,
- Zo_CompensationText = 3714,
- Zo_ConfigStatus = 3731,
- Zo_Contact = 3744,
- Zo_ControlSequenceOfOperation = 3752,
- Zo_Coordinate1 = 3779,
- Zo_Coordinate2 = 3791,
- Zo_Coordinate3 = 3803,
- Zo_CurrentGroup = 3815,
- Zo_CurrentPositionLift = 3828,
- Zo_CurrentPositionLiftPercentage = 3848,
- Zo_CurrentPositionTilt = 3878,
- Zo_CurrentPositionTiltPercentage = 3898,
- Zo_CurrentScene = 3928,
- Zo_CurrentTemperature = 3941,
- Zo_CurrentTemperatureSetPoint = 3960,
- Zo_CurrentZoneSensitivityLevel = 3987,
- Zo_CustomerName = 4015,
- Zo_DCCurrent = 4028,
- Zo_DCCurrentDivisor = 4038,
- Zo_DCCurrentMax = 4055,
- Zo_DCCurrentMin = 4068,
- Zo_DCCurrentMultiplier = 4081,
- Zo_DCCurrentOverload = 4101,
- Zo_DCOverloadAlarmsMask = 4119,
- Zo_DCPower = 4140,
- Zo_DCPowerDivisor = 4148,
- Zo_DCPowerMax = 4163,
- Zo_DCPowerMin = 4174,
- Zo_DCPowerMultiplier = 4185,
- Zo_DCVoltage = 4203,
- Zo_DCVoltageDivisor = 4213,
- Zo_DCVoltageMax = 4230,
- Zo_DCVoltageMin = 4243,
- Zo_DCVoltageMultiplier = 4256,
- Zo_DCVoltageOverload = 4276,
- Zo_DataQualityID = 4294,
- Zo_DateCode = 4308,
- Zo_DecelerationTimeLift = 4317,
- Zo_DefaultMoveRate = 4338,
- Zo_DehumidificationCooling = 4354,
- Zo_DehumidificationHysteresis = 4378,
- Zo_DehumidificationLockout = 4405,
- Zo_DehumidificationMaxCool = 4429,
- Zo_DeviceEnabled = 4453,
- Zo_DeviceTempAlarmMask = 4467,
- Zo_Dimmer = 4487,
- Zo_DimmerDown = 4494,
- Zo_DimmerMove = 4505,
- Zo_DimmerOptions = 4516,
- Zo_DimmerRemainingTime = 4530,
- Zo_DimmerStep = 4550,
- Zo_DimmerStepDown = 4561,
- Zo_DimmerStepUp = 4576,
- Zo_DimmerStop = 4589,
- Zo_DimmerUp = 4600,
- Zo_DisableLocalConfig = 4609,
- Zo_DoorClosedEvents = 4628,
- Zo_DoorOpenEvents = 4645,
- Zo_DoorState = 4660,
- Zo_DriftCompensation = 4670,
- Zo_DstEnd = 4688,
- Zo_DstShift = 4695,
- Zo_DstStart = 4704,
- Zo_ElectricalMeasurementType = 4713,
- Zo_EnergyFormatting = 4739,
- Zo_EnergyRemote = 4756,
- Zo_EnergyTotal = 4769,
- Zo_EnhancedColorMode = 4781,
- Zo_EnhancedCurrentHue = 4799,
- Zo_EurotronicErrors = 4818,
- Zo_EurotronicHostFlags = 4835,
- Zo_FanMode = 4855,
- Zo_FanModeSequence = 4863,
- Zo_FastPollTimeout = 4879,
- Zo_FastPollTimeoutMax = 4895,
- Zo_Fire = 4914,
- Zo_FlowMaxMeasuredValue = 4919,
- Zo_FlowMinMeasuredValue = 4940,
- Zo_FlowRate = 4961,
- Zo_FlowTolerance = 4970,
- Zo_GenericDeviceClass = 4984,
- Zo_GenericDeviceType = 5003,
- Zo_GetAllGroups = 5021,
- Zo_GetGroup = 5034,
- Zo_GetSceneMembership = 5043,
- Zo_GlassBreak = 5062,
- Zo_GroupNameSupport = 5073,
- Zo_HVACSystemTypeConfiguration = 5090,
- Zo_HWVersion = 5118,
- Zo_HarmonicCurrentMultiplier = 5128,
- Zo_HighTempDwellTripPoint = 5154,
- Zo_HighTempThreshold = 5177,
- Zo_Hue = 5195,
- Zo_HueMove = 5199,
- Zo_HueSat = 5207,
- Zo_HueStep = 5214,
- Zo_HueStepDown = 5222,
- Zo_HueStepUp = 5234,
- Zo_Humidity = 5244,
- Zo_HumidityMaxMeasuredValue = 5253,
- Zo_HumidityMinMeasuredValue = 5278,
- Zo_HumidityTolerance = 5303,
- Zo_IASCIEAddress = 5321,
- Zo_Identify = 5335,
- Zo_IdentifyQuery = 5344,
- Zo_IdentifyTime = 5358,
- Zo_Illuminance = 5371,
- Zo_IlluminanceLevelStatus = 5383,
- Zo_IlluminanceLightSensorType = 5406,
- Zo_IlluminanceMaxMeasuredValue = 5433,
- Zo_IlluminanceMinMeasuredValue = 5461,
- Zo_IlluminanceTargetLevel = 5489,
- Zo_IlluminanceTolerance = 5512,
- Zo_InstalledClosedLimitLift = 5533,
- Zo_InstalledClosedLimitTilt = 5558,
- Zo_InstalledOpenLimitLift = 5583,
- Zo_InstalledOpenLimitTilt = 5606,
- Zo_IntermediateSetpointsLift = 5629,
- Zo_IntermediateSetpointsTilt = 5655,
- Zo_IntrinsicBallastFactor = 5681,
- Zo_LampAlarmMode = 5704,
- Zo_LampBurnHours = 5718,
- Zo_LampBurnHoursTripPoint = 5732,
- Zo_LampManufacturer = 5755,
- Zo_LampRatedHours = 5772,
- Zo_LampType = 5787,
- Zo_LastConfiguredBy = 5796,
- Zo_LastMessageLQI = 5813,
- Zo_LastMessageRSSI = 5828,
- Zo_LastSetTime = 5844,
- Zo_LegrandHeatingMode = 5856,
- Zo_LegrandMode = 5875,
- Zo_LegrandOpt1 = 5887,
- Zo_LegrandOpt2 = 5899,
- Zo_LegrandOpt3 = 5911,
- Zo_LidlPower = 5923,
- Zo_LineCurrent = 5933,
- Zo_LineCurrentPhB = 5945,
- Zo_LineCurrentPhC = 5960,
- Zo_LocalTemperature = 5975,
- Zo_LocalTemperatureCalibration = 5992,
- Zo_LocalTime = 6020,
- Zo_LocationAge = 6030,
- Zo_LocationDescription = 6042,
- Zo_LocationMethod = 6062,
- Zo_LocationPower = 6077,
- Zo_LocationType = 6091,
- Zo_LockAlarmMask = 6104,
- Zo_LockDefaultConfigurationRegister = 6118,
- Zo_LockEnableInsideStatusLED = 6151,
- Zo_LockEnableLocalProgramming = 6177,
- Zo_LockEnableLogging = 6204,
- Zo_LockEnableOneTouchLocking = 6222,
- Zo_LockEnablePrivacyModeButton = 6248,
- Zo_LockKeypadOperationEventMask = 6276,
- Zo_LockKeypadProgrammingEventMask = 6305,
- Zo_LockLEDSettings = 6336,
- Zo_LockLanguage = 6352,
- Zo_LockManualOperationEventMask = 6365,
- Zo_LockOperatingMode = 6394,
- Zo_LockRFIDOperationEventMask = 6412,
- Zo_LockRFIDProgrammingEventMask = 6439,
- Zo_LockRFOperationEventMask = 6468,
- Zo_LockRFProgrammingEventMask = 6493,
- Zo_LockSoundVolume = 6520,
- Zo_LockState = 6536,
- Zo_LockSupportedOperatingModes = 6546,
- Zo_LockType = 6574,
- Zo_LongPollInterval = 6583,
- Zo_LongPollIntervalMin = 6600,
- Zo_LowTempDwellTripPoint = 6620,
- Zo_LowTempThreshold = 6642,
- Zo_MainsAlarmMask = 6659,
- Zo_MainsFrequency = 6674,
- Zo_MainsVoltage = 6689,
- Zo_MainsVoltageDwellTripPoint = 6702,
- Zo_MainsVoltageMaxThreshold = 6729,
- Zo_MainsVoltageMinThreshold = 6754,
- Zo_Manufacturer = 6779,
- Zo_MaxCoolSetpointLimit = 6792,
- Zo_MaxHeatSetpointLimit = 6813,
- Zo_MaxPINCodeLength = 6834,
- Zo_MaxRFIDCodeLength = 6851,
- Zo_MaxTempExperienced = 6869,
- Zo_Measured11thHarmonicCurrent = 6888,
- Zo_Measured1stHarmonicCurrent = 6916,
- Zo_Measured3rdHarmonicCurrent = 6943,
- Zo_Measured5thHarmonicCurrent = 6970,
- Zo_Measured7thHarmonicCurrent = 6997,
- Zo_Measured9thHarmonicCurrent = 7024,
- Zo_MeasuredPhase11thHarmonicCurrent = 7051,
- Zo_MeasuredPhase1stHarmonicCurrent = 7084,
- Zo_MeasuredPhase3rdHarmonicCurrent = 7116,
- Zo_MeasuredPhase5thHarmonicCurrent = 7148,
- Zo_MeasuredPhase7thHarmonicCurrent = 7180,
- Zo_MeasuredPhase9thHarmonicCurrent = 7212,
- Zo_MeterTypeID = 7244,
- Zo_MinCoolSetpointLimit = 7256,
- Zo_MinHeatSetpointLimit = 7277,
- Zo_MinPINCodeLength = 7298,
- Zo_MinRFIDCodeLength = 7315,
- Zo_MinSetpointDeadBand = 7333,
- Zo_MinTempExperienced = 7353,
- Zo_Mode = 7372,
- Zo_Model = 7377,
- Zo_ModelId = 7383,
- Zo_MotorStepSize = 7391,
- Zo_Movement = 7405,
- Zo_MullerLightMode = 7414,
- Zo_MultiApplicationType = 7430,
- Zo_MultiDescription = 7451,
- Zo_MultiInApplicationType = 7468,
- Zo_MultiInDescription = 7491,
- Zo_MultiInNumberOfStates = 7510,
- Zo_MultiInOutOfService = 7532,
- Zo_MultiInReliability = 7552,
- Zo_MultiInStatusFlags = 7571,
- Zo_MultiInValue = 7590,
- Zo_MultiNumberOfStates = 7603,
- Zo_MultiOutApplicationType = 7623,
- Zo_MultiOutDescription = 7647,
- Zo_MultiOutNumberOfStates = 7667,
- Zo_MultiOutOfService = 7690,
- Zo_MultiOutOutOfService = 7708,
- Zo_MultiOutReliability = 7729,
- Zo_MultiOutRelinquishDefault = 7749,
- Zo_MultiOutStatusFlags = 7775,
- Zo_MultiOutValue = 7795,
- Zo_MultiReliability = 7809,
- Zo_MultiRelinquishDefault = 7826,
- Zo_MultiStatusFlags = 7849,
- Zo_MultiValue = 7866,
- Zo_MultipleScheduling = 7877,
- Zo_NeutralCurrent = 7896,
- Zo_NumberOfDevices = 7911,
- Zo_NumberOfHolidaySchedulesSupported = 7927,
- Zo_NumberOfLogRecordsSupported = 7961,
- Zo_NumberOfPINUsersSupported = 7989,
- Zo_NumberOfPrimaries = 8015,
- Zo_NumberOfRFIDUsersSupported = 8033,
- Zo_NumberOfResets = 8060,
- Zo_NumberOfTotalUsersSupported = 8075,
- Zo_NumberOfWeekDaySchedulesSupportedPerUser = 8103,
- Zo_NumberOfYearDaySchedulesSupportedPerUser = 8144,
- Zo_NumberOfZoneSensitivityLevelsSupported = 8185,
- Zo_NumberRSSIMeasurements = 8224,
- Zo_NumberofActuationsLift = 8247,
- Zo_NumberofActuationsTilt = 8270,
- Zo_Occupancy = 8293,
- Zo_OccupancySensorType = 8303,
- Zo_OccupiedCoolingSetpoint = 8323,
- Zo_OccupiedHeatingSetpoint = 8347,
- Zo_OffTransitionTime = 8371,
- Zo_OffWaitTime = 8389,
- Zo_OnLevel = 8401,
- Zo_OnOff = 8409,
- Zo_OnOffTransitionTime = 8415,
- Zo_OnTime = 8435,
- Zo_OnTransitionTime = 8442,
- Zo_OpenPeriod = 8459,
- Zo_OppleMode = 8470,
- Zo_OutdoorTemperature = 8480,
- Zo_OverTempTotalDwell = 8499,
- Zo_PICoolingDemand = 8518,
- Zo_PIHeatingDemand = 8534,
- Zo_PIROccupiedToUnoccupiedDelay = 8550,
- Zo_PIRUnoccupiedToOccupiedDelay = 8579,
- Zo_PIRUnoccupiedToOccupiedThreshold = 8608,
- Zo_POD = 8641,
- Zo_Panic = 8645,
- Zo_PartNumber = 8651,
- Zo_PathLossExponent = 8662,
- Zo_PersistentMemoryWrites = 8679,
- Zo_PersonalAlarm = 8702,
- Zo_PhaseHarmonicCurrentMultiplier = 8716,
- Zo_PhysicalClosedLimit = 8747,
- Zo_PhysicalClosedLimitLift = 8767,
- Zo_PhysicalClosedLimitTilt = 8791,
- Zo_PhysicalEnvironment = 8815,
- Zo_Power = 8835,
- Zo_PowerDivisor = 8841,
- Zo_PowerFactor = 8854,
- Zo_PowerFactorPhB = 8866,
- Zo_PowerFactorPhC = 8881,
- Zo_PowerMultiplier = 8896,
- Zo_PowerOffEffect = 8912,
- Zo_PowerOnRecall = 8927,
- Zo_PowerOnTimer = 8941,
- Zo_PowerSource = 8954,
- Zo_PowerThreshold = 8966,
- Zo_Pressure = 8981,
- Zo_PressureMaxMeasuredValue = 8990,
- Zo_PressureMaxScaledValue = 9015,
- Zo_PressureMinMeasuredValue = 9038,
- Zo_PressureMinScaledValue = 9063,
- Zo_PressureScale = 9086,
- Zo_PressureScaledTolerance = 9100,
- Zo_PressureScaledValue = 9124,
- Zo_PressureTolerance = 9144,
- Zo_Primary1Intensity = 9162,
- Zo_Primary1X = 9180,
- Zo_Primary1Y = 9190,
- Zo_Primary2Intensity = 9200,
- Zo_Primary2X = 9218,
- Zo_Primary2Y = 9228,
- Zo_Primary3Intensity = 9238,
- Zo_Primary3X = 9256,
- Zo_Primary3Y = 9266,
- Zo_Primary4Intensity = 9276,
- Zo_Primary4X = 9294,
- Zo_Primary4Y = 9304,
- Zo_Primary5Intensity = 9314,
- Zo_Primary5X = 9332,
- Zo_Primary5Y = 9342,
- Zo_Primary6Intensity = 9352,
- Zo_Primary6X = 9370,
- Zo_Primary6Y = 9380,
- Zo_ProductCode = 9390,
- Zo_ProductRevision = 9402,
- Zo_ProductURL = 9418,
- Zo_QualityMeasure = 9429,
- Zo_RGB = 9444,
- Zo_RHDehumidificationSetpoint = 9448,
- Zo_RMSCurrent = 9475,
- Zo_RMSCurrentMax = 9486,
- Zo_RMSCurrentMaxPhB = 9500,
- Zo_RMSCurrentMaxPhC = 9517,
- Zo_RMSCurrentMin = 9534,
- Zo_RMSCurrentMinPhB = 9548,
- Zo_RMSCurrentMinPhC = 9565,
- Zo_RMSCurrentPhB = 9582,
- Zo_RMSCurrentPhC = 9596,
- Zo_RMSExtremeOverVoltage = 9610,
- Zo_RMSExtremeOverVoltagePeriod = 9632,
- Zo_RMSExtremeOverVoltagePeriodPhB = 9660,
- Zo_RMSExtremeOverVoltagePeriodPhC = 9691,
- Zo_RMSExtremeUnderVoltage = 9722,
- Zo_RMSExtremeUnderVoltagePeriod = 9745,
- Zo_RMSExtremeUnderVoltagePeriodPhB = 9774,
- Zo_RMSExtremeUnderVoltagePeriodPhC = 9806,
- Zo_RMSVoltage = 9838,
- Zo_RMSVoltageMax = 9849,
- Zo_RMSVoltageMaxPhB = 9863,
- Zo_RMSVoltageMaxPhC = 9880,
- Zo_RMSVoltageMin = 9897,
- Zo_RMSVoltageMinPhB = 9911,
- Zo_RMSVoltageMinPhC = 9928,
- Zo_RMSVoltagePhB = 9945,
- Zo_RMSVoltagePhC = 9959,
- Zo_RMSVoltageSag = 9973,
- Zo_RMSVoltageSagPeriod = 9987,
- Zo_RMSVoltageSagPeriodPhB = 10007,
- Zo_RMSVoltageSagPeriodPhC = 10030,
- Zo_RMSVoltageSwell = 10053,
- Zo_RMSVoltageSwellPeriod = 10069,
- Zo_RMSVoltageSwellPeriodPhB = 10091,
- Zo_RMSVoltageSwellPeriodPhC = 10116,
- Zo_ReactiveCurrent = 10141,
- Zo_ReactiveCurrentPhB = 10157,
- Zo_ReactiveCurrentPhC = 10176,
- Zo_ReactivePower = 10195,
- Zo_ReactivePowerPhB = 10209,
- Zo_ReactivePowerPhC = 10226,
- Zo_RecallScene = 10243,
- Zo_RelativeHumidity = 10255,
- Zo_RelativeHumidityDisplay = 10272,
- Zo_RelativeHumidityMode = 10296,
- Zo_RemainingTime = 10317,
- Zo_RemoteSensing = 10331,
- Zo_RemoveAllGroups = 10345,
- Zo_RemoveAllScenes = 10361,
- Zo_RemoveGroup = 10377,
- Zo_RemoveScene = 10389,
- Zo_ReportingPeriod = 10401,
- Zo_ResetAlarm = 10417,
- Zo_ResetAllAlarms = 10428,
- Zo_SWBuildID = 10443,
- Zo_Sat = 10453,
- Zo_SatMove = 10457,
- Zo_SatStep = 10465,
- Zo_SceneCount = 10473,
- Zo_SceneNameSupport = 10484,
- Zo_SceneValid = 10501,
- Zo_ScheduleMode = 10512,
- Zo_SeaPressure = 10525,
- Zo_ShortPollInterval = 10537,
- Zo_Shutter = 10555,
- Zo_ShutterClose = 10563,
- Zo_ShutterLift = 10576,
- Zo_ShutterOpen = 10588,
- Zo_ShutterStop = 10600,
- Zo_ShutterTilt = 10612,
- Zo_SoftwareRevision = 10624,
- Zo_StackVersion = 10641,
- Zo_StandardTime = 10654,
- Zo_StartUpOnOff = 10667,
- Zo_Status = 10680,
- Zo_StoreScene = 10687,
- Zo_SwitchActions = 10698,
- Zo_SwitchType = 10712,
- Zo_SystemMode = 10723,
- Zo_TRVBoost = 10734,
- Zo_TRVChildProtection = 10743,
- Zo_TRVMirrorDisplay = 10762,
- Zo_TRVMode = 10779,
- Zo_TRVWindowOpen = 10787,
- Zo_TempTarget = 10801,
- Zo_Temperature = 10812,
- Zo_TemperatureDisplayMode = 10824,
- Zo_TemperatureMaxMeasuredValue = 10847,
- Zo_TemperatureMinMeasuredValue = 10875,
- Zo_TemperatureTolerance = 10903,
- Zo_TerncyDuration = 10924,
- Zo_TerncyRotate = 10939,
- Zo_ThSetpoint = 10952,
- Zo_ThermostatAlarmMask = 10963,
- Zo_ThermostatKeypadLockout = 10983,
- Zo_ThermostatOccupancy = 11007,
- Zo_ThermostatRunningMode = 11027,
- Zo_ThermostatScheduleProgrammingVisibility = 11049,
- Zo_Time = 11089,
- Zo_TimeEpoch = 11094,
- Zo_TimeStatus = 11104,
- Zo_TimeZone = 11115,
- Zo_TotalActivePower = 11124,
- Zo_TotalApparentPower = 11141,
- Zo_TotalProfileNum = 11160,
- Zo_TotalReactivePower = 11176,
- Zo_TuyaCalibration = 11195,
- Zo_TuyaCalibrationTime = 11211,
- Zo_TuyaMCUVersion = 11231,
- Zo_TuyaMotorReversal = 11246,
- Zo_TuyaMovingState = 11264,
- Zo_TuyaQuery = 11280,
- Zo_UnoccupiedCoolingSetpoint = 11290,
- Zo_UnoccupiedHeatingSetpoint = 11316,
- Zo_UtilityName = 11342,
- Zo_ValidUntilTime = 11354,
- Zo_ValvePosition = 11369,
- Zo_VelocityLift = 11383,
- Zo_ViewGroup = 11396,
- Zo_ViewScene = 11406,
- Zo_Water = 11416,
- Zo_WhitePointX = 11422,
- Zo_WhitePointY = 11434,
- Zo_WindowCoveringType = 11446,
- Zo_X = 11465,
- Zo_Y = 11467,
- Zo_ZCLVersion = 11469,
- Zo_ZoneID = 11480,
- Zo_ZoneState = 11487,
- Zo_ZoneStatus = 11497,
- Zo_ZoneStatusChange = 11508,
- Zo_ZoneType = 11525,
- Zo__ = 11534,
- Zo_xx = 11536,
- Zo_xx000A00 = 11539,
- Zo_xx0A = 11548,
- Zo_xx0A00 = 11553,
- Zo_xx19 = 11560,
- Zo_xx190A = 11565,
- Zo_xx190A00 = 11572,
- Zo_xxxx = 11581,
- Zo_xxxx00 = 11586,
- Zo_xxxx0A00 = 11593,
- Zo_xxxxyy = 11602,
- Zo_xxxxyyyy = 11609,
- Zo_xxxxyyyy0A00 = 11618,
- Zo_xxxxyyzz = 11631,
- Zo_xxyy = 11640,
- Zo_xxyy0A00 = 11645,
- Zo_xxyyyy = 11654,
- Zo_xxyyyy000000000000 = 11661,
- Zo_xxyyyy0A0000000000 = 11680,
- Zo_xxyyyyzz = 11699,
- Zo_xxyyyyzzzz = 11708,
- Zo_xxyyzzzz = 11719,
+ Zo_BlockedGPDID = 3162,
+ Zo_CIE = 3175,
+ Zo_CO = 3179,
+ Zo_CT = 3182,
+ Zo_CalculationPeriod = 3185,
+ Zo_CcommissioningExitMode = 3203,
+ Zo_CheckinInterval = 3226,
+ Zo_CheckinIntervalMin = 3242,
+ Zo_ClientActiveFunctionality = 3261,
+ Zo_ClientFunctionality = 3287,
+ Zo_ClosedLimit = 3307,
+ Zo_Color = 3319,
+ Zo_ColorCapabilities = 3325,
+ Zo_ColorLoopActive = 3343,
+ Zo_ColorLoopDirection = 3359,
+ Zo_ColorLoopStartEnhancedHue = 3378,
+ Zo_ColorLoopStoredEnhancedHue = 3404,
+ Zo_ColorLoopTime = 3431,
+ Zo_ColorMode = 3445,
+ Zo_ColorMove = 3455,
+ Zo_ColorPointBIntensity = 3465,
+ Zo_ColorPointBX = 3486,
+ Zo_ColorPointBY = 3499,
+ Zo_ColorPointGIntensity = 3512,
+ Zo_ColorPointGX = 3533,
+ Zo_ColorPointGY = 3546,
+ Zo_ColorPointRIntensity = 3559,
+ Zo_ColorPointRX = 3580,
+ Zo_ColorPointRY = 3593,
+ Zo_ColorStep = 3606,
+ Zo_ColorTempMove = 3616,
+ Zo_ColorTempMoveDown = 3630,
+ Zo_ColorTempMoveStop = 3648,
+ Zo_ColorTempMoveUp = 3666,
+ Zo_ColorTempPhysicalMaxMireds = 3682,
+ Zo_ColorTempPhysicalMinMireds = 3709,
+ Zo_ColorTempStep = 3736,
+ Zo_ColorTempStepDown = 3750,
+ Zo_ColorTempStepUp = 3768,
+ Zo_CommissioningWindow = 3784,
+ Zo_CommunicationMode = 3804,
+ Zo_CompanyName = 3822,
+ Zo_CompensationText = 3834,
+ Zo_ConfigStatus = 3851,
+ Zo_Contact = 3864,
+ Zo_ControlSequenceOfOperation = 3872,
+ Zo_Coordinate1 = 3899,
+ Zo_Coordinate2 = 3911,
+ Zo_Coordinate3 = 3923,
+ Zo_CurrentGroup = 3935,
+ Zo_CurrentPositionLift = 3948,
+ Zo_CurrentPositionLiftPercentage = 3968,
+ Zo_CurrentPositionTilt = 3998,
+ Zo_CurrentPositionTiltPercentage = 4018,
+ Zo_CurrentScene = 4048,
+ Zo_CurrentTemperature = 4061,
+ Zo_CurrentTemperatureSetPoint = 4080,
+ Zo_CurrentZoneSensitivityLevel = 4107,
+ Zo_CustomerName = 4135,
+ Zo_DCCurrent = 4148,
+ Zo_DCCurrentDivisor = 4158,
+ Zo_DCCurrentMax = 4175,
+ Zo_DCCurrentMin = 4188,
+ Zo_DCCurrentMultiplier = 4201,
+ Zo_DCCurrentOverload = 4221,
+ Zo_DCOverloadAlarmsMask = 4239,
+ Zo_DCPower = 4260,
+ Zo_DCPowerDivisor = 4268,
+ Zo_DCPowerMax = 4283,
+ Zo_DCPowerMin = 4294,
+ Zo_DCPowerMultiplier = 4305,
+ Zo_DCVoltage = 4323,
+ Zo_DCVoltageDivisor = 4333,
+ Zo_DCVoltageMax = 4350,
+ Zo_DCVoltageMin = 4363,
+ Zo_DCVoltageMultiplier = 4376,
+ Zo_DCVoltageOverload = 4396,
+ Zo_DataQualityID = 4414,
+ Zo_DateCode = 4428,
+ Zo_DecelerationTimeLift = 4437,
+ Zo_DefaultMoveRate = 4458,
+ Zo_DehumidificationCooling = 4474,
+ Zo_DehumidificationHysteresis = 4498,
+ Zo_DehumidificationLockout = 4525,
+ Zo_DehumidificationMaxCool = 4549,
+ Zo_DeviceEnabled = 4573,
+ Zo_DeviceTempAlarmMask = 4587,
+ Zo_Dimmer = 4607,
+ Zo_DimmerDown = 4614,
+ Zo_DimmerMove = 4625,
+ Zo_DimmerOptions = 4636,
+ Zo_DimmerRemainingTime = 4650,
+ Zo_DimmerStep = 4670,
+ Zo_DimmerStepDown = 4681,
+ Zo_DimmerStepUp = 4696,
+ Zo_DimmerStop = 4709,
+ Zo_DimmerUp = 4720,
+ Zo_DisableLocalConfig = 4729,
+ Zo_DoorClosedEvents = 4748,
+ Zo_DoorOpenEvents = 4765,
+ Zo_DoorState = 4780,
+ Zo_DriftCompensation = 4790,
+ Zo_DstEnd = 4808,
+ Zo_DstShift = 4815,
+ Zo_DstStart = 4824,
+ Zo_ElectricalMeasurementType = 4833,
+ Zo_EnergyFormatting = 4859,
+ Zo_EnergyRemote = 4876,
+ Zo_EnergyTotal = 4889,
+ Zo_EnhancedColorMode = 4901,
+ Zo_EnhancedCurrentHue = 4919,
+ Zo_EurotronicErrors = 4938,
+ Zo_EurotronicHostFlags = 4955,
+ Zo_FanMode = 4975,
+ Zo_FanModeSequence = 4983,
+ Zo_FastPollTimeout = 4999,
+ Zo_FastPollTimeoutMax = 5015,
+ Zo_Fire = 5034,
+ Zo_FlowMaxMeasuredValue = 5039,
+ Zo_FlowMinMeasuredValue = 5060,
+ Zo_FlowRate = 5081,
+ Zo_FlowTolerance = 5090,
+ Zo_GenericDeviceClass = 5104,
+ Zo_GenericDeviceType = 5123,
+ Zo_GetAllGroups = 5141,
+ Zo_GetGroup = 5154,
+ Zo_GetSceneMembership = 5163,
+ Zo_GlassBreak = 5182,
+ Zo_GroupNameSupport = 5193,
+ Zo_HVACSystemTypeConfiguration = 5210,
+ Zo_HWVersion = 5238,
+ Zo_HarmonicCurrentMultiplier = 5248,
+ Zo_HighTempDwellTripPoint = 5274,
+ Zo_HighTempThreshold = 5297,
+ Zo_Hue = 5315,
+ Zo_HueMove = 5319,
+ Zo_HueSat = 5327,
+ Zo_HueStep = 5334,
+ Zo_HueStepDown = 5342,
+ Zo_HueStepUp = 5354,
+ Zo_Humidity = 5364,
+ Zo_HumidityMaxMeasuredValue = 5373,
+ Zo_HumidityMinMeasuredValue = 5398,
+ Zo_HumidityTolerance = 5423,
+ Zo_IASCIEAddress = 5441,
+ Zo_Identify = 5455,
+ Zo_IdentifyQuery = 5464,
+ Zo_IdentifyTime = 5478,
+ Zo_Illuminance = 5491,
+ Zo_IlluminanceLevelStatus = 5503,
+ Zo_IlluminanceLightSensorType = 5526,
+ Zo_IlluminanceMaxMeasuredValue = 5553,
+ Zo_IlluminanceMinMeasuredValue = 5581,
+ Zo_IlluminanceTargetLevel = 5609,
+ Zo_IlluminanceTolerance = 5632,
+ Zo_InstalledClosedLimitLift = 5653,
+ Zo_InstalledClosedLimitTilt = 5678,
+ Zo_InstalledOpenLimitLift = 5703,
+ Zo_InstalledOpenLimitTilt = 5726,
+ Zo_IntermediateSetpointsLift = 5749,
+ Zo_IntermediateSetpointsTilt = 5775,
+ Zo_IntrinsicBallastFactor = 5801,
+ Zo_LampAlarmMode = 5824,
+ Zo_LampBurnHours = 5838,
+ Zo_LampBurnHoursTripPoint = 5852,
+ Zo_LampManufacturer = 5875,
+ Zo_LampRatedHours = 5892,
+ Zo_LampType = 5907,
+ Zo_LastConfiguredBy = 5916,
+ Zo_LastMessageLQI = 5933,
+ Zo_LastMessageRSSI = 5948,
+ Zo_LastSetTime = 5964,
+ Zo_LegrandHeatingMode = 5976,
+ Zo_LegrandMode = 5995,
+ Zo_LegrandOpt1 = 6007,
+ Zo_LegrandOpt2 = 6019,
+ Zo_LegrandOpt3 = 6031,
+ Zo_LidlPower = 6043,
+ Zo_LineCurrent = 6053,
+ Zo_LineCurrentPhB = 6065,
+ Zo_LineCurrentPhC = 6080,
+ Zo_LinkKey = 6095,
+ Zo_LocalTemperature = 6103,
+ Zo_LocalTemperatureCalibration = 6120,
+ Zo_LocalTime = 6148,
+ Zo_LocationAge = 6158,
+ Zo_LocationDescription = 6170,
+ Zo_LocationMethod = 6190,
+ Zo_LocationPower = 6205,
+ Zo_LocationType = 6219,
+ Zo_LockAlarmMask = 6232,
+ Zo_LockDefaultConfigurationRegister = 6246,
+ Zo_LockEnableInsideStatusLED = 6279,
+ Zo_LockEnableLocalProgramming = 6305,
+ Zo_LockEnableLogging = 6332,
+ Zo_LockEnableOneTouchLocking = 6350,
+ Zo_LockEnablePrivacyModeButton = 6376,
+ Zo_LockKeypadOperationEventMask = 6404,
+ Zo_LockKeypadProgrammingEventMask = 6433,
+ Zo_LockLEDSettings = 6464,
+ Zo_LockLanguage = 6480,
+ Zo_LockManualOperationEventMask = 6493,
+ Zo_LockOperatingMode = 6522,
+ Zo_LockRFIDOperationEventMask = 6540,
+ Zo_LockRFIDProgrammingEventMask = 6567,
+ Zo_LockRFOperationEventMask = 6596,
+ Zo_LockRFProgrammingEventMask = 6621,
+ Zo_LockSoundVolume = 6648,
+ Zo_LockState = 6664,
+ Zo_LockSupportedOperatingModes = 6674,
+ Zo_LockType = 6702,
+ Zo_LongPollInterval = 6711,
+ Zo_LongPollIntervalMin = 6728,
+ Zo_LowTempDwellTripPoint = 6748,
+ Zo_LowTempThreshold = 6770,
+ Zo_MainsAlarmMask = 6787,
+ Zo_MainsFrequency = 6802,
+ Zo_MainsVoltage = 6817,
+ Zo_MainsVoltageDwellTripPoint = 6830,
+ Zo_MainsVoltageMaxThreshold = 6857,
+ Zo_MainsVoltageMinThreshold = 6882,
+ Zo_Manufacturer = 6907,
+ Zo_MaxCoolSetpointLimit = 6920,
+ Zo_MaxHeatSetpointLimit = 6941,
+ Zo_MaxPINCodeLength = 6962,
+ Zo_MaxProxyTableEntries = 6979,
+ Zo_MaxRFIDCodeLength = 7000,
+ Zo_MaxSearchCounter = 7018,
+ Zo_MaxSinkTableEntries = 7035,
+ Zo_MaxTempExperienced = 7055,
+ Zo_Measured11thHarmonicCurrent = 7074,
+ Zo_Measured1stHarmonicCurrent = 7102,
+ Zo_Measured3rdHarmonicCurrent = 7129,
+ Zo_Measured5thHarmonicCurrent = 7156,
+ Zo_Measured7thHarmonicCurrent = 7183,
+ Zo_Measured9thHarmonicCurrent = 7210,
+ Zo_MeasuredPhase11thHarmonicCurrent = 7237,
+ Zo_MeasuredPhase1stHarmonicCurrent = 7270,
+ Zo_MeasuredPhase3rdHarmonicCurrent = 7302,
+ Zo_MeasuredPhase5thHarmonicCurrent = 7334,
+ Zo_MeasuredPhase7thHarmonicCurrent = 7366,
+ Zo_MeasuredPhase9thHarmonicCurrent = 7398,
+ Zo_MeterTypeID = 7430,
+ Zo_MinCoolSetpointLimit = 7442,
+ Zo_MinHeatSetpointLimit = 7463,
+ Zo_MinPINCodeLength = 7484,
+ Zo_MinRFIDCodeLength = 7501,
+ Zo_MinSetpointDeadBand = 7519,
+ Zo_MinTempExperienced = 7539,
+ Zo_Mode = 7558,
+ Zo_Model = 7563,
+ Zo_ModelId = 7569,
+ Zo_MotorStepSize = 7577,
+ Zo_Movement = 7591,
+ Zo_MullerLightMode = 7600,
+ Zo_MultiApplicationType = 7616,
+ Zo_MultiDescription = 7637,
+ Zo_MultiInApplicationType = 7654,
+ Zo_MultiInDescription = 7677,
+ Zo_MultiInNumberOfStates = 7696,
+ Zo_MultiInOutOfService = 7718,
+ Zo_MultiInReliability = 7738,
+ Zo_MultiInStatusFlags = 7757,
+ Zo_MultiInValue = 7776,
+ Zo_MultiNumberOfStates = 7789,
+ Zo_MultiOutApplicationType = 7809,
+ Zo_MultiOutDescription = 7833,
+ Zo_MultiOutNumberOfStates = 7853,
+ Zo_MultiOutOfService = 7876,
+ Zo_MultiOutOutOfService = 7894,
+ Zo_MultiOutReliability = 7915,
+ Zo_MultiOutRelinquishDefault = 7935,
+ Zo_MultiOutStatusFlags = 7961,
+ Zo_MultiOutValue = 7981,
+ Zo_MultiReliability = 7995,
+ Zo_MultiRelinquishDefault = 8012,
+ Zo_MultiStatusFlags = 8035,
+ Zo_MultiValue = 8052,
+ Zo_MultipleScheduling = 8063,
+ Zo_NeutralCurrent = 8082,
+ Zo_NotificationRetryNumber = 8097,
+ Zo_NotificationRetryTimer = 8121,
+ Zo_NumberOfDevices = 8144,
+ Zo_NumberOfHolidaySchedulesSupported = 8160,
+ Zo_NumberOfLogRecordsSupported = 8194,
+ Zo_NumberOfPINUsersSupported = 8222,
+ Zo_NumberOfPrimaries = 8248,
+ Zo_NumberOfRFIDUsersSupported = 8266,
+ Zo_NumberOfResets = 8293,
+ Zo_NumberOfTotalUsersSupported = 8308,
+ Zo_NumberOfWeekDaySchedulesSupportedPerUser = 8336,
+ Zo_NumberOfYearDaySchedulesSupportedPerUser = 8377,
+ Zo_NumberOfZoneSensitivityLevelsSupported = 8418,
+ Zo_NumberRSSIMeasurements = 8457,
+ Zo_NumberofActuationsLift = 8480,
+ Zo_NumberofActuationsTilt = 8503,
+ Zo_Occupancy = 8526,
+ Zo_OccupancySensorType = 8536,
+ Zo_OccupiedCoolingSetpoint = 8556,
+ Zo_OccupiedHeatingSetpoint = 8580,
+ Zo_OffTransitionTime = 8604,
+ Zo_OffWaitTime = 8622,
+ Zo_OnLevel = 8634,
+ Zo_OnOff = 8642,
+ Zo_OnOffTransitionTime = 8648,
+ Zo_OnTime = 8668,
+ Zo_OnTransitionTime = 8675,
+ Zo_OpenPeriod = 8692,
+ Zo_OppleMode = 8703,
+ Zo_OutdoorTemperature = 8713,
+ Zo_OverTempTotalDwell = 8732,
+ Zo_PICoolingDemand = 8751,
+ Zo_PIHeatingDemand = 8767,
+ Zo_PIROccupiedToUnoccupiedDelay = 8783,
+ Zo_PIRUnoccupiedToOccupiedDelay = 8812,
+ Zo_PIRUnoccupiedToOccupiedThreshold = 8841,
+ Zo_POD = 8874,
+ Zo_Panic = 8878,
+ Zo_PartNumber = 8884,
+ Zo_PathLossExponent = 8895,
+ Zo_PersistentMemoryWrites = 8912,
+ Zo_PersonalAlarm = 8935,
+ Zo_PhaseHarmonicCurrentMultiplier = 8949,
+ Zo_PhysicalClosedLimit = 8980,
+ Zo_PhysicalClosedLimitLift = 9000,
+ Zo_PhysicalClosedLimitTilt = 9024,
+ Zo_PhysicalEnvironment = 9048,
+ Zo_Power = 9068,
+ Zo_PowerDivisor = 9074,
+ Zo_PowerFactor = 9087,
+ Zo_PowerFactorPhB = 9099,
+ Zo_PowerFactorPhC = 9114,
+ Zo_PowerMultiplier = 9129,
+ Zo_PowerOffEffect = 9145,
+ Zo_PowerOnRecall = 9160,
+ Zo_PowerOnTimer = 9174,
+ Zo_PowerSource = 9187,
+ Zo_PowerThreshold = 9199,
+ Zo_Pressure = 9214,
+ Zo_PressureMaxMeasuredValue = 9223,
+ Zo_PressureMaxScaledValue = 9248,
+ Zo_PressureMinMeasuredValue = 9271,
+ Zo_PressureMinScaledValue = 9296,
+ Zo_PressureScale = 9319,
+ Zo_PressureScaledTolerance = 9333,
+ Zo_PressureScaledValue = 9357,
+ Zo_PressureTolerance = 9377,
+ Zo_Primary1Intensity = 9395,
+ Zo_Primary1X = 9413,
+ Zo_Primary1Y = 9423,
+ Zo_Primary2Intensity = 9433,
+ Zo_Primary2X = 9451,
+ Zo_Primary2Y = 9461,
+ Zo_Primary3Intensity = 9471,
+ Zo_Primary3X = 9489,
+ Zo_Primary3Y = 9499,
+ Zo_Primary4Intensity = 9509,
+ Zo_Primary4X = 9527,
+ Zo_Primary4Y = 9537,
+ Zo_Primary5Intensity = 9547,
+ Zo_Primary5X = 9565,
+ Zo_Primary5Y = 9575,
+ Zo_Primary6Intensity = 9585,
+ Zo_Primary6X = 9603,
+ Zo_Primary6Y = 9613,
+ Zo_ProductCode = 9623,
+ Zo_ProductRevision = 9635,
+ Zo_ProductURL = 9651,
+ Zo_ProxyTable = 9662,
+ Zo_QualityMeasure = 9673,
+ Zo_RGB = 9688,
+ Zo_RHDehumidificationSetpoint = 9692,
+ Zo_RMSCurrent = 9719,
+ Zo_RMSCurrentMax = 9730,
+ Zo_RMSCurrentMaxPhB = 9744,
+ Zo_RMSCurrentMaxPhC = 9761,
+ Zo_RMSCurrentMin = 9778,
+ Zo_RMSCurrentMinPhB = 9792,
+ Zo_RMSCurrentMinPhC = 9809,
+ Zo_RMSCurrentPhB = 9826,
+ Zo_RMSCurrentPhC = 9840,
+ Zo_RMSExtremeOverVoltage = 9854,
+ Zo_RMSExtremeOverVoltagePeriod = 9876,
+ Zo_RMSExtremeOverVoltagePeriodPhB = 9904,
+ Zo_RMSExtremeOverVoltagePeriodPhC = 9935,
+ Zo_RMSExtremeUnderVoltage = 9966,
+ Zo_RMSExtremeUnderVoltagePeriod = 9989,
+ Zo_RMSExtremeUnderVoltagePeriodPhB = 10018,
+ Zo_RMSExtremeUnderVoltagePeriodPhC = 10050,
+ Zo_RMSVoltage = 10082,
+ Zo_RMSVoltageMax = 10093,
+ Zo_RMSVoltageMaxPhB = 10107,
+ Zo_RMSVoltageMaxPhC = 10124,
+ Zo_RMSVoltageMin = 10141,
+ Zo_RMSVoltageMinPhB = 10155,
+ Zo_RMSVoltageMinPhC = 10172,
+ Zo_RMSVoltagePhB = 10189,
+ Zo_RMSVoltagePhC = 10203,
+ Zo_RMSVoltageSag = 10217,
+ Zo_RMSVoltageSagPeriod = 10231,
+ Zo_RMSVoltageSagPeriodPhB = 10251,
+ Zo_RMSVoltageSagPeriodPhC = 10274,
+ Zo_RMSVoltageSwell = 10297,
+ Zo_RMSVoltageSwellPeriod = 10313,
+ Zo_RMSVoltageSwellPeriodPhB = 10335,
+ Zo_RMSVoltageSwellPeriodPhC = 10360,
+ Zo_ReactiveCurrent = 10385,
+ Zo_ReactiveCurrentPhB = 10401,
+ Zo_ReactiveCurrentPhC = 10420,
+ Zo_ReactivePower = 10439,
+ Zo_ReactivePowerPhB = 10453,
+ Zo_ReactivePowerPhC = 10470,
+ Zo_RecallScene = 10487,
+ Zo_RelativeHumidity = 10499,
+ Zo_RelativeHumidityDisplay = 10516,
+ Zo_RelativeHumidityMode = 10540,
+ Zo_RemainingTime = 10561,
+ Zo_RemoteSensing = 10575,
+ Zo_RemoveAllGroups = 10589,
+ Zo_RemoveAllScenes = 10605,
+ Zo_RemoveGroup = 10621,
+ Zo_RemoveScene = 10633,
+ Zo_ReportingPeriod = 10645,
+ Zo_ResetAlarm = 10661,
+ Zo_ResetAllAlarms = 10672,
+ Zo_SWBuildID = 10687,
+ Zo_Sat = 10697,
+ Zo_SatMove = 10701,
+ Zo_SatStep = 10709,
+ Zo_SceneCount = 10717,
+ Zo_SceneNameSupport = 10728,
+ Zo_SceneValid = 10745,
+ Zo_ScheduleMode = 10756,
+ Zo_SeaPressure = 10769,
+ Zo_SecurityLevel = 10781,
+ Zo_ServerActiveFunctionality = 10795,
+ Zo_ServerFunctionality = 10821,
+ Zo_SharedSecurityKey = 10841,
+ Zo_SharedSecurityKeyType = 10859,
+ Zo_ShortPollInterval = 10881,
+ Zo_Shutter = 10899,
+ Zo_ShutterClose = 10907,
+ Zo_ShutterLift = 10920,
+ Zo_ShutterOpen = 10932,
+ Zo_ShutterStop = 10944,
+ Zo_ShutterTilt = 10956,
+ Zo_SinkTable = 10968,
+ Zo_SoftwareRevision = 10978,
+ Zo_StackVersion = 10995,
+ Zo_StandardTime = 11008,
+ Zo_StartUpOnOff = 11021,
+ Zo_Status = 11034,
+ Zo_StoreScene = 11041,
+ Zo_SwitchActions = 11052,
+ Zo_SwitchType = 11066,
+ Zo_SystemMode = 11077,
+ Zo_TRVBoost = 11088,
+ Zo_TRVChildProtection = 11097,
+ Zo_TRVMirrorDisplay = 11116,
+ Zo_TRVMode = 11133,
+ Zo_TRVWindowOpen = 11141,
+ Zo_TempTarget = 11155,
+ Zo_Temperature = 11166,
+ Zo_TemperatureDisplayMode = 11178,
+ Zo_TemperatureMaxMeasuredValue = 11201,
+ Zo_TemperatureMinMeasuredValue = 11229,
+ Zo_TemperatureTolerance = 11257,
+ Zo_TerncyDuration = 11278,
+ Zo_TerncyRotate = 11293,
+ Zo_ThSetpoint = 11306,
+ Zo_ThermostatAlarmMask = 11317,
+ Zo_ThermostatKeypadLockout = 11337,
+ Zo_ThermostatOccupancy = 11361,
+ Zo_ThermostatRunningMode = 11381,
+ Zo_ThermostatScheduleProgrammingVisibility = 11403,
+ Zo_Time = 11443,
+ Zo_TimeEpoch = 11448,
+ Zo_TimeStatus = 11458,
+ Zo_TimeZone = 11469,
+ Zo_TotalActivePower = 11478,
+ Zo_TotalApparentPower = 11495,
+ Zo_TotalProfileNum = 11514,
+ Zo_TotalReactivePower = 11530,
+ Zo_TuyaCalibration = 11549,
+ Zo_TuyaCalibrationTime = 11565,
+ Zo_TuyaMCUVersion = 11585,
+ Zo_TuyaMotorReversal = 11600,
+ Zo_TuyaMovingState = 11618,
+ Zo_TuyaQuery = 11634,
+ Zo_UnoccupiedCoolingSetpoint = 11644,
+ Zo_UnoccupiedHeatingSetpoint = 11670,
+ Zo_UtilityName = 11696,
+ Zo_ValidUntilTime = 11708,
+ Zo_ValvePosition = 11723,
+ Zo_VelocityLift = 11737,
+ Zo_ViewGroup = 11750,
+ Zo_ViewScene = 11760,
+ Zo_Water = 11770,
+ Zo_WhitePointX = 11776,
+ Zo_WhitePointY = 11788,
+ Zo_WindowCoveringType = 11800,
+ Zo_X = 11819,
+ Zo_Y = 11821,
+ Zo_ZCLVersion = 11823,
+ Zo_ZoneID = 11834,
+ Zo_ZoneState = 11841,
+ Zo_ZoneStatus = 11851,
+ Zo_ZoneStatusChange = 11862,
+ Zo_ZoneType = 11879,
+ Zo__ = 11888,
+ Zo_xx = 11890,
+ Zo_xx000A00 = 11893,
+ Zo_xx0A = 11902,
+ Zo_xx0A00 = 11907,
+ Zo_xx19 = 11914,
+ Zo_xx190A = 11919,
+ Zo_xx190A00 = 11926,
+ Zo_xxxx = 11935,
+ Zo_xxxx00 = 11940,
+ Zo_xxxx0A00 = 11947,
+ Zo_xxxxyy = 11956,
+ Zo_xxxxyyyy = 11963,
+ Zo_xxxxyyyy0A00 = 11972,
+ Zo_xxxxyyzz = 11985,
+ Zo_xxyy = 11994,
+ Zo_xxyy0A00 = 11999,
+ Zo_xxyyyy = 12008,
+ Zo_xxyyyy000000000000 = 12015,
+ Zo_xxyyyy0A0000000000 = 12034,
+ Zo_xxyyyyzz = 12053,
+ Zo_xxyyyyzzzz = 12062,
+ Zo_xxyyzzzz = 12073,
};
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 bae1ad62e..7d9daf00c 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
@@ -187,8 +187,8 @@ const uint8_t Z_EXPORT_DATA = 0x80;
enum Cx_cluster_short {
Cx0000, Cx0001, Cx0002, Cx0003, Cx0004, Cx0005, Cx0006, Cx0007,
Cx0008, Cx0009, Cx000A, Cx000B, Cx000C, Cx000D, Cx000E, Cx000F,
- Cx0010, Cx0011, Cx0012, Cx0013, Cx0014, Cx001A, Cx0020, Cx0100,
- Cx0101, Cx0102, Cx0201, Cx0202, Cx0203, Cx0204,
+ Cx0010, Cx0011, Cx0012, Cx0013, Cx0014, Cx001A, Cx0020, Cx0021,
+ Cx0100, Cx0101, Cx0102, Cx0201, Cx0202, Cx0203, Cx0204,
Cx0300, Cx0301, Cx0400, Cx0401, Cx0402, Cx0403,
Cx0404, Cx0405, Cx0406, Cx0500, Cx0702, Cx0B01, Cx0B04, Cx0B05,
CxEF00, CxFC01, CxFC40, CxFCC0, CxFCCC,
@@ -197,8 +197,8 @@ enum Cx_cluster_short {
const uint16_t Cx_cluster[] PROGMEM = {
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x001A, 0x0020, 0x0100,
- 0x0101, 0x0102, 0x0201, 0x0202, 0x0203, 0x0204,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x001A, 0x0020, 0x0021,
+ 0x0100, 0x0101, 0x0102, 0x0201, 0x0202, 0x0203, 0x0204,
0x0300, 0x0301, 0x0400, 0x0401, 0x0402, 0x0403,
0x0404, 0x0405, 0x0406, 0x0500, 0x0702, 0x0B01, 0x0B04, 0x0B05,
0xEF00, 0xFC01, 0xFC40, 0xFCC0, 0xFCCC,
@@ -746,6 +746,27 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
{ Zuint32, Cx0020, 0x0005, Z_(LongPollIntervalMin), Cm1, 0 },
{ Zuint16, Cx0020, 0x0006, Z_(FastPollTimeoutMax), Cm1, 0 },
+ // Green Power
+ { Zuint8, Cx0021, 0x0000, Z_(MaxSinkTableEntries), Cm1, 0 },
+ { Zoctstr16,Cx0021, 0x0001, Z_(SinkTable), Cm1, 0 },
+ { Zmap8, Cx0021, 0x0002, Z_(CommunicationMode), Cm1, 0 },
+ { Zmap8, Cx0021, 0x0003, Z_(CcommissioningExitMode),Cm1, 0 },
+ { Zuint16, Cx0021, 0x0004, Z_(CommissioningWindow), Cm1, 0 },
+ { Zmap8, Cx0021, 0x0005, Z_(SecurityLevel), Cm1, 0 },
+ { Zmap24, Cx0021, 0x0006, Z_(ServerFunctionality), Cm1, 0 },
+ { Zmap24, Cx0021, 0x0007, Z_(ServerActiveFunctionality), Cm1, 0 },
+ { Zuint8, Cx0021, 0x0010, Z_(MaxProxyTableEntries), Cm1, 0 },
+ { Zoctstr16,Cx0021, 0x0011, Z_(ProxyTable), Cm1, 0 },
+ { Zuint8, Cx0021, 0x0012, Z_(NotificationRetryNumber),Cm1, 0 },
+ { Zuint8, Cx0021, 0x0013, Z_(NotificationRetryTimer),Cm1, 0 },
+ { Zuint8, Cx0021, 0x0014, Z_(MaxSearchCounter), Cm1, 0 },
+ { Zoctstr16,Cx0021, 0x0015, Z_(BlockedGPDID), Cm1, 0 },
+ { Zmap24, Cx0021, 0x0016, Z_(ClientFunctionality), Cm1, 0 },
+ { Zmap24, Cx0021, 0x0017, Z_(ClientActiveFunctionality), Cm1, 0 },
+ { Zmap8, Cx0021, 0x0020, Z_(SharedSecurityKeyType),Cm1, 0 },
+ { Zkey128, Cx0021, 0x0021, Z_(SharedSecurityKey), Cm1, 0 },
+ { Zkey128, Cx0021, 0x0022, Z_(LinkKey), Cm1, 0 },
+
// Shade Configuration cluster
{ Zuint16, Cx0100, 0x0000, Z_(PhysicalClosedLimit), Cm1, 0 },
{ Zuint8, Cx0100, 0x0001, Z_(MotorStepSize), 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 065c847fd..4bcef8961 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
@@ -108,7 +108,7 @@ public:
manuf(manuf_code), transactseq(transact_seq), cmd(cmd_id),
payload(buf_len ? buf_len : 250), // allocate the data frame from source or preallocate big enough
cluster(clusterid), groupaddr(groupaddr),
- shortaddr(srcaddr), _srcendpoint(srcendpoint), dstendpoint(dstendpoint), _wasbroadcast(wasbroadcast),
+ shortaddr(srcaddr), srcendpoint(srcendpoint), dstendpoint(dstendpoint), _wasbroadcast(wasbroadcast),
_linkquality(linkquality), _securityuse(securityuse), _seqnumber(seqnumber)
{
_frame_control.d8 = frame_control;
@@ -128,7 +128,7 @@ public:
"\"manuf\":\"0x%04X\",\"transact\":%d,"
"\"cmdid\":\"0x%02X\",\"payload\":\"%_B\"}}"),
groupaddr, cluster, shortaddr,
- _srcendpoint, dstendpoint, _wasbroadcast,
+ srcendpoint, dstendpoint, _wasbroadcast,
_linkquality, _securityuse, _seqnumber,
_frame_control,
_frame_control.b.frame_type, _frame_control.b.direction, _frame_control.b.disable_def_resp,
@@ -207,7 +207,7 @@ public:
inline uint16_t getClusterId(void) const { return cluster; }
inline uint8_t getLinkQuality(void) const { return _linkquality; }
inline uint8_t getCmdId(void) const { return cmd; }
- inline uint16_t getSrcEndpoint(void) const { return _srcendpoint; }
+ inline uint16_t getSrcEndpoint(void) const { return srcendpoint; }
const SBuffer &getPayload(void) const { return payload; }
uint16_t getManufCode(void) const { return manuf; }
@@ -234,9 +234,11 @@ public:
bool direct = false; // true if direct, false if discover router
bool transacSet = false; // is transac already set
+ uint8_t srcendpoint = 0x00; // 0x00 is invalid for the src endpoint
+ bool direction = false; // false = client to server (default), true = server to client (rare)
+
// below private attributes are not used when sending a message
private:
- uint8_t _srcendpoint = 0x00; // 0x00 is invalid for the src endpoint
ZCLHeaderFrameControl_t _frame_control = { .d8 = 0 };
bool _wasbroadcast = false;
uint8_t _linkquality = 0x00;
@@ -531,6 +533,16 @@ uint32_t parseSingleAttribute(Z_attribute & attr, const SBuffer &buf,
attr.setUInt(uint16_val);
}
break;
+ case Zdata24: // data16
+ case Zmap24: // map16
+ {
+ uint32_t uint32_val = buf.get16(i);
+ uint8_t high = buf.get8(i+2);
+ uint32_val = uint32_val | (high << 16);
+ // i += 3;
+ attr.setUInt(uint32_val);
+ }
+ break;
case Zdata32: // data32
case Zmap32: // map32
{
@@ -549,7 +561,7 @@ uint32_t parseSingleAttribute(Z_attribute & attr, const SBuffer &buf,
}
break;
- // TODO
+ // All other fixed size, convert to a HEX dump
case ZToD: // ToD
case Zdate: // date
case ZclusterId: // clusterId
@@ -558,17 +570,19 @@ uint32_t parseSingleAttribute(Z_attribute & attr, const SBuffer &buf,
case ZEUI64: // EUI64
case Zkey128: // key128
case Zsemi: // semi (float on 2 bytes)
+ {
+ attr.setBuf(buf, i, len);
+ }
+ // i += 16;
break;
// Other un-implemented data types
- case Zdata24: // data24
case Zdata40: // data40
case Zdata48: // data48
case Zdata56: // data56
case Zdata64: // data64
break;
// map
- case Zmap24: // map24
case Zmap40: // map40
case Zmap48: // map48
case Zmap56: // map56
@@ -621,7 +635,7 @@ void ZCLFrame::parseReportAttributes(Z_attribute_list& attr_list) {
ZCLFrame zcl(2); // message is 2 bytes
zcl.shortaddr = shortaddr;
zcl.cluster = cluster;
- zcl.dstendpoint = _srcendpoint;
+ zcl.dstendpoint = srcendpoint;
zcl.cmd = ZCL_DEFAULT_RESPONSE;
zcl.manuf = manuf;
zcl.clusterSpecific = false; /* not cluster specific */
@@ -768,7 +782,7 @@ void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) {
if (attr_rgb == nullptr) { // make sure we didn't already computed it
uint8_t brightness = 255;
if (device.valid()) {
- const Z_Data_Light & light = device.data.find(_srcendpoint);
+ const Z_Data_Light & light = device.data.find(srcendpoint);
if ((&light != &z_data_unk) && (light.validDimmer())) {
// Dimmer has a valid value
brightness = changeUIntScale(light.getDimmer(), 0, 254, 0, 255); // range is 0..255
@@ -798,7 +812,7 @@ void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) {
}
break;
case 0x05000002: // ZoneStatus
- const Z_Data_Alarm & alarm = (const Z_Data_Alarm&) zigbee_devices.getShortAddr(shortaddr).data.find(Z_Data_Type::Z_Alarm, _srcendpoint);
+ const Z_Data_Alarm & alarm = (const Z_Data_Alarm&) zigbee_devices.getShortAddr(shortaddr).data.find(Z_Data_Type::Z_Alarm, srcendpoint);
if (&alarm != nullptr) {
alarm.convertZoneStatus(attr_list, attr.getUInt());
}
@@ -821,12 +835,12 @@ void ZCLFrame::generateCallBacks(Z_attribute_list& attr_list) {
uint32_t occupancy = attr.getUInt();
if (occupancy) {
uint32_t pir_timer = OCCUPANCY_TIMEOUT;
- const Z_Data_PIR & pir_found = (const Z_Data_PIR&) zigbee_devices.getShortAddr(shortaddr).data.find(Z_Data_Type::Z_PIR, _srcendpoint);
+ const Z_Data_PIR & pir_found = (const Z_Data_PIR&) zigbee_devices.getShortAddr(shortaddr).data.find(Z_Data_Type::Z_PIR, srcendpoint);
if (&pir_found != nullptr) {
pir_timer = pir_found.getTimeoutSeconds() * 1000;
}
if (pir_timer > 0) {
- zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, pir_timer, cluster, _srcendpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback);
+ zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, pir_timer, cluster, srcendpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback);
}
} else {
zigbee_devices.resetTimersForDevice(shortaddr, 0 /* groupaddr */, Z_CAT_VIRTUAL_OCCUPANCY);
@@ -1049,7 +1063,7 @@ void ZCLFrame::parseResponse_inner(uint8_t cmd, bool cluster_specific, uint8_t s
// "StatusMessage"
attr_list.addAttributePMEM(PSTR(D_JSON_ZIGBEE_STATUS_MSG)).setStr(getZigbeeStatusMessage(status).c_str());
// Add Endpoint
- attr_list.addAttributePMEM(PSTR(D_CMND_ZIGBEE_ENDPOINT)).setUInt(_srcendpoint);
+ attr_list.addAttributePMEM(PSTR(D_CMND_ZIGBEE_ENDPOINT)).setUInt(srcendpoint);
// Add Group if non-zero
if (groupaddr) { // TODO what about group zero
attr_list.group_id = groupaddr;
@@ -1082,16 +1096,16 @@ void Z_ResetDebounce(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, u
void ZCLFrame::parseClusterSpecificCommand(Z_attribute_list& attr_list) {
// Check if debounce is active and if the packet is a duplicate
Z_Device & device = zigbee_devices.getShortAddr(shortaddr);
- if ((device.debounce_endpoint != 0) && (device.debounce_endpoint == _srcendpoint) && (device.debounce_transact == transactseq)) {
+ if ((device.debounce_endpoint != 0) && (device.debounce_endpoint == srcendpoint) && (device.debounce_transact == transactseq)) {
// this is a duplicate, drop the packet
- AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Discarding duplicate command from 0x%04X, endpoint %d"), shortaddr, _srcendpoint);
+ AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Discarding duplicate command from 0x%04X, endpoint %d"), shortaddr, srcendpoint);
} else {
// reset the duplicate marker, parse the packet normally, and set a timer to reset the marker later (which will discard any existing timer for the same device/endpoint)
- device.debounce_endpoint = _srcendpoint;
+ device.debounce_endpoint = srcendpoint;
device.debounce_transact = transactseq;
- zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, USE_ZIGBEE_DEBOUNCE_COMMANDS, 0 /*clusterid*/, _srcendpoint, Z_CAT_DEBOUNCE_CMD, 0, &Z_ResetDebounce);
+ zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, USE_ZIGBEE_DEBOUNCE_COMMANDS, 0 /*clusterid*/, srcendpoint, Z_CAT_DEBOUNCE_CMD, 0, &Z_ResetDebounce);
- convertClusterSpecific(attr_list, cluster, cmd, _frame_control.b.direction, shortaddr, _srcendpoint, payload);
+ convertClusterSpecific(attr_list, cluster, cmd, _frame_control.b.direction, shortaddr, srcendpoint, payload);
if (!Settings->flag5.zb_disable_autoquery) {
// read attributes unless disabled
if (!_frame_control.b.direction) { // only handle server->client (i.e. device->coordinator)
@@ -1107,7 +1121,7 @@ void ZCLFrame::parseClusterSpecificCommand(Z_attribute_list& attr_list) {
ZCLFrame zcl(2); // message is 4 bytes
zcl.shortaddr = shortaddr;
zcl.cluster = cluster;
- zcl.dstendpoint = _srcendpoint;
+ zcl.dstendpoint = srcendpoint;
zcl.cmd = ZCL_DEFAULT_RESPONSE;
zcl.manuf = manuf;
zcl.clusterSpecific = false; /* not cluster specific */
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_0_statemachine.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_0_statemachine.ino
index eb7e2074a..34e97ec14 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_0_statemachine.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_0_statemachine.ino
@@ -315,16 +315,22 @@ ZBM(ZBR_ZDO_ACTIVEEPREQ, Z_SRSP | Z_ZDO, ZDO_ACTIVE_EP_REQ, Z_SUCCESS) // 65050
// Change #14819 - we now allow some EP to be alreaady declared
ZBM(ZBR_ZDO_ACTIVEEPRSP_SUCESS, Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP, 0x00, 0x00 /* srcAddr */, Z_SUCCESS) // 45050000xxxx - no Ep running
ZBM(ZBR_ZDO_ACTIVEEPRSP_OK, Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP, 0x00, 0x00 /* srcAddr */, Z_SUCCESS,
- 0x00, 0x00 /* nwkaddr */, 0x02 /* activeepcount */, 0x0B, 0x01 /* the actual endpoints */) // 25050000 - no Ep running
+ 0x00, 0x00 /* nwkaddr */, 0x03 /* activeepcount */, 0xF2, 0x0B, 0x01 /* the actual endpoints */) // 4585000000000003F20B01
// Z_AF:register profile:104, ep:01
ZBM(ZBS_AF_REGISTER01, Z_SREQ | Z_AF, AF_REGISTER, 0x01 /* endpoint */, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), // 24000401050000000000
0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, 0x00 /* LatencyReq */,
- 0x00 /* AppNumInClusters */, 0x00 /* AppNumInClusters */)
+ 0x00 /* AppNumInClusters */, 0x00 /* AppNumOutClusters */)
ZBM(ZBR_AF_REGISTER, Z_SRSP | Z_AF, AF_REGISTER, Z_SUCCESS) // 640000
ZBM(ZBS_AF_REGISTER0B, Z_SREQ | Z_AF, AF_REGISTER, 0x0B /* endpoint */, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), // 2400040B050000000000
0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, 0x00 /* LatencyReq */,
- 0x00 /* AppNumInClusters */, 0x00 /* AppNumInClusters */)
+ 0x00 /* AppNumInClusters */, 0x00 /* AppNumOutClusters */)
+// Green Power endpoint 242 0xF2
+ZBM(ZBS_AF_REGISTERF2, Z_SREQ | Z_AF, AF_REGISTER, 0xF2 /* endpoint */, Z_B0(Z_PROF_GP), Z_B1(Z_PROF_GP), //
+ 0x05, 0x61 /* AppDeviceId */, 0x00 /* AppDevVer */, 0x00 /* LatencyReq */,
+ 0x00 /* AppNumInClusters */,
+ 0x01 /* AppNumOutClusters */,
+ 0x21,0x00) // 0x0021
// Z_AF:register profile:104, ep:01 - main clusters for router or device
ZBM(ZBS_AF_REGISTER_ALL, Z_SREQ | Z_AF, AF_REGISTER, 0x01 /* endpoint */, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), // 24000401050000000000
0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, 0x00 /* LatencyReq */,
@@ -333,7 +339,7 @@ ZBM(ZBS_AF_REGISTER_ALL, Z_SREQ | Z_AF, AF_REGISTER, 0x01 /* endpoint */, Z_B0(Z
0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102
0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403
0x05,0x04, 0x06,0x04, // 0x0405, 0x0406
- 0x00 /* AppNumInClusters */)
+ 0x00 /* AppNumOutClusters */)
// Z_ZDO:mgmtPermitJoinReq
ZBM(ZBS_PERMITJOINREQ_CLOSE, Z_SREQ | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_REQ, 0x02 /* AddrMode */, // 25360200000000
@@ -506,6 +512,8 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
ZI_WAIT_RECV(1000, ZBR_AF_REGISTER)
ZI_SEND(ZBS_AF_REGISTER0B) // Z_AF register for endpoint 0B, profile 0x0104 Home Automation
ZI_WAIT_RECV(1000, ZBR_AF_REGISTER)
+ ZI_SEND(ZBS_AF_REGISTERF2) // Z_AF register for endpoint F2, profile 0xa1e0 Green Power
+ ZI_WAIT_RECV(1000, ZBR_AF_REGISTER)
// Write again channels, see https://github.com/Koenkk/zigbee-herdsman/blob/37bea20ba04ee5d4938abc21a7569b43f831de32/src/adapter/z-stack/adapter/startZnp.ts#L244-L245
ZI_SEND(ZBS_W_CHANN) // write CHANNEL
ZI_WAIT_RECV(1000, ZBR_WNV_OK)
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 4edf32a09..4e82814ba 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
@@ -2232,7 +2232,7 @@ void ZCLFrame::autoResponder(const uint16_t *attr_list_ids, size_t attr_len) {
",\"Endpoint\":%d"
",\"Response\":%s}"
),
- shortaddr, cluster, _srcendpoint,
+ shortaddr, cluster, srcendpoint,
attr_list.toString().c_str());
// send
@@ -2240,7 +2240,7 @@ void ZCLFrame::autoResponder(const uint16_t *attr_list_ids, size_t attr_len) {
ZCLFrame zcl(buf.len()); // message is 4 bytes
zcl.shortaddr = shortaddr;
zcl.cluster = cluster;
- zcl.dstendpoint = _srcendpoint;
+ zcl.dstendpoint = srcendpoint;
zcl.cmd = ZCL_READ_ATTRIBUTES_RESPONSE;
zcl.clusterSpecific = false; /* not cluster specific */
zcl.needResponse = false; /* noresponse */
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_9_serial.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_9_serial.ino
index c532e2363..05a049c8c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_9_serial.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_9_serial.ino
@@ -775,14 +775,19 @@ void ZigbeeZCLSend_Raw(const ZCLFrame &zcl) {
buf.add8(zcl.dstendpoint); // dest endpoint
}
buf.add16(0x0000); // dest Pan ID, 0x0000 = intra-pan
- buf.add8(0x01); // source endpoint
+ if (zcl.srcendpoint) {
+ buf.add8(zcl.srcendpoint); // source endpoint
+ } else {
+ buf.add8(1); // set endpoint to 1 if not specified
+ }
buf.add16(zcl.cluster);
buf.add8(zcl.transactseq); // transactseq
- buf.add8(0x30); // 30 options
+ buf.add8(zcl.direct ? 0x00 : 0x30); // 30 options
buf.add8(0x1E); // 1E radius
buf.add16(3 + zcl.payload.len() + (zcl.manuf ? 2 : 0));
- buf.add8((zcl.needResponse ? 0x00 : 0x10) | (zcl.clusterSpecific ? 0x01 : 0x00) | (zcl.manuf ? 0x04 : 0x00)); // Frame Control Field
+ buf.add8((zcl.needResponse ? 0x00 : 0x10) | (zcl.clusterSpecific ? 0x01 : 0x00) |
+ (zcl.manuf ? 0x04 : 0x00) | (zcl.direction ? 0x08 : 0x00)); // Frame Control Field
if (zcl.manuf) {
buf.add16(zcl.manuf); // add Manuf Id if not null
}
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 1318d11a3..96f15cdc2 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
@@ -730,8 +730,17 @@ void CmndZbSend(void) {
// parse "Device" and "Group"
JsonParserToken val_device = root[PSTR(D_CMND_ZIGBEE_DEVICE)];
if (val_device) {
- zcl.shortaddr = zigbee_devices.parseDeviceFromName(val_device.getStr()).shortaddr;
- if (!zcl.validShortaddr()) { ResponseCmndChar_P(PSTR(D_ZIGBEE_INVALID_PARAM)); return; }
+ uint16_t parsed_shortaddr = BAD_SHORTADDR;
+ zcl.shortaddr = zigbee_devices.parseDeviceFromName(val_device.getStr(), &parsed_shortaddr).shortaddr;
+ if (!zcl.validShortaddr()) {
+ if (parsed_shortaddr != BAD_SHORTADDR) {
+ // we still got a short address
+ zcl.shortaddr = parsed_shortaddr;
+ } else {
+ ResponseCmndChar_P(PSTR(D_ZIGBEE_INVALID_PARAM));
+ return;
+ }
+ }
}
if (!zcl.validShortaddr()) { // if not found, check if we have a group
JsonParserToken val_group = root[PSTR(D_CMND_ZIGBEE_GROUP)];
@@ -760,6 +769,10 @@ void CmndZbSend(void) {
ResponseCmndChar_P(PSTR("Missing endpoint"));
return;
}
+ // Special case for Green Power, if dstendpoint is 0xF2, then source endpoint should also be 0xF2
+ if (zcl.dstendpoint == 0xF2) {
+ zcl.srcendpoint = 0xF2;
+ }
// from here endpoint is valid and non-zero
// cluster may be already specified or 0xFFFF
@@ -1517,6 +1530,7 @@ void CmndZbPermitJoin(void) {
// ZNP Version
#ifdef USE_ZIGBEE_ZNP
+ // put all routers in pairing mode
SBuffer buf(34);
buf.add8(Z_SREQ | Z_ZDO); // 25
buf.add8(ZDO_MGMT_PERMIT_JOIN_REQ); // 36
@@ -1527,6 +1541,22 @@ void CmndZbPermitJoin(void) {
ZigbeeZNPSend(buf.getBuffer(), buf.len());
+ // send Green Power pairing mode
+ ZCLFrame zcl(4); // message is 4 bytes max
+
+ zcl.cmd = 0x02; // GP Proxy Commissioning Mode
+ zcl.cluster = 0x0021; // GP cluster
+ zcl.shortaddr = 0xFFFC; // Broadcast to all routers
+ zcl.srcendpoint = 0xF2; // GP endpoint
+ zcl.dstendpoint = 0xF2; // GP endpoint
+ zcl.needResponse = false; // as per GP spec The Disable default response sub-field of the Frame Control Field of the ZCL header shall be set to 0b1."
+ zcl.clusterSpecific = true; // command
+ zcl.direct = true; // broadcast so no need to discover routes
+ zcl.direction = true; // server to client
+ zcl.payload.add8(0x0B); // Action=1, gpsCommissioningExitMode=0b101 (window expiration + GP Proxy Commissioning Mode)
+ zcl.payload.add16(duration);
+ zigbeeZCLSendCmd(zcl);
+
#endif // USE_ZIGBEE_ZNP
// EZSP VERSION
From 14642fb2147b17a2382fa15341aff8c7ac7e20e1 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 1 Sep 2022 09:43:20 +0200
Subject: [PATCH 105/366] Update changelogs
---
CHANGELOG.md | 2 +-
RELEASENOTES.md | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cfe3871bb..5afd4066a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file.
- Support for Modbus writing using ModbusBridge by JeroenSt (#16351)
- Support for Ethernet in ESP32 safeboot firmware (#16388)
- Flowrate meter flow amount/duration, show values in table format (#16385)
-- Zigbee prepare for Green Power support
+- Zigbee prepare for Green Power support (#16407)
### Changed
- TasmotaModbus library from v3.5.0 to v3.6.0 (#16351)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index f4912f2dc..c128647a0 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -113,6 +113,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- 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)
- Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` [#16252](https://github.com/arendst/Tasmota/issues/16252)
+- Zigbee prepare for Green Power support [#16407](https://github.com/arendst/Tasmota/issues/16407)
- Flowrate meter flow amount/duration, show values in table format [#16385](https://github.com/arendst/Tasmota/issues/16385)
- Support for Ethernet in ESP32 safeboot firmware [#16388](https://github.com/arendst/Tasmota/issues/16388)
- ESP32-S3 support for internal temperature sensor
From 684584a5e525586a890e192cd11890728a4e8f2b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 2 Sep 2022 11:24:47 +0200
Subject: [PATCH 106/366] Command ``SetOption146 1`` to enable display of ESP32
internal temperature
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/include/tasmota_types.h | 2 +-
.../xsns_127_esp32_sensors.ino | 96 ++++++++++---------
tools/decode-status.py | 5 +-
5 files changed, 58 insertions(+), 47 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5afd4066a..ae972b3c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
- Support for Ethernet in ESP32 safeboot firmware (#16388)
- Flowrate meter flow amount/duration, show values in table format (#16385)
- Zigbee prepare for Green Power support (#16407)
+- Command ``SetOption146 1`` to enable display of ESP32 internal temperature
### Changed
- TasmotaModbus library from v3.5.0 to v3.6.0 (#16351)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index c128647a0..efcc3a1c2 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.1.1.1
### Added
+- Command ``SetOption146 1`` to enable display of ESP32 internal temperature
- Command ``StatusRetain`` [#11109](https://github.com/arendst/Tasmota/issues/11109)
- 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)
diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h
index b6eaad2cc..16a29c6ae 100644
--- a/tasmota/include/tasmota_types.h
+++ b/tasmota/include/tasmota_types.h
@@ -179,7 +179,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
uint32_t data; // Allow bit manipulation using SetOption
struct { // SetOption146 .. SetOption177
- uint32_t spare00 : 1; // bit 0
+ uint32_t use_esp32_temperature : 1; // bit 0 (v12.1.1.1) - SetOption146 - (ESP32) Show ESP32 internal temperature sensor
uint32_t spare01 : 1; // bit 1
uint32_t spare02 : 1; // bit 2
uint32_t spare03 : 1; // bit 3
diff --git a/tasmota/tasmota_xsns_sensor/xsns_127_esp32_sensors.ino b/tasmota/tasmota_xsns_sensor/xsns_127_esp32_sensors.ino
index 93c9b24eb..6da0baaca 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_127_esp32_sensors.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_127_esp32_sensors.ino
@@ -54,63 +54,71 @@ void Esp32SensorInit(void) {
#endif // CONFIG_IDF_TARGET_ESP32
void Esp32SensorShow(bool json) {
- static bool add_global_temp = false;
+ bool json_end = false;
- if (json) {
- add_global_temp = !ResponseContains_P(PSTR(D_JSON_TEMPERATURE));
+ if (Settings->flag6.use_esp32_temperature) { // SetOption146 - (ESP32) Show ESP32 internal temperature sensor
+ float c = CpuTemperature(); // in Celsius
+ float t = ConvertTempToFahrenheit(c);
+
+ if (json) {
+ if (!ResponseContains_P(PSTR(D_JSON_TEMPERATURE))) {
+ UpdateGlobalTemperature(c);
+ }
+ ResponseAppend_P(PSTR(",\"ESP32\":{\"" D_JSON_TEMPERATURE "\":%*_f"), Settings->flag2.temperature_resolution, &t);
+ json_end = true;
+
+#ifdef USE_DOMOTICZ
+// Instead of below code use a rule like 'on tele-esp32#temperature do dzsend1 9988,%value% endon'
+// where 9988 is the domoticz sensor Idx
+// if (0 == TasmotaGlobal.tele_period) {
+// if (!ResponseContains_P(PSTR(D_JSON_TEMPERATURE))) { // Only send if no other sensor already did
+// DomoticzFloatSensor(DZ_TEMP, t);
+// }
+// }
+#endif // USE_DOMOTICZ
+
+#ifdef USE_WEBSERVER
+ } else {
+ WSContentSend_Temp("ESP32", t);
+#endif // USE_WEBSERVER
+ }
}
- float c = CpuTemperature(); // in Celsius
- if (add_global_temp) {
- UpdateGlobalTemperature(c);
- }
- float t = ConvertTempToFahrenheit(c);
#if CONFIG_IDF_TARGET_ESP32
- int value = 0;
if (HEData.present) {
+ int value = 0;
for (uint32_t i = 0; i < HALLEFFECT_SAMPLE_COUNT; i++) {
value += hallRead();
}
value /= HALLEFFECT_SAMPLE_COUNT;
+
+ if (json) {
+ if (!json_end) {
+ ResponseAppend_P(PSTR(",\"ESP32\":{"));
+ } else {
+ ResponseAppend_P(PSTR(","));
+ }
+ ResponseAppend_P(PSTR("\"" D_JSON_HALLEFFECT "\":%d"), value);
+ json_end = true;
+
+#ifdef USE_DOMOTICZ
+// Instead of below code use a rule like 'on tele-esp32#halleffect do dzsend1 9988,%value% endon'
+// where 9988 is the domoticz sensor Idx
+// if (0 == TasmotaGlobal.tele_period) {
+// DomoticzSensor(DZ_COUNT, value);
+// }
+#endif // USE_DOMOTICZ
+
+#ifdef USE_WEBSERVER
+ } else {
+ WSContentSend_P(HTTP_SNS_HALL_EFFECT, "ESP32", value);
+#endif // USE_WEBSERVER
+ }
}
#endif // CONFIG_IDF_TARGET_ESP32
- if (json) {
- bool temperature_present = (ResponseContains_P(PSTR(D_JSON_TEMPERATURE)));
- ResponseAppend_P(PSTR(",\"ESP32\":{\"" D_JSON_TEMPERATURE "\":%*_f"), Settings->flag2.temperature_resolution, &t);
-
-#if CONFIG_IDF_TARGET_ESP32
- if (HEData.present) {
- ResponseAppend_P(PSTR(",\"" D_JSON_HALLEFFECT "\":%d"), value);
- }
-#endif // CONFIG_IDF_TARGET_ESP32
-
+ if (json_end) {
ResponseJsonEnd();
-#ifdef USE_DOMOTICZ
- if (0 == TasmotaGlobal.tele_period) {
- if (!temperature_present) { // Only send if no other sensor already did
- DomoticzFloatSensor(DZ_TEMP, t);
- }
-
-#if CONFIG_IDF_TARGET_ESP32
- if (HEData.present) {
- DomoticzSensor(DZ_COUNT, value);
- }
-#endif // CONFIG_IDF_TARGET_ESP32
-
- }
-#endif // USE_DOMOTICZ
-#ifdef USE_WEBSERVER
- } else {
- WSContentSend_Temp("ESP32", t);
-
-#if CONFIG_IDF_TARGET_ESP32
- if (HEData.present) {
- WSContentSend_P(HTTP_SNS_HALL_EFFECT, "ESP32", value);
- }
-#endif // CONFIG_IDF_TARGET_ESP32
-
-#endif // USE_WEBSERVER
}
}
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 8923981d3..92de04297 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -201,7 +201,8 @@ a_setoption = [[
"(Zigbee) Include time in `ZbReceived` messages like other sensors",
"(MQTT) Retain on Status"
],[
- "","","","",
+ "(ESP32) Show ESP32 internal temperature sensor",
+ "","","",
"","","","",
"","","","",
"","","","",
@@ -319,7 +320,7 @@ else:
obj = json.load(fp)
def StartDecode():
- print ("\n*** decode-status.py v12.1.0.1 by Theo Arends and Jacek Ziolkowski ***")
+ print ("\n*** decode-status.py v12.1.1.1 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj))
From 86e45969bde16bf221f012e1209b57db62ba2c2b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 2 Sep 2022 13:13:47 +0200
Subject: [PATCH 107/366] Support for DFRobot SEN0390 V30B ambient light sensor
Add support for DFRobot SEN0390 V30B ambient light sensor (#16105)
---
BUILDS.md | 329 +++++++++---------
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/include/tasmota_configurations.h | 1 +
.../include/tasmota_configurations_ESP32.h | 2 +
tasmota/my_user_config.h | 1 +
tasmota/tasmota_support/support_features.ino | 4 +-
.../tasmota_xsns_sensor/xsns_99_luxv30b.ino | 212 +++++++++++
tools/decode-status.py | 2 +-
9 files changed, 387 insertions(+), 166 deletions(-)
create mode 100644 tasmota/tasmota_xsns_sensor/xsns_99_luxv30b.ino
diff --git a/BUILDS.md b/BUILDS.md
index 0850b2a2f..579d82d83 100644
--- a/BUILDS.md
+++ b/BUILDS.md
@@ -6,176 +6,177 @@ l = lite, t = tasmota, k = knx, s = sensors, i = ir, d = display
Note: `minimal` variant is not listed as it shouldn't be used outside of the [upgrading](https://tasmota.github.io/docs/Upgrading/) process.
-| Feature or Sensor | l | t | k | s | i | d | Remarks
-|-----------------------|---|-------|---|---|---|---|--------
-| MY_LANGUAGE en_GB | x | x / x | x | x | x | x |
-| USE_IMPROV | x | x / x | x | x | x | x |
-| USE_UFILESYS | - | - / x | - | - | - | - |
-| USE_ARDUINO_OTA | - | - / - | - | - | - | - |
-| USE_DOMOTICZ | - | x / x | x | x | x | - |
-| USE_HOME_ASSISTANT | - | - / - | - | - | - | - |
-| USE_TASMOTA_DISCOVERY | x | x / x | x | x | x | x |
-| USE_MQTT_TLS* | - | - / x | - | - | - | - |
-| USE_MQTT_AWS_IOT | - | - / - | - | - | - | - |
-| USE_4K_RSA | - | - / - | - | - | - | - |
-| USE_TELEGRAM | - | - / - | - | - | - | - |
-| USE_KNX | - | - / x | x | - | - | - |
-| USE_WEBSERVER | x | x / x | x | x | x | x |
-| USE_WEBSEND_RESPONSE | - | - / - | - | - | - | - |
-| USE_EMULATION_HUE | x | x / x | - | x | - | - |
-| USE_EMULATION_WEMO | x | x / x | - | x | - | - |
-| USE_DISCOVERY | - | - / - | - | - | - | - |
-| WEBSERVER_ADVERTISE | - | x / - | x | - | - | x |
-| MQTT_HOST_DISCOVERY | - | - / - | - | - | - | - |
-| USE_TIMERS | x | x / x | x | x | x | x |
-| USE_TIMERS_WEB | x | x / x | x | x | x | x |
-| USE_SUNRISE | x | x / x | x | x | x | x |
-| USE_RULES | x | x / x | x | x | x | x |
-| USE_SCRIPT | - | - / - | - | - | - | - |
-| USE_EXPRESSION | - | - / - | - | - | - | - |
-| SUPPORT_IF_STATEMENT | - | - / - | - | - | - | - |
-| USE_HOTPLUG | - | - / - | - | - | - | - |
-| USE_PROMETHEUS | - | - / - | - | - | - | - |
-| USE_PING | - | - / - | - | - | - | - |
-| | | | | | | |
-| Feature or Sensor | l | t | k | s | i | d | Remarks
-| ROTARY_V1 | - | x / x | - | x | - | - |
-| USE_SONOFF_RF | - | x / - | x | x | - | - |
-| USE_RF_FLASH | - | x / - | x | x | - | - |
-| USE_SONOFF_SC | - | x / - | x | x | - | - |
-| USE_TUYA_MCU | x | x / - | x | x | - | x |
-| USE_ARMTRONIX_DIMMERS | - | x / - | x | - | - | - |
-| USE_PS_16_DZ | - | x / - | x | - | - | - |
-| USE_SONOFF_IFAN | - | x / - | x | - | - | - |
-| USE_BUZZER | - | x / x | x | x | - | - |
-| USE_ARILUX_RF | - | x / - | x | - | - | - |
-| USE_SHUTTER | - | x / x | x | - | - | - |
-| USE_DEEPSLEEP | - | x / x | - | x | - | - |
-| USE_EXS_DIMMER | - | x / - | x | - | - | - |
-| USE_DEVICE_GROUPS | - | x / x | - | - | - | - |
-| USE_PWM_DIMMER | - | x / - | x | - | - | - |
-| USE_KEELOQ | - | - / - | - | - | - | - |
-| USE_SONOFF_D1 | - | x / - | x | - | - | - |
-| USE_SHELLY_DIMMER | - | x / - | - | - | - | - |
-| USE_AC_ZERO_CROSS_DIMMER | - | x / x | x | x | x | x |
-| | | | | | | |
-| Feature or Sensor | l | t | k | s | i | d | Remarks
-| USE_LIGHT | x | x / x | x | x | x | x |
-| USE_WS2812 | - | x / x | x | x | - | x |
-| USE_WS2812_DMA | - | - / - | - | - | - | - |
-| USE_MY92X1 | - | x / - | x | x | - | x |
-| USE_SM16716 | - | x / - | x | x | - | x |
-| USE_SM2135 | - | x / - | x | x | - | x |
-| USE_SM2335 | - | x / - | x | x | - | x |
-| USE_BP5758D | - | x / - | x | x | - | x |
-| USE_SONOFF_L1 | - | x / - | x | x | - | x |
-| USE_ELECTRIQ_MOODL | - | x / - | x | x | - | x |
-| | | | | | | |
-| USE_ENERGY_SENSOR | x | x / x | x | x | - | - |
-| USE_ENERGY_DUMMY | x | x / x | x | x | - | - |
-| USE_PZEM004T | - | x / x | x | x | - | - |
-| USE_PZEM_AC | - | x / x | x | x | - | - |
-| USE_PZEM_DC | - | x / x | x | x | - | - |
-| USE_MCP39F501 | x | x / - | x | x | - | - |
-| USE_SDM72 | - | - / x | - | x | - | - |
-| USE_SDM120 | - | - / x | - | x | - | - |
-| USE_SDM230 | - | - / x | - | - | - | - |
-| USE_SDM630 | - | - / x | - | x | - | - |
-| USE_DDS2382 | - | - / x | - | x | - | - |
-| USE_DDSU666 | - | - / x | - | x | - | - |
-| USE_SOLAX_X1 | - | - / - | - | - | - | - |
-| USE_LE01MR | - | - / - | - | - | - | - |
-| USE_BL09XX | x | x / x | x | x | - | - |
-| USE_TELEINFO | - | - / - | - | - | - | - |
-| USE_IEM3000 | - | - / - | - | - | - | - |
-| USE_WE517 | - | - / - | - | - | - | - |
-| | | | | | | |
-| USE_ADC_VCC | x | - / - | - | - | x | - |
-| USE_COUNTER | - | x / x | x | x | - | x |
-| USE_DS18x20 | - | x / x | x | x | - | x |
-| USE_DHT | - | x / x | x | x | - | x |
-| USE_MAX31855 | - | - / x | - | x | - | - |
-| USE_MAX31865 | - | - / - | - | - | - | - |
-| USE_THERMOSTAT | - | - / - | - | - | - | - |
-| USE_LMT01 | - | - / x | - | x | - | - |
-| | | | | | | |
-| Feature or Sensor | l | t | k | s | i | d | Remarks
-| USE_I2C | - | x / x | x | x | - | x |
-| USE_SHT | - | - / x | - | x | - | - |
-| USE_HTU | - | - / x | - | x | - | - |
-| USE_BMP | - | - / x | - | x | - | - |
-| USE_BME68X | - | - / x | - | x | - | - |
-| USE_BH1750 | - | - / x | - | x | - | - |
-| USE_VEML6070 | - | - / x | - | x | - | - |
-| USE_ADS1115 | - | - / x | - | x | - | - |
-| USE_INA219 | - | - / x | - | x | - | - |
-| USE_INA226 | - | - / - | - | - | - | - |
-| USE_SHT3X | - | - / x | - | x | - | - |
-| USE_TSL2561 | - | - / - | - | - | - | - |
-| USE_TSL2591 | - | - / - | - | - | - | - |
-| USE_MGS | - | - / x | - | x | - | - |
-| USE_SGP30 | - | - / x | - | x | - | - |
-| USE_SGP40 | - | - / x | - | x | - | - |
-| USE_SI1145 | - | - / - | - | - | - | - |
-| USE_LM75AD | - | - / x | - | x | - | - |
-| USE_APDS9960 | - | - / - | - | - | - | - |
-| USE_MCP230xx | - | - / - | - | - | - | - |
-| USE_PCA9685 | - | - / - | - | - | - | - |
-| USE_MPR121 | - | - / - | - | - | - | - |
-| USE_CCS811 | - | - / - | - | x | - | - |
-| USE_CCS811_V2 | - | - / x | - | - | - | - |
-| USE_MPU6050 | - | - / - | - | - | - | - |
-| USE_DS3231 | - | - / - | - | - | - | - |
-| USE_MGC3130 | - | - / - | - | - | - | - |
-| USE_MAX44009 | - | - / - | - | - | - | - |
-| USE_SCD30 | - | - / x | - | x | - | - |
-| USE_SCD40 | - | - / x | - | - | - | - |
-| USE_SPS30 | - | - / - | - | - | - | - |
-| USE_ADE7880 | - | - / - | - | - | - | - |
-| USE_ADE7953 | - | x / x | x | x | - | x |
-| USE_VL53L0X | - | - / x | - | x | - | - |
-| USE_VL53L1X | - | - / - | - | - | - | - |
-| USE_MLX90614 | - | - / - | - | - | - | - |
-| USE_CHIRP | - | - / - | - | - | - | - |
-| USE_PAJ7620 | - | - / - | - | - | - | - |
-| USE_PCF8574 | - | - / - | - | - | - | - |
-| | | | | | | |
-| Feature or Sensor | l | t | k | s | i | d | Remarks
-| USE_HIH6 | - | - / x | - | x | - | - |
-| USE_DHT12 | - | - / x | - | x | - | - |
-| USE_DS1624 | - | - / x | - | x | - | - |
-| USE_AHT1x | - | - / - | - | - | - | - |
-| USE_HDC1080 | - | - / - | - | - | - | - |
-| USE_WEMOS_MOTOR_V1 | - | - / x | - | x | - | - |
-| USE_IAQ | - | - / x | - | x | - | - |
-| USE_AS3935 | - | - / x | - | x | - | - |
-| USE_VEML6075 | - | - / - | - | - | - | - |
-| USE_VEML7700 | - | - / - | - | - | - | - |
-| USE_MCP9808 | - | - / - | - | - | - | - |
-| USE_MLX90640 | - | - / - | - | - | - | - |
-| USE_HP303B | - | - / - | - | - | - | - |
-| USE_EZOCO2 | - | - / - | - | - | - | - |
-| USE_EZODO | - | - / - | - | - | - | - |
-| USE_EZOEC | - | - / - | - | - | - | - |
-| USE_EZOFLO | - | - / - | - | - | - | - |
-| USE_EZOHUM | - | - / - | - | - | - | - |
-| USE_EZOO2 | - | - / - | - | - | - | - |
-| USE_EZOORP | - | - / - | - | - | - | - |
-| USE_EZOPH | - | - / - | - | - | - | - |
-| USE_EZOPMP | - | - / - | - | - | - | - |
-| USE_EZOPRS | - | - / - | - | - | - | - |
-| USE_EZORGB | - | - / - | - | - | - | - |
-| USE_EZORTD | - | - / - | - | - | - | - |
-| USE_SEESAW_SOIL | - | - / - | - | - | - | - |
-| USE_TOF10120 | - | - / - | - | - | - | - |
-| USE_BM8563 | - | - / - | - | - | - | - |
-| USE_AM2320 | - | - / - | - | - | - | - |
+| Feature or Sensor | l | t | k | s | i | d | Remarks
+|---------------------------|---|-------|---|---|---|---|--------
+| MY_LANGUAGE en_GB | x | x / x | x | x | x | x |
+| USE_IMPROV | x | x / x | x | x | x | x |
+| USE_UFILESYS | - | - / x | - | - | - | - |
+| USE_ARDUINO_OTA | - | - / - | - | - | - | - |
+| USE_DOMOTICZ | - | x / x | x | x | x | - |
+| USE_HOME_ASSISTANT | - | - / - | - | - | - | - |
+| USE_TASMOTA_DISCOVERY | x | x / x | x | x | x | x |
+| USE_MQTT_TLS* | - | - / x | - | - | - | - |
+| USE_MQTT_AWS_IOT | - | - / - | - | - | - | - |
+| USE_4K_RSA | - | - / - | - | - | - | - |
+| USE_TELEGRAM | - | - / - | - | - | - | - |
+| USE_KNX | - | - / x | x | - | - | - |
+| USE_WEBSERVER | x | x / x | x | x | x | x |
+| USE_WEBSEND_RESPONSE | - | - / - | - | - | - | - |
+| USE_EMULATION_HUE | x | x / x | - | x | - | - |
+| USE_EMULATION_WEMO | x | x / x | - | x | - | - |
+| USE_DISCOVERY | - | - / - | - | - | - | - |
+| WEBSERVER_ADVERTISE | - | x / - | x | - | - | x |
+| MQTT_HOST_DISCOVERY | - | - / - | - | - | - | - |
+| USE_TIMERS | x | x / x | x | x | x | x |
+| USE_TIMERS_WEB | x | x / x | x | x | x | x |
+| USE_SUNRISE | x | x / x | x | x | x | x |
+| USE_RULES | x | x / x | x | x | x | x |
+| USE_SCRIPT | - | - / - | - | - | - | - |
+| USE_EXPRESSION | - | - / - | - | - | - | - |
+| SUPPORT_IF_STATEMENT | - | - / - | - | - | - | - |
+| USE_HOTPLUG | - | - / - | - | - | - | - |
+| USE_PROMETHEUS | - | - / - | - | - | - | - |
+| USE_PING | - | - / - | - | - | - | - |
+| | | | | | | |
+| Feature or Sensor | l | t | k | s | i | d | Remarks
+| ROTARY_V1 | - | x / x | - | x | - | - |
+| USE_SONOFF_RF | - | x / - | x | x | - | - |
+| USE_RF_FLASH | - | x / - | x | x | - | - |
+| USE_SONOFF_SC | - | x / - | x | x | - | - |
+| USE_TUYA_MCU | x | x / - | x | x | - | x |
+| USE_ARMTRONIX_DIMMERS | - | x / - | x | - | - | - |
+| USE_PS_16_DZ | - | x / - | x | - | - | - |
+| USE_SONOFF_IFAN | - | x / - | x | - | - | - |
+| USE_BUZZER | - | x / x | x | x | - | - |
+| USE_ARILUX_RF | - | x / - | x | - | - | - |
+| USE_SHUTTER | - | x / x | x | - | - | - |
+| USE_DEEPSLEEP | - | x / x | - | x | - | - |
+| USE_EXS_DIMMER | - | x / - | x | - | - | - |
+| USE_DEVICE_GROUPS | - | x / x | - | - | - | - |
+| USE_PWM_DIMMER | - | x / - | x | - | - | - |
+| USE_KEELOQ | - | - / - | - | - | - | - |
+| USE_SONOFF_D1 | - | x / - | x | - | - | - |
+| USE_SHELLY_DIMMER | - | x / - | - | - | - | - |
+| USE_AC_ZERO_CROSS_DIMMER | - | x / x | x | x | x | x |
+| | | | | | | |
+| Feature or Sensor | l | t | k | s | i | d | Remarks
+| USE_LIGHT | x | x / x | x | x | x | x |
+| USE_WS2812 | - | x / x | x | x | - | x |
+| USE_WS2812_DMA | - | - / - | - | - | - | - |
+| USE_MY92X1 | - | x / - | x | x | - | x |
+| USE_SM16716 | - | x / - | x | x | - | x |
+| USE_SM2135 | - | x / - | x | x | - | x |
+| USE_SM2335 | - | x / - | x | x | - | x |
+| USE_BP5758D | - | x / - | x | x | - | x |
+| USE_SONOFF_L1 | - | x / - | x | x | - | x |
+| USE_ELECTRIQ_MOODL | - | x / - | x | x | - | x |
+| | | | | | | |
+| USE_ENERGY_SENSOR | x | x / x | x | x | - | - |
+| USE_ENERGY_DUMMY | x | x / x | x | x | - | - |
+| USE_PZEM004T | - | x / x | x | x | - | - |
+| USE_PZEM_AC | - | x / x | x | x | - | - |
+| USE_PZEM_DC | - | x / x | x | x | - | - |
+| USE_MCP39F501 | x | x / - | x | x | - | - |
+| USE_SDM72 | - | - / x | - | x | - | - |
+| USE_SDM120 | - | - / x | - | x | - | - |
+| USE_SDM230 | - | - / x | - | - | - | - |
+| USE_SDM630 | - | - / x | - | x | - | - |
+| USE_DDS2382 | - | - / x | - | x | - | - |
+| USE_DDSU666 | - | - / x | - | x | - | - |
+| USE_SOLAX_X1 | - | - / - | - | - | - | - |
+| USE_LE01MR | - | - / - | - | - | - | - |
+| USE_BL09XX | x | x / x | x | x | - | - |
+| USE_TELEINFO | - | - / - | - | - | - | - |
+| USE_IEM3000 | - | - / - | - | - | - | - |
+| USE_WE517 | - | - / - | - | - | - | - |
+| | | | | | | |
+| USE_ADC_VCC | x | - / - | - | - | x | - |
+| USE_COUNTER | - | x / x | x | x | - | x |
+| USE_DS18x20 | - | x / x | x | x | - | x |
+| USE_DHT | - | x / x | x | x | - | x |
+| USE_MAX31855 | - | - / x | - | x | - | - |
+| USE_MAX31865 | - | - / - | - | - | - | - |
+| USE_THERMOSTAT | - | - / - | - | - | - | - |
+| USE_LMT01 | - | - / x | - | x | - | - |
+| | | | | | | |
+| Feature or Sensor | l | t | k | s | i | d | Remarks
+| USE_I2C | - | x / x | x | x | - | x |
+| USE_SHT | - | - / x | - | x | - | - |
+| USE_HTU | - | - / x | - | x | - | - |
+| USE_BMP | - | - / x | - | x | - | - |
+| USE_BME68X | - | - / x | - | x | - | - |
+| USE_BH1750 | - | - / x | - | x | - | - |
+| USE_VEML6070 | - | - / x | - | x | - | - |
+| USE_ADS1115 | - | - / x | - | x | - | - |
+| USE_INA219 | - | - / x | - | x | - | - |
+| USE_INA226 | - | - / - | - | - | - | - |
+| USE_SHT3X | - | - / x | - | x | - | - |
+| USE_TSL2561 | - | - / - | - | - | - | - |
+| USE_TSL2591 | - | - / - | - | - | - | - |
+| USE_MGS | - | - / x | - | x | - | - |
+| USE_SGP30 | - | - / x | - | x | - | - |
+| USE_SGP40 | - | - / x | - | x | - | - |
+| USE_SI1145 | - | - / - | - | - | - | - |
+| USE_LM75AD | - | - / x | - | x | - | - |
+| USE_APDS9960 | - | - / - | - | - | - | - |
+| USE_MCP230xx | - | - / - | - | - | - | - |
+| USE_PCA9685 | - | - / - | - | - | - | - |
+| USE_MPR121 | - | - / - | - | - | - | - |
+| USE_CCS811 | - | - / - | - | x | - | - |
+| USE_CCS811_V2 | - | - / x | - | - | - | - |
+| USE_MPU6050 | - | - / - | - | - | - | - |
+| USE_DS3231 | - | - / - | - | - | - | - |
+| USE_MGC3130 | - | - / - | - | - | - | - |
+| USE_MAX44009 | - | - / - | - | - | - | - |
+| USE_SCD30 | - | - / x | - | x | - | - |
+| USE_SCD40 | - | - / x | - | - | - | - |
+| USE_SPS30 | - | - / - | - | - | - | - |
+| USE_ADE7880 | - | - / - | - | - | - | - |
+| USE_ADE7953 | - | x / x | x | x | - | x |
+| USE_VL53L0X | - | - / x | - | x | - | - |
+| USE_VL53L1X | - | - / - | - | - | - | - |
+| USE_MLX90614 | - | - / - | - | - | - | - |
+| USE_CHIRP | - | - / - | - | - | - | - |
+| USE_PAJ7620 | - | - / - | - | - | - | - |
+| USE_PCF8574 | - | - / - | - | - | - | - |
+| | | | | | | |
+| Feature or Sensor | l | t | k | s | i | d | Remarks
+| USE_HIH6 | - | - / x | - | x | - | - |
+| USE_DHT12 | - | - / x | - | x | - | - |
+| USE_DS1624 | - | - / x | - | x | - | - |
+| USE_AHT1x | - | - / - | - | - | - | - |
+| USE_HDC1080 | - | - / - | - | - | - | - |
+| USE_WEMOS_MOTOR_V1 | - | - / x | - | x | - | - |
+| USE_IAQ | - | - / x | - | x | - | - |
+| USE_AS3935 | - | - / x | - | x | - | - |
+| USE_VEML6075 | - | - / - | - | - | - | - |
+| USE_VEML7700 | - | - / - | - | - | - | - |
+| USE_MCP9808 | - | - / - | - | - | - | - |
+| USE_MLX90640 | - | - / - | - | - | - | - |
+| USE_HP303B | - | - / - | - | - | - | - |
+| USE_EZOCO2 | - | - / - | - | - | - | - |
+| USE_EZODO | - | - / - | - | - | - | - |
+| USE_EZOEC | - | - / - | - | - | - | - |
+| USE_EZOFLO | - | - / - | - | - | - | - |
+| USE_EZOHUM | - | - / - | - | - | - | - |
+| USE_EZOO2 | - | - / - | - | - | - | - |
+| USE_EZOORP | - | - / - | - | - | - | - |
+| USE_EZOPH | - | - / - | - | - | - | - |
+| USE_EZOPMP | - | - / - | - | - | - | - |
+| USE_EZOPRS | - | - / - | - | - | - | - |
+| USE_EZORGB | - | - / - | - | - | - | - |
+| USE_EZORTD | - | - / - | - | - | - | - |
+| USE_SEESAW_SOIL | - | - / - | - | - | - | - |
+| USE_TOF10120 | - | - / - | - | - | - | - |
+| USE_BM8563 | - | - / - | - | - | - | - |
+| USE_AM2320 | - | - / - | - | - | - | - |
| USE_T67XX | - | - / - | - | - | - | - |
| USE_HM330X | - | - / - | - | - | - | - |
| USE_HDC2010 | - | - / - | - | - | - | - |
| USE_PCF85363 | - | - / - | - | - | - | - |
| USE_DS3502 | - | - / - | - | - | - | - |
| USE_HYT | - | - / - | - | - | - | - |
+| USE_LUXV30B | - | - / - | - | - | - | - |
| | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_SPI | - | - / - | - | - | - | x |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae972b3c4..b18d77223 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Flowrate meter flow amount/duration, show values in table format (#16385)
- Zigbee prepare for Green Power support (#16407)
- Command ``SetOption146 1`` to enable display of ESP32 internal temperature
+- Support for DFRobot SEN0390 V30B ambient light sensor (#16105)
### Changed
- TasmotaModbus library from v3.5.0 to v3.6.0 (#16351)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index efcc3a1c2..a578efce2 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -113,6 +113,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command ``StatusRetain`` [#11109](https://github.com/arendst/Tasmota/issues/11109)
- 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)
- Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` [#16252](https://github.com/arendst/Tasmota/issues/16252)
- Zigbee prepare for Green Power support [#16407](https://github.com/arendst/Tasmota/issues/16407)
- Flowrate meter flow amount/duration, show values in table format [#16385](https://github.com/arendst/Tasmota/issues/16385)
diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h
index 5da4fddb7..5fbf62f63 100644
--- a/tasmota/include/tasmota_configurations.h
+++ b/tasmota/include/tasmota_configurations.h
@@ -153,6 +153,7 @@
//#define USE_HDC2010 // [I2cDriver64] Enable HDC2010 temperature/humidity sensor (I2C address 0x40) (+1k5 code)
//#define USE_DS3502 // [I2CDriver67] Enable DS3502 digital potentiometer (I2C address 0x28 - 0x2B) (+0k4 code)
//#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_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index 4544f7da6..34db4eff8 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -410,6 +410,7 @@
//#define USE_T67XX // [I2cDriver61] Enable Telaire T67XX CO2 sensor (I2C address 0x15) (+1k3 code)
//#define USE_DS3502 // [I2CDriver67] Enable DS3502 digital potentiometer (I2C address 0x28 - 0x2B) (+0k4 code)
//#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_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
@@ -617,6 +618,7 @@
//#define USE_SEESAW_SOIL // [I2cDriver56] Enable Capacitice Soil Moisture & Temperature Sensor (I2C addresses 0x36 - 0x39) (+1k3 code)
//#define USE_DS3502 // [I2CDriver67] Enable DS3502 digital potentiometer (I2C address 0x28 - 0x2B) (+0k4 code)
//#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_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index e29a81bc7..90fbf28a3 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -681,6 +681,7 @@
// #define USE_HDC2010 // [I2cDriver64] Enable HDC2010 temperature/humidity sensor (I2C address 0x40) (+1k5 code)
// #define USE_DS3502 // [I2CDriver67] Enable DS3502 digital potentiometer (I2C address 0x28 - 0x2B) (+0k4 code)
// #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_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino
index 5341e07f3..73ecc03d7 100644
--- a/tasmota/tasmota_support/support_features.ino
+++ b/tasmota/tasmota_support/support_features.ino
@@ -828,7 +828,9 @@ void ResponseAppendFeatures(void)
#if defined(USE_I2C) && defined(USE_SGP40)
feature9 |= 0x00000001; // xsns_98_sgp40.ino
#endif
-// feature9 |= 0x00000002;
+#if defined(USE_I2C) && defined(USE_LUXV30B)
+ feature9 |= 0x00000002;
+#endif
// feature9 |= 0x00000004;
// feature9 |= 0x00000008;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_99_luxv30b.ino b/tasmota/tasmota_xsns_sensor/xsns_99_luxv30b.ino
new file mode 100644
index 000000000..b833a5c07
--- /dev/null
+++ b/tasmota/tasmota_xsns_sensor/xsns_99_luxv30b.ino
@@ -0,0 +1,212 @@
+/*
+ xsns_99_luxv30b.ino - Driver for DFRobot V30B lux sensor
+
+ Copyright (C) 2022 Marius Bezuidenhout
+
+ 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_LUXV30B
+/**************************************************************************************************
+ * DFRobot SEN0390 V30B ambient light sensor
+ *
+ * https://wiki.dfrobot.com/Ambient_Light_Sensor_0_200klx_SKU_SEN0390
+ * https://github.com/DFRobot/DFRobot_B_LUX_V30B/
+ *
+ * I2C Address: 0x4A
+ * ================================================================================================
+ * This driver use the I2C mode. Uses address 0x94 and 0x95. Its address cannot be changed.
+ *
+ * Supply Voltage: 2.7-6V
+ * Operating Current: 0.7mA
+ * Detection Range: 0-200klx
+ * Accuracy: 0.054lx
+ * Operating Temperature Range: -40°C~+85°C
+ * I2C Address: 0x4A
+ *
+ * Pin assignments:
+ *
+ * ------------------------------------------
+ * | Num | Label | Description |
+ * 1 VCC 2.7-6V +
+ * 2 SCL I2C Serial Clock Line
+ * 3 SDA I2C Serial Data
+ * 4 GND Ground
+ * 5 EN Sensor Chip-select Enable/Disable port, High to enable, Low to disable sensor
+ *
+ *
+ * You can write the desired configuration to the configuration register(address:0x04), setting
+ * different acquisition accuracy.
+ * You can read the light intensity data from the data register(address:0x00~0x03).
+ * ------------------------------------------------------------------------------------------
+ * | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
+ * ------------------------------------------------------------------------------------------
+ * | 0 | MANUAL | 0 | 0 | CDR | TIM |
+ * ------------------------------------------------------------------------------------------
+ * MANUAL :Manual configuration register.
+ * 0 represents the default automatic mode.In this mode ,CDR and TIM are automatically assigned.
+ * 1 represents the configuration of manual mode.In this mode,CDR and TIM can be set by the user.
+ * CDR :Shunt ratio register.
+ * 0 represents the default of not dividing,all the current of the photodiode into the ADC
+ * 1 represents the division of 8,as long as 1/8 of the current of the photodiode changes to ADC.
+ * This mode is used in high brightness situations.
+ * TIM[2:0]:Acquisition time.
+ * ------------------------------------------------------------------------------------------------
+ * TIM[2:0] | TIME(ms) | Introduction |
+ * ------------------------------------------------------------------------------------------------
+ * 000 | 800 | Preferred mode in low light environment |
+ * ------------------------------------------------------------------------------------------------
+ * 001 | 400 | --- |
+ * ------------------------------------------------------------------------------------------------
+ * 010 | 200 | --- |
+ * ------------------------------------------------------------------------------------------------
+ * 011 | 100 | In the strong light environment, select the mode preferentially |
+ * ------------------------------------------------------------------------------------------------
+ * 100 | 50 | Manual mode only |
+ * ------------------------------------------------------------------------------------------------
+ * 101 | 250 | Manual mode only |
+ * ------------------------------------------------------------------------------------------------
+ * 110 | 12.5 | Manual mode only |
+ * ------------------------------------------------------------------------------------------------
+ * 111 | 6.25 | Manual mode only |
+ * ------------------------------------------------------------------------------------------------
+ * Accuracy that can be set in manual mode:
+ * -------------------------------------------------------------------------------------------------------------
+ * | Light conditions | | TIM & CDR |
+ * -------------------------------------------------------------------------------------------------------------
+ * | Minimum accuracy | Maximum accuracy | Maximum | Acquisition time(ms) | TIM | CDR |
+ * —------------------------------------------------------------------------------------------------------------
+ * 0.054 11.52 2938 800 000 0
+ * 0.09 23.04 5875 400 001 0
+ * 0.18 46.08 11750 200 010 0
+ * 0.36 92.16 23501 100 011 0
+ * 0.36 92.16 23501 800 000 1
+ * 0.72 184.32 47002 50 100 0
+ * 0.72 184.32 47002 400 001 1
+ * 1.44 368.64 94003 25 101 0
+ * 1.44 368.64 94003 200 010 1
+ * 2.88 737.28 200000 12.5 110 0
+ * 2.88 737.28 200000 100 011 1
+ * 5.76 737.28 200000 6.25 111 0
+ * 5.76 737.28 200000 50 100 1
+ * 11.52 737.28 200000 25 101 1
+ * 23.04 737.28 200000 12.5 110 1
+ * 46.08 737.28 200000 6.25 111 1
+ * —------------------------------------------------------------------------------------------------------------
+ * *************************************************************************************************/
+
+#define XSNS_99 99
+#define XI2C_70 70 // See I2CDEVICES.md
+
+#define LUXV30B_ADDR 0x4A // Two wire library uses 7-bit addresses throughout
+#define LUXV30B_DATAREG 0x00 // Address of the data register
+#define LUXV30B_CONFREG 0x04 // Address of the configuration register
+
+class LuxV30b {
+ public:
+ LuxV30b();
+ void Detect();
+ bool Found();
+ void Read();
+ void Show(uint8_t function);
+ private:
+ float Lux();
+ bool _found;
+ uint32_t _lux;
+};
+
+LuxV30b::LuxV30b() {
+ _found = false;
+ _lux = 0;
+}
+
+void LuxV30b::Detect() {
+ if (!I2cSetDevice(LUXV30B_ADDR)) { return; }
+
+ _found = true;
+ I2cSetActiveFound(LUXV30B_ADDR, "LUXV30B");
+}
+
+bool LuxV30b::Found() {
+ return _found;
+}
+
+void LuxV30b::Read() {
+ _lux = I2cRead8(LUXV30B_ADDR, 0);
+ delay(8);
+ _lux |= I2cRead8(LUXV30B_ADDR, 1) << 8;
+ delay(8);
+ _lux |= I2cRead8(LUXV30B_ADDR, 2) << 16;
+ delay(8);
+ _lux |= I2cRead8(LUXV30B_ADDR, 3) << 24;
+}
+
+float LuxV30b::Lux() {
+ return ((float)_lux * 1.4) / 1000;
+}
+
+void LuxV30b::Show(uint8_t function) {
+// if (0 < Lux()) {
+ if (_lux) {
+ char lux[FLOATSZ];
+ dtostrfd(Lux(), 2, lux);
+ if (FUNC_JSON_APPEND == function) {
+ ResponseAppend_P(PSTR(",\"LUXV30B\":{\"" D_JSON_ILLUMINANCE "\":%s}"), lux);
+#ifdef USE_DOMOTICZ
+// Instead of below code use a rule like 'on tele-luxv30b#illuminance do dzsend1 9988,%value% endon'
+// where 9988 is the domoticz sensor Idx
+// if (0 == TasmotaGlobal.tele_period) { DomoticzSensor(DZ_ILLUMINANCE, lux); }
+#endif // USE_DOMOTICZ
+#ifdef USE_WEBSERVER
+ } else {
+ WSContentSend_PD(PSTR("{s}LUXV30B " D_ILLUMINANCE "{m}%s " D_UNIT_LUX "{e}"), lux);
+#endif // USE_WEBSERVER
+ }
+ }
+}
+
+LuxV30b Luxv30b;
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns99(uint8_t function) {
+ if (!I2cEnabled(XI2C_70)) { return false; }
+
+ bool result = false;
+
+ if (FUNC_INIT == function) {
+ Luxv30b.Detect();
+ }
+ else if (Luxv30b.Found()) {
+ switch (function) {
+ case FUNC_EVERY_SECOND:
+ Luxv30b.Read();
+ break;
+ case FUNC_JSON_APPEND:
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+#endif // USE_WEBSERVER
+ Luxv30b.Show(function);
+ break;
+ }
+ }
+ return result;
+}
+
+#endif // USE_LUXV30B
+#endif // USE_I2C
\ No newline at end of file
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 92de04297..465bd4712 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -285,7 +285,7 @@ a_features = [[
"USE_PCF85363","USE_DS3502","USE_IMPROV","USE_FLOWRATEMETER",
"USE_BP5758D","USE_HYT","USE_SM2335","USE_DISPLAY_TM1621_SONOFF"
],[
- "USE_SGP40","","","",
+ "USE_SGP40","USE_LUXV30B","","",
"","","","",
"","","","",
"","","","",
From 5639b48c1ad02d0065e50cd306f1c86a616507b0 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 2 Sep 2022 13:14:59 +0200
Subject: [PATCH 108/366] Update I2CDEVICES.md
---
I2CDEVICES.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/I2CDEVICES.md b/I2CDEVICES.md
index ef3ec0da8..0841866c9 100644
--- a/I2CDEVICES.md
+++ b/I2CDEVICES.md
@@ -103,4 +103,5 @@ Index | Define | Driver | Device | Address(es) | Description
66 | USE_PCF85363 | xsns_99 | PCF85363 | 0x51 | Real time clock
67 | USE_DS3502 | xdrv_61 | DS3502 | 0x28 - 0x2B | Digital potentiometer
68 | USE_HYT | xsns_97 | HYTxxx | 0x28 | Temperature and Humidity sensor
- 69 | USE_SGP40 | xsns_98 | SGP40 | 0x59 | Gas (TVOC) and air quality
+ 69 | USE_SGP40 | xsns_98 | SGP40 | 0x59 | Gas (TVOC) and air quality
+ 70 | USE_LUXV30B | xsns_99 | LUXV30B | 0x4A | DFRobot SEN0390 V30B lux sensor
From a43eaef01be11431d00d16ee41388d87402e7b20 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 2 Sep 2022 15:26:44 +0200
Subject: [PATCH 109/366] Add influxdb support to zigbee (#16417)
---
tasmota/include/tasmota_configurations.h | 2 ++
tasmota/include/tasmota_configurations_ESP32.h | 2 ++
.../tasmota_xdrv_driver/xdrv_23_zigbee_2a_devices_impl.ino | 4 ++++
tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino | 6 +++---
4 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h
index 5fbf62f63..58cb80798 100644
--- a/tasmota/include/tasmota_configurations.h
+++ b/tasmota/include/tasmota_configurations.h
@@ -500,6 +500,8 @@
#undef FALLBACK_MODULE
#define FALLBACK_MODULE SONOFF_ZB_BRIDGE // [Module2] Select default module on fast reboot where USER_MODULE is user template
+#define USE_INFLUXDB // Enable influxdb support (+5k code)
+
#undef SERIAL_LOG_LEVEL
#define SERIAL_LOG_LEVEL LOG_LEVEL_NONE // [SerialLog] (LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index 34db4eff8..dc827d7e1 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -459,6 +459,8 @@
#undef FALLBACK_MODULE
#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template
+#define USE_INFLUXDB // Enable influxdb support (+5k code)
+
#undef USE_DOMOTICZ
#undef USE_HOME_ASSISTANT
#define USE_TASMOTA_DISCOVERY // Enable Tasmota Discovery support (+2k code)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_2a_devices_impl.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_2a_devices_impl.ino
index 80156abaa..ab3057106 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_2a_devices_impl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_2a_devices_impl.ino
@@ -565,6 +565,10 @@ void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_l
ResponseAppend_P(PSTR("}"));
}
+#ifdef USE_INFLUXDB
+ InfluxDbProcess(1); // Use a copy of ResponseData
+#endif
+
if (Settings->flag4.zigbee_distinct_topics) {
char subtopic[TOPSZ];
if (Settings->flag4.zb_topic_fname && friendlyName && strlen(friendlyName)) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino b/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino
index 48adb935c..d98011399 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino
@@ -373,7 +373,7 @@ void InfluxDbProcessJson(bool use_copy = false) {
}
void InfluxDbProcess(bool use_copy) {
- if (Settings->sbflag1.influxdb_sensor) {
+ if (Settings->sbflag1.influxdb_sensor) { // IfxSensor
InfluxDbProcessJson(use_copy);
}
}
@@ -476,9 +476,9 @@ void CmndInfluxDbState(void) {
void CmndInfluxDbSensor(void) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
- Settings->sbflag1.influxdb_sensor = XdrvMailbox.payload;
+ Settings->sbflag1.influxdb_sensor = XdrvMailbox.payload; // IfxSensor
}
- ResponseCmndStateText(Settings->sbflag1.influxdb_sensor);
+ ResponseCmndStateText(Settings->sbflag1.influxdb_sensor); // IfxSensor
}
void CmndInfluxDbLog(void) {
From 2cca11f54bc649c3e115665aa5b6c92fe461ccbc Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 2 Sep 2022 17:12:42 +0200
Subject: [PATCH 110/366] Fix OTA upload when filesystem is added
Fix OTA upload when filesystem is added.
An OTA upload to OTA server fails without this test as it overrules the user upload script.
---
pio-tools/post_esp32.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py
index ab3440ea7..d4a425ac2 100644
--- a/pio-tools/post_esp32.py
+++ b/pio-tools/post_esp32.py
@@ -168,7 +168,9 @@ def esp32_create_combined_bin(source, target, env):
else:
print("Upload new safeboot binary only")
- if(fs_offset != -1):
+# if(fs_offset != -1):
+ upload_port = env.subst("$UPLOAD_PORT")
+ if("upload-tasmota.php" not in upload_port) and (fs_offset != -1):
fs_bin = join(env.subst("$BUILD_DIR"),"littlefs.bin")
if exists(fs_bin):
before_reset = env.BoardConfig().get("upload.before_reset", "default_reset")
From d3fbc98601659276e8cab5f395816fa4a514bd3c Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Fri, 2 Sep 2022 22:27:46 +0200
Subject: [PATCH 111/366] ZIgbee extend ZNP timeout
---
tasmota/berry/zigbee/tubezb_cc2652_flasher.be | 176 ++++++++++++++++++
.../xdrv_23_zigbee_7_0_statemachine.ino | 4 +-
2 files changed, 178 insertions(+), 2 deletions(-)
create mode 100644 tasmota/berry/zigbee/tubezb_cc2652_flasher.be
diff --git a/tasmota/berry/zigbee/tubezb_cc2652_flasher.be b/tasmota/berry/zigbee/tubezb_cc2652_flasher.be
new file mode 100644
index 000000000..f96d7b8a6
--- /dev/null
+++ b/tasmota/berry/zigbee/tubezb_cc2652_flasher.be
@@ -0,0 +1,176 @@
+
+#################################################################################
+#
+# class `sonoff_zb_pro_flasher`
+#
+#################################################################################
+
+class tubezb_cc2652_flasher
+ static CCFG_address = 0x057FD8
+ static CCFG_reference = 0xC5FE0FC5 # DIO 15 for BSL
+
+ #################################################################################
+ # Flashing from Intel HEX files
+ #################################################################################
+ var filename # filename of hex file
+ var f # file object
+ var file_checked # was the file already parsed. It cannot be flashed if not previously parsed and validated
+ var file_validated # was the file already validated. It cannot be flashed if not previously parsed and validated
+ var file_hex # intelhex object
+ var flasher # low-level flasher object (cc2652_flasher instance)
+
+ def init()
+ self.file_checked = false
+ self.file_validated = false
+ end
+
+ def load(filename)
+ import intelhex
+
+ if type(filename) != 'string' raise "value_error", "invalid file name" end
+ self.filename = filename
+ self.file_hex = intelhex(filename) # prepare the parser object
+ self.file_checked = false
+ self.file_validated = false
+ end
+
+ #################################################################################
+ # check that the HEX file is valid
+ # parse it completely once, and verify some values
+ #################################################################################
+ def check()
+ self.file_hex.parse(/ -> self._check_pre(),
+ / address, len, data, offset -> self._check_cb(address, len, data, offset),
+ / -> self._check_post()
+ )
+ end
+
+ #################################################################################
+ # Flash the firmware to the device
+ #
+ #################################################################################
+ def flash()
+ if !self.file_checked
+ print("FLH: firmware not checked, use `cc.check()`")
+ raise "flash_error", "firmware not checked"
+ end
+ if !self.file_validated
+ print("FLH: firmware not validated, use `cc.check()`")
+ raise "flash_error", "firmware not validated"
+ end
+
+ import cc2652_flasher # this stops zigbee and configures serial
+ self.flasher = cc2652_flasher
+
+ try
+ self.file_hex.parse(/ -> self._flash_pre(),
+ / address, len, data, offset -> self._flash_cb(address, len, data, offset),
+ / -> self._flash_post()
+ )
+ except .. as e, m
+ self.file_checked = false
+ self.file_validated = false
+ raise e, m
+ end
+ end
+
+ #################################################################################
+ # Dump firmware to local file
+ #
+ #################################################################################
+ def dump_to_file(filename)
+ import cc2652_flasher # this stops zigbee and configures serial
+ self.flasher = cc2652_flasher
+ print("FLH: Dump started (takes 3 minutes during which Tasmota is unresponsive)")
+ self.flasher.start()
+ self.flasher.ping()
+ self.flasher.flash_dump_to_file(filename, 0x000000, 0x58000)
+ print("FLH: Dump completed")
+ end
+
+ #################################################################################
+ # low-level
+ #################################################################################
+ def _flash_pre()
+ print("FLH: Flashing started (takes 5 minutes during which Tasmota is unresponsive)")
+ self.flasher.start()
+ self.flasher.ping()
+ # erase flash
+ self.flasher.flash_erase()
+ end
+
+ def _flash_post()
+ print("FLH: Flashing completed: OK")
+ var flash_crc = self.flasher.cmd_crc32(0x0,0x30000)
+ print("FLH: Flash crc32 0x000000 - 0x2FFFF = " + str(flash_crc));
+ # tasmota.log("FLH: Verification of HEX file OK", 2)
+ end
+
+ def _flash_cb(addr, sz, data, offset)
+ var payload = data[offset .. offset + sz - 1]
+
+ # final check
+ if size(payload) != sz raise "flash_error", "incomplete payload" end
+
+ self.flasher.flash_write(addr, payload)
+ end
+
+
+ # start verification (log only)
+ def _check_pre()
+ print("FLH: Starting verification of HEX file")
+ # tasmota.log("FLH: Starting verification of HEX file", 2)
+ end
+
+ # don't flash so ignore data
+ # check CCFG at location 0x57FD8 (4 bytes)
+ def _check_cb(addr, sz, data, offset)
+ # import string
+
+ # check than sz is a multiple of 4
+ if (sz % 4 != 0)
+ import string
+ raise "value_error", string.format("size of payload is not a mutliple of 4: 0x%06X", addr)
+ end
+
+ # print(string.format("> addr=0x%06X sz=0x%02X data=%s", addr, sz, data[offset..offset+sz-1]))
+ var CCFG = self.CCFG_address
+ if addr <= CCFG && addr+sz > CCFG+4
+ # we have CCFG in the buffer
+ var ccfg_bytes = data.get(4 + CCFG - addr, 4)
+
+ if ccfg_bytes != self.CCFG_reference
+ import string
+ raise "value_error", string.format("incorrect CCFG, BSL is not set to DIO_8 LOW (0x%08X expected 0x%08X)", ccfg_bytes, self.CCFG_reference) end
+ self.file_validated = true # if we are here, it means that the file looks correct
+ end
+ end
+
+ def _check_post()
+ print("FLH: Verification of HEX file OK")
+ # tasmota.log("FLH: Verification of HEX file OK", 2)
+ self.file_checked = true
+ end
+
+end
+
+return tubezb_cc2652_flasher()
+
+
+#-
+# Flash local firmware
+
+import sonoff_zb_pro_flasher as cc
+cc.load("SonoffZBPro_coord_20220219.hex")
+cc.check()
+cc.flash()
+
+-#
+
+#-
+# Dump local firmware
+
+import sonoff_zb_pro_flasher as cc
+cc.dump_to_file("SonoffZBPro_dump.bin")
+
+-#
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_0_statemachine.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_0_statemachine.ino
index 34e97ec14..08211a1d0 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_0_statemachine.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_0_statemachine.ino
@@ -473,7 +473,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord)
ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) // set any failure to ABORT
ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator
- ZI_WAIT_RECV(5000, ZBR_STARTUPFROMAPP) // wait for sync ack of command
+ ZI_WAIT_RECV(10000, ZBR_STARTUPFROMAPP) // wait for sync ack of command
ZI_WAIT_UNTIL_FUNC(20000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started, max 20s
ZI_GOTO(ZIGBEE_LABEL_COORD_STARTED)
@@ -493,7 +493,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
ZI_WAIT_RECV(2000, ZBR_W_BDB_CHANN_OK)
// all is good, we can start
ZI_SEND(ZBS_BDB_START_COMMIS) // start coordinator
- ZI_WAIT_RECV(5000, ZBR_BDB_START_COMMIS) // wait for sync ack of command
+ ZI_WAIT_RECV(10000, ZBR_BDB_START_COMMIS) // wait for sync ack of command
ZI_WAIT_UNTIL_FUNC(20000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started, max 20s
// ======================================================================
From c73d7835546c5e353900f03de4fa494ac3012a82 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Fri, 2 Sep 2022 22:36:11 +0200
Subject: [PATCH 112/366] ZIgbee add GP UI indicator
---
.../xdrv_23_zigbee_2_devices.ino | 8 ++--
.../xdrv_23_zigbee_A_impl.ino | 42 +++++++++++--------
2 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_2_devices.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_2_devices.ino
index 869ee7679..ed8ff9e42 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_2_devices.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_2_devices.ino
@@ -734,7 +734,7 @@ public:
// other status - device wide data is 8 bytes
// START OF DEVICE WIDE DATA
uint32_t last_seen; // Last seen time (epoch)
- uint32_t batt_last_seen; // Time when we last received battery status (epoch), 0 means unknown, 0xFFFFFFFF means that the device has no battery
+ uint32_t batt_last_seen; // Time when we last received battery status (epoch), 0 means unknown, 0xFFFFFFFF means that the device has no battery, 0xFFFFFFFE means the device is Green Power, all values above 0xFFFFFFF0 are reserved
uint32_t batt_last_probed; // Time when the device was last probed for batteyr values
uint8_t lqi; // lqi from last message, 0xFF means unknown
uint8_t batt_percent; // battery percentage (0..100), 0xFF means unknwon
@@ -783,7 +783,7 @@ public:
inline bool validLqi(void) const { return 0xFF != lqi; }
inline bool validBatteryPercent(void) const { return 0xFF != batt_percent; }
inline bool validLastSeen(void) const { return 0x0 != last_seen; }
- inline bool validBattLastSeen(void) const { return (0x0 != batt_last_seen) && (0xFFFFFFFF != batt_last_seen); }
+ inline bool validBattLastSeen(void) const { return (0x0 != batt_last_seen) && (batt_last_seen < 0xFFFFFFF0); }
inline void setReachable(bool _reachable) { reachable = _reachable; }
inline bool getReachable(void) const { return reachable; }
@@ -806,7 +806,9 @@ public:
}
}
inline void setHasNoBattery(void) { batt_last_seen = 0xFFFFFFFF; }
- inline bool hasNoBattery(void) const { return 0xFFFFFFFF == batt_last_seen; }
+ inline bool hasNoBattery(void) const { return batt_last_seen >= 0xFFFFFFF0; }
+ inline void setGP(void) { batt_last_seen = 0xFFFFFFFE; } // Green Power
+ inline bool isGP(void) const { return 0xFFFFFFFE == batt_last_seen; }
// Add an endpoint to a device
bool addEndpoint(uint8_t endpoint);
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 96f15cdc2..37b000b00 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
@@ -1872,6 +1872,10 @@ const char ZB_WEB_U[] PROGMEM =
""
"\0"
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ //=ZB_WEB_GP
+ "GP"
+ "\0"
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++++
//=ZB_WEB_LAST_SEEN
"🕗%02d%c"
"\0"
@@ -1911,16 +1915,17 @@ enum {
ZB_WEB_MAP_REFRESH=1164,
ZB_WEB_STATUS_LINE=1230,
ZB_WEB_BATTERY=1338,
- ZB_WEB_LAST_SEEN=1410,
- ZB_WEB_COLOR_RGB=1458,
- ZB_WEB_LINE_START=1518,
- ZB_WEB_LIGHT_CT=1558,
- ZB_WEB_END_STATUS=1613,
- ZB_WEB_LINE_END=1630,
+ ZB_WEB_GP=1410,
+ ZB_WEB_LAST_SEEN=1466,
+ ZB_WEB_COLOR_RGB=1514,
+ ZB_WEB_LINE_START=1574,
+ ZB_WEB_LIGHT_CT=1614,
+ ZB_WEB_END_STATUS=1669,
+ ZB_WEB_LINE_END=1686,
};
-// Compressed from 1649 to 1124, -31.8%
-const char ZB_WEB[] PROGMEM = "\x00\x68\x3D\x0E\xCA\xB1\xC1\x33\xF0\xF6\xD1\xEE\x3D\x3D\x46\x41\x33\xF0\xE8\x6D"
+// Compressed from 1705 to 1156, -32.2%
+const char ZB_WEB[] PROGMEM = "\x00\x6B\x3D\x0E\xCA\xB1\xC1\x33\xF0\xF6\xD1\xEE\x3D\x3D\x46\x41\x33\xF0\xE8\x6D"
"\xA1\x15\x08\x79\xF6\x51\xDD\x3C\xCC\x6F\xFD\x47\x58\x62\xB4\x21\x0E\xF1\xED\x1F"
"\xD1\x28\x51\xE6\x72\x99\x0C\x36\x1E\x0C\x67\x51\xD7\xED\x36\xB3\xCC\xE7\x99\xF4"
"\x7D\x1E\xE2\x04\x3C\x40\x2B\x04\x3C\x28\x10\xB0\x93\x99\xA4\x30\xD8\x08\x36\x8E"
@@ -1968,15 +1973,16 @@ const char ZB_WEB[] PROGMEM = "\x00\x68\x3D\x0E\xCA\xB1\xC1\x33\xF0\xF6\xD1\xEE\
"\x35\x16\xA3\xEB\xC7\xD8\x21\xE7\x1E\xD3\xEC\xFC\x9C\x2F\x9E\x9A\x08\x52\xCF\x60"
"\xEA\x3D\x80\x85\x82\x9E\xC3\xE8\x43\xE8\xFA\x3E\xBC\x08\x9D\x2A\x01\x03\xAC\xEB"
"\x1C\x11\xE6\x7D\x08\x30\xD8\x08\x7C\xFA\x1F\x47\x1D\x11\xB0\xFA\x38\xE8\x8D\x87"
- "\xD1\xC7\x44\x6C\x3D\x87\xE1\xE8\x76\x69\xF9\x38\x5F\x3D\x28\x40\x43\xC2\xC1\x43"
- "\x01\x3F\x47\x91\xB0\xE4\x22\x30\x73\x77\xC7\x83\xE9\xD1\x08\x7D\x07\x38\x5F\x40"
- "\x8D\xAA\x9B\x01\x1B\x46\x0C\x23\xCC\xF2\x3E\x8E\x3A\x22\x36\x1F\x47\x1D\x11\x1B"
- "\x0F\xA3\x8E\x88\x8D\x80\x83\x9D\x82\x44\xF0\x47\xE1\xF0\x10\xF8\x78\x41\xE0\x5E"
- "\x19\x7C\x7C\x3D\x87\x30\xF6\x1F\x87\xE8\xF2\x59\xEF\x9E\x0A\x70\xBE\x08\x5D\x17"
- "\x2A\x01\x42\xE0\xC4\x83\x2A\x2B\x47\xD0\x87\xB0\xFC\x3D\x3C\x36\xC2\x08\xFC\x3F"
- "\x47\x91\xC5\xF5\xF3\xC1\xDC\x3D\x0E\xC2\x04\x19\x87\xD0\x84\x68\x08\x5D\x18\x29"
- "\xC2\xF8\x21\x74\x1D\xCE\xCA\x10\xFC\x3E\xBC\x7B\x59\xEE\x9C\x2F\x82\x3F\x4E\xE8"
- "\x10\x79\x39\x9C\x2F\x9B";
+ "\xD1\xC7\x44\x6C\x3D\x87\xE1\xE8\x76\x69\xF9\x38\x5F\x04\x1E\x86\xD8\x21\x68\xA4"
+ "\x3D\xF6\xF9\x10\xCC\x1F\x7F\x3E\xC1\x2B\xA1\xDE\x73\x08\x8C\x1C\xC3\xC1\xF6\x7E"
+ "\x11\x0F\x10\xC0\x42\xE8\x77\xCE\x17\xCF\x4A\x10\x10\xF4\x30\x50\xCE\x4F\xD1\xE4"
+ "\x6C\x39\x08\x8C\x1C\xDD\xF1\xE0\xFA\x74\x42\x1F\x41\xCE\x17\xD0\x23\x70\x1A\x6C"
+ "\x04\x6D\xF8\x30\x8F\x33\xC8\xFA\x38\xE8\x88\xD8\x7D\x1C\x74\x44\x6C\x3E\x8E\x3A"
+ "\x22\x36\x02\x0E\xE6\x09\x13\xC1\x1F\x8B\x40\x43\xE2\xC1\x07\x81\x78\x65\xF1\xF0"
+ "\xF6\x1C\xC3\xD8\x7E\x1F\xA3\xC9\x67\xBE\x78\x29\xC2\xF8\x21\x74\x6A\x01\x0B\x86"
+ "\x92\x0C\xA9\x1F\x42\x1E\xC3\xF0\xF4\xF0\xDB\x08\x23\xF0\xFD\x1E\x47\x17\xD7\xCF"
+ "\x07\x70\xF4\x3B\x08\x10\x66\x1F\x42\x11\xA0\x22\x70\x4E\x08\x3D\x0A\xF3\xB2\x84"
+ "\x3F\x0F\xAF\x1E\xD6\x7B\xA7\x0B\xE0\x8F\xD3\xF2\x04\x1E\x5C\x67\x0B\xE6";
// ++++++++++++++++++++^^^^^^^^^^^^^^^^^^^++++++++++++++++++++
// ++++++++++++++++++++ DO NOT EDIT ABOVE ++++++++++++++++++++
@@ -2136,6 +2142,8 @@ void ZigbeeShow(bool json)
changeUIntScale(device.batt_percent, 0, 100, 0, 14),
(color & 0xFF0000) >> 16, (color & 0x00FF00) >> 8, (color & 0x0000FF)
);
+ } else if (device.isGP()) { // display GP in green for Green Power
+ snprintf_P(sbatt, sizeof(sbatt), msg[ZB_WEB_GP]);
}
uint32_t num_bars = 0;
From 34084c6e7521f2f9acc67809770b990007fc70c7 Mon Sep 17 00:00:00 2001
From: Christian Baars |