From 6e4517de02a7abd723ca619bea901f9d4dc24443 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Thu, 12 Sep 2024 19:38:04 +0200 Subject: [PATCH] Berry virtual Energy driver (#22134) --- CHANGELOG.md | 1 + lib/libesp32/berry_tasmota/src/be_energylib.c | 2 + tasmota/include/tasmota_template.h | 4 +- .../xdrv_52_3_berry_energy.ino | 6 ++ .../xdrv_52_3_berry_tasmota_global.ino | 5 +- tasmota/tasmota_xnrg_energy/xnrg_28_berry.ino | 80 +++++++++++++++++++ 6 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 tasmota/tasmota_xnrg_energy/xnrg_28_berry.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e2ac2f6b..bc96335c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - Matter support for Zigbee Occupancy and Light 0/1/2 (OnOff / Dimmer / White Color Temperature) (#22110) - KNX additional KnxTx functions and define KNX_USE_DPT9 (#22071) - Support for I2C M5Unit (Mini)Scales using HX711 driver +- Berry virtual Energy driver ### Breaking Changed diff --git a/lib/libesp32/berry_tasmota/src/be_energylib.c b/lib/libesp32/berry_tasmota/src/be_energylib.c index 854f41d60..3785e2980 100644 --- a/lib/libesp32/berry_tasmota/src/be_energylib.c +++ b/lib/libesp32/berry_tasmota/src/be_energylib.c @@ -14,6 +14,7 @@ extern struct ENERGY Energy; extern int module_energy_update_total(bvm *vm); +extern int module_energy_driver_enabled(bvm *vm); #include "solidify/solidified_energy.h" #include "be_fixed_energy.h" @@ -37,6 +38,7 @@ module energy (scope: global) { tomap, closure(module_energy_tomap_closure) update_total, func(module_energy_update_total) + driver_enabled, func(module_energy_driver_enabled) // is the Berry virtual driver active? } @const_object_info_end */ diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 7005d81bf..3846ecc76 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -233,7 +233,7 @@ enum ProgramSelectablePins { GPIO_USER, // User configurable needs to be 2047 GPIO_MAX }; -#define MAX_OPTIONS_A 8 // Increase if more bits are used from GpioOptionABits +#define MAX_OPTIONS_A 9 // Increase if more bits are used from GpioOptionABits typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... uint32_t data; // Allow bit manipulation using SetOption @@ -246,7 +246,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t linkind_support : 1; // bit 5 (v10.1.0.4) - Option_A6 - (Light) LinkInd support uint32_t shelly_pro : 1; // bit 6 (v12.2.0.1) - Option_A7 - (Device) Shelly Pro uint32_t ifan04_h : 1; // bit 7 (v14.1.0.4) - Option_A8 - (Device) Sonoff ifan04-H - uint32_t spare08 : 1; // bit 8 + uint32_t berry_energy : 1; // bit 8 (v14.2.0.4) - Option_A9 - (Energy) Enable Berry energy driver uint32_t spare09 : 1; // bit 9 uint32_t spare10 : 1; // bit 10 uint32_t spare11 : 1; // bit 11 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_energy.ino index 510fc6dd8..7ef71c4cf 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_energy.ino @@ -37,6 +37,12 @@ extern "C" { EnergyUpdateTotal(); be_return_nil(vm); } + + extern int module_energy_driver_enabled(bvm *vm); + int module_energy_driver_enabled(bvm *vm) { + be_pushbool(vm, 28 == TasmotaGlobal.energy_driver); + be_return(vm); + } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Winvalid-offsetof" // avoid warnings since we're using offsetof() in a risky way diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino index 9a6410ea7..3b5a0f95e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino @@ -33,11 +33,12 @@ extern "C" { extern const be_ctypes_structure_t be_tasmota_global_struct = { sizeof(TasmotaGlobal), /* size in bytes */ - 9, /* number of elements */ + 10, /* number of elements */ nullptr, - (const be_ctypes_structure_item_t[9]) { + (const be_ctypes_structure_item_t[10]) { // Warning: fields below need to be in alphabetical order { "devices_present", offsetof(TasmotaGlobal_t, devices_present), 0, 0, ctypes_u8, 0 }, + { "energy_driver", offsetof(TasmotaGlobal_t, energy_driver), 0, 0, ctypes_u8, 0 }, { "fast_loop_enabled", offsetof(TasmotaGlobal_t, berry_fast_loop_enabled), 0, 0, ctypes_u8, 0 }, { "masterlog_level", offsetof(TasmotaGlobal_t, masterlog_level), 0, 0, ctypes_u8, 0 }, { "maxlog_level", offsetof(TasmotaGlobal_t, maxlog_level), 0, 0, ctypes_u8, 0 }, diff --git a/tasmota/tasmota_xnrg_energy/xnrg_28_berry.ino b/tasmota/tasmota_xnrg_energy/xnrg_28_berry.ino new file mode 100644 index 000000000..e4155df2f --- /dev/null +++ b/tasmota/tasmota_xnrg_energy/xnrg_28_berry.ino @@ -0,0 +1,80 @@ +/* + xnrg_28_berry.ino - Berry empty energy sensor which implementation is delegated to Berry + + Copyright (C) 2021 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef ESP32 +#ifdef USE_ENERGY_SENSOR +#ifdef USE_BERRY + +/*********************************************************************************************\ + * Provides the stub for a pure Berry energy monitoring driver + * + * Enable by selecting any GPIO as Option A9 +\*********************************************************************************************/ + +#define XNRG_28 28 + +#define NRG_BERRY_U_COMMON true // Phase voltage = false, Common voltage = true +#define NRG_BERRY_F_COMMON true // Phase frequency = false, Common frequency = true +#define NRG_BERRY_DC false // AC = false, DC = true; +#define NRG_BERRY_OVERTEMP true // Use global temperature for overtemp detection + +/********************************************************************************************/ + +void NrgBerryEverySecond(void) { + if (TasmotaGlobal.gpio_optiona.berry_energy) { // active only if OPTION_A 9 + // the only required action every second is to compute the power delta for the last second from `active_power` + for (uint32_t channel = 0; channel < Energy->phase_count; channel++) { + Energy->kWhtoday_delta[channel] += Energy->active_power[channel] * 1000 / 36; + Energy->data_valid[channel] = 0; // mark data as valid to reset the energy watchdog + } + EnergyUpdateToday(); // centrak management of power counters + } +} + +void NrgBerryDrvInit(void) { + if (TasmotaGlobal.gpio_optiona.berry_energy) { // active only if OPTION_A 9 + // set some default parameters + Energy->voltage_common = NRG_BERRY_U_COMMON; // Phase voltage = false, Common voltage = true + Energy->frequency_common = NRG_BERRY_F_COMMON; // Phase frequency = false, Common frequency = true + Energy->type_dc = NRG_BERRY_DC; // AC = false, DC = true; + Energy->use_overtemp = NRG_BERRY_OVERTEMP; // Use global temperature for overtemp detection + + TasmotaGlobal.energy_driver = XNRG_28; // if OPTION_A 9 is set, mark this driver as the active driver, so it can be tested in Berry + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xnrg28(uint32_t function) { + switch (function) { + case FUNC_ENERGY_EVERY_SECOND: + NrgBerryEverySecond(); + break; + case FUNC_PRE_INIT: + NrgBerryDrvInit(); + break; + } + return false; +} + +#endif // USE_BERRY +#endif // USE_ENERGY_SENSOR +#endif // ESP32