From c8b8fe2da4f9347cd8190b4965ddfe2d7e83091f Mon Sep 17 00:00:00 2001
From: jeevasdev
Date: Tue, 15 Feb 2022 13:51:43 +1100
Subject: [PATCH 01/25] Added support for BL6523 chipset based Energy Monitors
---
tasmota/language/af_AF.h | 2 +
tasmota/language/bg_BG.h | 2 +
tasmota/language/cs_CZ.h | 2 +
tasmota/language/de_DE.h | 2 +
tasmota/language/el_GR.h | 2 +
tasmota/language/en_GB.h | 2 +
tasmota/language/es_ES.h | 2 +
tasmota/language/fr_FR.h | 2 +
tasmota/language/fy_NL.h | 2 +
tasmota/language/he_HE.h | 2 +
tasmota/language/hu_HU.h | 2 +
tasmota/language/it_IT.h | 2 +
tasmota/language/ko_KO.h | 2 +
tasmota/language/nl_NL.h | 2 +
tasmota/language/pl_PL.h | 2 +
tasmota/language/pt_BR.h | 2 +
tasmota/language/pt_PT.h | 2 +
tasmota/language/ro_RO.h | 2 +
tasmota/language/ru_RU.h | 2 +
tasmota/language/sk_SK.h | 2 +
tasmota/language/sv_SE.h | 2 +
tasmota/language/tr_TR.h | 2 +
tasmota/language/uk_UA.h | 2 +
tasmota/language/vi_VN.h | 2 +
tasmota/language/zh_CN.h | 2 +
tasmota/language/zh_TW.h | 2 +
tasmota/tasmota_template.h | 6 +
tasmota/xsns_96_bl6523.ino | 353 +++++++++++++++++++++++++++++++++++++
28 files changed, 411 insertions(+)
create mode 100644 tasmota/xsns_96_bl6523.ino
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 60460a97a..8a2c5e5f0 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 602091030..41485e29a 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index 1a731d7fa..2a6f91636 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index bd4306de9..2c020ad3e 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Herzschlag"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index df9fd6fff..98b58c971 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index 71bd64bac..8de4e9743 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index a317601ad..0831d4c8b 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 8a28c747d..5671da05d 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 7addac432..8305f8aac 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 9c0941429..e72ff9d8e 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index 6fad9fbb5..702a476e4 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 9a5c7a78c..6a8ad1b93 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 - RX"
#define D_SENSOR_HRG15_TX "HRG15 - TX"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Battito cardiaco"
#define D_GPIO_SHIFT595_SRCLK "74x595 - SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 - RCLK"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 85306451c..713e3be14 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 17803a9b0..e4d5e8916 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index 1b83b5639..64b3347d6 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "Kierunek wiatru"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index b3314554e..038d8354d 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index 357aec476..932a10650 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index ab325f19a..6c5433891 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index 927a5e38d..845bc6f30 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 322b412cb..3b2883bf2 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index ed1298eb2..38697b695 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index b238b88b9..e76e8076d 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index b75e1f04a..5e4a99e10 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index 13242d134..f52e6599a 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index bd9b96293..882d9756e 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 8689fcddd..b7eb80a67 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -847,6 +847,8 @@
#define D_SENSOR_HRG15_RX "HRG15 Rx"
#define D_SENSOR_HRG15_TX "HRG15 Tx"
#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING"
+#define D_SENSOR_BL6523_TX "BL6523 Tx"
+#define D_SENSOR_BL6523_RX "BL6523 Rx"
#define D_SENSOR_HEARTBEAT "Heartbeat"
#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK"
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h
index 615c48630..7af28acd4 100644
--- a/tasmota/tasmota_template.h
+++ b/tasmota/tasmota_template.h
@@ -172,6 +172,7 @@ enum UserSelectablePins {
GPIO_MCP2515_CS, // MCP2515 Chip Select
GPIO_HRG15_TX, GPIO_HRG15_RX, // Hydreon RG-15 rain sensor serial interface
GPIO_VINDRIKTNING_RX, // IKEA VINDRIKTNING Serial interface
+ GPIO_BL6523_TX, GPIO_BL6523_RX, // BL6523 based Watt meter Serial interface
GPIO_BL0939_RX, // BL0939 Serial interface (Dual R3 v2)
GPIO_BL0942_RX, // BL0942 Serial interface
GPIO_HM330X_SET, // HM330X SET pin (sleep when low)
@@ -393,6 +394,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_MCP2515_CS "|"
D_SENSOR_HRG15_TX "|" D_SENSOR_HRG15_RX "|"
D_SENSOR_VINDRIKTNING_RX "|"
+ D_SENSOR_BL6523_TX "|" D_SENSOR_BL6523_RX "|"
D_SENSOR_BL0939_RX "|"
D_SENSOR_BL0942_RX "|"
D_SENSOR_HM330X_SET "|"
@@ -812,6 +814,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#ifdef USE_VINDRIKTNING
AGPIO(GPIO_VINDRIKTNING_RX),
#endif
+#ifdef USE_BL6523
+ AGPIO(GPIO_BL6523_TX),
+ AGPIO(GPIO_BL6523_RX),
+#endif
#ifdef USE_HM330X
AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low)
#endif
diff --git a/tasmota/xsns_96_bl6523.ino b/tasmota/xsns_96_bl6523.ino
new file mode 100644
index 000000000..7587a897f
--- /dev/null
+++ b/tasmota/xsns_96_bl6523.ino
@@ -0,0 +1,353 @@
+/*
+ xsns_96_bl6523.ino - Chinese bl6523 based Watt hour meter support for Tasmota
+
+ Copyright (C) 2022 Jeevas Vasudevan and the Internet
+
+ 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_BL6523
+/*********************************************************************************************\
+ * Chinese BL6523 based Watt hour meter
+ *
+ * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
+ * To use Tasmota the user needs to add an ESP8266 or ESP32
+ * Three lines need to be connected via 1KOhh resistors to ESP from the main board(RX,TX GND)
+ *
+ * Connection Eg (ESP8266) - Non - Isolated:
+ * BL6523 RX ->1KOhm-> ESP IO4(D2) (Should be Input Capable)
+ * BL6523 TX ->1KOhm-> ESP IO5(D1) (Should be Input Capable)
+ * BL6523 GND -> ESP GND
+ *
+ * Connection Eg (ESP32) - Non - Isolated:
+ * BL6523 RX ->1KOhm-> ESP IO4 (Should be Input Capable)
+ * BL6523 TX ->1KOhm-> ESP IO5 (Should be Input Capable)
+ * BL6523 GND -> ESP GND
+ *
+ * To build add the below to user_config_override.h
+ * #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
+ *
+ * After Installation use the below template sample:
+ * {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
+\*********************************************************************************************/
+
+#define XSNS_96 96
+
+#include
+
+#define BL6523_RX_DATASET_SIZE 2
+#define BL6523_TX_DATASET_SIZE 4
+
+#define BL6523_BAUD 4800
+#define BL6523_REG_AMPS 0x05
+#define BL6523_REG_VOLTS 0x07
+#define BL6523_REG_FREQ 0x09
+#define BL6523_REG_WATTS 0x0A
+#define BL6523_REG_POWF 0x08
+#define BL6523_REG_WATTHR 0x0C
+
+/* No idea how to derive human readable units from the byte stream.
+For now dividing the 24-bit values with below constants seems to yield something sane
+that matches whatever displayed in the screen of my 240v model. Probably it would be possible
+to extract these values from the write register commands (0xCA).*/
+#define BL6523_DIV_AMPS 297899.4f
+#define BL6523_DIV_VOLTS 13304.0f
+#define BL6523_DIV_FREQ 3907.0f
+#define BL6523_DIV_WATTS 707.0f
+#define BL6523_DIV_WATTHR 674.0f
+
+TasmotaSerial *Bl6523RxSerial;
+TasmotaSerial *Bl6523TxSerial;
+
+struct BL6523
+{
+ uint32_t amps = 0;
+ uint32_t volts = 0;
+ uint32_t freq = 0;
+ uint32_t watts = 0;
+ uint32_t powf = 0;
+ uint32_t watthr = 0;
+
+ uint8_t type = 1;
+ uint8_t valid = 0;
+ uint8_t got_data_stone = 0;
+ bool discovery_triggered = false;
+} Bl6523;
+
+bool Bl6523ReadData(void)
+{
+
+ if (!Bl6523RxSerial->available())
+ {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 No Rx Data available " ));
+ return false;
+ }
+
+ while ((Bl6523RxSerial->peek() != 0x35) && Bl6523RxSerial->available())
+ {
+ Bl6523RxSerial->read();
+ }
+
+ if (Bl6523RxSerial->available() < BL6523_RX_DATASET_SIZE)
+ {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Rx less than expected " ));
+ return false;
+ }
+
+ uint8_t rx_buffer[BL6523_RX_DATASET_SIZE];
+ Bl6523RxSerial->readBytes(rx_buffer, BL6523_RX_DATASET_SIZE);
+ Bl6523RxSerial->flush(); // Make room for another burst
+
+ AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE);
+
+ while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE)
+ {
+ // sleep till TX buffer is full
+ unsigned long timeout = millis() + 10;
+ while (millis() < timeout) {}
+ }
+
+
+ uint8_t tx_buffer[BL6523_TX_DATASET_SIZE];
+ Bl6523TxSerial->readBytes(tx_buffer, BL6523_TX_DATASET_SIZE);
+ Bl6523TxSerial->flush(); // Make room for another burst
+
+
+ AddLogBuffer(LOG_LEVEL_DEBUG_MORE, tx_buffer, BL6523_TX_DATASET_SIZE);
+
+ /* Checksum: (Addr+Data_L+Data_M+Data_H) & 0xFF, then byte invert */
+ uint8_t crc = rx_buffer[1]; //Addr
+ for (uint32_t i = 0; i < (BL6523_TX_DATASET_SIZE - 1); i++)
+ {
+ crc += tx_buffer[i]; //Add Data_L,Data_M and Data_H to Addr
+ }
+ crc &= 0xff; // Bitwise AND 0xFF
+ crc = ~crc; // Invert the byte
+ if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1])
+ {
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6523 : " D_CHECKSUM_FAILURE));
+ Bl6523TxSerial->flush();
+ Bl6523RxSerial->flush();
+ return false;
+ }
+
+ /* WRITE DATA (format: command(write->0xCA) address data_low data_mid data_high checksum )
+WRITE Sample(RX):
+RX: CA 3E 55 00 00 6C (WRPROT - allow)
+RX: CA 14 00 00 10 DB (MODE)
+RX: CA 15 04 00 00 E6 (GAIN - IB 16x gain )
+RX: CA 19 08 00 00 DE (WA_CFDIV )
+RX: CA 3E AA 00 00 17 (WRPROT - disable)
+*/
+
+ /* READ DATA (format: command(read->0x35) address data_low data_mid data_high checksum )
+READ Sample(RX-TX) Data:
+RX: 35 05 TX: E4 00 00 16 (IA rms )
+RX: 35 07 TX: D5 A3 2E 52 (V rms )
+RX: 35 09 TX: F0 FB 02 09 (FREQ)
+RX: 35 0A TX: 00 00 00 F5 (WATT)
+RX: 35 08 TX: 00 00 00 F7 (PF)
+RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
+*/
+
+switch(rx_buffer[1]) {
+ case BL6523_REG_AMPS :
+ Bl6523.amps = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<0;
+ break;
+ case BL6523_REG_VOLTS :
+ Bl6523.volts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<1;
+ break;
+ case BL6523_REG_FREQ :
+ Bl6523.freq = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<2;
+ break;
+ case BL6523_REG_WATTS :
+ Bl6523.watts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<3;
+ break;
+ case BL6523_REG_POWF :
+ Bl6523.powf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<4;
+ break;
+ case BL6523_REG_WATTHR :
+ Bl6523.watthr = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<5;
+ break;
+ default :
+ break;
+}
+
+AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Amps: %d Volts: %d Freq: %d Watts: %d PowF: %d WattHr: %d"), Bl6523.amps, Bl6523.volts, Bl6523.freq, Bl6523.watts, Bl6523.powf, Bl6523.watthr);
+
+ if (!Bl6523.discovery_triggered)
+ {
+ TasmotaGlobal.discovery_counter = 1; // force TasDiscovery()
+ Bl6523.discovery_triggered = true;
+ }
+ return true;
+
+}
+
+/*********************************************************************************************/
+
+void Bl6523Update(void)
+{ // Every 250 millisecond
+ if (Bl6523ReadData())
+ {
+ Bl6523.valid = 60;
+ }
+ else
+ {
+ if (Bl6523.valid) {
+ Bl6523.valid--;
+ }
+ }
+}
+
+/*********************************************************************************************/
+
+void Bl6523Init(void)
+{
+ Bl6523.type = 0;
+ if ((PinUsed(GPIO_BL6523_RX)) && (PinUsed(GPIO_BL6523_TX)))
+ {
+ Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1);
+ Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1);
+ if ((Bl6523RxSerial->begin(BL6523_BAUD)) && (Bl6523TxSerial->begin(BL6523_BAUD)))
+ {
+ if (Bl6523RxSerial->hardwareSerial())
+ {
+ ClaimSerial();
+ }
+ if (Bl6523TxSerial->hardwareSerial())
+ {
+ ClaimSerial();
+ }
+ Bl6523.type = 1;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " ));
+ }
+ }
+}
+
+#ifdef USE_WEBSERVER
+const char HTTP_BL6523_SNM[] PROGMEM = "{s}BL6523 Smart Energy Monitor{m}{e}"; // {s} = , {m} = | , {e} = |
+const char HTTP_BL6523_SNS[] PROGMEM = "{s} %s {m}%s {e}"; // {s} = , {m} = | , {e} = |
+#endif // USE_WEBSERVER
+
+void Bl6523Show(bool json)
+{
+ uint32_t powf_word = 0;
+ float amps = 0.0f, volts = 0.0f, freq = 0.0f, watts = 0.0f, powf = 0.0f, watthr = 0 .0f;
+ char amps_str[12], volts_str[12], freq_str[12];
+ char watts_str[12], powf_str[12], watthr_str[12];
+
+ if (Bl6523.valid)
+ {
+
+ amps = (float)Bl6523.amps / BL6523_DIV_AMPS;
+ volts = (float)Bl6523.volts / BL6523_DIV_VOLTS;
+ freq = (float)Bl6523.freq / BL6523_DIV_FREQ;
+ watts = (float)Bl6523.watts / BL6523_DIV_WATTS;
+
+ /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。)
+ Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5
+ */
+ powf = 0.0f;
+ powf_word = Bl6523.powf & 0x7fffff; //Extract the 23 bits
+ for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
+ powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
+ powf_word = powf_word & (0x7fffff >> (1+i));
+ }
+ powf = (Bl6523.powf >> 23) ? (0.0f - (~powf)) : powf; // Negate if sign bit(24) is set
+
+ watthr = (float)Bl6523.watthr / BL6523_DIV_WATTHR;
+
+ ext_snprintf_P(amps_str, sizeof(amps_str), PSTR("%3_f"), &s);
+ ext_snprintf_P(volts_str, sizeof(volts_str), PSTR("%2_f"), &volts);
+ ext_snprintf_P(freq_str, sizeof(freq_str), PSTR("%2_f"), &freq);
+ ext_snprintf_P(watts_str, sizeof(watts_str), PSTR("%3_f"), &watts);
+ ext_snprintf_P(powf_str, sizeof(powf_str), PSTR("%2_f"), &powf);
+ ext_snprintf_P(watthr_str, sizeof(watthr_str), PSTR("%3_f"), &watthr);
+
+ if (json)
+ {
+ ResponseAppend_P(PSTR(",\"BL6523\":{"));
+ ResponseAppend_P(PSTR("\"Amps\":%s,"), amps_str);
+ ResponseAppend_P(PSTR("\"Volts\":%s,"), volts_str);
+ ResponseAppend_P(PSTR("\"Freq\":%s,"), freq_str);
+ ResponseAppend_P(PSTR("\"Watts\":%s,"), watts_str);
+ ResponseAppend_P(PSTR("\"Powf\":%s,"), powf_str);
+ ResponseAppend_P(PSTR("\"WattHr\":%s"), watthr_str);
+ ResponseJsonEnd();
+#ifdef USE_DOMOTICZ
+ if (0 == TasmotaGlobal.tele_period)
+ {
+ DomoticzSensor(DZ_CURRENT, amps_str); // Amps
+ DomoticzSensor(DZ_VOLTAGE, volts_str); // Voltage
+ DomoticzSensor(DZ_COUNT, freq_str); // Frequency
+ DomoticzSensor(DZ_ILLUMINANCE, watts_str); // Watts
+ DomoticzSensor(DZ_P1_SMART_METER, powf_str); // Power Factor
+ DomoticzSensor(DZ_POWER_ENERGY, watthr_str); // WattHour
+ }
+#endif // USE_DOMOTICZ
+#ifdef USE_WEBSERVER
+ }
+ else
+ {
+ WSContentSend_PD(HTTP_BL6523_SNM);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Amps:"), amps_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Volts:"), volts_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Freq:"), freq_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Watts:"), watts_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("PowF:"), powf_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("WattHr:"), watthr_str);
+#endif // USE_WEBSERVER
+ }
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns96(uint8_t function)
+{
+ bool result = false;
+
+ if (Bl6523.type)
+ {
+ switch (function)
+ {
+ case FUNC_EVERY_250_MSECOND:
+ Bl6523Update();
+ break;
+ case FUNC_JSON_APPEND:
+ Bl6523Show(1);
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ Bl6523Show(0);
+ break;
+#endif // USE_WEBSERVER
+ case FUNC_INIT:
+ Bl6523Init();
+ break;
+ }
+ }
+ return result;
+}
+
+#endif // USE_BL6523
\ No newline at end of file
From 73e3b4447758065b6cef47a194d0966aae57ed4c Mon Sep 17 00:00:00 2001
From: jeevasdev
Date: Tue, 15 Feb 2022 20:41:25 +1100
Subject: [PATCH 02/25] Converted BL6523 to nrg driver
---
tasmota/tasmota_template.h | 6 +
tasmota/xnrg_22_bl6523.ino | 355 +++++++++++++++++++++++++++++++++++++
2 files changed, 361 insertions(+)
create mode 100644 tasmota/xnrg_22_bl6523.ino
diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h
index 7af28acd4..fc57e9825 100644
--- a/tasmota/tasmota_template.h
+++ b/tasmota/tasmota_template.h
@@ -183,6 +183,7 @@ enum UserSelectablePins {
GPIO_SDM230_TX, GPIO_SDM230_RX, // SDM230 Serial interface
GPIO_ADC_MQ, // Analog MQ Sensor
GPIO_CM11_TXD, GPIO_CM11_RXD, // CM11 Serial interface
+ GPIO_BL6523_TX, GPIO_BL6523_RX, // BL6523 based Watt meter Serial interface
GPIO_SENSOR_END };
enum ProgramSelectablePins {
@@ -405,6 +406,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_SDM230_TX "|" D_SENSOR_SDM230_RX "|"
D_SENSOR_ADC_MQ "|"
D_SENSOR_CM11_TX "|" D_SENSOR_CM11_RX "|"
+ D_SENSOR_BL6523_TX "|" D_SENSOR_BL6523_RX "|"
;
const char kSensorNamesFixed[] PROGMEM =
@@ -772,6 +774,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_SDM230_TX), // SDM230 Serial interface
AGPIO(GPIO_SDM230_RX), // SDM230 Serial interface
#endif
+#ifdef USE_BL6523
+ AGPIO(GPIO_BL6523_TX), // BL6523 based Watt meter Serial interface
+ AGPIO(GPIO_BL6523_RX), // BL6523 based Watt meter Serial interface
+#endif
#endif // USE_ENERGY_SENSOR
/*-------------------------------------------------------------------------------------------*\
diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino
new file mode 100644
index 000000000..98b39780f
--- /dev/null
+++ b/tasmota/xnrg_22_bl6523.ino
@@ -0,0 +1,355 @@
+/*
+ xsns_96_bl6523.ino - Chinese bl6523 based Watt hour meter support for Tasmota
+
+ Copyright (C) 2022 Jeevas Vasudevan and the Internet
+
+ 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_ENERGY_SENSOR
+#ifdef USE_BL6523
+/*********************************************************************************************\
+ * Chinese BL6523 based Watt hour meter
+ *
+ * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
+ * To use Tasmota the user needs to add an ESP8266 or ESP32
+ * Three lines need to be connected via 1KOhh resistors to ESP from the main board(RX,TX GND)
+ *
+ * Connection Eg (ESP8266) - Non - Isolated:
+ * BL6523 RX ->1KOhm-> ESP IO4(D2) (Should be Input Capable)
+ * BL6523 TX ->1KOhm-> ESP IO5(D1) (Should be Input Capable)
+ * BL6523 GND -> ESP GND
+ *
+ * Connection Eg (ESP32) - Non - Isolated:
+ * BL6523 RX ->1KOhm-> ESP IO4 (Should be Input Capable)
+ * BL6523 TX ->1KOhm-> ESP IO5 (Should be Input Capable)
+ * BL6523 GND -> ESP GND
+ *
+ * To build add the below to user_config_override.h
+ * #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
+ *
+ * After Installation use the below template sample:
+ * {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
+\*********************************************************************************************/
+
+#define XNRG_22 22
+
+#include
+
+#define BL6523_RX_DATASET_SIZE 2
+#define BL6523_TX_DATASET_SIZE 4
+
+#define BL6523_BAUD 4800
+#define BL6523_REG_AMPS 0x05
+#define BL6523_REG_VOLTS 0x07
+#define BL6523_REG_FREQ 0x09
+#define BL6523_REG_WATTS 0x0A
+#define BL6523_REG_POWF 0x08
+#define BL6523_REG_WATTHR 0x0C
+
+/* No idea how to derive human readable units from the byte stream.
+For now dividing the 24-bit values with below constants seems to yield something sane
+that matches whatever displayed in the screen of my 240v model. Probably it would be possible
+to extract these values from the write register commands (0xCA).*/
+#define BL6523_DIV_AMPS 297899.4f
+#define BL6523_DIV_VOLTS 13304.0f
+#define BL6523_DIV_FREQ 3907.0f
+#define BL6523_DIV_WATTS 707.0f
+#define BL6523_DIV_WATTHR 674.0f
+
+TasmotaSerial *Bl6523RxSerial;
+TasmotaSerial *Bl6523TxSerial;
+
+struct BL6523
+{
+ uint32_t amps = 0;
+ uint32_t volts = 0;
+ uint32_t freq = 0;
+ uint32_t watts = 0;
+ uint32_t powf = 0;
+ uint32_t watthr = 0;
+
+ uint8_t type = 1;
+ uint8_t valid = 0;
+ uint8_t got_data_stone = 0;
+ bool discovery_triggered = false;
+} Bl6523;
+
+bool Bl6523ReadData(void)
+{
+
+ if (!Bl6523RxSerial->available())
+ {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 No Rx Data available " ));
+ return false;
+ }
+
+ while ((Bl6523RxSerial->peek() != 0x35) && Bl6523RxSerial->available())
+ {
+ Bl6523RxSerial->read();
+ }
+
+ if (Bl6523RxSerial->available() < BL6523_RX_DATASET_SIZE)
+ {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Rx less than expected " ));
+ return false;
+ }
+
+ uint8_t rx_buffer[BL6523_RX_DATASET_SIZE];
+ Bl6523RxSerial->readBytes(rx_buffer, BL6523_RX_DATASET_SIZE);
+ Bl6523RxSerial->flush(); // Make room for another burst
+
+ AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE);
+
+ while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE)
+ {
+ // sleep till TX buffer is full
+ unsigned long timeout = millis() + 10;
+ while (millis() < timeout) {}
+ }
+
+
+ uint8_t tx_buffer[BL6523_TX_DATASET_SIZE];
+ Bl6523TxSerial->readBytes(tx_buffer, BL6523_TX_DATASET_SIZE);
+ Bl6523TxSerial->flush(); // Make room for another burst
+
+
+ AddLogBuffer(LOG_LEVEL_DEBUG_MORE, tx_buffer, BL6523_TX_DATASET_SIZE);
+
+ /* Checksum: (Addr+Data_L+Data_M+Data_H) & 0xFF, then byte invert */
+ uint8_t crc = rx_buffer[1]; //Addr
+ for (uint32_t i = 0; i < (BL6523_TX_DATASET_SIZE - 1); i++)
+ {
+ crc += tx_buffer[i]; //Add Data_L,Data_M and Data_H to Addr
+ }
+ crc &= 0xff; // Bitwise AND 0xFF
+ crc = ~crc; // Invert the byte
+ if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1])
+ {
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6523 : " D_CHECKSUM_FAILURE));
+ Bl6523TxSerial->flush();
+ Bl6523RxSerial->flush();
+ return false;
+ }
+
+ /* WRITE DATA (format: command(write->0xCA) address data_low data_mid data_high checksum )
+WRITE Sample(RX):
+RX: CA 3E 55 00 00 6C (WRPROT - allow)
+RX: CA 14 00 00 10 DB (MODE)
+RX: CA 15 04 00 00 E6 (GAIN - IB 16x gain )
+RX: CA 19 08 00 00 DE (WA_CFDIV )
+RX: CA 3E AA 00 00 17 (WRPROT - disable)
+*/
+
+ /* READ DATA (format: command(read->0x35) address data_low data_mid data_high checksum )
+READ Sample(RX-TX) Data:
+RX: 35 05 TX: E4 00 00 16 (IA rms )
+RX: 35 07 TX: D5 A3 2E 52 (V rms )
+RX: 35 09 TX: F0 FB 02 09 (FREQ)
+RX: 35 0A TX: 00 00 00 F5 (WATT)
+RX: 35 08 TX: 00 00 00 F7 (PF)
+RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
+*/
+
+switch(rx_buffer[1]) {
+ case BL6523_REG_AMPS :
+ Bl6523.amps = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<0;
+ break;
+ case BL6523_REG_VOLTS :
+ Bl6523.volts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<1;
+ break;
+ case BL6523_REG_FREQ :
+ Bl6523.freq = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<2;
+ break;
+ case BL6523_REG_WATTS :
+ Bl6523.watts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<3;
+ break;
+ case BL6523_REG_POWF :
+ Bl6523.powf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<4;
+ break;
+ case BL6523_REG_WATTHR :
+ Bl6523.watthr = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ Bl6523.got_data_stone |= 1<<5;
+ break;
+ default :
+ break;
+}
+
+AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Amps: %d Volts: %d Freq: %d Watts: %d PowF: %d WattHr: %d"), Bl6523.amps, Bl6523.volts, Bl6523.freq, Bl6523.watts, Bl6523.powf, Bl6523.watthr);
+
+ if (!Bl6523.discovery_triggered)
+ {
+ TasmotaGlobal.discovery_counter = 1; // force TasDiscovery()
+ Bl6523.discovery_triggered = true;
+ }
+ return true;
+
+}
+
+/*********************************************************************************************/
+
+void Bl6523Update(void)
+{ // Every 250 millisecond
+ if (Bl6523ReadData())
+ {
+ Bl6523.valid = 60;
+ }
+ else
+ {
+ if (Bl6523.valid) {
+ Bl6523.valid--;
+ }
+ }
+}
+
+/*********************************************************************************************/
+
+void Bl6523Init(void)
+{
+ Bl6523.type = 0;
+ if ((PinUsed(GPIO_BL6523_RX)) && (PinUsed(GPIO_BL6523_TX)))
+ {
+ Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1);
+ Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1);
+ if ((Bl6523RxSerial->begin(BL6523_BAUD)) && (Bl6523TxSerial->begin(BL6523_BAUD)))
+ {
+ if (Bl6523RxSerial->hardwareSerial())
+ {
+ ClaimSerial();
+ }
+ if (Bl6523TxSerial->hardwareSerial())
+ {
+ ClaimSerial();
+ }
+ Bl6523.type = 1;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " ));
+ }
+ }
+}
+
+#ifdef USE_WEBSERVER
+const char HTTP_BL6523_SNM[] PROGMEM = "{s}BL6523 Smart Energy Monitor{m}{e}"; // {s} = , {m} = | , {e} = |
+const char HTTP_BL6523_SNS[] PROGMEM = "{s} %s {m}%s {e}"; // {s} = , {m} = | , {e} = |
+#endif // USE_WEBSERVER
+
+void Bl6523Show(bool json)
+{
+ uint32_t powf_word = 0;
+ float amps = 0.0f, volts = 0.0f, freq = 0.0f, watts = 0.0f, powf = 0.0f, watthr = 0.0f;
+ char amps_str[12], volts_str[12], freq_str[12];
+ char watts_str[12], powf_str[12], watthr_str[12];
+
+ if (Bl6523.valid)
+ {
+
+ amps = (float)Bl6523.amps / BL6523_DIV_AMPS;
+ volts = (float)Bl6523.volts / BL6523_DIV_VOLTS;
+ freq = (float)Bl6523.freq / BL6523_DIV_FREQ;
+ watts = (float)Bl6523.watts / BL6523_DIV_WATTS;
+
+ /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。)
+ Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5
+ */
+ powf = 0.0f;
+ powf_word = (Bl6523.powf >> 23) ? ~(Bl6523.powf & 0x7fffff) : Bl6523.powf & 0x7fffff; //Extract the 23 bits and invert if sign bit(24) is set
+ for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
+ powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
+ powf_word = powf_word & (0x7fffff >> (1+i));
+ }
+ powf = (Bl6523.powf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set
+
+ watthr = (float)Bl6523.watthr / BL6523_DIV_WATTHR;
+
+ ext_snprintf_P(amps_str, sizeof(amps_str), PSTR("%3_f"), &s);
+ ext_snprintf_P(volts_str, sizeof(volts_str), PSTR("%2_f"), &volts);
+ ext_snprintf_P(freq_str, sizeof(freq_str), PSTR("%2_f"), &freq);
+ ext_snprintf_P(watts_str, sizeof(watts_str), PSTR("%3_f"), &watts);
+ ext_snprintf_P(powf_str, sizeof(powf_str), PSTR("%2_f"), &powf);
+ ext_snprintf_P(watthr_str, sizeof(watthr_str), PSTR("%3_f"), &watthr);
+
+ if (json)
+ {
+ ResponseAppend_P(PSTR(",\"BL6523\":{"));
+ ResponseAppend_P(PSTR("\"Amps\":%s,"), amps_str);
+ ResponseAppend_P(PSTR("\"Volts\":%s,"), volts_str);
+ ResponseAppend_P(PSTR("\"Freq\":%s,"), freq_str);
+ ResponseAppend_P(PSTR("\"Watts\":%s,"), watts_str);
+ ResponseAppend_P(PSTR("\"Powf\":%s,"), powf_str);
+ ResponseAppend_P(PSTR("\"WattHr\":%s"), watthr_str);
+ ResponseJsonEnd();
+#ifdef USE_DOMOTICZ
+ if (0 == TasmotaGlobal.tele_period)
+ {
+ DomoticzSensor(DZ_CURRENT, amps_str); // Amps
+ DomoticzSensor(DZ_VOLTAGE, volts_str); // Voltage
+ DomoticzSensor(DZ_COUNT, freq_str); // Frequency
+ DomoticzSensor(DZ_ILLUMINANCE, watts_str); // Watts
+ DomoticzSensor(DZ_P1_SMART_METER, powf_str); // Power Factor
+ DomoticzSensor(DZ_POWER_ENERGY, watthr_str); // WattHour
+ }
+#endif // USE_DOMOTICZ
+#ifdef USE_WEBSERVER
+ }
+ else
+ {
+ WSContentSend_PD(HTTP_BL6523_SNM);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Amps:"), amps_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Volts:"), volts_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Freq:"), freq_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Watts:"), watts_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("PowF:"), powf_str);
+ WSContentSend_PD(HTTP_BL6523_SNS, PSTR("WattHr:"), watthr_str);
+#endif // USE_WEBSERVER
+ }
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xnrg22(uint8_t function)
+{
+ bool result = false;
+
+if ( FUNC_INIT == function )
+{
+ Bl6523Init();
+}
+else if ( Bl6523.type )
+ {
+ switch (function)
+ {
+ case FUNC_EVERY_250_MSECOND:
+ Bl6523Update();
+ break;
+ case FUNC_JSON_APPEND:
+ Bl6523Show(1);
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ Bl6523Show(0);
+ break;
+#endif // USE_WEBSERVER
+ }
+ }
+ return result;
+}
+
+#endif // USE_BL6523
+#endif // USE_ENERGY_SENSOR
\ No newline at end of file
From 6a7cb4f95e79869827f15a0b5102810145c5a558 Mon Sep 17 00:00:00 2001
From: jeevasdev
Date: Tue, 15 Feb 2022 21:03:30 +1100
Subject: [PATCH 03/25] Squashed commit of the following:
commit 1dc0638bbe4901efbe2c0bacefbcc32dac08e8ea
Author: jeevasdev
Date: Tue Feb 15 20:37:14 2022 +1100
Converted to xnrg as per review comment.
commit fa5570b0980e4bff1773a72eb417d8853f5c9e8e
Author: jeevasdev
Date: Tue Feb 15 13:46:50 2022 +1100
Added helper message to main comment.
commit bf7864fb56885161a19855a2ae92fe8a9348a8be
Author: jeevasdev
Date: Tue Feb 15 13:43:45 2022 +1100
Added BL6523 language files.
commit 0920d5c530b8253c12e436437b2954913ef1126d
Author: jeevasdev
Date: Tue Feb 15 13:34:34 2022 +1100
Added BL6523 to tasmota_template.
commit e119fc8a044e47179169b0caa7f1e31d099b4932
Author: jeevasdev
Date: Tue Feb 15 13:28:38 2022 +1100
Add BL6523 based smartmeter support main ino.
---
tasmota/xsns_96_bl6523.ino | 353 -------------------------------------
1 file changed, 353 deletions(-)
delete mode 100644 tasmota/xsns_96_bl6523.ino
diff --git a/tasmota/xsns_96_bl6523.ino b/tasmota/xsns_96_bl6523.ino
deleted file mode 100644
index 7587a897f..000000000
--- a/tasmota/xsns_96_bl6523.ino
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- xsns_96_bl6523.ino - Chinese bl6523 based Watt hour meter support for Tasmota
-
- Copyright (C) 2022 Jeevas Vasudevan and the Internet
-
- 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_BL6523
-/*********************************************************************************************\
- * Chinese BL6523 based Watt hour meter
- *
- * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
- * To use Tasmota the user needs to add an ESP8266 or ESP32
- * Three lines need to be connected via 1KOhh resistors to ESP from the main board(RX,TX GND)
- *
- * Connection Eg (ESP8266) - Non - Isolated:
- * BL6523 RX ->1KOhm-> ESP IO4(D2) (Should be Input Capable)
- * BL6523 TX ->1KOhm-> ESP IO5(D1) (Should be Input Capable)
- * BL6523 GND -> ESP GND
- *
- * Connection Eg (ESP32) - Non - Isolated:
- * BL6523 RX ->1KOhm-> ESP IO4 (Should be Input Capable)
- * BL6523 TX ->1KOhm-> ESP IO5 (Should be Input Capable)
- * BL6523 GND -> ESP GND
- *
- * To build add the below to user_config_override.h
- * #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
- *
- * After Installation use the below template sample:
- * {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
-\*********************************************************************************************/
-
-#define XSNS_96 96
-
-#include
-
-#define BL6523_RX_DATASET_SIZE 2
-#define BL6523_TX_DATASET_SIZE 4
-
-#define BL6523_BAUD 4800
-#define BL6523_REG_AMPS 0x05
-#define BL6523_REG_VOLTS 0x07
-#define BL6523_REG_FREQ 0x09
-#define BL6523_REG_WATTS 0x0A
-#define BL6523_REG_POWF 0x08
-#define BL6523_REG_WATTHR 0x0C
-
-/* No idea how to derive human readable units from the byte stream.
-For now dividing the 24-bit values with below constants seems to yield something sane
-that matches whatever displayed in the screen of my 240v model. Probably it would be possible
-to extract these values from the write register commands (0xCA).*/
-#define BL6523_DIV_AMPS 297899.4f
-#define BL6523_DIV_VOLTS 13304.0f
-#define BL6523_DIV_FREQ 3907.0f
-#define BL6523_DIV_WATTS 707.0f
-#define BL6523_DIV_WATTHR 674.0f
-
-TasmotaSerial *Bl6523RxSerial;
-TasmotaSerial *Bl6523TxSerial;
-
-struct BL6523
-{
- uint32_t amps = 0;
- uint32_t volts = 0;
- uint32_t freq = 0;
- uint32_t watts = 0;
- uint32_t powf = 0;
- uint32_t watthr = 0;
-
- uint8_t type = 1;
- uint8_t valid = 0;
- uint8_t got_data_stone = 0;
- bool discovery_triggered = false;
-} Bl6523;
-
-bool Bl6523ReadData(void)
-{
-
- if (!Bl6523RxSerial->available())
- {
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 No Rx Data available " ));
- return false;
- }
-
- while ((Bl6523RxSerial->peek() != 0x35) && Bl6523RxSerial->available())
- {
- Bl6523RxSerial->read();
- }
-
- if (Bl6523RxSerial->available() < BL6523_RX_DATASET_SIZE)
- {
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Rx less than expected " ));
- return false;
- }
-
- uint8_t rx_buffer[BL6523_RX_DATASET_SIZE];
- Bl6523RxSerial->readBytes(rx_buffer, BL6523_RX_DATASET_SIZE);
- Bl6523RxSerial->flush(); // Make room for another burst
-
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE);
-
- while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE)
- {
- // sleep till TX buffer is full
- unsigned long timeout = millis() + 10;
- while (millis() < timeout) {}
- }
-
-
- uint8_t tx_buffer[BL6523_TX_DATASET_SIZE];
- Bl6523TxSerial->readBytes(tx_buffer, BL6523_TX_DATASET_SIZE);
- Bl6523TxSerial->flush(); // Make room for another burst
-
-
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, tx_buffer, BL6523_TX_DATASET_SIZE);
-
- /* Checksum: (Addr+Data_L+Data_M+Data_H) & 0xFF, then byte invert */
- uint8_t crc = rx_buffer[1]; //Addr
- for (uint32_t i = 0; i < (BL6523_TX_DATASET_SIZE - 1); i++)
- {
- crc += tx_buffer[i]; //Add Data_L,Data_M and Data_H to Addr
- }
- crc &= 0xff; // Bitwise AND 0xFF
- crc = ~crc; // Invert the byte
- if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1])
- {
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6523 : " D_CHECKSUM_FAILURE));
- Bl6523TxSerial->flush();
- Bl6523RxSerial->flush();
- return false;
- }
-
- /* WRITE DATA (format: command(write->0xCA) address data_low data_mid data_high checksum )
-WRITE Sample(RX):
-RX: CA 3E 55 00 00 6C (WRPROT - allow)
-RX: CA 14 00 00 10 DB (MODE)
-RX: CA 15 04 00 00 E6 (GAIN - IB 16x gain )
-RX: CA 19 08 00 00 DE (WA_CFDIV )
-RX: CA 3E AA 00 00 17 (WRPROT - disable)
-*/
-
- /* READ DATA (format: command(read->0x35) address data_low data_mid data_high checksum )
-READ Sample(RX-TX) Data:
-RX: 35 05 TX: E4 00 00 16 (IA rms )
-RX: 35 07 TX: D5 A3 2E 52 (V rms )
-RX: 35 09 TX: F0 FB 02 09 (FREQ)
-RX: 35 0A TX: 00 00 00 F5 (WATT)
-RX: 35 08 TX: 00 00 00 F7 (PF)
-RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
-*/
-
-switch(rx_buffer[1]) {
- case BL6523_REG_AMPS :
- Bl6523.amps = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<0;
- break;
- case BL6523_REG_VOLTS :
- Bl6523.volts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<1;
- break;
- case BL6523_REG_FREQ :
- Bl6523.freq = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<2;
- break;
- case BL6523_REG_WATTS :
- Bl6523.watts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<3;
- break;
- case BL6523_REG_POWF :
- Bl6523.powf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<4;
- break;
- case BL6523_REG_WATTHR :
- Bl6523.watthr = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<5;
- break;
- default :
- break;
-}
-
-AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Amps: %d Volts: %d Freq: %d Watts: %d PowF: %d WattHr: %d"), Bl6523.amps, Bl6523.volts, Bl6523.freq, Bl6523.watts, Bl6523.powf, Bl6523.watthr);
-
- if (!Bl6523.discovery_triggered)
- {
- TasmotaGlobal.discovery_counter = 1; // force TasDiscovery()
- Bl6523.discovery_triggered = true;
- }
- return true;
-
-}
-
-/*********************************************************************************************/
-
-void Bl6523Update(void)
-{ // Every 250 millisecond
- if (Bl6523ReadData())
- {
- Bl6523.valid = 60;
- }
- else
- {
- if (Bl6523.valid) {
- Bl6523.valid--;
- }
- }
-}
-
-/*********************************************************************************************/
-
-void Bl6523Init(void)
-{
- Bl6523.type = 0;
- if ((PinUsed(GPIO_BL6523_RX)) && (PinUsed(GPIO_BL6523_TX)))
- {
- Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1);
- Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1);
- if ((Bl6523RxSerial->begin(BL6523_BAUD)) && (Bl6523TxSerial->begin(BL6523_BAUD)))
- {
- if (Bl6523RxSerial->hardwareSerial())
- {
- ClaimSerial();
- }
- if (Bl6523TxSerial->hardwareSerial())
- {
- ClaimSerial();
- }
- Bl6523.type = 1;
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " ));
- }
- }
-}
-
-#ifdef USE_WEBSERVER
-const char HTTP_BL6523_SNM[] PROGMEM = "{s}BL6523 Smart Energy Monitor{m}{e}"; // {s} = , {m} = | , {e} = |
-const char HTTP_BL6523_SNS[] PROGMEM = "{s} %s {m}%s {e}"; // {s} = , {m} = | , {e} = |
-#endif // USE_WEBSERVER
-
-void Bl6523Show(bool json)
-{
- uint32_t powf_word = 0;
- float amps = 0.0f, volts = 0.0f, freq = 0.0f, watts = 0.0f, powf = 0.0f, watthr = 0 .0f;
- char amps_str[12], volts_str[12], freq_str[12];
- char watts_str[12], powf_str[12], watthr_str[12];
-
- if (Bl6523.valid)
- {
-
- amps = (float)Bl6523.amps / BL6523_DIV_AMPS;
- volts = (float)Bl6523.volts / BL6523_DIV_VOLTS;
- freq = (float)Bl6523.freq / BL6523_DIV_FREQ;
- watts = (float)Bl6523.watts / BL6523_DIV_WATTS;
-
- /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。)
- Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5
- */
- powf = 0.0f;
- powf_word = Bl6523.powf & 0x7fffff; //Extract the 23 bits
- for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
- powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
- powf_word = powf_word & (0x7fffff >> (1+i));
- }
- powf = (Bl6523.powf >> 23) ? (0.0f - (~powf)) : powf; // Negate if sign bit(24) is set
-
- watthr = (float)Bl6523.watthr / BL6523_DIV_WATTHR;
-
- ext_snprintf_P(amps_str, sizeof(amps_str), PSTR("%3_f"), &s);
- ext_snprintf_P(volts_str, sizeof(volts_str), PSTR("%2_f"), &volts);
- ext_snprintf_P(freq_str, sizeof(freq_str), PSTR("%2_f"), &freq);
- ext_snprintf_P(watts_str, sizeof(watts_str), PSTR("%3_f"), &watts);
- ext_snprintf_P(powf_str, sizeof(powf_str), PSTR("%2_f"), &powf);
- ext_snprintf_P(watthr_str, sizeof(watthr_str), PSTR("%3_f"), &watthr);
-
- if (json)
- {
- ResponseAppend_P(PSTR(",\"BL6523\":{"));
- ResponseAppend_P(PSTR("\"Amps\":%s,"), amps_str);
- ResponseAppend_P(PSTR("\"Volts\":%s,"), volts_str);
- ResponseAppend_P(PSTR("\"Freq\":%s,"), freq_str);
- ResponseAppend_P(PSTR("\"Watts\":%s,"), watts_str);
- ResponseAppend_P(PSTR("\"Powf\":%s,"), powf_str);
- ResponseAppend_P(PSTR("\"WattHr\":%s"), watthr_str);
- ResponseJsonEnd();
-#ifdef USE_DOMOTICZ
- if (0 == TasmotaGlobal.tele_period)
- {
- DomoticzSensor(DZ_CURRENT, amps_str); // Amps
- DomoticzSensor(DZ_VOLTAGE, volts_str); // Voltage
- DomoticzSensor(DZ_COUNT, freq_str); // Frequency
- DomoticzSensor(DZ_ILLUMINANCE, watts_str); // Watts
- DomoticzSensor(DZ_P1_SMART_METER, powf_str); // Power Factor
- DomoticzSensor(DZ_POWER_ENERGY, watthr_str); // WattHour
- }
-#endif // USE_DOMOTICZ
-#ifdef USE_WEBSERVER
- }
- else
- {
- WSContentSend_PD(HTTP_BL6523_SNM);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Amps:"), amps_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Volts:"), volts_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Freq:"), freq_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Watts:"), watts_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("PowF:"), powf_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("WattHr:"), watthr_str);
-#endif // USE_WEBSERVER
- }
- }
-}
-
-/*********************************************************************************************\
- * Interface
-\*********************************************************************************************/
-
-bool Xsns96(uint8_t function)
-{
- bool result = false;
-
- if (Bl6523.type)
- {
- switch (function)
- {
- case FUNC_EVERY_250_MSECOND:
- Bl6523Update();
- break;
- case FUNC_JSON_APPEND:
- Bl6523Show(1);
- break;
-#ifdef USE_WEBSERVER
- case FUNC_WEB_SENSOR:
- Bl6523Show(0);
- break;
-#endif // USE_WEBSERVER
- case FUNC_INIT:
- Bl6523Init();
- break;
- }
- }
- return result;
-}
-
-#endif // USE_BL6523
\ No newline at end of file
From cf09c5246ed343c61ed0104f895682d6582a03ca Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 15 Feb 2022 12:11:45 +0100
Subject: [PATCH 04/25] Zigbee ZStack3 fix to changing channel
---
tasmota/xdrv_23_zigbee_0_constants.ino | 11 ++-
tasmota/xdrv_23_zigbee_1_headers.ino | 1 +
tasmota/xdrv_23_zigbee_7_0_statemachine.ino | 75 ++++++++++++++++-----
tasmota/xdrv_23_zigbee_8_parsers.ino | 4 +-
4 files changed, 72 insertions(+), 19 deletions(-)
diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino
index d7a5a7aad..ac2aae6ed 100644
--- a/tasmota/xdrv_23_zigbee_0_constants.ino
+++ b/tasmota/xdrv_23_zigbee_0_constants.ino
@@ -52,7 +52,8 @@ enum ZnpSubsystem {
Z_SAPI = 0x06,
Z_UTIL = 0x07,
Z_DEBUG = 0x08,
- Z_APP = 0x09
+ Z_APP = 0x09,
+ Z_APP_CNF = 0x0F, // new in ZStacK 3
};
#endif // USE_ZIGBEE_ZNP
@@ -1103,6 +1104,14 @@ enum Z_Util {
Z_UTIL_ZCL_KEY_ESTABLISH_IND = 0xE1
};
+enum Z_App_Cnf {
+ Z_APP_CNF_BDB_START_COMMISSIONING = 0x05,
+ Z_APP_CNF_BDB_SET_CHANNEL = 0x08,
+ Z_APP_CNF_BDB_SET_TC_REQUIRE_KEY_EXCHANGE = 0x09,
+ Z_APP_CNF_BDB_COMMISSIONING_NOTIFICATION = 0x80,
+ Z_APP_CNF_BDB_SET_NWK_FRAME_COUNTER = 0xFF,
+};
+
enum ZCL_Global_Commands {
ZCL_READ_ATTRIBUTES = 0x00,
ZCL_READ_ATTRIBUTES_RESPONSE = 0x01,
diff --git a/tasmota/xdrv_23_zigbee_1_headers.ino b/tasmota/xdrv_23_zigbee_1_headers.ino
index 3e541aa7d..063c6ddc6 100644
--- a/tasmota/xdrv_23_zigbee_1_headers.ino
+++ b/tasmota/xdrv_23_zigbee_1_headers.ino
@@ -80,6 +80,7 @@ const uint8_t ZIGBEE_LABEL_INIT_DEVICE = 14; // Init ZNP as end-device
const uint8_t ZIGBEE_LABEL_START_DEVICE = 15; // Start ZNP as end-device
const uint8_t ZIGBEE_LABEL_START_ROUTER_DEVICE = 16; // Start common to router and device
const uint8_t ZIGBEE_LABEL_ZB3_INIT = 17; // check parameters for ZB3
+const uint8_t ZIGBEE_LABEL_COORD_STARTED = 18; // Coordinator has started
const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST = 19; // common post configuration for router and device
const uint8_t ZIGBEE_LABEL_READY = 20; // goto label 20 for main loop
const uint8_t ZIGBEE_LABEL_MAIN_LOOP = 21; // main loop
diff --git a/tasmota/xdrv_23_zigbee_7_0_statemachine.ino b/tasmota/xdrv_23_zigbee_7_0_statemachine.ino
index 3fd21ad51..13f301b29 100644
--- a/tasmota/xdrv_23_zigbee_7_0_statemachine.ino
+++ b/tasmota/xdrv_23_zigbee_7_0_statemachine.ino
@@ -223,6 +223,16 @@ const uint32_t ZB_ALL_CHANNELS = 0x07FFF800;
ZBR(ZBS_W_ALL_CHANN, Z_SREQ | Z_SYS, SYS_OSAL_NV_WRITE, CONF_CHANLIST,0x00, 0x00, 0x04 /* len */,
Z_B0(ZB_ALL_CHANNELS), Z_B1(ZB_ALL_CHANNELS), Z_B2(ZB_ALL_CHANNELS), Z_B3(ZB_ALL_CHANNELS),
/*0x00, 0x08, 0x00, 0x00*/ ) // 21098400000400F8FF7F
+
+// Configure BDB Channels
+ZBR(ZBS_W_BDB_CHANN, Z_SREQ | Z_APP_CNF, Z_APP_CNF_BDB_SET_CHANNEL, 0x01 /*primary*/,
+ Z_B0(USE_ZIGBEE_CHANNEL_MASK), Z_B1(USE_ZIGBEE_CHANNEL_MASK), Z_B2(USE_ZIGBEE_CHANNEL_MASK), Z_B3(USE_ZIGBEE_CHANNEL_MASK),
+ /*0x00, 0x08, 0x00, 0x00*/ ) // 2F0801xxxxxxxx
+// Configure BDB Channels secondary channel to zeroes
+ZBM(ZBS_W_BDB_CHANN2, Z_SREQ | Z_APP_CNF, Z_APP_CNF_BDB_SET_CHANNEL, 0x00 /*secondary*/,
+ 0x00, 0x08, 0x00, 0x00 ) // 2F080000000000
+ZBM(ZBR_W_BDB_CHANN_OK, Z_SRSP | Z_APP_CNF, Z_APP_CNF_BDB_SET_CHANNEL, Z_SUCCESS ) // 6F0800
+
// Write Logical Type = 00 = coordinator
ZBM(ZBS_W_LOGTYP_COORD, Z_SREQ | Z_SYS, SYS_OSAL_NV_WRITE, CONF_LOGICAL_TYPE,0x00, 0x00, 0x01 /* len */, 0x00 ) // 21098700000100
// Write Logical Type = 01 = router
@@ -263,6 +273,10 @@ ZBM(AREQ_STARTUPFROMAPP, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND ) // 45C00xx -
ZBM(AREQ_STARTUPFROMAPP_COORD, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND, ZDO_DEV_ZB_COORD ) // 45C009 + 08 = starting, 09 = started
ZBM(AREQ_STARTUPFROMAPP_ROUTER, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND, ZDO_DEV_ROUTER ) // 45C009 + 02 = looking PanID, 07 = started
ZBM(AREQ_STARTUPFROMAPP_DEVICE, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND, ZDO_DEV_END_DEVICE ) // 45C009 + 02 = looking PanID, 06 = started
+// BDB START Commissioning
+ZBM(ZBS_BDB_START_COMMIS, Z_SREQ | Z_APP_CNF, Z_APP_CNF_BDB_START_COMMISSIONING, 0x04 /*mode*/) // 2F0504
+ZBM(ZBR_BDB_START_COMMIS, Z_SRSP | Z_APP_CNF, Z_APP_CNF_BDB_START_COMMISSIONING, Z_SUCCESS) // 6F0500
+
// GetDeviceInfo
ZBM(ZBS_GETDEVICEINFO, Z_SREQ | Z_UTIL, Z_UTIL_GET_DEVICE_INFO ) // 2700
ZBM(ZBR_GETDEVICEINFO, Z_SRSP | Z_UTIL, Z_UTIL_GET_DEVICE_INFO, Z_SUCCESS ) // Ex= 6700.00.6263151D004B1200.0000.07.09.00
@@ -296,8 +310,10 @@ ZBM(AREQ_ZDO_NODEDESCRSP, Z_AREQ | Z_ZDO, ZDO_NODE_DESC_RSP) // 4582
// Z_ZDO:activeEpReq
ZBM(ZBS_ZDO_ACTIVEEPREQ, Z_SREQ | Z_ZDO, ZDO_ACTIVE_EP_REQ, 0x00, 0x00, 0x00, 0x00) // 250500000000
ZBM(ZBR_ZDO_ACTIVEEPREQ, Z_SRSP | Z_ZDO, ZDO_ACTIVE_EP_REQ, Z_SUCCESS) // 65050000
-ZBM(ZBR_ZDO_ACTIVEEPRSP_NONE, Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP, 0x00, 0x00 /* srcAddr */, Z_SUCCESS,
- 0x00, 0x00 /* nwkaddr */, 0x00 /* activeepcount */) // 45050000 - no Ep running
+// ZBM(ZBR_ZDO_ACTIVEEPRSP_NONE, Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP, 0x00, 0x00 /* srcAddr */, Z_SUCCESS,
+// 0x00, 0x00 /* nwkaddr */, 0x00 /* activeepcount */) // 45050000 - no Ep running
+// 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
@@ -371,6 +387,10 @@ void ZNP_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_pa
ZBW(ZBS_W_CHANN, Z_SREQ | Z_SYS, SYS_OSAL_NV_WRITE, CONF_CHANLIST,0x00, 0x00, 0x04 /* len */,
Z_B0(zb_channel_mask), Z_B1(zb_channel_mask), Z_B2(zb_channel_mask), Z_B3(zb_channel_mask),
/*0x00, 0x08, 0x00, 0x00*/ ) // 210984000004xxxxxxxx
+ // Write BDB Channel ID - ZStack3 specific
+ ZBW(ZBS_W_BDB_CHANN, Z_SREQ | Z_APP_CNF, Z_APP_CNF_BDB_SET_CHANNEL, 0x01 /*primary*/,
+ Z_B0(zb_channel_mask), Z_B1(zb_channel_mask), Z_B2(zb_channel_mask), Z_B3(zb_channel_mask),
+ /*0x00, 0x08, 0x00, 0x00*/ ) // 2F0801xxxxxxxx
// Write precfgkey
ZBW(ZBS_W_PFGK, Z_SREQ | Z_SYS, SYS_OSAL_NV_WRITE, CONF_PRECFGKEY,0x00, 0x00,
0x10 /* len */,
@@ -401,7 +421,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
ZI_WAIT(15500) // wait for 15 seconds for Tasmota to stabilize
//ZI_MQTT_STATE(ZIGBEE_STATUS_BOOT, "Booting")
- ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting CC2530 device")
+ ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting ZNP device")
ZI_CALL(&ZNP_Reset_Device, 0) // LOW = reset
ZI_WAIT(100) // wait for .1 second
@@ -434,34 +454,54 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
ZI_SEND(ZBS_PFGKEN) // check PFGKEN
ZI_WAIT_RECV(1000, ZBR_PFGKEN)
+ ZI_LABEL(ZIGBEE_LABEL_START_COORD)
+ // Check if the MCU is running ZStack3, it so goto ZIGBEE_LABEL_ZB3_INIT, or continue
ZI_CALL(&Z_GotoZB3, ZIGBEE_LABEL_ZB3_INIT)
+ // ======================================================================
+ // Start procedure for ZStack 1.2
+ // ======================================================================
ZI_SEND(ZBS_PFGK) // check PFGK on ZB1.2
ZI_WAIT_RECV(1000, ZBR_PFGK)
- ZI_GOTO(ZIGBEE_LABEL_START_COORD)
- ZI_LABEL(ZIGBEE_LABEL_ZB3_INIT)
- ZI_SEND(ZBS_PFGK3) // check PFGK on ZB3
- ZI_WAIT_RECV(1000, ZBR_PFGK3)
- //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "zigbee configuration ok")
// all is good, we can start
-
- ZI_LABEL(ZIGBEE_LABEL_START_COORD) // START ZNP App
ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord)
- ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT)
- // Z_ZDO:startupFromApp
- //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "starting zigbee coordinator")
- ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator
+ 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_UNTIL_FUNC(20000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started, max 20s
+ ZI_GOTO(ZIGBEE_LABEL_COORD_STARTED)
+
+ // ======================================================================
+ // Start procedure for ZStack 3
+ // ======================================================================
+ ZI_LABEL(ZIGBEE_LABEL_ZB3_INIT)
+ ZI_SEND(ZBS_PFGK3) // check PFGK on ZB3
+ ZI_WAIT_RECV(1000, ZBR_PFGK3)
+
+ ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord)
+ ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) // set any failure to ABORT
+ // Set channel mask for primary and secondary, using BDB_SET_CHANNEL
+ ZI_SEND(ZBS_W_BDB_CHANN) // set channel for primary network
+ ZI_WAIT_RECV(2000, ZBR_W_BDB_CHANN_OK)
+ ZI_SEND(ZBS_W_BDB_CHANN2) // no channel for secondary network
+ 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_UNTIL_FUNC(20000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started, max 20s
+
+ // ======================================================================
+ // Coordinator has started, to post-configuration
+ // ======================================================================
+ ZI_LABEL(ZIGBEE_LABEL_COORD_STARTED) // Coordinator has started
ZI_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo
ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &ZNP_ReceiveDeviceInfo)
- //ZI_WAIT_RECV(2000, ZBR_GETDEVICEINFO) // memorize info
ZI_SEND(ZBS_ZDO_NODEDESCREQ) // Z_ZDO:nodeDescReq
ZI_WAIT_RECV(1000, ZBR_ZDO_NODEDESCREQ)
ZI_WAIT_UNTIL(5000, AREQ_ZDO_NODEDESCRSP)
ZI_SEND(ZBS_ZDO_ACTIVEEPREQ) // Z_ZDO:activeEpReq
ZI_WAIT_RECV(1000, ZBR_ZDO_ACTIVEEPREQ)
- ZI_WAIT_UNTIL(1000, ZBR_ZDO_ACTIVEEPRSP_NONE)
+ ZI_WAIT_UNTIL(1000, ZBR_ZDO_ACTIVEEPRSP_SUCESS)
ZI_SEND(ZBS_AF_REGISTER01) // Z_AF register for endpoint 01, profile 0x0104 Home Automation
ZI_WAIT_RECV(1000, ZBR_AF_REGISTER)
ZI_SEND(ZBS_AF_REGISTER0B) // Z_AF register for endpoint 0B, profile 0x0104 Home Automation
@@ -495,6 +535,9 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
ZI_WAIT_FOREVER()
ZI_GOTO(ZIGBEE_LABEL_READY)
+ // ======================================================================
+ // Wrong configuration, do a factory reset and push configuration
+ // ======================================================================
ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_COORD) // reformat device
ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting)
//ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "zigbee bad configuration of device, doing a factory reset")
diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino
index 2f3b9688f..0e1abe0a4 100644
--- a/tasmota/xdrv_23_zigbee_8_parsers.ino
+++ b/tasmota/xdrv_23_zigbee_8_parsers.ino
@@ -51,7 +51,7 @@ void EZ_RSTACK(uint8_t reset_code) {
default: reason_str = PSTR("Unknown"); break;
}
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
- "\"Status\":%d,\"Message\":\"EFR32 booted\",\"RestartReason\":\"%s\""
+ "\"Status\":%d,\"Message\":\"EFR32 EZSP booted\",\"RestartReason\":\"%s\""
",\"Code\":%d}}"),
ZIGBEE_STATUS_BOOT, reason_str, reset_code);
@@ -418,7 +418,7 @@ int32_t ZNP_Reboot(int32_t res, SBuffer &buf) {
}
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
- "\"Status\":%d,\"Message\":\"CCxxxx booted\",\"RestartReason\":\"%s\""
+ "\"Status\":%d,\"Message\":\"CCxxxx ZNP booted\",\"RestartReason\":\"%s\""
",\"MajorRel\":%d,\"MinorRel\":%d}}"),
ZIGBEE_STATUS_BOOT, reason_str,
major_rel, minor_rel);
From c074573f099ffba8ab8090801d4b20bbfae3b229 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 15 Feb 2022 14:32:42 +0100
Subject: [PATCH 05/25] Fix wiegand 34-bit rfid reading and presentation
Fix wiegand 34-bit rfid reading and presentation (#14834)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/xsns_82_wiegand.ino | 16 ++++++++++------
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3d974890..f5c2badd7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file.
- GPIO OptionE1 selection regression (#14821)
- BL0939, BL0940 and BL0942 energy monitoring buffer miscompares resulting in wrong daily energy values regression from v9.5.0.8 (#14829)
- Orno WE517 power meter phase 2 current reactive (#14841)
+- Wiegand 34-bit rfid reading and presentation (#14834)
## [Released]
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 45636d317..a4187f10d 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -123,6 +123,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- SSPM energy yesterday when zero
- GPIO OptionE1 selection regression [#14821](https://github.com/arendst/Tasmota/issues/14821)
- BL0939, BL0940 and BL0942 energy monitoring buffer miscompares resulting in wrong daily energy values regression from v9.5.0.8 [#14829](https://github.com/arendst/Tasmota/issues/14829)
+- Wiegand 34-bit rfid reading and presentation [#14834](https://github.com/arendst/Tasmota/issues/14834)
- Orno WE517 power meter phase 2 current reactive [#14841](https://github.com/arendst/Tasmota/issues/14841)
### Removed
diff --git a/tasmota/xsns_82_wiegand.ino b/tasmota/xsns_82_wiegand.ino
index beaf49153..5aaa22d4f 100644
--- a/tasmota/xsns_82_wiegand.ino
+++ b/tasmota/xsns_82_wiegand.ino
@@ -37,7 +37,11 @@
* Rule:
* on wiegand#uid=4302741608 do publish cmnd/ailight/power 2 endon
*
- * contains:
+ * 20220215
+ * - fix 34-bit size parity chk
+ * - fix 64-bit representation after removal of %llu support (Tasmota does not support 64-bit decimal output specifier (%llu) saving 60k code)
+ * ---
+ * 20201101
* - fix for #11047 Wiegand 26/34 missed some key press if they are press at normal speed
* - removed testing code for tests without attached hardware
* - added SetOption123 0-Wiegand UID decimal (default) 1-Wiegand UID hexadecimal
@@ -264,8 +268,8 @@ uint64_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitCount) {
break;
case 34:
- evenParityBit = (rfidIn & 0x400000000) ? 0x80 : 0;
- rfidIn = (rfidIn & 0x3FFFFFFFE) >>1;
+ evenParityBit = (rfidIn & 0x200000000) ? 0x80 : 0;
+ rfidIn = (rfidIn & 0x1FFFFFFFE) >>1;
break;
default:
@@ -274,7 +278,7 @@ uint64_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitCount) {
calcParity = CalculateParities(rfidIn, bitCount); // Check result on http://www.ccdesignworks.com/wiegand_calc.htm with raw tag as input
if (calcParity != (evenParityBit | oddParityBit)) { // Parity bit is wrong
rfidIn=0;
- AddLog(LOG_LEVEL_DEBUG, PSTR("WIE: %llu parity error"), rfidIn);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("WIE: %_X parity error"), &rfidIn);
}
#if (DEV_WIEGAND_TEST_MODE)>0
AddLog(LOG_LEVEL_INFO, PSTR("WIE: even (left) parity: %u "), (evenParityBit>>7));
@@ -412,7 +416,7 @@ void Wiegand::ScanForTag() {
if (GetOption(WIEGAND_OPTION_HEX) == 0) {
ResponseTime_P(PSTR(",\"Wiegand\":{\"UID\":%lu,\"" D_JSON_SIZE "\":%d}}"), (uint32_t)rfid, tagSize);
} else {
- ResponseTime_P(PSTR(",\"Wiegand\":{\"UID\":\"%2_X" WIEGAND_OPTION_HEX_POSTFIX "\",\"" D_JSON_SIZE "\":\"%X" WIEGAND_OPTION_HEX_POSTFIX "\"}}"), &rfid, tagSize);
+ ResponseTime_P(PSTR(",\"Wiegand\":{\"UID\":\"%1_X" WIEGAND_OPTION_HEX_POSTFIX "\",\"" D_JSON_SIZE "\":%d}}"), &rfid, tagSize);
}
MqttPublishTeleSensor();
}
@@ -443,7 +447,7 @@ void Wiegand::Show(void) {
if (GetOption(WIEGAND_OPTION_HEX) == 0) {
WSContentSend_P(PSTR("{s}Wiegand UID{m}%lu{e}"), (tagSize>0) ? (uint32_t)rfid : (uint32_t)webRFIDKeypadBuffer);
} else {
- WSContentSend_P(PSTR("{s}Wiegand UID{m}%2_X" WIEGAND_OPTION_HEX_POSTFIX "{e}"), (tagSize>0) ? &rfid : &webRFIDKeypadBuffer);
+ WSContentSend_P(PSTR("{s}Wiegand UID{m}%1_X" WIEGAND_OPTION_HEX_POSTFIX "{e}"), (tagSize>0) ? &rfid : &webRFIDKeypadBuffer);
}
#if (DEV_WIEGAND_TEST_MODE)>0
AddLog(LOG_LEVEL_INFO, PSTR("WIE: Tag %llu, Bits %u"), rfid, bitCount);
From f2bd57c5e6915a7f63f495aed0fb8641b64b32ba Mon Sep 17 00:00:00 2001
From: jeevasdev
Date: Wed, 16 Feb 2022 02:32:29 +1100
Subject: [PATCH 06/25] NRG sensor rewrite.
---
tasmota/tasmota_template.h | 6 --
tasmota/xnrg_22_bl6523.ino | 162 +++++++++++--------------------------
2 files changed, 49 insertions(+), 119 deletions(-)
diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h
index fc57e9825..3c2ab3902 100644
--- a/tasmota/tasmota_template.h
+++ b/tasmota/tasmota_template.h
@@ -172,7 +172,6 @@ enum UserSelectablePins {
GPIO_MCP2515_CS, // MCP2515 Chip Select
GPIO_HRG15_TX, GPIO_HRG15_RX, // Hydreon RG-15 rain sensor serial interface
GPIO_VINDRIKTNING_RX, // IKEA VINDRIKTNING Serial interface
- GPIO_BL6523_TX, GPIO_BL6523_RX, // BL6523 based Watt meter Serial interface
GPIO_BL0939_RX, // BL0939 Serial interface (Dual R3 v2)
GPIO_BL0942_RX, // BL0942 Serial interface
GPIO_HM330X_SET, // HM330X SET pin (sleep when low)
@@ -395,7 +394,6 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_MCP2515_CS "|"
D_SENSOR_HRG15_TX "|" D_SENSOR_HRG15_RX "|"
D_SENSOR_VINDRIKTNING_RX "|"
- D_SENSOR_BL6523_TX "|" D_SENSOR_BL6523_RX "|"
D_SENSOR_BL0939_RX "|"
D_SENSOR_BL0942_RX "|"
D_SENSOR_HM330X_SET "|"
@@ -820,10 +818,6 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#ifdef USE_VINDRIKTNING
AGPIO(GPIO_VINDRIKTNING_RX),
#endif
-#ifdef USE_BL6523
- AGPIO(GPIO_BL6523_TX),
- AGPIO(GPIO_BL6523_RX),
-#endif
#ifdef USE_HM330X
AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low)
#endif
diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino
index 98b39780f..28d7e2f0c 100644
--- a/tasmota/xnrg_22_bl6523.ino
+++ b/tasmota/xnrg_22_bl6523.ino
@@ -36,7 +36,8 @@
* BL6523 GND -> ESP GND
*
* To build add the below to user_config_override.h
- * #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
+ * #define USE_ENERGY_SENSOR // Enable Energy sensor framework
+ * #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
*
* After Installation use the below template sample:
* {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
@@ -57,6 +58,8 @@
#define BL6523_REG_POWF 0x08
#define BL6523_REG_WATTHR 0x0C
+#define SINGLE_PHASE 0
+
/* No idea how to derive human readable units from the byte stream.
For now dividing the 24-bit values with below constants seems to yield something sane
that matches whatever displayed in the screen of my 240v model. Probably it would be possible
@@ -72,13 +75,6 @@ TasmotaSerial *Bl6523TxSerial;
struct BL6523
{
- uint32_t amps = 0;
- uint32_t volts = 0;
- uint32_t freq = 0;
- uint32_t watts = 0;
- uint32_t powf = 0;
- uint32_t watthr = 0;
-
uint8_t type = 1;
uint8_t valid = 0;
uint8_t got_data_stone = 0;
@@ -87,6 +83,8 @@ struct BL6523
bool Bl6523ReadData(void)
{
+ uint32_t powf_word = 0, powf_buf = 0;
+ float powf = 0.0f;
if (!Bl6523RxSerial->available())
{
@@ -163,35 +161,39 @@ RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
switch(rx_buffer[1]) {
case BL6523_REG_AMPS :
- Bl6523.amps = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<0;
+ Energy.current[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_AMPS; // 1.260 A
break;
case BL6523_REG_VOLTS :
- Bl6523.volts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<1;
+ Energy.voltage[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_VOLTS; // 230.2 V
break;
case BL6523_REG_FREQ :
- Bl6523.freq = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<2;
+ Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_FREQ; // 50.0 Hz
break;
case BL6523_REG_WATTS :
- Bl6523.watts = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<3;
+ Energy.active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_WATTS; // -196.3 W
break;
case BL6523_REG_POWF :
- Bl6523.powf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<4;
+ /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。)
+ Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5
+ */
+ powf = 0.0f;
+ powf_buf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
+ powf_word = (powf_buf >> 23) ? ~(powf_buf & 0x7fffff) : powf_buf & 0x7fffff; //Extract the 23 bits and invert if sign bit(24) is set
+ for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
+ powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
+ powf_word = powf_word & (0x7fffff >> (1+i));
+ }
+ powf = (powf_buf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set
+ Energy.power_factor[SINGLE_PHASE] = powf;
break;
case BL6523_REG_WATTHR :
- Bl6523.watthr = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
- Bl6523.got_data_stone |= 1<<5;
+ Energy.import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / BL6523_DIV_WATTHR; // 6.216 kWh => used in EnergyUpdateTotal()
break;
default :
break;
}
-
-AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Amps: %d Volts: %d Freq: %d Watts: %d PowF: %d WattHr: %d"), Bl6523.amps, Bl6523.volts, Bl6523.freq, Bl6523.watts, Bl6523.powf, Bl6523.watthr);
-
+ Energy.data_valid[SINGLE_PHASE] = 0;
+ EnergyUpdateTotal();
if (!Bl6523.discovery_triggered)
{
TasmotaGlobal.discovery_counter = 1; // force TasDiscovery()
@@ -221,9 +223,8 @@ void Bl6523Update(void)
void Bl6523Init(void)
{
- Bl6523.type = 0;
- if ((PinUsed(GPIO_BL6523_RX)) && (PinUsed(GPIO_BL6523_TX)))
- {
+
+ Bl6523.type = 0;
Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1);
Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1);
if ((Bl6523RxSerial->begin(BL6523_BAUD)) && (Bl6523TxSerial->begin(BL6523_BAUD)))
@@ -237,86 +238,29 @@ void Bl6523Init(void)
ClaimSerial();
}
Bl6523.type = 1;
+ Energy.phase_count = 1;
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " ));
}
- }
+ else
+ {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Failure! " ));
+ TasmotaGlobal.energy_driver = ENERGY_NONE;
+ }
+
}
-#ifdef USE_WEBSERVER
-const char HTTP_BL6523_SNM[] PROGMEM = "{s}BL6523 Smart Energy Monitor{m}{e}"; // {s} = , {m} = | , {e} = |
-const char HTTP_BL6523_SNS[] PROGMEM = "{s} %s {m}%s {e}"; // {s} = , {m} = | , {e} = |
-#endif // USE_WEBSERVER
-
-void Bl6523Show(bool json)
+void Bl6523DrvInit(void)
{
- uint32_t powf_word = 0;
- float amps = 0.0f, volts = 0.0f, freq = 0.0f, watts = 0.0f, powf = 0.0f, watthr = 0.0f;
- char amps_str[12], volts_str[12], freq_str[12];
- char watts_str[12], powf_str[12], watthr_str[12];
-
- if (Bl6523.valid)
- {
-
- amps = (float)Bl6523.amps / BL6523_DIV_AMPS;
- volts = (float)Bl6523.volts / BL6523_DIV_VOLTS;
- freq = (float)Bl6523.freq / BL6523_DIV_FREQ;
- watts = (float)Bl6523.watts / BL6523_DIV_WATTS;
-
- /* Power factor =(sign bit)*((PF[22]×2^-1)+(PF[21]×2^-2)+。。。)
- Eg., reg value 0x7FFFFF(HEX) -> PF 1, 0x800000(HEX) -> -1, 0x400000(HEX) -> 0.5
- */
- powf = 0.0f;
- powf_word = (Bl6523.powf >> 23) ? ~(Bl6523.powf & 0x7fffff) : Bl6523.powf & 0x7fffff; //Extract the 23 bits and invert if sign bit(24) is set
- for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
- powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
- powf_word = powf_word & (0x7fffff >> (1+i));
- }
- powf = (Bl6523.powf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set
-
- watthr = (float)Bl6523.watthr / BL6523_DIV_WATTHR;
-
- ext_snprintf_P(amps_str, sizeof(amps_str), PSTR("%3_f"), &s);
- ext_snprintf_P(volts_str, sizeof(volts_str), PSTR("%2_f"), &volts);
- ext_snprintf_P(freq_str, sizeof(freq_str), PSTR("%2_f"), &freq);
- ext_snprintf_P(watts_str, sizeof(watts_str), PSTR("%3_f"), &watts);
- ext_snprintf_P(powf_str, sizeof(powf_str), PSTR("%2_f"), &powf);
- ext_snprintf_P(watthr_str, sizeof(watthr_str), PSTR("%3_f"), &watthr);
-
- if (json)
- {
- ResponseAppend_P(PSTR(",\"BL6523\":{"));
- ResponseAppend_P(PSTR("\"Amps\":%s,"), amps_str);
- ResponseAppend_P(PSTR("\"Volts\":%s,"), volts_str);
- ResponseAppend_P(PSTR("\"Freq\":%s,"), freq_str);
- ResponseAppend_P(PSTR("\"Watts\":%s,"), watts_str);
- ResponseAppend_P(PSTR("\"Powf\":%s,"), powf_str);
- ResponseAppend_P(PSTR("\"WattHr\":%s"), watthr_str);
- ResponseJsonEnd();
-#ifdef USE_DOMOTICZ
- if (0 == TasmotaGlobal.tele_period)
- {
- DomoticzSensor(DZ_CURRENT, amps_str); // Amps
- DomoticzSensor(DZ_VOLTAGE, volts_str); // Voltage
- DomoticzSensor(DZ_COUNT, freq_str); // Frequency
- DomoticzSensor(DZ_ILLUMINANCE, watts_str); // Watts
- DomoticzSensor(DZ_P1_SMART_METER, powf_str); // Power Factor
- DomoticzSensor(DZ_POWER_ENERGY, watthr_str); // WattHour
- }
-#endif // USE_DOMOTICZ
-#ifdef USE_WEBSERVER
- }
- else
- {
- WSContentSend_PD(HTTP_BL6523_SNM);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Amps:"), amps_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Volts:"), volts_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Freq:"), freq_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("Watts:"), watts_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("PowF:"), powf_str);
- WSContentSend_PD(HTTP_BL6523_SNS, PSTR("WattHr:"), watthr_str);
-#endif // USE_WEBSERVER
- }
+ if (PinUsed(GPIO_BL6523_RX) && PinUsed(GPIO_BL6523_TX)) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 PreInit Success " ));
+ TasmotaGlobal.energy_driver = XNRG_22;
}
+ else
+ {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 PreInit Failure! " ));
+ TasmotaGlobal.energy_driver = ENERGY_NONE;
+ }
+
}
/*********************************************************************************************\
@@ -327,27 +271,19 @@ bool Xnrg22(uint8_t function)
{
bool result = false;
-if ( FUNC_INIT == function )
-{
- Bl6523Init();
-}
-else if ( Bl6523.type )
- {
switch (function)
{
case FUNC_EVERY_250_MSECOND:
Bl6523Update();
break;
- case FUNC_JSON_APPEND:
- Bl6523Show(1);
+ case FUNC_INIT:
+ Bl6523Init();
break;
-#ifdef USE_WEBSERVER
- case FUNC_WEB_SENSOR:
- Bl6523Show(0);
+ case FUNC_PRE_INIT:
+ Bl6523DrvInit();
break;
-#endif // USE_WEBSERVER
}
- }
+
return result;
}
From a5e840ff5e36bb3200906edccb2470c284f16bb5 Mon Sep 17 00:00:00 2001
From: jeevasdev
Date: Wed, 16 Feb 2022 03:04:28 +1100
Subject: [PATCH 07/25] Trim Log messages.
---
tasmota/xnrg_22_bl6523.ino | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tasmota/xnrg_22_bl6523.ino b/tasmota/xnrg_22_bl6523.ino
index 28d7e2f0c..a2d09d0bb 100644
--- a/tasmota/xnrg_22_bl6523.ino
+++ b/tasmota/xnrg_22_bl6523.ino
@@ -88,7 +88,7 @@ bool Bl6523ReadData(void)
if (!Bl6523RxSerial->available())
{
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 No Rx Data available " ));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:No Rx Data available" ));
return false;
}
@@ -99,7 +99,7 @@ bool Bl6523ReadData(void)
if (Bl6523RxSerial->available() < BL6523_RX_DATASET_SIZE)
{
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Rx less than expected " ));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Rx less than expected" ));
return false;
}
@@ -134,7 +134,7 @@ bool Bl6523ReadData(void)
crc = ~crc; // Invert the byte
if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1])
{
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6523 : " D_CHECKSUM_FAILURE));
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6:" D_CHECKSUM_FAILURE));
Bl6523TxSerial->flush();
Bl6523RxSerial->flush();
return false;
@@ -239,11 +239,11 @@ void Bl6523Init(void)
}
Bl6523.type = 1;
Energy.phase_count = 1;
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Success " ));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Success" ));
}
else
{
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 Init Failure! " ));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Failure!" ));
TasmotaGlobal.energy_driver = ENERGY_NONE;
}
@@ -252,12 +252,12 @@ void Bl6523Init(void)
void Bl6523DrvInit(void)
{
if (PinUsed(GPIO_BL6523_RX) && PinUsed(GPIO_BL6523_TX)) {
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 PreInit Success " ));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Success" ));
TasmotaGlobal.energy_driver = XNRG_22;
}
else
{
- AddLog(LOG_LEVEL_DEBUG, PSTR("BL6523 PreInit Failure! " ));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Failure!" ));
TasmotaGlobal.energy_driver = ENERGY_NONE;
}
From 5f64dc38e094dee09533463c305e28756162acbf Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 15 Feb 2022 17:35:09 +0100
Subject: [PATCH 08/25] Berry instance variables are never methods
---
lib/libesp32/berry/src/be_vm.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/libesp32/berry/src/be_vm.c b/lib/libesp32/berry/src/be_vm.c
index 622930526..66bec1f31 100644
--- a/lib/libesp32/berry/src/be_vm.c
+++ b/lib/libesp32/berry/src/be_vm.c
@@ -904,7 +904,11 @@ newframe: /* a new call frame */
if (var_isinstance(a) && var_isstr(b)) {
binstance *obj = var_toobj(a);
bstring *attr = var_tostr(b);
- if (!be_instance_setmember(vm, obj, attr, c)) {
+ bvalue result = *c;
+ if (var_isfunction(&result)) {
+ var_markstatic(&result);
+ }
+ if (!be_instance_setmember(vm, obj, attr, &result)) {
reg = vm->reg;
vm_error(vm, "attribute_error",
"class '%s' cannot assign to attribute '%s'",
From 4566aaee05b1750e47601dd457fd777f90b306f5 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 15 Feb 2022 17:52:45 +0100
Subject: [PATCH 09/25] Refactor wiegand to 32-bit
Refactor wiegand from 64-bit to 32-bit while keeping full 34-bit support
---
tasmota/xsns_82_wiegand.ino | 184 ++++++++++++++++--------------------
1 file changed, 84 insertions(+), 100 deletions(-)
diff --git a/tasmota/xsns_82_wiegand.ino b/tasmota/xsns_82_wiegand.ino
index 5aaa22d4f..9908e7a55 100644
--- a/tasmota/xsns_82_wiegand.ino
+++ b/tasmota/xsns_82_wiegand.ino
@@ -40,6 +40,8 @@
* 20220215
* - fix 34-bit size parity chk
* - fix 64-bit representation after removal of %llu support (Tasmota does not support 64-bit decimal output specifier (%llu) saving 60k code)
+ * - change internal rfid size from uint64_t to uint32_t
+ * - limited max amount of kaypad presses to a 32-bit number (at least 999999999)
* ---
* 20201101
* - fix for #11047 Wiegand 26/34 missed some key press if they are press at normal speed
@@ -106,23 +108,21 @@ class Wiegand {
#if (DEV_WIEGAND_TEST_MODE!=1)
private:
#endif //(DEV_WIEGAND_TEST_MODE==1)
- uint64_t CheckAndConvertRfid(uint64_t,uint16_t);
+ uint32_t CheckAndConvertRfid(uint64_t,uint16_t);
uint8_t CalculateParities(uint64_t, int);
bool WiegandConversion (uint64_t , uint16_t );
- void setOutputFormat(void); // fix output HEX format
void HandleKeyPad(void); //handle one tag for multi key strokes
-
static void handleD0Interrupt(void);
static void handleD1Interrupt(void);
static void handleDxInterrupt(int in); // fix #11047
static void ClearRFIDBuffer(int);
- uint64_t rfid;
+ uint32_t rfid;
uint32_t tagSize;
const char* outFormat;
- uint64_t mqttRFIDKeypadBuffer;
- uint64_t webRFIDKeypadBuffer;
+ uint32_t mqttRFIDKeypadBuffer;
+ uint32_t webRFIDKeypadBuffer;
static volatile uint64_t rfidBuffer;
static volatile uint16_t bitCount;
@@ -149,15 +149,14 @@ volatile bool Wiegand::CodeComplete;
volatile RFID_store Wiegand::rfid_found[WIEGAND_RFID_ARRAY_SIZE];
volatile int Wiegand::currentFoundRFIDcount;
-
-
void IRAM_ATTR Wiegand::ClearRFIDBuffer(int endIndex = WIEGAND_RFID_ARRAY_SIZE) {
- currentFoundRFIDcount=WIEGAND_RFID_ARRAY_SIZE-endIndex; // clear all buffers
- for (int i= 0; i < endIndex; i++) {
- rfid_found[i].RFID=0;
- rfid_found[i].bitCount=0;
- }
+ currentFoundRFIDcount = WIEGAND_RFID_ARRAY_SIZE - endIndex; // clear all buffers
+ for (uint32_t i = 0; i < endIndex; i++) {
+ rfid_found[i].RFID=0;
+ rfid_found[i].bitCount=0;
+ }
}
+
void IRAM_ATTR Wiegand::handleD1Interrupt() { // Receive a 1 bit. (D0=high & D1=low)
handleDxInterrupt(1);
}
@@ -167,9 +166,9 @@ void IRAM_ATTR Wiegand::handleD0Interrupt() { // Receive a 0 bit. (D0=low & D1=
}
void IRAM_ATTR Wiegand::handleDxInterrupt(int in) {
- unsigned long curTime = micros(); // to be sure I will use micros() instead of millis() overflow is handle by using the minus operator to compare
- unsigned long diffTime= curTime - lastFoundTime;
- if ( (diffTime > CodeGapTime) && (bitCount > 0)) {
+ uint32_t curTime = micros(); // to be sure I will use micros() instead of millis() overflow is handle by using the minus operator to compare
+ uint32_t diffTime = curTime - lastFoundTime;
+ if ((diffTime > CodeGapTime) && (bitCount > 0)) {
// previous RFID tag (key pad numer)is complete. Will be detected by the code ending gap
// one bit will take the time of impulse_time + impulse_gap_time. it (bitTime) will be recalculated each time an impulse is detected
// the devices will add some inter_code_gap_time to separate codes this will be much longer than the bit_time. (WIEGAND_CODE_GAP_FACTOR)
@@ -192,7 +191,7 @@ void IRAM_ATTR Wiegand::handleDxInterrupt(int in) {
FirstBitTimeStamp = (curTime != 0) ? curTime : 1; // accept 1µs differenct to avoid a miss the first timestamp if curTime is 0.
}
else if (bitCount == 2) { // only calculate once per RFID tag, but restrict to values, which are in within a plausible range
- bitTime = ((diffTime > (WIEGAND_BIT_TIME_DEFAULT/4)) && (diffTime < (4*WIEGAND_BIT_TIME_DEFAULT))) ? diffTime : WIEGAND_BIT_TIME_DEFAULT;
+ bitTime = ((diffTime > (WIEGAND_BIT_TIME_DEFAULT / 4)) && (diffTime < (4 * WIEGAND_BIT_TIME_DEFAULT))) ? diffTime : WIEGAND_BIT_TIME_DEFAULT;
CodeGapTime = WIEGAND_CODE_GAP_FACTOR * bitTime;
}
//save current rfid in array otherwise we will never see the last found tag
@@ -247,7 +246,7 @@ void Wiegand::Init() {
#endif // DEV_WIEGAND_TEST_MODE>0
}
-uint64_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitCount) {
+uint32_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitCount) {
uint8_t evenParityBit = 0;
uint8_t oddParityBit = (uint8_t) (rfidIn & 0x1); // Last bit = odd parity
uint8_t calcParity = 0;
@@ -277,8 +276,8 @@ uint64_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitCount) {
}
calcParity = CalculateParities(rfidIn, bitCount); // Check result on http://www.ccdesignworks.com/wiegand_calc.htm with raw tag as input
if (calcParity != (evenParityBit | oddParityBit)) { // Parity bit is wrong
+ AddLog(LOG_LEVEL_DEBUG, PSTR("WIE: %_X parity error"), &rfidIn); // Print up to uint64_t
rfidIn=0;
- AddLog(LOG_LEVEL_DEBUG, PSTR("WIE: %_X parity error"), &rfidIn);
}
#if (DEV_WIEGAND_TEST_MODE)>0
AddLog(LOG_LEVEL_INFO, PSTR("WIE: even (left) parity: %u "), (evenParityBit>>7));
@@ -286,10 +285,10 @@ uint64_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitCount) {
AddLog(LOG_LEVEL_INFO, PSTR("WIE: odd (right) parity: %u "), oddParityBit);
AddLog(LOG_LEVEL_INFO, PSTR("WIE: odd (calc) parity: %u "), (calcParity & 0x01));
#endif // DEV_WIEGAND_TEST_MODE>0
- return rfidIn;
+ return (uint32_t)rfidIn;
}
-uint8_t Wiegand::CalculateParities(uint64_t tagWithoutParities, int tag_size=26) {
+uint8_t Wiegand::CalculateParities(uint64_t tagWithoutParities, int tag_size = 26) {
// tag_size is the size of the final tag including the 2 parity bits
// So length if the tagWithoutParities should be (tag_size-2) !! That will be not profed and
// lead to wrong results if the input value is larger!
@@ -299,7 +298,7 @@ uint8_t Wiegand::CalculateParities(uint64_t tagWithoutParities, int tag_size=26)
tag_size -= 2;
if (tag_size <= 0) { return retValue; } // Prohibit div zero exception and other wrong inputs
uint8_t parity = 1; // Check for odd parity on LSB
- for (uint8_t i = 0; i < (tag_size / 2); i++) {
+ for (uint32_t i = 0; i < (tag_size / 2); i++) {
parity ^= (tagWithoutParities & 1);
tagWithoutParities >>= 1;
}
@@ -318,53 +317,47 @@ uint8_t Wiegand::CalculateParities(uint64_t tagWithoutParities, int tag_size=26)
bool Wiegand::WiegandConversion (uint64_t rfidBuffer, uint16_t bitCount) {
bool bRet = false;
#if (DEV_WIEGAND_TEST_MODE)>0
- AddLog(LOG_LEVEL_INFO, PSTR("WIE: Raw tag %llu, Bit count %u"), rfidBuffer, bitCount);
+ AddLog(LOG_LEVEL_INFO, PSTR("WIE: Raw tag %_X, Bit count %u"), &rfidBuffer, bitCount); // Print up to uint64_t
#endif // DEV_WIEGAND_TEST_MODE>0
- if ((24 == bitCount) || (26 == bitCount) || (32 == bitCount) || (34 == bitCount)) {
- // 24, 26, 32, 34-bit Wiegand codes
- rfid = CheckAndConvertRfid(rfidBuffer, bitCount);
- tagSize = bitCount;
+ if ((24 == bitCount) || (26 == bitCount) || (32 == bitCount) || (34 == bitCount)) {
+ // 24, 26, 32, 34-bit Wiegand codes
+ rfid = CheckAndConvertRfid(rfidBuffer, bitCount);
+ tagSize = bitCount;
+ bRet = true;
+ }
+ else if (4 == bitCount) {
+ // 4-bit Wiegand codes for keypads
+ rfid = (uint32_t)(rfidBuffer & 0x0000000F);
+ tagSize = bitCount;
+ bRet = true;
+ }
+ else if (8 == bitCount) {
+ // 8-bit Wiegand codes for keypads with integrity
+ // 8-bit Wiegand keyboard data, high nibble is the "NOT" of low nibble
+ // eg if key 1 pressed, data=E1 in binary 11100001 , high nibble=1110 , low nibble = 0001
+ char highNibble = (rfidBuffer & 0xf0) >>4;
+ char lowNibble = (rfidBuffer & 0x0f);
+ if (lowNibble == (~highNibble & 0x0f)) { // Check if low nibble matches the "NOT" of high nibble.
+ rfid = (uint32_t)(lowNibble);
bRet = true;
- }
- else if (4 == bitCount) {
- // 4-bit Wiegand codes for keypads
- rfid = (int)(rfidBuffer & 0x0000000F);
- tagSize = bitCount;
- bRet = true;
- }
- else if (8 == bitCount) {
- // 8-bit Wiegand codes for keypads with integrity
- // 8-bit Wiegand keyboard data, high nibble is the "NOT" of low nibble
- // eg if key 1 pressed, data=E1 in binary 11100001 , high nibble=1110 , low nibble = 0001
- char highNibble = (rfidBuffer & 0xf0) >>4;
- char lowNibble = (rfidBuffer & 0x0f);
- if (lowNibble == (~highNibble & 0x0f)) { // Check if low nibble matches the "NOT" of high nibble.
- rfid = (int)(lowNibble);
- bRet = true;
- } else {
- bRet = false;
- }
- tagSize = bitCount;
} else {
- // Time reached but unknown bitCount, clear and start again
- tagSize = 0;
bRet = false;
}
+ tagSize = bitCount;
+ } else {
+ // Time reached but unknown bitCount, clear and start again
+ tagSize = 0;
+ bRet = false;
+ }
#if (DEV_WIEGAND_TEST_MODE)>0
- AddLog(LOG_LEVEL_INFO, PSTR("WIE: Tag out %llu, tag size %u "), rfid, tagSize);
+ AddLog(LOG_LEVEL_INFO, PSTR("WIE: Tag out %u, tag size %u "), rfid, tagSize);
#endif // DEV_WIEGAND_TEST_MODE>0
return bRet;
}
-void Wiegand::setOutputFormat(void)
-{
- if (GetOption(WIEGAND_OPTION_HEX) == 0) { outFormat = "u"; }
- else { outFormat = "X" WIEGAND_OPTION_HEX_POSTFIX ; }
-}
-
void Wiegand::HandleKeyPad(void) { // will be called if a valid key pad input was recognized
- if (GetOption(WIEGAND_OPTION_KEYPAD_TO_TAG) == 0) { // handle all key pad inputs as ONE Tag until # is recognized
- if ( (tagSize == 4) || (tagSize == 8) ) {
+ if (GetOption(WIEGAND_OPTION_KEYPAD_TO_TAG) == 0) { // handle all key pad inputs as ONE Tag until # is recognized
+ if ((tagSize == 4) || (tagSize == 8)) {
//only handle Keypad strokes if it is requested
if (rfid >= 0x0a) { // # * as end of input detected -> all key values which are larger than 9
rfid = mqttRFIDKeypadBuffer; // original tagsize of 4 or 8 will be kept.
@@ -372,7 +365,7 @@ void Wiegand::HandleKeyPad(void) { // will be called if a valid key pad input wa
mqttRFIDKeypadBuffer = 0;
}
else {
- mqttRFIDKeypadBuffer = (mqttRFIDKeypadBuffer*10)+rfid; //left shift + new key
+ mqttRFIDKeypadBuffer = (mqttRFIDKeypadBuffer * 10) + rfid; //left shift + new key
webRFIDKeypadBuffer = mqttRFIDKeypadBuffer; // visualising the current typed keys
rfid = 0;
tagSize = 0;
@@ -386,38 +379,33 @@ void Wiegand::HandleKeyPad(void) { // will be called if a valid key pad input wa
}
void Wiegand::ScanForTag() {
- unsigned long startTime = micros();
+ uint32_t startTime = micros();
handleDxInterrupt(3);
- if (currentFoundRFIDcount > 0) {
- unsigned int lastFoundRFIDcount = currentFoundRFIDcount;
- #if (DEV_WIEGAND_TEST_MODE)>0
- AddLog(LOG_LEVEL_INFO, PSTR("WIE: ScanForTag(). bitTime: %0lu lastFoundTime: %0lu RFIDS in buffer: %lu"), bitTime, lastFoundTime, currentFoundRFIDcount);
- #endif
- // format MQTT output
-// setOutputFormat();
-// char sFormat[50];
-// snprintf( sFormat, 50, PSTR(",\"Wiegand\":{\"UID\":%%0ll%s,\"" D_JSON_SIZE "\":%%%s}}"), outFormat, outFormat);
- for (int i= 0; i < WIEGAND_RFID_ARRAY_SIZE; i++)
- {
- if (rfid_found[i].RFID != 0 || (rfid_found[i].RFID == 0 && i == 0)) {
- uint64_t oldTag = rfid;
+ if (currentFoundRFIDcount > 0) {
+ uint32_t lastFoundRFIDcount = currentFoundRFIDcount;
+#if (DEV_WIEGAND_TEST_MODE)>0
+ AddLog(LOG_LEVEL_INFO, PSTR("WIE: ScanForTag(). bitTime: %u lastFoundTime: %u RFIDS in buffer: %u"), bitTime, lastFoundTime, currentFoundRFIDcount);
+#endif
+ for (uint32_t i = 0; i < WIEGAND_RFID_ARRAY_SIZE; i++) {
+ if (rfid_found[i].RFID != 0 || (rfid_found[i].RFID == 0 && i == 0)) {
+ uint32_t oldTag = rfid;
bool validKey = WiegandConversion(rfid_found[i].RFID, rfid_found[i].bitCount);
- #if (DEV_WIEGAND_TEST_MODE)>0
- AddLog(LOG_LEVEL_INFO, PSTR("WIE: ValidKey: %d Previous tag %llu"), validKey, oldTag);
- #endif // DEV_WIEGAND_TEST_MODE>0
+#if (DEV_WIEGAND_TEST_MODE)>0
+ AddLog(LOG_LEVEL_INFO, PSTR("WIE: ValidKey %d, Previous tag %u"), validKey, oldTag);
+#endif // DEV_WIEGAND_TEST_MODE>0
if (validKey) { // Only in case of valid key do action. Issue#10585
HandleKeyPad(); //support one tag for multi key input
- if (tagSize>0) { //do output only for rfids which are complete
+ if (tagSize > 0) { //do output only for rfids which are complete
if (oldTag == rfid) {
AddLog(LOG_LEVEL_DEBUG, PSTR("WIE: Old tag"));
}
-// ResponseTime_P(sFormat, rfid, tagSize);
-// Tasmota does not support 64-bit decimal output specifier (%llu) saving 60k code
+ ResponseTime_P(PSTR(",\"Wiegand\":{\"UID\":"));
if (GetOption(WIEGAND_OPTION_HEX) == 0) {
- ResponseTime_P(PSTR(",\"Wiegand\":{\"UID\":%lu,\"" D_JSON_SIZE "\":%d}}"), (uint32_t)rfid, tagSize);
+ ResponseAppend_P(PSTR("%u"), rfid);
} else {
- ResponseTime_P(PSTR(",\"Wiegand\":{\"UID\":\"%1_X" WIEGAND_OPTION_HEX_POSTFIX "\",\"" D_JSON_SIZE "\":%d}}"), &rfid, tagSize);
+ ResponseAppend_P(PSTR("\"%X" WIEGAND_OPTION_HEX_POSTFIX "\""), rfid);
}
+ ResponseAppend_P(PSTR(",\"" D_JSON_SIZE "\":%d}}"), tagSize);
MqttPublishTeleSensor();
}
}
@@ -426,33 +414,29 @@ void Wiegand::ScanForTag() {
if (currentFoundRFIDcount > lastFoundRFIDcount) {
// if that happens: we need to move the id found during the loop to top of the array
// and correct the currentFoundRFIDcount
- AddLog(LOG_LEVEL_INFO, PSTR("WIE: ScanForTag() %lu tags added while working on buffer"), (currentFoundRFIDcount-lastFoundRFIDcount));
+ AddLog(LOG_LEVEL_INFO, PSTR("WIE: ScanForTag() %u tags added while working on buffer"), (currentFoundRFIDcount - lastFoundRFIDcount));
}
ClearRFIDBuffer(); //reset array
- #if (DEV_WIEGAND_TEST_MODE)>0
- AddLog(LOG_LEVEL_INFO, PSTR("WIE: ScanForTag() time elapsed %lu"), (micros() - startTime));
- #endif
+#if (DEV_WIEGAND_TEST_MODE)>0
+ AddLog(LOG_LEVEL_INFO, PSTR("WIE: ScanForTag() time elapsed %u"), (micros() - startTime));
+#endif
}
-
}
#ifdef USE_WEBSERVER
void Wiegand::Show(void) {
-// setOutputFormat();
-// char sFormat [30];
-// snprintf( sFormat, 30,PSTR("{s}Wiegand UID{m}%%ll%s {e}"), outFormat);
-// if (tagSize>0) { WSContentSend_PD(sFormat, rfid); }
-// else { WSContentSend_PD(sFormat, webRFIDKeypadBuffer); }
-// Tasmota does not support 64-bit decimal output specifier (%llu) saving 60k code
- if (GetOption(WIEGAND_OPTION_HEX) == 0) {
- WSContentSend_P(PSTR("{s}Wiegand UID{m}%lu{e}"), (tagSize>0) ? (uint32_t)rfid : (uint32_t)webRFIDKeypadBuffer);
- } else {
- WSContentSend_P(PSTR("{s}Wiegand UID{m}%1_X" WIEGAND_OPTION_HEX_POSTFIX "{e}"), (tagSize>0) ? &rfid : &webRFIDKeypadBuffer);
- }
- #if (DEV_WIEGAND_TEST_MODE)>0
- AddLog(LOG_LEVEL_INFO, PSTR("WIE: Tag %llu, Bits %u"), rfid, bitCount);
- #endif // DEV_WIEGAND_TEST_MODE>0
+ WSContentSend_P(PSTR("{s}Wiegand UID{m}"));
+ if (GetOption(WIEGAND_OPTION_HEX) == 0) {
+ WSContentSend_P(PSTR("%u"), (tagSize > 0) ? rfid : webRFIDKeypadBuffer);
+ } else {
+ WSContentSend_P(PSTR("%X" WIEGAND_OPTION_HEX_POSTFIX), (tagSize > 0) ? rfid : webRFIDKeypadBuffer);
+ }
+ WSContentSend_P(PSTR("{e}"));
+
+#if (DEV_WIEGAND_TEST_MODE)>0
+ AddLog(LOG_LEVEL_INFO, PSTR("WIE: Tag %u, Bits %u"), rfid, bitCount);
+#endif // DEV_WIEGAND_TEST_MODE>0
}
#endif // USE_WEBSERVER
From b75919c487e4fb3017f7d313b6beb59c2a557b55 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 15 Feb 2022 20:02:31 +0100
Subject: [PATCH 10/25] remove not needed code
which will conflict with next Arduino core build
---
lib/lib_basic/OneWire-Stickbreaker/OneWire.h | 52 ++++++++++----------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/lib/lib_basic/OneWire-Stickbreaker/OneWire.h b/lib/lib_basic/OneWire-Stickbreaker/OneWire.h
index 2747bea4e..5f4b613c2 100644
--- a/lib/lib_basic/OneWire-Stickbreaker/OneWire.h
+++ b/lib/lib_basic/OneWire-Stickbreaker/OneWire.h
@@ -210,14 +210,14 @@ void directModeInput(IO_REG_TYPE pin)
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
}
-#elif ESP_IDF_VERSION_MAJOR > 3 // ESP32-S2 needs IDF 4.2 or later
- int8_t rtc_io = esp32_gpioMux[pin].rtc;
- uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
- if ( rtc_reg ) // RTC pins PULL settings
- {
- ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
- ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
- }
+//#elif ESP_IDF_VERSION_MAJOR > 3 // ESP32-S2 needs IDF 4.2 or later
+// int8_t rtc_io = esp32_gpioMux[pin].rtc;
+// uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
+// if ( rtc_reg ) // RTC pins PULL settings
+// {
+// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
+// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
+// }
#endif
// Input
if ( pin < 32 )
@@ -225,13 +225,13 @@ void directModeInput(IO_REG_TYPE pin)
else
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
- uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
- pinFunction |= FUN_IE; // input enable but required for output as well?
- pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
+// uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
+// pinFunction |= FUN_IE; // input enable but required for output as well?
+// pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
- ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
+// ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
- GPIO.pin[pin].val = 0;
+// GPIO.pin[pin].val = 0;
}
#endif
}
@@ -252,14 +252,14 @@ void directModeOutput(IO_REG_TYPE pin)
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
}
-#elif ESP_IDF_VERSION_MAJOR > 3 // ESP32-S2 needs IDF 4.2 or later
- int8_t rtc_io = esp32_gpioMux[pin].rtc;
- uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
- if ( rtc_reg ) // RTC pins PULL settings
- {
- ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
- ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
- }
+//#elif ESP_IDF_VERSION_MAJOR > 3 // ESP32-S2 needs IDF 4.2 or later
+// int8_t rtc_io = esp32_gpioMux[pin].rtc;
+// uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
+// if ( rtc_reg ) // RTC pins PULL settings
+// {
+// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
+// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
+// }
#endif
// Output
if ( pin < 32 )
@@ -267,13 +267,13 @@ void directModeOutput(IO_REG_TYPE pin)
else // already validated to pins <= 33
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
- uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
- pinFunction |= FUN_IE; // input enable but required for output as well?
- pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
+// uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
+// pinFunction |= FUN_IE; // input enable but required for output as well?
+// pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
- ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
+// ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
- GPIO.pin[pin].val = 0;
+// GPIO.pin[pin].val = 0;
}
#endif
}
From ecd4ec76f3cd74115703e1c3b065d234006a7836 Mon Sep 17 00:00:00 2001
From: stefanbode
Date: Tue, 15 Feb 2022 20:26:49 +0100
Subject: [PATCH 11/25] prevent deepsleep if teleperiod <> 100 or 300
because teleperiod is send directly after start, deepsleep will wait for the second teleperiod in cases where it is defined e.g. to 60. #14860
---
tasmota/xdrv_29_deepsleep.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/xdrv_29_deepsleep.ino b/tasmota/xdrv_29_deepsleep.ino
index 144327d85..ae987ba69 100644
--- a/tasmota/xdrv_29_deepsleep.ino
+++ b/tasmota/xdrv_29_deepsleep.ino
@@ -178,7 +178,7 @@ bool Xdrv29(uint8_t function)
DeepSleepEverySecond();
break;
case FUNC_AFTER_TELEPERIOD:
- if (DeepSleepEnabled() && !deepsleep_flag) {
+ if (DeepSleepEnabled() && !deepsleep_flag && (Settings->tele_period == 10 || Settings->tele_period == 300 || millis() > 20000 )) {
deepsleep_flag = DEEPSLEEP_START_COUNTDOWN; // Start deepsleep in 4 seconds
}
break;
From 0ab3dd8edd5b096faaa2545207f8bfad2e0f1496 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 15 Feb 2022 21:44:45 +0100
Subject: [PATCH 12/25] Berry add hue_bridge.light_to_id()
---
lib/libesp32/berry/generate/be_const_strtab.h | 1 +
.../berry/generate/be_const_strtab_def.h | 5 +-
.../berry_tasmota/src/be_hue_bridge_lib.c | 681 ++++++++++--------
.../berry_tasmota/src/embedded/hue_bridge.be | 9 +
4 files changed, 378 insertions(+), 318 deletions(-)
diff --git a/lib/libesp32/berry/generate/be_const_strtab.h b/lib/libesp32/berry/generate/be_const_strtab.h
index 834714ee9..b6fb90f13 100644
--- a/lib/libesp32/berry/generate/be_const_strtab.h
+++ b/lib/libesp32/berry/generate/be_const_strtab.h
@@ -526,6 +526,7 @@ extern const bcstring be_const_str_length_X20in_X20bits_X20must_X20be_X20between
extern const bcstring be_const_str_light;
extern const bcstring be_const_str_light_X20must_X20be_X20of_X20class_X20_X27light_state_X27;
extern const bcstring be_const_str_light_state;
+extern const bcstring be_const_str_light_to_id;
extern const bcstring be_const_str_lights;
extern const bcstring be_const_str_line_dsc;
extern const bcstring be_const_str_list;
diff --git a/lib/libesp32/berry/generate/be_const_strtab_def.h b/lib/libesp32/berry/generate/be_const_strtab_def.h
index 777e7d55a..30fb8e581 100644
--- a/lib/libesp32/berry/generate/be_const_strtab_def.h
+++ b/lib/libesp32/berry/generate/be_const_strtab_def.h
@@ -518,6 +518,7 @@ be_define_const_str(length_X20in_X20bits_X20must_X20be_X20between_X200_X20and_X2
be_define_const_str(light, "light", 3801947695u, 0, 5, NULL);
be_define_const_str(light_X20must_X20be_X20of_X20class_X20_X27light_state_X27, "light must be of class 'light_state'", 3669350396u, 0, 36, NULL);
be_define_const_str(light_state, "light_state", 905783845u, 0, 11, NULL);
+be_define_const_str(light_to_id, "light_to_id", 1117015647u, 0, 11, &be_const_str_signal_arcs);
be_define_const_str(lights, "lights", 425118420u, 0, 6, &be_const_str_success);
be_define_const_str(line_dsc, "line_dsc", 4094490978u, 0, 8, &be_const_str_web_add_button);
be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_url_encode);
@@ -890,7 +891,7 @@ static const bstring* const m_string_table[] = {
(const bstring *)&be_const_str_SERIAL_6N2,
(const bstring *)&be_const_str__drivers,
(const bstring *)&be_const_str__X28_X29,
- (const bstring *)&be_const_str_signal_arcs,
+ (const bstring *)&be_const_str_light_to_id,
(const bstring *)&be_const_str_AudioGeneratorMP3,
(const bstring *)&be_const_str_BRY_X3A_X20ERROR_X2C_X20bad_X20json_X3A_X20,
(const bstring *)&be_const_str_clear_to,
@@ -1287,6 +1288,6 @@ static const bstring* const m_string_table[] = {
static const struct bconststrtab m_const_string_table = {
.size = 420,
- .count = 863,
+ .count = 864,
.table = m_string_table
};
diff --git a/lib/libesp32/berry_tasmota/src/be_hue_bridge_lib.c b/lib/libesp32/berry_tasmota/src/be_hue_bridge_lib.c
index bda0f8ca7..eaffff5b2 100644
--- a/lib/libesp32/berry_tasmota/src/be_hue_bridge_lib.c
+++ b/lib/libesp32/berry_tasmota/src/be_hue_bridge_lib.c
@@ -6,6 +6,363 @@
#if defined(USE_EMULATION) && defined(USE_EMULATION_HUE)
+/********************************************************************
+** Solidified function: full_status
+********************************************************************/
+be_local_closure(hue_bridge_monad_full_status, /* name */
+ be_nested_proto(
+ 11, /* nstack */
+ 2, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 8]) { /* constants */
+ /* K0 */ be_nested_str(hue_ntv),
+ /* K1 */ be_nested_str(lights),
+ /* K2 */ be_nested_str(contains),
+ /* K3 */ be_nested_str(full_state),
+ /* K4 */ be_nested_str(light),
+ /* K5 */ be_nested_str(name),
+ /* K6 */ be_nested_str(model),
+ /* K7 */ be_nested_str(manuf),
+ }),
+ &be_const_str_full_status,
+ &be_const_str_solidified,
+ ( &(const binstruction[17]) { /* code */
+ 0xA40A0000, // 0000 IMPORT R2 K0
+ 0x880C0101, // 0001 GETMBR R3 R0 K1
+ 0x8C0C0702, // 0002 GETMET R3 R3 K2
+ 0x5C140200, // 0003 MOVE R5 R1
+ 0x7C0C0400, // 0004 CALL R3 2
+ 0x780E0009, // 0005 JMPF R3 #0010
+ 0x880C0101, // 0006 GETMBR R3 R0 K1
+ 0x940C0601, // 0007 GETIDX R3 R3 R1
+ 0x8C100503, // 0008 GETMET R4 R2 K3
+ 0x5C180200, // 0009 MOVE R6 R1
+ 0x941C0704, // 000A GETIDX R7 R3 K4
+ 0x94200705, // 000B GETIDX R8 R3 K5
+ 0x94240706, // 000C GETIDX R9 R3 K6
+ 0x94280707, // 000D GETIDX R10 R3 K7
+ 0x7C100C00, // 000E CALL R4 6
+ 0x80040800, // 000F RET 1 R4
+ 0x80000000, // 0010 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: hue_status
+********************************************************************/
+be_local_closure(hue_bridge_monad_hue_status, /* name */
+ be_nested_proto(
+ 6, /* nstack */
+ 2, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 5]) { /* constants */
+ /* K0 */ be_nested_str(hue_ntv),
+ /* K1 */ be_nested_str(lights),
+ /* K2 */ be_nested_str(contains),
+ /* K3 */ be_nested_str(light_state),
+ /* K4 */ be_nested_str(light),
+ }),
+ &be_const_str_hue_status,
+ &be_const_str_solidified,
+ ( &(const binstruction[13]) { /* code */
+ 0xA40A0000, // 0000 IMPORT R2 K0
+ 0x880C0101, // 0001 GETMBR R3 R0 K1
+ 0x8C0C0702, // 0002 GETMET R3 R3 K2
+ 0x5C140200, // 0003 MOVE R5 R1
+ 0x7C0C0400, // 0004 CALL R3 2
+ 0x780E0005, // 0005 JMPF R3 #000C
+ 0x8C0C0503, // 0006 GETMET R3 R2 K3
+ 0x88140101, // 0007 GETMBR R5 R0 K1
+ 0x94140A01, // 0008 GETIDX R5 R5 R1
+ 0x94140B04, // 0009 GETIDX R5 R5 K4
+ 0x7C0C0400, // 000A CALL R3 2
+ 0x80040600, // 000B RET 1 R3
+ 0x80000000, // 000C RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: add_light
+********************************************************************/
+be_local_closure(hue_bridge_monad_add_light, /* name */
+ be_nested_proto(
+ 10, /* nstack */
+ 6, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[14]) { /* constants */
+ /* K0 */ be_nested_str(int),
+ /* K1 */ be_nested_str(value_error),
+ /* K2 */ be_nested_str(id_X20must_X20be_X20of_X20type_X20_X27int_X27),
+ /* K3 */ be_nested_str(light_state),
+ /* K4 */ be_nested_str(light_X20must_X20be_X20of_X20class_X20_X27light_state_X27),
+ /* K5 */ be_const_int(0),
+ /* K6 */ be_nested_str(missing_X20name),
+ /* K7 */ be_nested_str(Unknown),
+ /* K8 */ be_nested_str(Tasmota),
+ /* K9 */ be_nested_str(lights),
+ /* K10 */ be_nested_str(light),
+ /* K11 */ be_nested_str(name),
+ /* K12 */ be_nested_str(model),
+ /* K13 */ be_nested_str(manuf),
+ }),
+ &be_const_str_add_light,
+ &be_const_str_solidified,
+ ( &(const binstruction[43]) { /* code */
+ 0x60180004, // 0000 GETGBL R6 G4
+ 0x5C1C0200, // 0001 MOVE R7 R1
+ 0x7C180200, // 0002 CALL R6 1
+ 0x20180D00, // 0003 NE R6 R6 K0
+ 0x781A0000, // 0004 JMPF R6 #0006
+ 0xB0060302, // 0005 RAISE 1 K1 K2
+ 0x6018000F, // 0006 GETGBL R6 G15
+ 0x5C1C0400, // 0007 MOVE R7 R2
+ 0xB8220600, // 0008 GETNGBL R8 K3
+ 0x7C180400, // 0009 CALL R6 2
+ 0x741A0000, // 000A JMPT R6 #000C
+ 0xB0060304, // 000B RAISE 1 K1 K4
+ 0x60180008, // 000C GETGBL R6 G8
+ 0x5C1C0600, // 000D MOVE R7 R3
+ 0x7C180200, // 000E CALL R6 1
+ 0x5C0C0C00, // 000F MOVE R3 R6
+ 0x6018000C, // 0010 GETGBL R6 G12
+ 0x5C1C0600, // 0011 MOVE R7 R3
+ 0x7C180200, // 0012 CALL R6 1
+ 0x1C180D05, // 0013 EQ R6 R6 K5
+ 0x781A0000, // 0014 JMPF R6 #0016
+ 0xB0060306, // 0015 RAISE 1 K1 K6
+ 0x5C180800, // 0016 MOVE R6 R4
+ 0x741A0000, // 0017 JMPT R6 #0019
+ 0x58100007, // 0018 LDCONST R4 K7
+ 0x5C180A00, // 0019 MOVE R6 R5
+ 0x741A0000, // 001A JMPT R6 #001C
+ 0x58140008, // 001B LDCONST R5 K8
+ 0x88180109, // 001C GETMBR R6 R0 K9
+ 0x601C0013, // 001D GETGBL R7 G19
+ 0x7C1C0000, // 001E CALL R7 0
+ 0x981E1402, // 001F SETIDX R7 K10 R2
+ 0x981E1603, // 0020 SETIDX R7 K11 R3
+ 0x60200008, // 0021 GETGBL R8 G8
+ 0x5C240800, // 0022 MOVE R9 R4
+ 0x7C200200, // 0023 CALL R8 1
+ 0x981E1808, // 0024 SETIDX R7 K12 R8
+ 0x60200008, // 0025 GETGBL R8 G8
+ 0x5C240A00, // 0026 MOVE R9 R5
+ 0x7C200200, // 0027 CALL R8 1
+ 0x981E1A08, // 0028 SETIDX R7 K13 R8
+ 0x98180207, // 0029 SETIDX R6 R1 R7
+ 0x80000000, // 002A RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: remove_light
+********************************************************************/
+be_local_closure(hue_bridge_monad_remove_light, /* name */
+ be_nested_proto(
+ 5, /* nstack */
+ 2, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 2]) { /* constants */
+ /* K0 */ be_nested_str(lights),
+ /* K1 */ be_nested_str(remove),
+ }),
+ &be_const_str_remove_light,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 5]) { /* code */
+ 0x88080100, // 0000 GETMBR R2 R0 K0
+ 0x8C080501, // 0001 GETMET R2 R2 K1
+ 0x5C100200, // 0002 MOVE R4 R1
+ 0x7C080400, // 0003 CALL R2 2
+ 0x80000000, // 0004 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: init
+********************************************************************/
+be_local_closure(hue_bridge_monad_init, /* name */
+ be_nested_proto(
+ 2, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str(lights),
+ }),
+ &be_const_str_init,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 4]) { /* code */
+ 0x60040013, // 0000 GETGBL R1 G19
+ 0x7C040000, // 0001 CALL R1 0
+ 0x90020001, // 0002 SETMBR R0 K0 R1
+ 0x80000000, // 0003 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: discover
+********************************************************************/
+be_local_closure(hue_bridge_monad_discover, /* name */
+ be_nested_proto(
+ 11, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[13]) { /* constants */
+ /* K0 */ be_nested_str(hue_ntv),
+ /* K1 */ be_nested_str(json),
+ /* K2 */ be_nested_str(string),
+ /* K3 */ be_nested_str(lights),
+ /* K4 */ be_nested_str(keys),
+ /* K5 */ be_nested_str(full_status),
+ /* K6 */ be_nested_str(_X22),
+ /* K7 */ be_nested_str(_X22_X3A),
+ /* K8 */ be_nested_str(push),
+ /* K9 */ be_nested_str(stop_iteration),
+ /* K10 */ be_const_int(0),
+ /* K11 */ be_nested_str(concat),
+ /* K12 */ be_nested_str(_X2C),
+ }),
+ &be_const_str_discover,
+ &be_const_str_solidified,
+ ( &(const binstruction[40]) { /* code */
+ 0xA4060000, // 0000 IMPORT R1 K0
+ 0xA40A0200, // 0001 IMPORT R2 K1
+ 0xA40E0400, // 0002 IMPORT R3 K2
+ 0x60100012, // 0003 GETGBL R4 G18
+ 0x7C100000, // 0004 CALL R4 0
+ 0x60140010, // 0005 GETGBL R5 G16
+ 0x88180103, // 0006 GETMBR R6 R0 K3
+ 0x8C180D04, // 0007 GETMET R6 R6 K4
+ 0x7C180200, // 0008 CALL R6 1
+ 0x7C140200, // 0009 CALL R5 1
+ 0xA802000F, // 000A EXBLK 0 #001B
+ 0x5C180A00, // 000B MOVE R6 R5
+ 0x7C180000, // 000C CALL R6 0
+ 0x8C1C0105, // 000D GETMET R7 R0 K5
+ 0x5C240C00, // 000E MOVE R9 R6
+ 0x7C1C0400, // 000F CALL R7 2
+ 0x781E0008, // 0010 JMPF R7 #001A
+ 0x60200008, // 0011 GETGBL R8 G8
+ 0x5C240C00, // 0012 MOVE R9 R6
+ 0x7C200200, // 0013 CALL R8 1
+ 0x00220C08, // 0014 ADD R8 K6 R8
+ 0x00201107, // 0015 ADD R8 R8 K7
+ 0x001C1007, // 0016 ADD R7 R8 R7
+ 0x8C200908, // 0017 GETMET R8 R4 K8
+ 0x5C280E00, // 0018 MOVE R10 R7
+ 0x7C200400, // 0019 CALL R8 2
+ 0x7001FFEF, // 001A JMP #000B
+ 0x58140009, // 001B LDCONST R5 K9
+ 0xAC140200, // 001C CATCH R5 1 0
+ 0xB0080000, // 001D RAISE 2 R0 R0
+ 0x6014000C, // 001E GETGBL R5 G12
+ 0x5C180800, // 001F MOVE R6 R4
+ 0x7C140200, // 0020 CALL R5 1
+ 0x24140B0A, // 0021 GT R5 R5 K10
+ 0x78160003, // 0022 JMPF R5 #0027
+ 0x8C14090B, // 0023 GETMET R5 R4 K11
+ 0x581C000C, // 0024 LDCONST R7 K12
+ 0x7C140400, // 0025 CALL R5 2
+ 0x80040A00, // 0026 RET 1 R5
+ 0x80000000, // 0027 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: light_to_id
+********************************************************************/
+be_local_closure(hue_bridge_monad_light_to_id, /* name */
+ be_nested_proto(
+ 5, /* nstack */
+ 2, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 4]) { /* constants */
+ /* K0 */ be_nested_str(lights),
+ /* K1 */ be_nested_str(keys),
+ /* K2 */ be_nested_str(light),
+ /* K3 */ be_nested_str(stop_iteration),
+ }),
+ &be_const_str_light_to_id,
+ &be_const_str_solidified,
+ ( &(const binstruction[20]) { /* code */
+ 0x60080010, // 0000 GETGBL R2 G16
+ 0x880C0100, // 0001 GETMBR R3 R0 K0
+ 0x8C0C0701, // 0002 GETMET R3 R3 K1
+ 0x7C0C0200, // 0003 CALL R3 1
+ 0x7C080200, // 0004 CALL R2 1
+ 0xA8020009, // 0005 EXBLK 0 #0010
+ 0x5C0C0400, // 0006 MOVE R3 R2
+ 0x7C0C0000, // 0007 CALL R3 0
+ 0x88100100, // 0008 GETMBR R4 R0 K0
+ 0x94100803, // 0009 GETIDX R4 R4 R3
+ 0x94100902, // 000A GETIDX R4 R4 K2
+ 0x1C100204, // 000B EQ R4 R1 R4
+ 0x78120001, // 000C JMPF R4 #000F
+ 0xA8040001, // 000D EXBLK 1 1
+ 0x80040600, // 000E RET 1 R3
+ 0x7001FFF5, // 000F JMP #0006
+ 0x58080003, // 0010 LDCONST R2 K3
+ 0xAC080200, // 0011 CATCH R2 1 0
+ 0xB0080000, // 0012 RAISE 2 R0 R0
+ 0x80000000, // 0013 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
/********************************************************************
** Solidified function: cmd
********************************************************************/
@@ -228,37 +585,6 @@ be_local_closure(hue_bridge_monad_cmd, /* name */
/*******************************************************************/
-/********************************************************************
-** Solidified function: remove_light
-********************************************************************/
-be_local_closure(hue_bridge_monad_remove_light, /* name */
- be_nested_proto(
- 5, /* nstack */
- 2, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 2]) { /* constants */
- /* K0 */ be_nested_str(lights),
- /* K1 */ be_nested_str(remove),
- }),
- &be_const_str_remove_light,
- &be_const_str_solidified,
- ( &(const binstruction[ 5]) { /* code */
- 0x88080100, // 0000 GETMBR R2 R0 K0
- 0x8C080501, // 0001 GETMET R2 R2 K1
- 0x5C100200, // 0002 MOVE R4 R1
- 0x7C080400, // 0003 CALL R2 2
- 0x80000000, // 0004 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
/********************************************************************
** Solidified function: groups
********************************************************************/
@@ -322,301 +648,24 @@ be_local_closure(hue_bridge_monad_groups, /* name */
/*******************************************************************/
-/********************************************************************
-** Solidified function: hue_status
-********************************************************************/
-be_local_closure(hue_bridge_monad_hue_status, /* name */
- be_nested_proto(
- 6, /* nstack */
- 2, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 5]) { /* constants */
- /* K0 */ be_nested_str(hue_ntv),
- /* K1 */ be_nested_str(lights),
- /* K2 */ be_nested_str(contains),
- /* K3 */ be_nested_str(light_state),
- /* K4 */ be_nested_str(light),
- }),
- &be_const_str_hue_status,
- &be_const_str_solidified,
- ( &(const binstruction[13]) { /* code */
- 0xA40A0000, // 0000 IMPORT R2 K0
- 0x880C0101, // 0001 GETMBR R3 R0 K1
- 0x8C0C0702, // 0002 GETMET R3 R3 K2
- 0x5C140200, // 0003 MOVE R5 R1
- 0x7C0C0400, // 0004 CALL R3 2
- 0x780E0005, // 0005 JMPF R3 #000C
- 0x8C0C0503, // 0006 GETMET R3 R2 K3
- 0x88140101, // 0007 GETMBR R5 R0 K1
- 0x94140A01, // 0008 GETIDX R5 R5 R1
- 0x94140B04, // 0009 GETIDX R5 R5 K4
- 0x7C0C0400, // 000A CALL R3 2
- 0x80040600, // 000B RET 1 R3
- 0x80000000, // 000C RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: add_light
-********************************************************************/
-be_local_closure(hue_bridge_monad_add_light, /* name */
- be_nested_proto(
- 10, /* nstack */
- 6, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[14]) { /* constants */
- /* K0 */ be_nested_str(int),
- /* K1 */ be_nested_str(value_error),
- /* K2 */ be_nested_str(id_X20must_X20be_X20of_X20type_X20_X27int_X27),
- /* K3 */ be_nested_str(light_state),
- /* K4 */ be_nested_str(light_X20must_X20be_X20of_X20class_X20_X27light_state_X27),
- /* K5 */ be_const_int(0),
- /* K6 */ be_nested_str(missing_X20name),
- /* K7 */ be_nested_str(Unknown),
- /* K8 */ be_nested_str(Tasmota),
- /* K9 */ be_nested_str(lights),
- /* K10 */ be_nested_str(light),
- /* K11 */ be_nested_str(name),
- /* K12 */ be_nested_str(model),
- /* K13 */ be_nested_str(manuf),
- }),
- &be_const_str_add_light,
- &be_const_str_solidified,
- ( &(const binstruction[43]) { /* code */
- 0x60180004, // 0000 GETGBL R6 G4
- 0x5C1C0200, // 0001 MOVE R7 R1
- 0x7C180200, // 0002 CALL R6 1
- 0x20180D00, // 0003 NE R6 R6 K0
- 0x781A0000, // 0004 JMPF R6 #0006
- 0xB0060302, // 0005 RAISE 1 K1 K2
- 0x6018000F, // 0006 GETGBL R6 G15
- 0x5C1C0400, // 0007 MOVE R7 R2
- 0xB8220600, // 0008 GETNGBL R8 K3
- 0x7C180400, // 0009 CALL R6 2
- 0x741A0000, // 000A JMPT R6 #000C
- 0xB0060304, // 000B RAISE 1 K1 K4
- 0x60180008, // 000C GETGBL R6 G8
- 0x5C1C0600, // 000D MOVE R7 R3
- 0x7C180200, // 000E CALL R6 1
- 0x5C0C0C00, // 000F MOVE R3 R6
- 0x6018000C, // 0010 GETGBL R6 G12
- 0x5C1C0600, // 0011 MOVE R7 R3
- 0x7C180200, // 0012 CALL R6 1
- 0x1C180D05, // 0013 EQ R6 R6 K5
- 0x781A0000, // 0014 JMPF R6 #0016
- 0xB0060306, // 0015 RAISE 1 K1 K6
- 0x5C180800, // 0016 MOVE R6 R4
- 0x741A0000, // 0017 JMPT R6 #0019
- 0x58100007, // 0018 LDCONST R4 K7
- 0x5C180A00, // 0019 MOVE R6 R5
- 0x741A0000, // 001A JMPT R6 #001C
- 0x58140008, // 001B LDCONST R5 K8
- 0x88180109, // 001C GETMBR R6 R0 K9
- 0x601C0013, // 001D GETGBL R7 G19
- 0x7C1C0000, // 001E CALL R7 0
- 0x981E1402, // 001F SETIDX R7 K10 R2
- 0x981E1603, // 0020 SETIDX R7 K11 R3
- 0x60200008, // 0021 GETGBL R8 G8
- 0x5C240800, // 0022 MOVE R9 R4
- 0x7C200200, // 0023 CALL R8 1
- 0x981E1808, // 0024 SETIDX R7 K12 R8
- 0x60200008, // 0025 GETGBL R8 G8
- 0x5C240A00, // 0026 MOVE R9 R5
- 0x7C200200, // 0027 CALL R8 1
- 0x981E1A08, // 0028 SETIDX R7 K13 R8
- 0x98180207, // 0029 SETIDX R6 R1 R7
- 0x80000000, // 002A RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: init
-********************************************************************/
-be_local_closure(hue_bridge_monad_init, /* name */
- be_nested_proto(
- 2, /* nstack */
- 1, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 1]) { /* constants */
- /* K0 */ be_nested_str(lights),
- }),
- &be_const_str_init,
- &be_const_str_solidified,
- ( &(const binstruction[ 4]) { /* code */
- 0x60040013, // 0000 GETGBL R1 G19
- 0x7C040000, // 0001 CALL R1 0
- 0x90020001, // 0002 SETMBR R0 K0 R1
- 0x80000000, // 0003 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: discover
-********************************************************************/
-be_local_closure(hue_bridge_monad_discover, /* name */
- be_nested_proto(
- 11, /* nstack */
- 1, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[13]) { /* constants */
- /* K0 */ be_nested_str(hue_ntv),
- /* K1 */ be_nested_str(json),
- /* K2 */ be_nested_str(string),
- /* K3 */ be_nested_str(lights),
- /* K4 */ be_nested_str(keys),
- /* K5 */ be_nested_str(full_status),
- /* K6 */ be_nested_str(_X22),
- /* K7 */ be_nested_str(_X22_X3A),
- /* K8 */ be_nested_str(push),
- /* K9 */ be_nested_str(stop_iteration),
- /* K10 */ be_const_int(0),
- /* K11 */ be_nested_str(concat),
- /* K12 */ be_nested_str(_X2C),
- }),
- &be_const_str_discover,
- &be_const_str_solidified,
- ( &(const binstruction[40]) { /* code */
- 0xA4060000, // 0000 IMPORT R1 K0
- 0xA40A0200, // 0001 IMPORT R2 K1
- 0xA40E0400, // 0002 IMPORT R3 K2
- 0x60100012, // 0003 GETGBL R4 G18
- 0x7C100000, // 0004 CALL R4 0
- 0x60140010, // 0005 GETGBL R5 G16
- 0x88180103, // 0006 GETMBR R6 R0 K3
- 0x8C180D04, // 0007 GETMET R6 R6 K4
- 0x7C180200, // 0008 CALL R6 1
- 0x7C140200, // 0009 CALL R5 1
- 0xA802000F, // 000A EXBLK 0 #001B
- 0x5C180A00, // 000B MOVE R6 R5
- 0x7C180000, // 000C CALL R6 0
- 0x8C1C0105, // 000D GETMET R7 R0 K5
- 0x5C240C00, // 000E MOVE R9 R6
- 0x7C1C0400, // 000F CALL R7 2
- 0x781E0008, // 0010 JMPF R7 #001A
- 0x60200008, // 0011 GETGBL R8 G8
- 0x5C240C00, // 0012 MOVE R9 R6
- 0x7C200200, // 0013 CALL R8 1
- 0x00220C08, // 0014 ADD R8 K6 R8
- 0x00201107, // 0015 ADD R8 R8 K7
- 0x001C1007, // 0016 ADD R7 R8 R7
- 0x8C200908, // 0017 GETMET R8 R4 K8
- 0x5C280E00, // 0018 MOVE R10 R7
- 0x7C200400, // 0019 CALL R8 2
- 0x7001FFEF, // 001A JMP #000B
- 0x58140009, // 001B LDCONST R5 K9
- 0xAC140200, // 001C CATCH R5 1 0
- 0xB0080000, // 001D RAISE 2 R0 R0
- 0x6014000C, // 001E GETGBL R5 G12
- 0x5C180800, // 001F MOVE R6 R4
- 0x7C140200, // 0020 CALL R5 1
- 0x24140B0A, // 0021 GT R5 R5 K10
- 0x78160003, // 0022 JMPF R5 #0027
- 0x8C14090B, // 0023 GETMET R5 R4 K11
- 0x581C000C, // 0024 LDCONST R7 K12
- 0x7C140400, // 0025 CALL R5 2
- 0x80040A00, // 0026 RET 1 R5
- 0x80000000, // 0027 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: full_status
-********************************************************************/
-be_local_closure(hue_bridge_monad_full_status, /* name */
- be_nested_proto(
- 11, /* nstack */
- 2, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 8]) { /* constants */
- /* K0 */ be_nested_str(hue_ntv),
- /* K1 */ be_nested_str(lights),
- /* K2 */ be_nested_str(contains),
- /* K3 */ be_nested_str(full_state),
- /* K4 */ be_nested_str(light),
- /* K5 */ be_nested_str(name),
- /* K6 */ be_nested_str(model),
- /* K7 */ be_nested_str(manuf),
- }),
- &be_const_str_full_status,
- &be_const_str_solidified,
- ( &(const binstruction[17]) { /* code */
- 0xA40A0000, // 0000 IMPORT R2 K0
- 0x880C0101, // 0001 GETMBR R3 R0 K1
- 0x8C0C0702, // 0002 GETMET R3 R3 K2
- 0x5C140200, // 0003 MOVE R5 R1
- 0x7C0C0400, // 0004 CALL R3 2
- 0x780E0009, // 0005 JMPF R3 #0010
- 0x880C0101, // 0006 GETMBR R3 R0 K1
- 0x940C0601, // 0007 GETIDX R3 R3 R1
- 0x8C100503, // 0008 GETMET R4 R2 K3
- 0x5C180200, // 0009 MOVE R6 R1
- 0x941C0704, // 000A GETIDX R7 R3 K4
- 0x94200705, // 000B GETIDX R8 R3 K5
- 0x94240706, // 000C GETIDX R9 R3 K6
- 0x94280707, // 000D GETIDX R10 R3 K7
- 0x7C100C00, // 000E CALL R4 6
- 0x80040800, // 000F RET 1 R4
- 0x80000000, // 0010 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
/********************************************************************
** Solidified class: hue_bridge_monad
********************************************************************/
be_local_class(hue_bridge_monad,
1,
NULL,
- be_nested_map(9,
+ be_nested_map(10,
( (struct bmapnode*) &(const bmapnode[]) {
- { be_const_key(lights, 1), be_const_var(0) },
- { be_const_key(groups, -1), be_const_closure(hue_bridge_monad_groups_closure) },
- { be_const_key(remove_light, 3), be_const_closure(hue_bridge_monad_remove_light_closure) },
- { be_const_key(discover, -1), be_const_closure(hue_bridge_monad_discover_closure) },
+ { be_const_key(lights, -1), be_const_var(0) },
+ { be_const_key(groups, 6), be_const_closure(hue_bridge_monad_groups_closure) },
{ be_const_key(hue_status, -1), be_const_closure(hue_bridge_monad_hue_status_closure) },
{ be_const_key(add_light, -1), be_const_closure(hue_bridge_monad_add_light_closure) },
- { be_const_key(cmd, 7), be_const_closure(hue_bridge_monad_cmd_closure) },
+ { be_const_key(remove_light, 8), be_const_closure(hue_bridge_monad_remove_light_closure) },
{ be_const_key(init, -1), be_const_closure(hue_bridge_monad_init_closure) },
- { be_const_key(full_status, -1), be_const_closure(hue_bridge_monad_full_status_closure) },
+ { be_const_key(cmd, -1), be_const_closure(hue_bridge_monad_cmd_closure) },
+ { be_const_key(light_to_id, -1), be_const_closure(hue_bridge_monad_light_to_id_closure) },
+ { be_const_key(discover, -1), be_const_closure(hue_bridge_monad_discover_closure) },
+ { be_const_key(full_status, 1), be_const_closure(hue_bridge_monad_full_status_closure) },
})),
be_str_literal("hue_bridge_monad")
);
diff --git a/lib/libesp32/berry_tasmota/src/embedded/hue_bridge.be b/lib/libesp32/berry_tasmota/src/embedded/hue_bridge.be
index a4054b923..eb19de84d 100644
--- a/lib/libesp32/berry_tasmota/src/embedded/hue_bridge.be
+++ b/lib/libesp32/berry_tasmota/src/embedded/hue_bridge.be
@@ -28,6 +28,15 @@ hue_bridge.init = def (m)
self.lights.remove(id)
end
+ # get id from light object
+ def light_to_id(l)
+ for id: self.lights.keys()
+ if l == self.lights[id]['light']
+ return id
+ end
+ end
+ end
+
# return the status of a single light by id
def hue_status(id)
import hue_ntv
From 42b73ecfce6bc11d33320b8c586bffb7c85bf922 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 15 Feb 2022 21:58:05 +0100
Subject: [PATCH 13/25] Berry add module mqtt
---
lib/libesp32/berry/default/be_modtab.c | 2 +
lib/libesp32/berry/generate/be_const_strtab.h | 2 +
.../berry/generate/be_const_strtab_def.h | 2105 +++++++++--------
lib/libesp32/berry/generate/be_fixed_mqtt.h | 19 +
.../berry_tasmota/src/be_mqtt_lib.cpp | 21 +
tasmota/xdrv_52_3_berry_mqtt.ino | 89 +
tasmota/xdrv_52_3_berry_tasmota.ino | 43 -
7 files changed, 1187 insertions(+), 1094 deletions(-)
create mode 100644 lib/libesp32/berry/generate/be_fixed_mqtt.h
create mode 100644 lib/libesp32/berry_tasmota/src/be_mqtt_lib.cpp
create mode 100644 tasmota/xdrv_52_3_berry_mqtt.ino
diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c
index e09106849..f5102c224 100644
--- a/lib/libesp32/berry/default/be_modtab.c
+++ b/lib/libesp32/berry/default/be_modtab.c
@@ -30,6 +30,7 @@ be_extern_native_module(cb);
/* Tasmota specific */
be_extern_native_module(python_compat);
be_extern_native_module(re);
+be_extern_native_module(mqtt);
be_extern_native_module(persist);
be_extern_native_module(autoconf);
be_extern_native_module(tapp);
@@ -108,6 +109,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
&be_native_module(python_compat),
&be_native_module(re),
&be_native_module(path),
+ &be_native_module(mqtt),
&be_native_module(persist),
#ifdef USE_AUTOCONF
&be_native_module(autoconf),
diff --git a/lib/libesp32/berry/generate/be_const_strtab.h b/lib/libesp32/berry/generate/be_const_strtab.h
index b6fb90f13..0ca3362ad 100644
--- a/lib/libesp32/berry/generate/be_const_strtab.h
+++ b/lib/libesp32/berry/generate/be_const_strtab.h
@@ -760,6 +760,7 @@ extern const bcstring be_const_str_strftime;
extern const bcstring be_const_str_string;
extern const bcstring be_const_str_strip;
extern const bcstring be_const_str_strptime;
+extern const bcstring be_const_str_subscribe;
extern const bcstring be_const_str_success;
extern const bcstring be_const_str_super;
extern const bcstring be_const_str_sys;
@@ -796,6 +797,7 @@ extern const bcstring be_const_str_type;
extern const bcstring be_const_str_type_error;
extern const bcstring be_const_str_udp;
extern const bcstring be_const_str_unknown_X20instruction;
+extern const bcstring be_const_str_unsubscribe;
extern const bcstring be_const_str_update;
extern const bcstring be_const_str_upper;
extern const bcstring be_const_str_url_encode;
diff --git a/lib/libesp32/berry/generate/be_const_strtab_def.h b/lib/libesp32/berry/generate/be_const_strtab_def.h
index 30fb8e581..ad5ef334d 100644
--- a/lib/libesp32/berry/generate/be_const_strtab_def.h
+++ b/lib/libesp32/berry/generate/be_const_strtab_def.h
@@ -1,747 +1,747 @@
-be_define_const_str(, "", 2166136261u, 0, 0, &be_const_str__def);
-be_define_const_str(_X0A, "\n", 252472541u, 0, 1, &be_const_str__X2D_X2D_X3A_X2D_X2D);
-be_define_const_str(_X20, " ", 621580159u, 0, 1, NULL);
-be_define_const_str(_X21_X3D, "!=", 2428715011u, 0, 2, &be_const_str_send);
-be_define_const_str(_X21_X3D_X3D, "!==", 559817114u, 0, 3, &be_const_str_yield);
-be_define_const_str(_X22, "\"", 655135397u, 0, 1, &be_const_str__X23autoexec_X2Ebat);
-be_define_const_str(_X22_X3A, "\":", 399167565u, 0, 2, &be_const_str_TAP_X3A_X20Loaded_X20Tasmota_X20App_X20_X27_X25s_X27);
-be_define_const_str(_X23, "#", 638357778u, 0, 1, &be_const_str_delete_all_configs);
-be_define_const_str(_X23autoexec_X2Ebat, "#autoexec.bat", 3382890497u, 0, 13, &be_const_str_constructor_cb);
-be_define_const_str(_X23autoexec_X2Ebe, "#autoexec.be", 1181757091u, 0, 12, &be_const_str__X3Clegend_X3E_X3Cb_X20title_X3D_X27New_X20autoconf_X27_X3E_X26nbsp_X3BSelect_X20new_X20auto_X2Dconfiguration_X3C_X2Fb_X3E_X3C_X2Flegend_X3E);
-be_define_const_str(_X23display_X2Eini, "#display.ini", 182218220u, 0, 12, &be_const_str_public_key);
-be_define_const_str(_X23init_X2Ebat, "#init.bat", 3297595077u, 0, 9, &be_const_str__X3D_X3C_X3E_X21);
-be_define_const_str(_X23preinit_X2Ebe, "#preinit.be", 687035716u, 0, 11, &be_const_str_eth);
+be_define_const_str(, "", 2166136261u, 0, 0, &be_const_str_SERIAL_6E1);
+be_define_const_str(_X0A, "\n", 252472541u, 0, 1, NULL);
+be_define_const_str(_X20, " ", 621580159u, 0, 1, &be_const_str_Unknown);
+be_define_const_str(_X21_X3D, "!=", 2428715011u, 0, 2, &be_const_str_LVG_X3A_X20object_X3A);
+be_define_const_str(_X21_X3D_X3D, "!==", 559817114u, 0, 3, &be_const_str_SERIAL_7O1);
+be_define_const_str(_X22, "\"", 655135397u, 0, 1, &be_const_str__X2Ep);
+be_define_const_str(_X22_X3A, "\":", 399167565u, 0, 2, NULL);
+be_define_const_str(_X23, "#", 638357778u, 0, 1, &be_const_str_a);
+be_define_const_str(_X23autoexec_X2Ebat, "#autoexec.bat", 3382890497u, 0, 13, &be_const_str_min);
+be_define_const_str(_X23autoexec_X2Ebe, "#autoexec.be", 1181757091u, 0, 12, &be_const_str__X3Coption_X20value_X3D_X27reset_X27_X3E_X26lt_X3BRemove_X20autoconf_X26gt_X3B_X3C_X2Foption_X3E);
+be_define_const_str(_X23display_X2Eini, "#display.ini", 182218220u, 0, 12, NULL);
+be_define_const_str(_X23init_X2Ebat, "#init.bat", 3297595077u, 0, 9, &be_const_str_bool);
+be_define_const_str(_X23preinit_X2Ebe, "#preinit.be", 687035716u, 0, 11, &be_const_str_setitem);
be_define_const_str(_X2502d_X25s_X2502d, "%02d%s%02d", 1587999717u, 0, 10, NULL);
-be_define_const_str(_X2504d_X2D_X2502d_X2D_X2502dT_X2502d_X3A_X2502d_X3A_X2502d, "%04d-%02d-%02dT%02d:%02d:%02d", 3425528601u, 0, 29, &be_const_str_CFG_X3A_X20downloading_X20_X27_X25s_X27);
-be_define_const_str(_X2508x_X2D_X2504x_X2D_X2504x_X2D_X2504x_X2D_X2504x_X2508x, "%08x-%04x-%04x-%04x-%04x%08x", 1670063141u, 0, 28, NULL);
-be_define_const_str(_X25s_X2Eautoconf, "%s.autoconf", 3560383524u, 0, 11, NULL);
-be_define_const_str(_X26lt_X3BError_X3A_X20apply_X20new_X20or_X20remove_X26gt_X3B, "<Error: apply new or remove>", 2855507949u, 0, 34, &be_const_str_EXTERNAL_I2S);
-be_define_const_str(_X26lt_X3BNone_X26gt_X3B, "<None>", 2602165498u, 0, 12, &be_const_str_isinstance);
-be_define_const_str(_X28_X29, "()", 685372826u, 0, 2, &be_const_str_find_key_i);
-be_define_const_str(_X2B, "+", 772578730u, 0, 1, &be_const_str_lower);
-be_define_const_str(_X2C, ",", 688690635u, 0, 1, &be_const_str_leds);
-be_define_const_str(_X2C_X22AXP192_X22_X3A_X7B_X22VBusVoltage_X22_X3A_X25_X2E3f_X2C_X22VBusCurrent_X22_X3A_X25_X2E1f_X2C_X22BattVoltage_X22_X3A_X25_X2E3f_X2C_X22BattCurrent_X22_X3A_X25_X2E1f_X2C_X22Temperature_X22_X3A_X25_X2E1f_X7D, ",\"AXP192\":{\"VBusVoltage\":%.3f,\"VBusCurrent\":%.1f,\"BattVoltage\":%.3f,\"BattCurrent\":%.1f,\"Temperature\":%.1f}", 2598755376u, 0, 106, &be_const_str_files);
-be_define_const_str(_X2D_X2D_X3A_X2D_X2D, "--:--", 1370615441u, 0, 5, &be_const_str_lv_coord_arr);
-be_define_const_str(_X2E, ".", 722245873u, 0, 1, &be_const_str_json_fdump_list);
-be_define_const_str(_X2E_X2E, "..", 2748622605u, 0, 2, &be_const_str_list);
-be_define_const_str(_X2Eautoconf, ".autoconf", 2524679088u, 0, 9, &be_const_str_get_current_module_path);
-be_define_const_str(_X2Ebe, ".be", 1325797348u, 0, 3, &be_const_str_BRY_X3A_X20argument_X20must_X20be_X20a_X20function);
-be_define_const_str(_X2Ebec, ".bec", 3985273221u, 0, 4, &be_const_str_get_vbus_voltage);
-be_define_const_str(_X2Elen, ".len", 850842136u, 0, 4, &be_const_str_rtc);
-be_define_const_str(_X2Ep, ".p", 1171526419u, 0, 2, &be_const_str_create_segment);
-be_define_const_str(_X2Ep1, ".p1", 249175686u, 0, 3, &be_const_str_draw_line_dsc_init);
-be_define_const_str(_X2Ep2, ".p2", 232398067u, 0, 3, &be_const_str_set);
-be_define_const_str(_X2Esize, ".size", 1965188224u, 0, 5, NULL);
-be_define_const_str(_X2Etapp, ".tapp", 1363391594u, 0, 5, &be_const_str_clear);
-be_define_const_str(_X2Ew, ".w", 1255414514u, 0, 2, &be_const_str_set_huesat);
-be_define_const_str(_X2F, "/", 705468254u, 0, 1, NULL);
-be_define_const_str(_X2F_X2Eautoconf, "/.autoconf", 2212074393u, 0, 10, &be_const_str_CFG_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s);
-be_define_const_str(_X2F_X3Frst_X3D, "/?rst=", 580074707u, 0, 6, &be_const_str_ctypes_bytes_dyn);
-be_define_const_str(_X2Fac, "/ac", 3904651978u, 0, 3, &be_const_str__X3Cp_X3E_X3Cform_X20id_X3Dreapply_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20);
-be_define_const_str(_X2Flights_X2F, "/lights/", 2370247908u, 0, 8, &be_const_str_init_draw_arc_dsc);
-be_define_const_str(_X2Fstate_X2F, "/state/", 4226179876u, 0, 7, &be_const_str__X3Cselect_X20name_X3D_X27zip_X27_X3E);
-be_define_const_str(_X3A, ":", 1057798253u, 0, 1, &be_const_str_day);
-be_define_const_str(_X3C, "<", 957132539u, 0, 1, &be_const_str_LVG_X3A_X20call_X20to_X20unsupported_X20callback);
-be_define_const_str(_X3C_X2Fform_X3E_X3C_X2Fp_X3E, "
", 3546571739u, 0, 11, &be_const_str_full_status);
-be_define_const_str(_X3C_X2Fselect_X3E_X3Cp_X3E_X3C_X2Fp_X3E, "", 1863865923u, 0, 16, &be_const_str_file);
-be_define_const_str(_X3C_X3D, "<=", 2499223986u, 0, 2, &be_const_str__X3Cp_X3E_X3Cform_X20id_X3Dzip_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20);
-be_define_const_str(_X3Cbutton_X20name_X3D_X27reapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3ERe_X2Dapply_X20current_X20configuration_X3C_X2Fbutton_X3E, "", 3147934216u, 0, 82, &be_const_str_False);
-be_define_const_str(_X3Cbutton_X20name_X3D_X27zipapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3EApply_X20configuration_X3C_X2Fbutton_X3E, "", 1205771629u, 0, 72, &be_const_str_erase);
-be_define_const_str(_X3Cfieldset_X3E_X3Cstyle_X3E_X2Ebdis_X7Bbackground_X3A_X23888_X3B_X7D_X2Ebdis_X3Ahover_X7Bbackground_X3A_X23888_X3B_X7D_X3C_X2Fstyle_X3E, "", 2052843416u, 0, 25, &be_const_str__X3E_X3D);
-be_define_const_str(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27ac_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3EAuto_X2Dconfiguration_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E, "", 2058443583u, 0, 110, &be_const_str_pixel_count);
-be_define_const_str(_X3Cp_X3E_X3Cform_X20id_X3Dreapply_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20, "", 3546571739u, 0, 11, &be_const_str_ctor);
+be_define_const_str(_X3C_X2Fselect_X3E_X3Cp_X3E_X3C_X2Fp_X3E, "", 1863865923u, 0, 16, &be_const_str_srand);
+be_define_const_str(_X3C_X3D, "<=", 2499223986u, 0, 2, &be_const_str_detect);
+be_define_const_str(_X3Cbutton_X20name_X3D_X27reapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3ERe_X2Dapply_X20current_X20configuration_X3C_X2Fbutton_X3E, "", 3147934216u, 0, 82, &be_const_str_consume_mono);
+be_define_const_str(_X3Cbutton_X20name_X3D_X27zipapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3EApply_X20configuration_X3C_X2Fbutton_X3E, "", 1205771629u, 0, 72, &be_const_str__X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E);
+be_define_const_str(_X3Cfieldset_X3E_X3Cstyle_X3E_X2Ebdis_X7Bbackground_X3A_X23888_X3B_X7D_X2Ebdis_X3Ahover_X7Bbackground_X3A_X23888_X3B_X7D_X3C_X2Fstyle_X3E, "", 2052843416u, 0, 25, &be_const_str_energy_struct);
+be_define_const_str(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27ac_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3EAuto_X2Dconfiguration_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E, "", 2058443583u, 0, 110, &be_const_str_loop);
+be_define_const_str(_X3Cp_X3E_X3Cform_X20id_X3Dreapply_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20, "", 3546571739u, 0, 11, &be_const_str_ctor);
-be_define_const_str(_X3C_X2Fselect_X3E_X3Cp_X3E_X3C_X2Fp_X3E, "", 1863865923u, 0, 16, &be_const_str_srand);
-be_define_const_str(_X3C_X3D, "<=", 2499223986u, 0, 2, &be_const_str_detect);
-be_define_const_str(_X3Cbutton_X20name_X3D_X27reapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3ERe_X2Dapply_X20current_X20configuration_X3C_X2Fbutton_X3E, "", 3147934216u, 0, 82, &be_const_str_consume_mono);
-be_define_const_str(_X3Cbutton_X20name_X3D_X27zipapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3EApply_X20configuration_X3C_X2Fbutton_X3E, "", 1205771629u, 0, 72, &be_const_str__X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E);
-be_define_const_str(_X3Cfieldset_X3E_X3Cstyle_X3E_X2Ebdis_X7Bbackground_X3A_X23888_X3B_X7D_X2Ebdis_X3Ahover_X7Bbackground_X3A_X23888_X3B_X7D_X3C_X2Fstyle_X3E, "", 2052843416u, 0, 25, &be_const_str_energy_struct);
-be_define_const_str(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27ac_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3EAuto_X2Dconfiguration_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E, "", 2058443583u, 0, 110, &be_const_str_loop);
-be_define_const_str(_X3Cp_X3E_X3Cform_X20id_X3Dreapply_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20, "", 3546571739u, 0, 11, &be_const_str_begin_multicast);
+be_define_const_str(_X3C_X2Fselect_X3E_X3Cp_X3E_X3C_X2Fp_X3E, "", 1863865923u, 0, 16, &be_const_str_lv_module_init);
+be_define_const_str(_X3C_X3D, "<=", 2499223986u, 0, 2, &be_const_str_invalidate);
+be_define_const_str(_X3Cbutton_X20name_X3D_X27reapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3ERe_X2Dapply_X20current_X20configuration_X3C_X2Fbutton_X3E, "", 3147934216u, 0, 82, &be_const_str_AudioFileSource);
+be_define_const_str(_X3Cbutton_X20name_X3D_X27zipapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3EApply_X20configuration_X3C_X2Fbutton_X3E, "", 1205771629u, 0, 72, NULL);
+be_define_const_str(_X3Cfieldset_X3E_X3Cstyle_X3E_X2Ebdis_X7Bbackground_X3A_X23888_X3B_X7D_X2Ebdis_X3Ahover_X7Bbackground_X3A_X23888_X3B_X7D_X3C_X2Fstyle_X3E, "", 2052843416u, 0, 25, &be_const_str_reverse_gamma10);
+be_define_const_str(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27ac_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3EAuto_X2Dconfiguration_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E, "", 2058443583u, 0, 110, NULL);
+be_define_const_str(_X3Cp_X3E_X3Cform_X20id_X3Dreapply_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20, "