From 9c8f3826b26112d5935647b2087a6e2abc8d56c9 Mon Sep 17 00:00:00 2001 From: lmelette <153835148+lmelette@users.noreply.github.com> Date: Wed, 17 Jul 2024 12:25:44 +0200 Subject: [PATCH] Added support for Wooliis LCD Coulometer/Battery Monitor (#21732) * Added support for Wooliis LCD Coulometer/Battery Monitor * Adjusted code structures and data types for Wooliis sensor --------- Co-authored-by: Luca Melette --- CODE_OWNERS.md | 1 + tasmota/berry/include/be_gpio_defines.h | 1 + tasmota/include/tasmota_template.h | 5 + tasmota/language/af_AF.h | 7 +- tasmota/language/bg_BG.h | 7 +- tasmota/language/ca_AD.h | 7 +- tasmota/language/cs_CZ.h | 7 +- tasmota/language/de_DE.h | 5 + tasmota/language/el_GR.h | 7 +- tasmota/language/en_GB.h | 7 +- tasmota/language/es_ES.h | 7 +- tasmota/language/fr_FR.h | 7 +- tasmota/language/fy_NL.h | 7 +- tasmota/language/he_HE.h | 7 +- tasmota/language/hu_HU.h | 7 +- tasmota/language/it_IT.h | 5 + tasmota/language/ko_KO.h | 7 +- tasmota/language/nl_NL.h | 7 +- tasmota/language/pl_PL.h | 7 +- tasmota/language/pt_BR.h | 7 +- tasmota/language/pt_PT.h | 7 +- tasmota/language/ro_RO.h | 7 +- tasmota/language/ru_RU.h | 7 +- tasmota/language/sk_SK.h | 7 +- tasmota/language/sv_SE.h | 7 +- tasmota/language/tr_TR.h | 7 +- tasmota/language/uk_UA.h | 7 +- tasmota/language/vi_VN.h | 7 +- tasmota/language/zh_CN.h | 7 +- tasmota/language/zh_TW.h | 7 +- tasmota/tasmota_support/support_features.ino | 4 +- .../tasmota_xsns_sensor/xsns_115_wooliis.ino | 228 ++++++++++++++++++ tools/decode-status.py | 2 +- tools/lv_gpio/lv_gpio_enum.h | 1 + 34 files changed, 400 insertions(+), 27 deletions(-) create mode 100644 tasmota/tasmota_xsns_sensor/xsns_115_wooliis.ino diff --git a/CODE_OWNERS.md b/CODE_OWNERS.md index 49fa17a4b..c6b33cdf6 100644 --- a/CODE_OWNERS.md +++ b/CODE_OWNERS.md @@ -229,6 +229,7 @@ In addition to @arendst the following code is mainly owned by: | xsns_112_ens210 | Christoph Friese | xsns_113_hc8 | Daniel Maier | xsns_114_amsx915 | Bastian Urschel +| xsns_115_wooliis | Luca Melette | | | xsns_127_esp32_sensors | @arendst | | diff --git a/tasmota/berry/include/be_gpio_defines.h b/tasmota/berry/include/be_gpio_defines.h index 61bd20c71..9b9880872 100644 --- a/tasmota/berry/include/be_gpio_defines.h +++ b/tasmota/berry/include/be_gpio_defines.h @@ -350,6 +350,7 @@ const be_const_member_t lv_gpio_constants[] = { { "WIEGAND_D0", (int32_t) GPIO_WIEGAND_D0 }, { "WIEGAND_D1", (int32_t) GPIO_WIEGAND_D1 }, { "WINDMETER_SPEED", (int32_t) GPIO_WINDMETER_SPEED }, + { "WOOLIIS_RX", (int32_t) GPIO_WOOLIIS_RX }, { "WS2812", (int32_t) GPIO_WS2812 }, { "XPT2046_CS", (int32_t) GPIO_XPT2046_CS }, { "ZEROCROSS", (int32_t) GPIO_ZEROCROSS }, diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 0494b340b..d2ca22f66 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -221,6 +221,7 @@ enum UserSelectablePins { GPIO_RN2XX3_TX, GPIO_RN2XX3_RX, GPIO_RN2XX3_RST, // RN2XX3 LoRaWan node Serial interface GPIO_TCP_TX_EN, // TCP to serial bridge, EN pin GPIO_ASR650X_TX, GPIO_ASR650X_RX, // ASR650X LoRaWan node Serial interface + GPIO_WOOLIIS_RX, // Wooliis Battery capacity monitor Serial RX GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage with max 2045 @@ -489,6 +490,7 @@ const char kSensorNames[] PROGMEM = D_GPIO_RN2XX3_TX "|" D_GPIO_RN2XX3_RX "|" D_GPIO_RN2XX3_RST "|" D_SENSOR_TCP_TXD_EN "|" D_GPIO_ASR650X_TX "|" D_GPIO_ASR650X_RX "|" + D_SENSOR_WOOLIIS_RX "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -1095,6 +1097,9 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_ASR650X_TX), AGPIO(GPIO_ASR650X_RX), // ASR650X LoRaWan node Serial interface #endif +#ifdef USE_WOOLIIS // xsns_115_wooliis.ino + AGPIO(GPIO_WOOLIIS_RX), // Wooliis Battery capacity monitor Serial interface +#endif /*-------------------------------------------------------------------------------------------*\ * Other sensors diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 13cbdde3a..500f1f430 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_AF_AF_H_ diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 02d35c195..3856e5d88 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "А" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_BG_BG_H_ diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index 5bbe9ea11..31bcd6b7c 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_CA_AD_H_ diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index bc101d689..ba9d81016 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_CS_CZ_H_ diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 1843b1a35..8274d77b4 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -1000,6 +1000,7 @@ #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" #define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Aufladen" +#define D_CAPACITY "Kapazität" + #endif // _LANGUAGE_DE_DE_H_ diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index c28ddc011..226a46170 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_EL_GR_H_ diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 813e248b8..9a3fedc45 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1270,4 +1271,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_EN_GB_H_ diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 006b8d0a7..1a1bef25e 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Cargando" +#define D_CAPACITY "Capacidad" + #endif // _LANGUAGE_ES_ES_H_ diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index b92fe6aae..f0d757644 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units @@ -1270,4 +1271,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "En charge" +#define D_CAPACITY "Capacité" + #endif // _LANGUAGE_FR_FR_H_ diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index d705ee5f2..24c9e5d16 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_FY_NL_H_ diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index f5ed94f1e..a9575056b 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_HE_HE_H_ diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 40d7b48f8..cd88f5cb1 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -1002,7 +1002,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1272,4 +1273,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_HU_HU_H_ diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index ed2984e64..2a3ea03ef 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -1000,6 +1000,7 @@ #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 - RX" #define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis RX" // Units #define D_UNIT_AMPERE "A" @@ -1270,4 +1271,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar - TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar - RX" +// xsns_115_wooliis.ino +#define D_CHARGING "In carica" +#define D_CAPACITY "Capacità" + #endif // _LANGUAGE_IT_IT_H_ diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 007e10ca2..e1b0c4dff 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_KO_KO_H_ diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 3edb51c8f..ac0922c17 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_NL_NL_H_ diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index dc320c42f..15bce353a 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_PL_PL_D_H_ diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 20ec59a28..770c668c9 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_PT_BR_H_ diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 2d3495c3f..972e107e5 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_PT_PT_H_ diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index a8ac820a6..96c5fabda 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_RO_RO_H_ diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 35e1df314..5b803c344 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -1000,7 +1000,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "А" @@ -1270,4 +1271,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_RU_RU_H_ diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 2350fbd69..742906602 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_SK_SK_H_ diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index fb5115ca7..9c5583e23 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_SV_SE_H_ diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 4fa1121bc..23b50706d 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_TR_TR_H_ diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index ac248bf8e..50a17d552 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "А" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_UK_UA_H_ diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 5cdea438a..69d5e821e 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_VI_VN_H_ diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 6eaa9867a..b99a96c83 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "A" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_ZH_CN_H_ diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 1e047a89a..86ed3e233 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -999,7 +999,8 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" // Units #define D_UNIT_AMPERE "安培" @@ -1269,4 +1270,8 @@ #define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" #define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" +// xsns_115_wooliis.ino +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + #endif // _LANGUAGE_ZH_TW_H_ diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino index fd5e2c5a8..be84d2617 100644 --- a/tasmota/tasmota_support/support_features.ino +++ b/tasmota/tasmota_support/support_features.ino @@ -922,7 +922,9 @@ constexpr uint32_t feature[] = { #if defined(USE_I2C) && defined(USE_QMP6988) 0x00000040 | // xsns_28_qmp6988.ino #endif -// 0x00000080 | // +#ifdef USE_WOOLIIS + 0x00000080 | // xsns_115_wooliis.ino +#endif // 0x00000100 | // // 0x00000200 | // // 0x00000400 | // diff --git a/tasmota/tasmota_xsns_sensor/xsns_115_wooliis.ino b/tasmota/tasmota_xsns_sensor/xsns_115_wooliis.ino new file mode 100644 index 000000000..2d6444be8 --- /dev/null +++ b/tasmota/tasmota_xsns_sensor/xsns_115_wooliis.ino @@ -0,0 +1,228 @@ +/* + xsns_115_wooliis.ino - Wooliis Hall Effect Coulometer (Battery capacity monitor) support for Tasmota + + Copyright (C) 2024 Luca Melette + + 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_WOOLIIS +/*********************************************************************************************\ + * Wooliis Hall Effect Coulometer (Battery capacity monitor) with LCD + * Model variants: WLS-PVA050 WLS-PVA100 WLS-PVA200 WLS-PVA400 (current ratings 50A, 100A, 200A, 400A) + * Similar models: WLS-MVAxxx, WLS-TVAxxx, WLS-HVAxxx (not investigated) + * + * Manufacturer links: + * (Chinese) http://www.wooliis.com/products_view.aspx?ID=75 + * (English) http://www.wooliis.com/Enproducts_view.aspx?ID=75 + * + * Alternative branding: Drok (Ebay), AiLi (Amazon) + * + * Inside the case, on the PCB, there is an active serial port with labels Gnd/TX/RX/Vcc. + * In some product variants, it might be connected to a Bluetooth module for remote operation. + * On the TX pin, meter readings are sent out every 5 secs using 9600 8N1 + * + * Values in binary messages can be mapped as follows: + * + * magic % Ah V A Wh_in Wh_out status ck + * b55b0101 64 03e8 0088 001d 00032b 0002b6 0000a8 6b + * + * And decoded as: + * - Charge = 100 % + * - Remaining capacity = 100 Ah + * - Voltage = 13.6V + * - Current = 2.9 A + * - Energy IN = 81.1 Wh + * - Energy OUT = 69.4 Wh + * - Status = charging + * + * Hardware Serial will be selected if GPIO3 = [Wooliis RX] +\*********************************************************************************************/ + +#define D_WOOLIIS "Wooliis" + +#define XSNS_115 115 + +#define D_IMPORT "Import" +#define D_EXPORT "Export" +#define D_JSON_CAPACITY "Capacity" +#define D_JSON_CHARGING "Charging" + +#include + +TasmotaSerial *WooliisSerial = nullptr; + +typedef struct wooliis_data_t { + float remaining_capacity; + float voltage; + float current; + float energy_in; + float energy_out; + uint8_t status; + uint8_t valid = 0; + uint8_t ready = 0; + uint8_t charge_percent; +} wooliis_data_t; + +wooliis_data_t *Wooliis = nullptr; + +/*********************************************************************************************/ + +void WooliisReadData() // process the data sent by Wooliis battery capacity monitors +{ + while (WooliisSerial->available() && WooliisSerial->peek() != 0xb5) { + WooliisSerial->read(); + } + if (WooliisSerial->available() < 21) { + return; + } + uint8_t buffer[21]; + WooliisSerial->readBytes(buffer, 21); + if (buffer[0] != 0xb5 && buffer[1] != 0x5b && buffer[2] == 0x01 && buffer[3] == 0x01) { + AddLog(LOG_LEVEL_DEBUG, PSTR("WLS: Flushing serial")); + WooliisSerial->flush(); // Out of sync or wrong sensor connected + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 21); + return; + } + + uint8_t checksum = 0; + for (uint32_t i = 0; i < 20; i++) { + checksum += buffer[i]; + } + checksum = 255 - checksum; + if (checksum != buffer[20]) { + AddLog(LOG_LEVEL_DEBUG, PSTR("WLS: " D_CHECKSUM_FAILURE)); + return; + } + + AddLog(LOG_LEVEL_DEBUG, PSTR("WLS: message received correctly!")); + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, 21); + + Wooliis->charge_percent = buffer[4]; + Wooliis->remaining_capacity = 0.1f * ((uint16_t)buffer[5]<<8 | buffer[6]); + Wooliis->voltage = 0.1f * ((uint16_t)buffer[7]<<8 | buffer[8]); + Wooliis->current = (buffer[19] ? -0.1f : 0.1f) * ((uint16_t)buffer[9]<<8 | buffer[10]); + Wooliis->energy_in = 0.1f * ((uint32_t)buffer[11]<<16 | (uint16_t)buffer[12]<<8 | buffer[13]); + Wooliis->energy_out = 0.1f * ((uint32_t)buffer[14]<<16 | (uint16_t)buffer[15]<<8 | buffer[16]); + Wooliis->status = buffer[19]; + + Wooliis->valid = 1; + + return; +} + +/*********************************************************************************************/ + +void WooliisSecond(void) // Every second +{ + if (Wooliis->ready) + WooliisReadData(); +} + +/*********************************************************************************************/ + +void WooliisInit(void) { + if (PinUsed(GPIO_WOOLIIS_RX)) { + WooliisSerial = new TasmotaSerial(Pin(GPIO_WOOLIIS_RX), -1, 1); + if (WooliisSerial->begin(9600)) { + if (WooliisSerial->hardwareSerial()) { ClaimSerial(); } + WooliisSerial->flush(); // Clear serial buffer + Wooliis = (wooliis_data_t*)calloc(sizeof(wooliis_data_t), 1); + if (nullptr == Wooliis) { return; } + Wooliis->ready = 1; + AddLog(LOG_LEVEL_DEBUG, PSTR("WLS: Serial ready")); + } + } +} + +#ifdef USE_WEBSERVER +const char HTTP_SNS_WOOLIIS_BCP[] = "{s}%s " D_BATTERY_CHARGE "{m}%d " D_UNIT_PERCENT "{e}"; +const char HTTP_SNS_WOOLIIS_CAP[] = "{s}%s " D_CAPACITY "{m}%*_f " D_UNIT_CHARGE "{e}"; +const char HTTP_SNS_WOOLIIS_CHG[] = "{s}%s " D_CHARGING "{m}%s{e}"; +const char HTTP_SNS_WOOLIIS_VOL[] = "{s}%s " D_VOLTAGE "{m}%*_f " D_UNIT_VOLT "{e}"; +const char HTTP_SNS_WOOLIIS_CUR[] = "{s}%s " D_CURRENT "{m}%*_f " D_UNIT_AMPERE "{e}"; +const char HTTP_SNS_WOOLIIS_POW[] = "{s}%s " D_POWERUSAGE "{m}%*_f " D_UNIT_WATT "{e}"; +const char HTTP_SNS_WOOLIIS_IMP[] = "{s}%s " D_IMPORT "{m}%*_f " D_UNIT_WATTHOUR "{e}"; +const char HTTP_SNS_WOOLIIS_EXP[] = "{s}%s " D_EXPORT "{m}%*_f " D_UNIT_WATTHOUR "{e}"; +#endif // USE_WEBSERVER + +void WooliisShow(bool json) { + if (Wooliis->valid) { + float power = Wooliis->voltage*Wooliis->current; + if (json) { + ResponseAppend_P(PSTR(",\"%s\":{"), D_WOOLIIS); + ResponseAppend_P(PSTR("\"%s\":%*_f,"), D_JSON_CAPACITY, Settings->flag2.energy_resolution, &Wooliis->remaining_capacity); + ResponseAppend_P(PSTR("\"%s\":%d,"), D_JSON_CHARGING, (Wooliis->status ? 1 : 0)); + ResponseAppend_P(PSTR("\"%s\":%*_f,"), D_JSON_VOLTAGE, Settings->flag2.voltage_resolution, &Wooliis->voltage); + ResponseAppend_P(PSTR("\"%s\":%*_f,"), D_JSON_CURRENT, Settings->flag2.current_resolution, &Wooliis->current); + ResponseAppend_P(PSTR("\"%s\":%*_f,"), D_JSON_POWERUSAGE, Settings->flag2.wattage_resolution, &power); + ResponseAppend_P(PSTR("\"%s\":%*_f,"), D_JSON_IMPORT, Settings->flag2.energy_resolution, &Wooliis->energy_in); + ResponseAppend_P(PSTR("\"%s\":%*_f"), D_JSON_EXPORT, Settings->flag2.energy_resolution, &Wooliis->energy_out); + ResponseJsonEnd(); +#ifdef USE_DOMOTICZ + if (0 == TasmotaGlobal.tele_period) { + char pe[16]; + snprintf_P(pe, sizeof(pe), PSTR("%d;%d"), Wooliis->voltage*Wooliis->current, Wooliis->energy_out); + DomoticzSensor(DZ_COUNT, Wooliis->charge_percent); + DomoticzSensor(DZ_VOLTAGE, Wooliis->voltage); + DomoticzSensor(DZ_CURRENT, Wooliis->current); + DomoticzSensor(DZ_POWER_ENERGY, pe); + } +#endif // USE_DOMOTICZ + } // if json +#ifdef USE_WEBSERVER + else { + WSContentSend_PD(HTTP_SNS_WOOLIIS_BCP, D_BATTERY, Wooliis->charge_percent); + WSContentSend_PD(HTTP_SNS_WOOLIIS_CAP, D_BATTERY, Settings->flag2.energy_resolution, &Wooliis->remaining_capacity); + WSContentSend_PD(HTTP_SNS_WOOLIIS_CHG, D_BATTERY, (Wooliis->status ? D_TRUE : D_FALSE)); + WSContentSend_PD(HTTP_SNS_WOOLIIS_VOL, D_BATTERY, Settings->flag2.voltage_resolution, &Wooliis->voltage); + WSContentSend_PD(HTTP_SNS_WOOLIIS_CUR, D_BATTERY, Settings->flag2.current_resolution, &Wooliis->current); + WSContentSend_PD(HTTP_SNS_WOOLIIS_POW, D_BATTERY, Settings->flag2.wattage_resolution, &power); + WSContentSend_PD(HTTP_SNS_WOOLIIS_IMP, D_BATTERY, Settings->flag2.energy_resolution, &Wooliis->energy_in); + WSContentSend_PD(HTTP_SNS_WOOLIIS_EXP, D_BATTERY, Settings->flag2.energy_resolution, &Wooliis->energy_out); + } +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns115(uint32_t function) +{ + bool result = false; + + if (FUNC_INIT == function) { + WooliisInit(); + } + else if (Wooliis) { + switch (function) { + case FUNC_EVERY_SECOND: + WooliisSecond(); + break; + case FUNC_JSON_APPEND: + WooliisShow(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + WooliisShow(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_WOOLIIS diff --git a/tools/decode-status.py b/tools/decode-status.py index 7147268e6..0f55bfbe3 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -305,7 +305,7 @@ a_features = [[ "USE_HC8","USE_HDMI_CEC","USE_BLE_ESP32","USE_MATTER_DEVICE" ],[ "USE_MAGIC_SWITCH","USE_PIPSOLAR","USE_GPIO_VIEWER","USE_AMSX915", - "USE_SPI_LORA","USE_SPL06_007","USE_QMP6988","", + "USE_SPI_LORA","USE_SPL06_007","USE_QMP6988","USE_WOOLIIS", "","","","", "","","","", "","","","", diff --git a/tools/lv_gpio/lv_gpio_enum.h b/tools/lv_gpio/lv_gpio_enum.h index ba2c64497..ad7df0fb7 100644 --- a/tools/lv_gpio/lv_gpio_enum.h +++ b/tools/lv_gpio/lv_gpio_enum.h @@ -365,5 +365,6 @@ RN2XX3_TX = GPIO_RN2XX3_TX RN2XX3_RX = GPIO_RN2XX3_RX RN2XX3_RST = GPIO_RN2XX3_RST +WOOLIIS_RX = GPIO_WOOLIIS_RX SENSOR_END = GPIO_SENSOR_END