mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-25 19:56:30 +00:00
Add split total energy
This commit is contained in:
parent
de75cd4c40
commit
c4bb190e82
@ -4,9 +4,17 @@ All notable changes to this project will be documented in this file.
|
|||||||
## [Unreleased] - Development
|
## [Unreleased] - Development
|
||||||
|
|
||||||
## [9.5.0.9]
|
## [9.5.0.9]
|
||||||
|
### Added
|
||||||
|
- Command ``SetOption129 1`` to enable split total energy results (#13030)
|
||||||
|
- Commands ``EnergyTotal<phase>``, ``EnergyToday<phase>`` and ``EnergyYesterday<phase>`` to (re)set energy values
|
||||||
|
- Commands ``EnergyUsage`` and ``EnergyExport`` to (re)set energy usage and export values
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
- ESP32 LVGL updated to v8.0.2
|
- ESP32 LVGL updated to v8.0.2
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Removed command ``EnergyReset`` as it is replaced by new commands
|
||||||
|
|
||||||
## [9.5.0.8] 20210927
|
## [9.5.0.8] 20210927
|
||||||
### Added
|
### Added
|
||||||
- Command ``WebGetConfig <url>`` if ``#define USE_WEBGETCONFIG`` is enabled to restore/init configuration from external webserver (#13034)
|
- Command ``WebGetConfig <url>`` if ``#define USE_WEBGETCONFIG`` is enabled to restore/init configuration from external webserver (#13034)
|
||||||
|
@ -110,6 +110,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
|||||||
- Command ``WebGetConfig <url>`` if ``#define USE_WEBGETCONFIG`` is enabled to restore/init configuration from external webserver [#13034](https://github.com/arendst/Tasmota/issues/13034)
|
- Command ``WebGetConfig <url>`` if ``#define USE_WEBGETCONFIG`` is enabled to restore/init configuration from external webserver [#13034](https://github.com/arendst/Tasmota/issues/13034)
|
||||||
- Command ``WebQuery <url> GET|POST|PUT|PATCH [<headers>] <body>`` to extent HTTP requests [#13209](https://github.com/arendst/Tasmota/issues/13209)
|
- Command ``WebQuery <url> GET|POST|PUT|PATCH [<headers>] <body>`` to extent HTTP requests [#13209](https://github.com/arendst/Tasmota/issues/13209)
|
||||||
- Commands ``EnergyTotal<phase>``, ``EnergyToday<phase>`` and ``EnergyYesterday<phase>`` to (re)set energy values
|
- Commands ``EnergyTotal<phase>``, ``EnergyToday<phase>`` and ``EnergyYesterday<phase>`` to (re)set energy values
|
||||||
|
- Commands ``EnergyUsage`` and ``EnergyExport`` to (re)set energy usage and export values
|
||||||
- Optional IP filter to command ``TCPStart`` [#12806](https://github.com/arendst/Tasmota/issues/12806)
|
- Optional IP filter to command ``TCPStart`` [#12806](https://github.com/arendst/Tasmota/issues/12806)
|
||||||
- Neopool commands ``NPPHRes``, ``NPCLRes`` and ``NPIonRes`` [#12813](https://github.com/arendst/Tasmota/issues/12813)
|
- Neopool commands ``NPPHRes``, ``NPCLRes`` and ``NPIonRes`` [#12813](https://github.com/arendst/Tasmota/issues/12813)
|
||||||
- Support for second DNS server
|
- Support for second DNS server
|
||||||
@ -145,6 +146,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Move firmware binaries to https://github.com/arendst/Tasmota-firmware/tree/main/release-firmware
|
- Move firmware binaries to https://github.com/arendst/Tasmota-firmware/tree/main/release-firmware
|
||||||
|
- Removed command ``EnergyReset`` as it is replaced by new commands
|
||||||
- IRremoteESP8266 library from v2.7.18 to v2.7.20
|
- IRremoteESP8266 library from v2.7.18 to v2.7.20
|
||||||
- NeoPixelBus library from v2.6.3 to v2.6.7
|
- NeoPixelBus library from v2.6.3 to v2.6.7
|
||||||
- Message ``Upload buffer miscompare`` into ``Not enough space``
|
- Message ``Upload buffer miscompare`` into ``Not enough space``
|
||||||
|
@ -432,10 +432,11 @@
|
|||||||
#define D_CMND_VOLTAGEHIGH "VoltageHigh"
|
#define D_CMND_VOLTAGEHIGH "VoltageHigh"
|
||||||
#define D_CMND_CURRENTLOW "CurrentLow"
|
#define D_CMND_CURRENTLOW "CurrentLow"
|
||||||
#define D_CMND_CURRENTHIGH "CurrentHigh"
|
#define D_CMND_CURRENTHIGH "CurrentHigh"
|
||||||
#define D_CMND_ENERGYRESET "EnergyReset"
|
|
||||||
#define D_CMND_ENERGYTODAY "EnergyToday"
|
#define D_CMND_ENERGYTODAY "EnergyToday"
|
||||||
#define D_CMND_ENERGYYESTERDAY "EnergyYesterday"
|
#define D_CMND_ENERGYYESTERDAY "EnergyYesterday"
|
||||||
#define D_CMND_ENERGYTOTAL "EnergyTotal"
|
#define D_CMND_ENERGYTOTAL "EnergyTotal"
|
||||||
|
#define D_CMND_ENERGYUSAGE "EnergyUsage"
|
||||||
|
#define D_CMND_ENERGYEXPORT "EnergyExport"
|
||||||
#define D_CMND_POWERSET "PowerSet"
|
#define D_CMND_POWERSET "PowerSet"
|
||||||
#define D_CMND_VOLTAGESET "VoltageSet"
|
#define D_CMND_VOLTAGESET "VoltageSet"
|
||||||
#define D_CMND_CURRENTSET "CurrentSet"
|
#define D_CMND_CURRENTSET "CurrentSet"
|
||||||
|
@ -56,7 +56,7 @@ const char kEnergyCommands[] PROGMEM = "|" // No prefix
|
|||||||
D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW "|"
|
D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW "|"
|
||||||
#endif // USE_ENERGY_POWER_LIMIT
|
#endif // USE_ENERGY_POWER_LIMIT
|
||||||
#endif // USE_ENERGY_MARGIN_DETECTION
|
#endif // USE_ENERGY_MARGIN_DETECTION
|
||||||
D_CMND_ENERGYRESET "|" D_CMND_ENERGYTODAY "|" D_CMND_ENERGYYESTERDAY "|" D_CMND_ENERGYTOTAL "|" D_CMND_TARIFF;
|
D_CMND_ENERGYTODAY "|" D_CMND_ENERGYYESTERDAY "|" D_CMND_ENERGYTOTAL "|" D_CMND_ENERGYUSAGE "|" D_CMND_ENERGYEXPORT "|" D_CMND_TARIFF;
|
||||||
|
|
||||||
void (* const EnergyCommand[])(void) PROGMEM = {
|
void (* const EnergyCommand[])(void) PROGMEM = {
|
||||||
&CmndPowerCal, &CmndVoltageCal, &CmndCurrentCal, &CmndFrequencyCal,
|
&CmndPowerCal, &CmndVoltageCal, &CmndCurrentCal, &CmndFrequencyCal,
|
||||||
@ -69,7 +69,7 @@ void (* const EnergyCommand[])(void) PROGMEM = {
|
|||||||
&CmndSafePower, &CmndSafePowerHold, &CmndSafePowerWindow,
|
&CmndSafePower, &CmndSafePowerHold, &CmndSafePowerWindow,
|
||||||
#endif // USE_ENERGY_POWER_LIMIT
|
#endif // USE_ENERGY_POWER_LIMIT
|
||||||
#endif // USE_ENERGY_MARGIN_DETECTION
|
#endif // USE_ENERGY_MARGIN_DETECTION
|
||||||
&CmndEnergyReset, &CmndEnergyToday, &CmndEnergyYesterday, &CmndEnergyTotal, &CmndTariff};
|
&CmndEnergyToday, &CmndEnergyYesterday, &CmndEnergyTotal, &CmndEnergyUsage, &CmndEnergyExport, &CmndTariff};
|
||||||
|
|
||||||
const char kEnergyPhases[] PROGMEM = "|%*_f / %*_f|%*_f / %*_f / %*_f||[%*_f,%*_f]|[%*_f,%*_f,%*_f]";
|
const char kEnergyPhases[] PROGMEM = "|%*_f / %*_f|%*_f / %*_f / %*_f||[%*_f,%*_f]|[%*_f,%*_f,%*_f]";
|
||||||
|
|
||||||
@ -81,9 +81,7 @@ struct ENERGY {
|
|||||||
float reactive_power[ENERGY_MAX_PHASES]; // 123.1 VAr
|
float reactive_power[ENERGY_MAX_PHASES]; // 123.1 VAr
|
||||||
float power_factor[ENERGY_MAX_PHASES]; // 0.12
|
float power_factor[ENERGY_MAX_PHASES]; // 0.12
|
||||||
float frequency[ENERGY_MAX_PHASES]; // 123.1 Hz
|
float frequency[ENERGY_MAX_PHASES]; // 123.1 Hz
|
||||||
#if defined(SDM630_IMPORT) || defined(SDM72_IMPEXP)
|
|
||||||
float import_active[ENERGY_MAX_PHASES]; // 123.123 kWh
|
float import_active[ENERGY_MAX_PHASES]; // 123.123 kWh
|
||||||
#endif // SDM630_IMPORT || SDM72_IMPEXP
|
|
||||||
float export_active[ENERGY_MAX_PHASES]; // 123.123 kWh
|
float export_active[ENERGY_MAX_PHASES]; // 123.123 kWh
|
||||||
float start_energy[ENERGY_MAX_PHASES]; // 12345.12345 kWh total previous
|
float start_energy[ENERGY_MAX_PHASES]; // 12345.12345 kWh total previous
|
||||||
float daily[ENERGY_MAX_PHASES]; // 123.123 kWh
|
float daily[ENERGY_MAX_PHASES]; // 123.123 kWh
|
||||||
@ -200,6 +198,7 @@ void EnergyUpdateToday(void) {
|
|||||||
Energy.total_sum = 0.0;
|
Energy.total_sum = 0.0;
|
||||||
Energy.yesterday_sum = 0.0;
|
Energy.yesterday_sum = 0.0;
|
||||||
Energy.daily_sum = 0.0;
|
Energy.daily_sum = 0.0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < Energy.phase_count; i++) {
|
for (uint32_t i = 0; i < Energy.phase_count; i++) {
|
||||||
if (Energy.kWhtoday_delta[i] > 1000) {
|
if (Energy.kWhtoday_delta[i] > 1000) {
|
||||||
uint32_t delta = Energy.kWhtoday_delta[i] / 1000;
|
uint32_t delta = Energy.kWhtoday_delta[i] / 1000;
|
||||||
@ -246,28 +245,29 @@ void EnergyUpdateToday(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnergyUpdateTotal(float value, bool kwh, uint32_t phase = 0);
|
void EnergyUpdateTotal(void) {
|
||||||
void EnergyUpdateTotal(float value, bool kwh, uint32_t phase)
|
// Provide total import active energy as float Energy.import_active[phase] in kWh: 98Wh = 0.098kWh
|
||||||
{
|
|
||||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total %4_f %sWh"), &value, (kwh) ? "k" : "");
|
|
||||||
|
|
||||||
uint32_t multiplier = (kwh) ? 100000 : 100; // kWh or Wh to deca milli Wh
|
for (uint32_t i = 0; i < Energy.phase_count; i++) {
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: EnergyTotal[%d] %4_f kWh"), i, &Energy.import_active[i]);
|
||||||
|
|
||||||
if (0 == Energy.start_energy[phase] || (value < Energy.start_energy[phase])) {
|
if (0 == Energy.start_energy[i] || (Energy.import_active[i] < Energy.start_energy[i])) {
|
||||||
Energy.start_energy[phase] = value; // Init after restart and handle roll-over if any
|
Energy.start_energy[i] = Energy.import_active[i]; // Init after restart and handle roll-over if any
|
||||||
}
|
}
|
||||||
else if (value != Energy.start_energy[phase]) {
|
else if (Energy.import_active[i] != Energy.start_energy[i]) {
|
||||||
Energy.kWhtoday[phase] = (unsigned long)((value - Energy.start_energy[phase]) * multiplier);
|
Energy.kWhtoday[i] = (uint32_t)((Energy.import_active[i] - Energy.start_energy[i]) * 100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Energy.total[i] < (Energy.import_active[i] - 0.01)) && // We subtract a little offset to avoid continuous updates
|
||||||
|
Settings->flag3.hardware_energy_total) { // SetOption72 - Enable hardware energy total counter as reference (#6561)
|
||||||
|
RtcSettings.energy_kWhtotal_ph[i] = (unsigned long)((Energy.import_active[i] * 100000) - Energy.kWhtoday_offset[i] - Energy.kWhtoday[i]);
|
||||||
|
Settings->energy_kWhtotal_ph[i] = RtcSettings.energy_kWhtotal_ph[i];
|
||||||
|
Energy.total[i] = (float)(RtcSettings.energy_kWhtotal_ph[i] + Energy.kWhtoday_offset[i] + Energy.kWhtoday[i]) / 100000;
|
||||||
|
Settings->energy_kWhtotal_time = (!Energy.kWhtoday_offset[i]) ? LocalTime() : Midnight();
|
||||||
|
// AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total updated with hardware value"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Energy.total[phase] < (value - 0.01)) && // We subtract a little offset to avoid continuous updates
|
|
||||||
Settings->flag3.hardware_energy_total) { // SetOption72 - Enable hardware energy total counter as reference (#6561)
|
|
||||||
RtcSettings.energy_kWhtotal_ph[phase] = (unsigned long)((value * multiplier) - Energy.kWhtoday_offset[phase] - Energy.kWhtoday[phase]);
|
|
||||||
Settings->energy_kWhtotal_ph[phase] = RtcSettings.energy_kWhtotal_ph[phase];
|
|
||||||
Energy.total[phase] = (float)(RtcSettings.energy_kWhtotal_ph[phase] + Energy.kWhtoday_offset[phase] + Energy.kWhtoday[phase]) / 100000;
|
|
||||||
Settings->energy_kWhtotal_time = (!Energy.kWhtoday_offset[phase]) ? LocalTime() : Midnight();
|
|
||||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Energy Total updated with hardware value"));
|
|
||||||
}
|
|
||||||
EnergyUpdateToday();
|
EnergyUpdateToday();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,50 +589,7 @@ void EnergyCommandCalResponse(uint32_t nvalue) {
|
|||||||
ResponseCmndNumber(nvalue);
|
ResponseCmndNumber(nvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndEnergyReset(void) {
|
void ResponseCmndEnergyTotalYesterdayToday(void) {
|
||||||
uint32_t values[2] = { 0 };
|
|
||||||
uint32_t params = ParseParameters(2, values);
|
|
||||||
values[0] *= 100;
|
|
||||||
|
|
||||||
if ((XdrvMailbox.index > 3) && (XdrvMailbox.index <= 5)) {
|
|
||||||
if (params > 0) {
|
|
||||||
switch (XdrvMailbox.index) {
|
|
||||||
case 4:
|
|
||||||
// Reset energy_usage.usage totals
|
|
||||||
RtcSettings.energy_usage.usage1_kWhtotal = values[0];
|
|
||||||
if (params > 1) {
|
|
||||||
RtcSettings.energy_usage.usage2_kWhtotal = values[1] * 100;
|
|
||||||
}
|
|
||||||
Settings->energy_usage.usage1_kWhtotal = RtcSettings.energy_usage.usage1_kWhtotal;
|
|
||||||
Settings->energy_usage.usage2_kWhtotal = RtcSettings.energy_usage.usage2_kWhtotal;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// Reset energy_usage.return totals
|
|
||||||
RtcSettings.energy_usage.return1_kWhtotal = values[0];
|
|
||||||
if (params > 1) {
|
|
||||||
RtcSettings.energy_usage.return2_kWhtotal = values[1] * 100;
|
|
||||||
}
|
|
||||||
Settings->energy_usage.return1_kWhtotal = RtcSettings.energy_usage.return1_kWhtotal;
|
|
||||||
Settings->energy_usage.return2_kWhtotal = RtcSettings.energy_usage.return2_kWhtotal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float usage1_kWhtotal = (float)Settings->energy_usage.usage1_kWhtotal / 100000;
|
|
||||||
float usage2_kWhtotal = (float)Settings->energy_usage.usage2_kWhtotal / 100000;
|
|
||||||
float return1_kWhtotal = (float)Settings->energy_usage.return1_kWhtotal / 100000;
|
|
||||||
float return2_kWhtotal = (float)Settings->energy_usage.return2_kWhtotal / 100000;
|
|
||||||
|
|
||||||
Response_P(PSTR("{\"%s\":{\"" D_JSON_USAGE "\":[%*_f,%*_f],\"" D_JSON_EXPORT "\":[%*_f,%*_f]}}"),
|
|
||||||
XdrvMailbox.command,
|
|
||||||
Settings->flag2.energy_resolution, &usage1_kWhtotal,
|
|
||||||
Settings->flag2.energy_resolution, &usage2_kWhtotal,
|
|
||||||
Settings->flag2.energy_resolution, &return1_kWhtotal,
|
|
||||||
Settings->flag2.energy_resolution, &return2_kWhtotal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CmndEnergyResponse(void) {
|
|
||||||
char value_chr[FLOATSZ * ENERGY_MAX_PHASES]; // Used by EnergyFormatIndex
|
char value_chr[FLOATSZ * ENERGY_MAX_PHASES]; // Used by EnergyFormatIndex
|
||||||
char value2_chr[FLOATSZ * ENERGY_MAX_PHASES];
|
char value2_chr[FLOATSZ * ENERGY_MAX_PHASES];
|
||||||
char value3_chr[FLOATSZ * ENERGY_MAX_PHASES];
|
char value3_chr[FLOATSZ * ENERGY_MAX_PHASES];
|
||||||
@ -653,12 +610,11 @@ void CmndEnergyResponse(void) {
|
|||||||
void CmndEnergyTotal(void) {
|
void CmndEnergyTotal(void) {
|
||||||
uint32_t values[2] = { 0 };
|
uint32_t values[2] = { 0 };
|
||||||
uint32_t params = ParseParameters(2, values);
|
uint32_t params = ParseParameters(2, values);
|
||||||
values[0] *= 100;
|
|
||||||
|
|
||||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Energy.phase_count) && (params > 0)) {
|
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Energy.phase_count) && (params > 0)) {
|
||||||
uint32_t phase = XdrvMailbox.index -1;
|
uint32_t phase = XdrvMailbox.index -1;
|
||||||
// Reset Energy Total
|
// Reset Energy Total
|
||||||
RtcSettings.energy_kWhtotal_ph[phase] = values[0];
|
RtcSettings.energy_kWhtotal_ph[phase] = values[0] * 100;
|
||||||
Settings->energy_kWhtotal_ph[phase] = RtcSettings.energy_kWhtotal_ph[phase];
|
Settings->energy_kWhtotal_ph[phase] = RtcSettings.energy_kWhtotal_ph[phase];
|
||||||
if (params > 1) {
|
if (params > 1) {
|
||||||
Settings->energy_kWhtotal_time = values[1];
|
Settings->energy_kWhtotal_time = values[1];
|
||||||
@ -667,33 +623,31 @@ void CmndEnergyTotal(void) {
|
|||||||
}
|
}
|
||||||
RtcSettings.energy_usage.last_usage_kWhtotal = (uint32_t)(Energy.total[phase] * 1000);
|
RtcSettings.energy_usage.last_usage_kWhtotal = (uint32_t)(Energy.total[phase] * 1000);
|
||||||
}
|
}
|
||||||
CmndEnergyResponse();
|
ResponseCmndEnergyTotalYesterdayToday();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndEnergyYesterday(void) {
|
void CmndEnergyYesterday(void) {
|
||||||
uint32_t values[2] = { 0 };
|
uint32_t values[2] = { 0 };
|
||||||
uint32_t params = ParseParameters(2, values);
|
uint32_t params = ParseParameters(2, values);
|
||||||
values[0] *= 100;
|
|
||||||
|
|
||||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Energy.phase_count) && (params > 0)) {
|
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Energy.phase_count) && (params > 0)) {
|
||||||
uint32_t phase = XdrvMailbox.index -1;
|
uint32_t phase = XdrvMailbox.index -1;
|
||||||
// Reset Energy Yesterday
|
// Reset Energy Yesterday
|
||||||
Settings->energy_kWhyesterday_ph[phase] = values[0];
|
Settings->energy_kWhyesterday_ph[phase] = values[0] * 100;
|
||||||
if (params > 1) {
|
if (params > 1) {
|
||||||
Settings->energy_kWhtotal_time = values[1];
|
Settings->energy_kWhtotal_time = values[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CmndEnergyResponse();
|
ResponseCmndEnergyTotalYesterdayToday();
|
||||||
}
|
}
|
||||||
void CmndEnergyToday(void) {
|
void CmndEnergyToday(void) {
|
||||||
uint32_t values[2] = { 0 };
|
uint32_t values[2] = { 0 };
|
||||||
uint32_t params = ParseParameters(2, values);
|
uint32_t params = ParseParameters(2, values);
|
||||||
values[0] *= 100;
|
|
||||||
|
|
||||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Energy.phase_count) && (params > 0)) {
|
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Energy.phase_count) && (params > 0)) {
|
||||||
uint32_t phase = XdrvMailbox.index -1;
|
uint32_t phase = XdrvMailbox.index -1;
|
||||||
// Reset Energy Today
|
// Reset Energy Today
|
||||||
Energy.kWhtoday_offset[phase] = values[0];
|
Energy.kWhtoday_offset[phase] = values[0] * 100;
|
||||||
Energy.kWhtoday[phase] = 0;
|
Energy.kWhtoday[phase] = 0;
|
||||||
Energy.kWhtoday_delta[phase] = 0;
|
Energy.kWhtoday_delta[phase] = 0;
|
||||||
Energy.start_energy[phase] = 0;
|
Energy.start_energy[phase] = 0;
|
||||||
@ -704,13 +658,55 @@ void CmndEnergyToday(void) {
|
|||||||
if (params > 1) {
|
if (params > 1) {
|
||||||
Settings->energy_kWhtotal_time = values[1];
|
Settings->energy_kWhtotal_time = values[1];
|
||||||
}
|
}
|
||||||
else {
|
else if (!RtcSettings.energy_kWhtotal_ph[phase] && !Energy.kWhtoday_offset[phase]) {
|
||||||
if (!RtcSettings.energy_kWhtotal_ph[phase] && !Energy.kWhtoday_offset[phase]) {
|
Settings->energy_kWhtotal_time = LocalTime();
|
||||||
Settings->energy_kWhtotal_time = LocalTime();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CmndEnergyResponse();
|
ResponseCmndEnergyTotalYesterdayToday();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResponseCmndEnergyUsageExport(void) {
|
||||||
|
float usage1_kWhtotal = (float)Settings->energy_usage.usage1_kWhtotal / 100000;
|
||||||
|
float usage2_kWhtotal = (float)Settings->energy_usage.usage2_kWhtotal / 100000;
|
||||||
|
float return1_kWhtotal = (float)Settings->energy_usage.return1_kWhtotal / 100000;
|
||||||
|
float return2_kWhtotal = (float)Settings->energy_usage.return2_kWhtotal / 100000;
|
||||||
|
|
||||||
|
Response_P(PSTR("{\"%s\":{\"" D_JSON_USAGE "\":[%*_f,%*_f],\"" D_JSON_EXPORT "\":[%*_f,%*_f]}}"),
|
||||||
|
XdrvMailbox.command,
|
||||||
|
Settings->flag2.energy_resolution, &usage1_kWhtotal,
|
||||||
|
Settings->flag2.energy_resolution, &usage2_kWhtotal,
|
||||||
|
Settings->flag2.energy_resolution, &return1_kWhtotal,
|
||||||
|
Settings->flag2.energy_resolution, &return2_kWhtotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmndEnergyUsage(void) {
|
||||||
|
uint32_t values[2] = { 0 };
|
||||||
|
uint32_t params = ParseParameters(2, values);
|
||||||
|
if (params > 0) {
|
||||||
|
// Reset energy_usage.usage totals
|
||||||
|
RtcSettings.energy_usage.usage1_kWhtotal = values[0] * 100;
|
||||||
|
if (params > 1) {
|
||||||
|
RtcSettings.energy_usage.usage2_kWhtotal = values[1] * 100;
|
||||||
|
}
|
||||||
|
Settings->energy_usage.usage1_kWhtotal = RtcSettings.energy_usage.usage1_kWhtotal;
|
||||||
|
Settings->energy_usage.usage2_kWhtotal = RtcSettings.energy_usage.usage2_kWhtotal;
|
||||||
|
}
|
||||||
|
ResponseCmndEnergyUsageExport();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmndEnergyExport(void) {
|
||||||
|
uint32_t values[2] = { 0 };
|
||||||
|
uint32_t params = ParseParameters(2, values);
|
||||||
|
if (params > 0) {
|
||||||
|
// Reset energy_usage.return totals
|
||||||
|
RtcSettings.energy_usage.return1_kWhtotal = values[0] * 100;
|
||||||
|
if (params > 1) {
|
||||||
|
RtcSettings.energy_usage.return2_kWhtotal = values[1] * 100;
|
||||||
|
}
|
||||||
|
Settings->energy_usage.return1_kWhtotal = RtcSettings.energy_usage.return1_kWhtotal;
|
||||||
|
Settings->energy_usage.return2_kWhtotal = RtcSettings.energy_usage.return2_kWhtotal;
|
||||||
|
}
|
||||||
|
ResponseCmndEnergyUsageExport();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndTariff(void) {
|
void CmndTariff(void) {
|
||||||
@ -960,9 +956,6 @@ void EnergyDrvInit(void) {
|
|||||||
Energy.reactive_power[phase] = NAN;
|
Energy.reactive_power[phase] = NAN;
|
||||||
Energy.power_factor[phase] = NAN;
|
Energy.power_factor[phase] = NAN;
|
||||||
Energy.frequency[phase] = NAN;
|
Energy.frequency[phase] = NAN;
|
||||||
#if defined(SDM630_IMPORT) || defined(SDM72_IMPEXP)
|
|
||||||
Energy.import_active[phase] = NAN;
|
|
||||||
#endif // SDM630_IMPORT || SDM72_IMPEXP
|
|
||||||
Energy.export_active[phase] = NAN;
|
Energy.export_active[phase] = NAN;
|
||||||
}
|
}
|
||||||
Energy.phase_count = 1; // Number of phases active
|
Energy.phase_count = 1; // Number of phases active
|
||||||
@ -1024,11 +1017,6 @@ const char HTTP_ENERGY_SNS2[] PROGMEM =
|
|||||||
|
|
||||||
const char HTTP_ENERGY_SNS3[] PROGMEM =
|
const char HTTP_ENERGY_SNS3[] PROGMEM =
|
||||||
"{s}" D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
"{s}" D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||||
|
|
||||||
#if defined(SDM630_IMPORT) || defined(SDM72_IMPEXP)
|
|
||||||
const char HTTP_ENERGY_SNS4[] PROGMEM =
|
|
||||||
"{s}" D_IMPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
|
||||||
#endif // SDM630_IMPORT || SDM72_IMPEXP
|
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
|
|
||||||
void EnergyShow(bool json) {
|
void EnergyShow(bool json) {
|
||||||
@ -1119,6 +1107,7 @@ void EnergyShow(bool json) {
|
|||||||
EnergyFormatSum(value_chr, energy_yesterday_ph, Settings->flag2.energy_resolution, json),
|
EnergyFormatSum(value_chr, energy_yesterday_ph, Settings->flag2.energy_resolution, json),
|
||||||
EnergyFormatSum(value2_chr, Energy.daily, Settings->flag2.energy_resolution, json));
|
EnergyFormatSum(value2_chr, Energy.daily, Settings->flag2.energy_resolution, json));
|
||||||
|
|
||||||
|
/*
|
||||||
#if defined(SDM630_IMPORT) || defined(SDM72_IMPEXP)
|
#if defined(SDM630_IMPORT) || defined(SDM72_IMPEXP)
|
||||||
if (!isnan(Energy.import_active[0])) {
|
if (!isnan(Energy.import_active[0])) {
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_ACTIVE "\":%s"),
|
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_ACTIVE "\":%s"),
|
||||||
@ -1129,6 +1118,7 @@ void EnergyShow(bool json) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // SDM630_IMPORT || SDM72_IMPEXP
|
#endif // SDM630_IMPORT || SDM72_IMPEXP
|
||||||
|
*/
|
||||||
|
|
||||||
if (!isnan(Energy.export_active[0])) {
|
if (!isnan(Energy.export_active[0])) {
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"),
|
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"),
|
||||||
@ -1243,12 +1233,6 @@ void EnergyShow(bool json) {
|
|||||||
if (!isnan(Energy.export_active[0])) {
|
if (!isnan(Energy.export_active[0])) {
|
||||||
WSContentSend_PD(HTTP_ENERGY_SNS3, EnergyFormat(value_chr, Energy.export_active, Settings->flag2.energy_resolution, json));
|
WSContentSend_PD(HTTP_ENERGY_SNS3, EnergyFormat(value_chr, Energy.export_active, Settings->flag2.energy_resolution, json));
|
||||||
}
|
}
|
||||||
#if defined(SDM630_IMPORT) || defined(SDM72_IMPEXP)
|
|
||||||
if (!isnan(Energy.import_active[0])) {
|
|
||||||
WSContentSend_PD(HTTP_ENERGY_SNS4, EnergyFormat(value_chr, Energy.import_active, Settings->flag2.energy_resolution, json));
|
|
||||||
}
|
|
||||||
#endif // SDM630_IMPORT || SDM72_IMPEXP
|
|
||||||
|
|
||||||
XnrgCall(FUNC_WEB_SENSOR);
|
XnrgCall(FUNC_WEB_SENSOR);
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
}
|
}
|
||||||
|
@ -891,8 +891,9 @@ void TuyaProcessStatePacket(void) {
|
|||||||
Tuya.lastPowerCheckTime = Rtc.utc_time;
|
Tuya.lastPowerCheckTime = Rtc.utc_time;
|
||||||
}
|
}
|
||||||
} else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER_TOTAL) {
|
} else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER_TOTAL) {
|
||||||
EnergyUpdateTotal((float)packetValue / 100,true);
|
Energy.import_active[0] = (float)packetValue / 100;
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Total_Power=%d"), Tuya.buffer[dpidStart], packetValue);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Total_Power=%d"), Tuya.buffer[dpidStart], packetValue);
|
||||||
|
EnergyUpdateTotal();
|
||||||
}
|
}
|
||||||
#endif // USE_ENERGY_SENSOR
|
#endif // USE_ENERGY_SENSOR
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,8 @@ TasmotaSerial *PzemSerial = nullptr;
|
|||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
struct PZEM {
|
struct PZEM {
|
||||||
float energy = 0;
|
// float energy = 0;
|
||||||
float last_energy = 0;
|
// float last_energy = 0;
|
||||||
uint8_t send_retry = 0;
|
uint8_t send_retry = 0;
|
||||||
uint8_t read_state = 0; // Set address
|
uint8_t read_state = 0; // Set address
|
||||||
uint8_t phase = 0;
|
uint8_t phase = 0;
|
||||||
@ -192,20 +192,11 @@ void PzemEvery250ms(void)
|
|||||||
Energy.active_power[Pzem.phase] = value;
|
Energy.active_power[Pzem.phase] = value;
|
||||||
break;
|
break;
|
||||||
case 4: // Total energy as 99999Wh
|
case 4: // Total energy as 99999Wh
|
||||||
/*
|
Energy.import_active[Pzem.phase] = value / 1000.0; // 99.999kWh
|
||||||
Pzem.energy += value;
|
|
||||||
if (Pzem.phase == Energy.phase_count -1) {
|
if (Pzem.phase == Energy.phase_count -1) {
|
||||||
if (Pzem.energy > Pzem.last_energy) { // Handle missed phase
|
if (TasmotaGlobal.uptime > PZEM_STABILIZE) {
|
||||||
if (TasmotaGlobal.uptime > PZEM_STABILIZE) {
|
EnergyUpdateTotal();
|
||||||
EnergyUpdateTotal(Pzem.energy, false);
|
|
||||||
}
|
|
||||||
Pzem.last_energy = Pzem.energy;
|
|
||||||
}
|
}
|
||||||
Pzem.energy = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (TasmotaGlobal.uptime > PZEM_STABILIZE) {
|
|
||||||
EnergyUpdateTotal(value, false, Pzem.phase);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -77,22 +77,11 @@ void PzemAcEverySecond(void)
|
|||||||
Energy.active_power[PzemAc.phase] = (float)((buffer[11] << 24) + (buffer[12] << 16) + (buffer[9] << 8) + buffer[10]) / 10.0; // 429496729.0 W
|
Energy.active_power[PzemAc.phase] = (float)((buffer[11] << 24) + (buffer[12] << 16) + (buffer[9] << 8) + buffer[10]) / 10.0; // 429496729.0 W
|
||||||
Energy.frequency[PzemAc.phase] = (float)((buffer[17] << 8) + buffer[18]) / 10.0; // 50.0 Hz
|
Energy.frequency[PzemAc.phase] = (float)((buffer[17] << 8) + buffer[18]) / 10.0; // 50.0 Hz
|
||||||
Energy.power_factor[PzemAc.phase] = (float)((buffer[19] << 8) + buffer[20]) / 100.0; // 1.00
|
Energy.power_factor[PzemAc.phase] = (float)((buffer[19] << 8) + buffer[20]) / 100.0; // 1.00
|
||||||
|
Energy.import_active[PzemAc.phase] = (float)((buffer[15] << 24) + (buffer[16] << 16) + (buffer[13] << 8) + buffer[14]) / 1000.0; // 4294967.295 kWh
|
||||||
/*
|
|
||||||
PzemAc.energy += (float)((buffer[15] << 24) + (buffer[16] << 16) + (buffer[13] << 8) + buffer[14]); // 4294967295 Wh
|
|
||||||
if (PzemAc.phase == Energy.phase_count -1) {
|
if (PzemAc.phase == Energy.phase_count -1) {
|
||||||
if (PzemAc.energy > PzemAc.last_energy) { // Handle missed phase
|
if (TasmotaGlobal.uptime > PZEM_AC_STABILIZE) {
|
||||||
if (TasmotaGlobal.uptime > PZEM_AC_STABILIZE) {
|
EnergyUpdateTotal();
|
||||||
EnergyUpdateTotal(PzemAc.energy, false);
|
|
||||||
}
|
|
||||||
PzemAc.last_energy = PzemAc.energy;
|
|
||||||
}
|
}
|
||||||
PzemAc.energy = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
float energy = (float)((buffer[15] << 24) + (buffer[16] << 16) + (buffer[13] << 8) + buffer[14]); // 4294967295 Wh
|
|
||||||
if (TasmotaGlobal.uptime > PZEM_AC_STABILIZE) {
|
|
||||||
EnergyUpdateTotal(energy, false, PzemAc.phase);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,21 +74,11 @@ void PzemDcEverySecond(void)
|
|||||||
Energy.voltage[PzemDc.channel] = (float)((buffer[3] << 8) + buffer[4]) / 100.0; // 655.00 V
|
Energy.voltage[PzemDc.channel] = (float)((buffer[3] << 8) + buffer[4]) / 100.0; // 655.00 V
|
||||||
Energy.current[PzemDc.channel] = (float)((buffer[5] << 8) + buffer[6]) / 100.0; // 655.00 A
|
Energy.current[PzemDc.channel] = (float)((buffer[5] << 8) + buffer[6]) / 100.0; // 655.00 A
|
||||||
Energy.active_power[PzemDc.channel] = (float)((buffer[9] << 24) + (buffer[10] << 16) + (buffer[7] << 8) + buffer[8]) / 10.0; // 429496729.0 W
|
Energy.active_power[PzemDc.channel] = (float)((buffer[9] << 24) + (buffer[10] << 16) + (buffer[7] << 8) + buffer[8]) / 10.0; // 429496729.0 W
|
||||||
/*
|
Energy.import_active[PzemDc.channel] = (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]) / 1000.0; // 4294967.295 kWh
|
||||||
PzemDc.energy += (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]); // 4294967295 Wh
|
|
||||||
if (PzemDc.channel == Energy.phase_count -1) {
|
if (PzemDc.channel == Energy.phase_count -1) {
|
||||||
if (PzemDc.energy > PzemDc.last_energy) { // Handle missed channel
|
if (TasmotaGlobal.uptime > PZEM_DC_STABILIZE) {
|
||||||
if (TasmotaGlobal.uptime > PZEM_DC_STABILIZE) {
|
EnergyUpdateTotal();
|
||||||
EnergyUpdateTotal(PzemDc.energy, false);
|
|
||||||
}
|
|
||||||
PzemDc.last_energy = PzemDc.energy;
|
|
||||||
}
|
}
|
||||||
PzemDc.energy = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
float energy = (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]); // 4294967295 Wh
|
|
||||||
if (TasmotaGlobal.uptime > PZEM_DC_STABILIZE) {
|
|
||||||
EnergyUpdateTotal(energy, false, PzemDc.channel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,8 @@ void SDM120Every250ms(void)
|
|||||||
Sdm120.start_address_count = sdm120_table; // No extended registers available
|
Sdm120.start_address_count = sdm120_table; // No extended registers available
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EnergyUpdateTotal(Sdm120.total_active, true); // 484.708 kWh
|
Energy.import_active[0] = Sdm120.total_active; // 484.708 kWh
|
||||||
|
EnergyUpdateTotal(); // 484.708 kWh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end data ready
|
} // end data ready
|
||||||
|
@ -75,9 +75,8 @@ void Dds2382EverySecond(void)
|
|||||||
offset = 19;
|
offset = 19;
|
||||||
}
|
}
|
||||||
Energy.export_active[0] = (float)((buffer[offset] << 24) + (buffer[offset +1] << 16) + (buffer[offset +2] << 8) + buffer[offset +3]) / 100.0; // 429496.729 kW
|
Energy.export_active[0] = (float)((buffer[offset] << 24) + (buffer[offset +1] << 16) + (buffer[offset +2] << 8) + buffer[offset +3]) / 100.0; // 429496.729 kW
|
||||||
float import_active = (float)((buffer[offset +4] << 24) + (buffer[offset +5] << 16) + (buffer[offset +6] << 8) + buffer[offset +7]) / 100.0; // 429496.729 kW
|
Energy.import_active[0] = (float)((buffer[offset +4] << 24) + (buffer[offset +5] << 16) + (buffer[offset +6] << 8) + buffer[offset +7]) / 100.0; // 429496.729 kW
|
||||||
|
EnergyUpdateTotal(); // 484.708 kWh
|
||||||
EnergyUpdateTotal(import_active, true); // 484.708 kWh
|
|
||||||
}
|
}
|
||||||
} // end data ready
|
} // end data ready
|
||||||
|
|
||||||
|
@ -60,11 +60,11 @@ const uint16_t sdm630_start_addresses[] {
|
|||||||
0x0160, // + + + kWh Phase 1 export active energy
|
0x0160, // + + + kWh Phase 1 export active energy
|
||||||
0x0162, // + + + kWh Phase 2 export active energy
|
0x0162, // + + + kWh Phase 2 export active energy
|
||||||
0x0164, // + + + kWh Phase 3 export active energy
|
0x0164, // + + + kWh Phase 3 export active energy
|
||||||
#ifdef SDM630_IMPORT
|
//#ifdef SDM630_IMPORT
|
||||||
0x015A, // + + + kWh Phase 1 import active energy
|
0x015A, // + + + kWh Phase 1 import active energy
|
||||||
0x015C, // + + + kWh Phase 2 import active energy
|
0x015C, // + + + kWh Phase 2 import active energy
|
||||||
0x015E, // + + + kWh Phase 3 import active energy
|
0x015E, // + + + kWh Phase 3 import active energy
|
||||||
#endif // SDM630_IMPORT
|
//#endif // SDM630_IMPORT
|
||||||
0x0156 // + + + kWh Total active energy
|
0x0156 // + + + kWh Total active energy
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -179,7 +179,6 @@ void SDM630Every250ms(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 19:
|
case 19:
|
||||||
#ifdef SDM630_IMPORT
|
|
||||||
Energy.import_active[0] = value;
|
Energy.import_active[0] = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -192,8 +191,8 @@ void SDM630Every250ms(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 22:
|
case 22:
|
||||||
#endif // SDM630_IMPORT
|
// Energy.import_active[0] = value;
|
||||||
EnergyUpdateTotal(value, true);
|
EnergyUpdateTotal();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@ const uint16_t Ddsu666_start_addresses[] {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct DDSU666 {
|
struct DDSU666 {
|
||||||
float import_active = NAN;
|
|
||||||
uint8_t read_state = 0;
|
uint8_t read_state = 0;
|
||||||
uint8_t send_retry = 0;
|
uint8_t send_retry = 0;
|
||||||
} Ddsu666;
|
} Ddsu666;
|
||||||
@ -106,7 +105,7 @@ void DDSU666Every250ms(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
Ddsu666.import_active = value; // 478.492 kWh
|
Energy.import_active[0] = value; // 478.492 kWh
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
@ -118,7 +117,7 @@ void DDSU666Every250ms(void)
|
|||||||
|
|
||||||
if (Ddsu666.read_state == 8) {
|
if (Ddsu666.read_state == 8) {
|
||||||
Ddsu666.read_state = 0;
|
Ddsu666.read_state = 0;
|
||||||
EnergyUpdateTotal(Ddsu666.import_active, true); // 484.708 kWh
|
EnergyUpdateTotal(); // 484.708 kWh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end data ready
|
} // end data ready
|
||||||
|
@ -100,7 +100,6 @@ struct SOLAXX1 {
|
|||||||
float dc2_voltage = 0;
|
float dc2_voltage = 0;
|
||||||
float dc1_current = 0;
|
float dc1_current = 0;
|
||||||
float dc2_current = 0;
|
float dc2_current = 0;
|
||||||
uint32_t energy_total = 0;
|
|
||||||
uint32_t runtime_total = 0;
|
uint32_t runtime_total = 0;
|
||||||
float dc1_power = 0;
|
float dc1_power = 0;
|
||||||
float dc2_power = 0;
|
float dc2_power = 0;
|
||||||
@ -272,7 +271,7 @@ void solaxX1250MSecond(void) // Every 250 milliseconds
|
|||||||
Energy.frequency[0] = (float)((value[25] << 8) | value[26]) * 0.01f; // AC Frequency
|
Energy.frequency[0] = (float)((value[25] << 8) | value[26]) * 0.01f; // AC Frequency
|
||||||
Energy.active_power[0] = (float)((value[27] << 8) | value[28]); // AC Power
|
Energy.active_power[0] = (float)((value[27] << 8) | value[28]); // AC Power
|
||||||
//temporal = (float)((value[29] << 8) | value[30]) * 0.1f; // Not Used
|
//temporal = (float)((value[29] << 8) | value[30]) * 0.1f; // Not Used
|
||||||
solaxX1.energy_total = ((value[31] << 24) | (value[32] << 16) | (value[33] << 8) | value[34]); // Energy Total
|
Energy.import_active[0] = (float)((value[31] << 24) | (value[32] << 16) | (value[33] << 8) | value[34]) * 0.1f; // Energy Total
|
||||||
solaxX1.runtime_total = ((value[35] << 24) | (value[36] << 16) | (value[37] << 8) | value[38]); // Work Time Total
|
solaxX1.runtime_total = ((value[35] << 24) | (value[36] << 16) | (value[37] << 8) | value[38]); // Work Time Total
|
||||||
solaxX1.status = (uint8_t)((value[39] << 8) | value[40]); // Work mode
|
solaxX1.status = (uint8_t)((value[39] << 8) | value[40]); // Work mode
|
||||||
//temporal = (float)((value[41] << 8) | value[42]); // Grid voltage fault value 0.1V
|
//temporal = (float)((value[41] << 8) | value[42]); // Grid voltage fault value 0.1V
|
||||||
@ -287,7 +286,7 @@ void solaxX1250MSecond(void) // Every 250 milliseconds
|
|||||||
solaxX1.dc1_power = solaxX1.dc1_voltage * solaxX1.dc1_current;
|
solaxX1.dc1_power = solaxX1.dc1_voltage * solaxX1.dc1_current;
|
||||||
solaxX1.dc2_power = solaxX1.dc2_voltage * solaxX1.dc2_current;
|
solaxX1.dc2_power = solaxX1.dc2_voltage * solaxX1.dc2_current;
|
||||||
|
|
||||||
EnergyUpdateTotal((float)solaxX1.energy_total * 0.1f, true); // 484.708 kWh
|
EnergyUpdateTotal(); // 484.708 kWh
|
||||||
}
|
}
|
||||||
} else { // end hasAddress
|
} else { // end hasAddress
|
||||||
// check address confirmation from inverter
|
// check address confirmation from inverter
|
||||||
@ -365,7 +364,7 @@ void solaxX1250MSecond(void) // Every 250 milliseconds
|
|||||||
|
|
||||||
solaxX1.temperature = solaxX1.dc1_voltage = solaxX1.dc2_voltage = solaxX1.dc1_current = solaxX1.dc2_current = solaxX1.dc1_power = 0;
|
solaxX1.temperature = solaxX1.dc1_voltage = solaxX1.dc2_voltage = solaxX1.dc1_current = solaxX1.dc2_current = solaxX1.dc1_power = 0;
|
||||||
solaxX1.dc2_power = solaxX1.status = Energy.current[0] = Energy.voltage[0] = Energy.frequency[0] = Energy.active_power[0] = 0;
|
solaxX1.dc2_power = solaxX1.status = Energy.current[0] = Energy.voltage[0] = Energy.frequency[0] = Energy.active_power[0] = 0;
|
||||||
//solaxX1.energy_today = solaxX1.energy_total = solaxX1.runtime_total = 0;
|
//solaxX1.energy_today = solaxX1.runtime_total = 0;
|
||||||
} else {
|
} else {
|
||||||
if (protocolStatus.queryOfflineSend) {
|
if (protocolStatus.queryOfflineSend) {
|
||||||
protocolStatus.status = 0b00001000; // queryOffline
|
protocolStatus.status = 0b00001000; // queryOffline
|
||||||
|
@ -181,7 +181,8 @@ void FifLEEvery250ms(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
Le01mr.total_active = value_buff * 0.01f; // [kWh]
|
Energy.import_active[0] = value_buff * 0.01f; // [kWh]
|
||||||
|
Le01mr.total_active = Energy.import_active[0] // Useless
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
@ -193,7 +194,7 @@ void FifLEEvery250ms(void)
|
|||||||
if (Le01mr.read_state == Le01mr.start_address_count) {
|
if (Le01mr.read_state == Le01mr.start_address_count) {
|
||||||
Le01mr.read_state = 0;
|
Le01mr.read_state = 0;
|
||||||
|
|
||||||
EnergyUpdateTotal(Le01mr.total_active, true);
|
EnergyUpdateTotal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end data ready
|
} // end data ready
|
||||||
|
@ -113,7 +113,7 @@ const char kTarifName[] PROGMEM =
|
|||||||
// tariff values for standard mode
|
// tariff values for standard mode
|
||||||
#define TELEINFO_STD_TARIFF_BASE PSTR("BASE")
|
#define TELEINFO_STD_TARIFF_BASE PSTR("BASE")
|
||||||
#define TELEINFO_STD_TARIFF_HC PSTR("HEURE CREUSE")
|
#define TELEINFO_STD_TARIFF_HC PSTR("HEURE CREUSE")
|
||||||
#define TELEINFO_STD_TARIFF_HP PSTR("HEURE PLEINE")
|
#define TELEINFO_STD_TARIFF_HP PSTR("HEURE PLEINE")
|
||||||
|
|
||||||
|
|
||||||
// Label used to do some post processing and/or calculation
|
// Label used to do some post processing and/or calculation
|
||||||
@ -122,7 +122,7 @@ enum TInfoLabel{
|
|||||||
LABEL_ADCO, LABEL_ADSC,
|
LABEL_ADCO, LABEL_ADSC,
|
||||||
LABEL_HCHC, LABEL_HCHP, LABEL_EAST, LABEL_EASF01, LABEL_EASF02,
|
LABEL_HCHC, LABEL_HCHP, LABEL_EAST, LABEL_EASF01, LABEL_EASF02,
|
||||||
LABEL_OPTARIF, LABEL_NGTF, LABEL_ISOUSC, LABEL_PREF, LABEL_PTEC, LABEL_LTARF, LABEL_NTARF,
|
LABEL_OPTARIF, LABEL_NGTF, LABEL_ISOUSC, LABEL_PREF, LABEL_PTEC, LABEL_LTARF, LABEL_NTARF,
|
||||||
LABEL_PAPP, LABEL_SINSTS, LABEL_IINST, LABEL_IINST1, LABEL_IINST2, LABEL_IINST3, LABEL_IRMS1, LABEL_IRMS2, LABEL_IRMS3,
|
LABEL_PAPP, LABEL_SINSTS, LABEL_IINST, LABEL_IINST1, LABEL_IINST2, LABEL_IINST3, LABEL_IRMS1, LABEL_IRMS2, LABEL_IRMS3,
|
||||||
LABEL_TENSION, LABEL_URMS1, LABEL_URMS2, LABEL_URMS3,
|
LABEL_TENSION, LABEL_URMS1, LABEL_URMS2, LABEL_URMS3,
|
||||||
LABEL_IMAX, LABEL_IMAX1, LABEL_IMAX2, LABEL_IMAX3, LABEL_PMAX, LABEL_SMAXSN,
|
LABEL_IMAX, LABEL_IMAX1, LABEL_IMAX2, LABEL_IMAX3, LABEL_PMAX, LABEL_SMAXSN,
|
||||||
LABEL_DEMAIN,
|
LABEL_DEMAIN,
|
||||||
@ -139,12 +139,12 @@ const char kLabel[] PROGMEM =
|
|||||||
"|DEMAIN"
|
"|DEMAIN"
|
||||||
;
|
;
|
||||||
|
|
||||||
// Blacklisted label from telemetry
|
// Blacklisted label from telemetry
|
||||||
// Each label shoud be enclosed by pipe
|
// Each label shoud be enclosed by pipe
|
||||||
const char kLabelBlacklist[]
|
const char kLabelBlacklist[]
|
||||||
// declared as progmem for ESP8266 just crash and reset on strstr()
|
// declared as progmem for ESP8266 just crash and reset on strstr()
|
||||||
#ifndef ESP8266
|
#ifndef ESP8266
|
||||||
PROGMEM
|
PROGMEM
|
||||||
#endif
|
#endif
|
||||||
=
|
=
|
||||||
"|PJOURF+1"
|
"|PJOURF+1"
|
||||||
@ -246,7 +246,7 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
|
|||||||
float volt = (float) atoi(me->value);
|
float volt = (float) atoi(me->value);
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s=%s, now %d"), me->name, me->value, (int) volt);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s=%s, now %d"), me->name, me->value, (int) volt);
|
||||||
|
|
||||||
if ( ilabel == LABEL_URMS2) {
|
if ( ilabel == LABEL_URMS2) {
|
||||||
Energy.voltage[1] = volt;
|
Energy.voltage[1] = volt;
|
||||||
} else if ( ilabel == LABEL_URMS3) {
|
} else if ( ilabel == LABEL_URMS3) {
|
||||||
Energy.voltage[2] = volt;
|
Energy.voltage[2] = volt;
|
||||||
@ -256,7 +256,7 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Current I phase 1 to 3
|
// Current I phase 1 to 3
|
||||||
else if (ilabel == LABEL_IINST
|
else if (ilabel == LABEL_IINST
|
||||||
|| ilabel == LABEL_IINST1 || ilabel == LABEL_IRMS1
|
|| ilabel == LABEL_IINST1 || ilabel == LABEL_IRMS1
|
||||||
|| ilabel == LABEL_IINST2 || ilabel == LABEL_IRMS2
|
|| ilabel == LABEL_IINST2 || ilabel == LABEL_IRMS2
|
||||||
|| ilabel == LABEL_IINST3 || ilabel == LABEL_IRMS3 )
|
|| ilabel == LABEL_IINST3 || ilabel == LABEL_IRMS3 )
|
||||||
@ -355,7 +355,8 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
|
|||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%u HP:%u Total:%u"), hc, hp, total);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%u HP:%u Total:%u"), hc, hp, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnergyUpdateTotal(total/1000.0f, true);
|
Energy.import_active[0] = total/1000.0f;
|
||||||
|
EnergyUpdateTotal();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wh total index (standard)
|
// Wh total index (standard)
|
||||||
@ -363,7 +364,8 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
|
|||||||
{
|
{
|
||||||
uint32_t total = atoi(me->value);
|
uint32_t total = atoi(me->value);
|
||||||
if (contrat != CONTRAT_BAS) {
|
if (contrat != CONTRAT_BAS) {
|
||||||
EnergyUpdateTotal(total/1000.0f, true);
|
Energy.import_active[0] = total/1000.0f;
|
||||||
|
EnergyUpdateTotal();
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Total:%uWh"), total);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Total:%uWh"), total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -372,7 +374,8 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
|
|||||||
else if ( ilabel == LABEL_EASF01)
|
else if ( ilabel == LABEL_EASF01)
|
||||||
{
|
{
|
||||||
if (contrat == CONTRAT_BAS) {
|
if (contrat == CONTRAT_BAS) {
|
||||||
EnergyUpdateTotal(atoi(me->value)/1000.0f, true);
|
Energy.import_active[0] = atoi(me->value)/1000.0f;
|
||||||
|
EnergyUpdateTotal();
|
||||||
}
|
}
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%u"), atoi(me->value));
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%u"), atoi(me->value));
|
||||||
}
|
}
|
||||||
@ -534,7 +537,7 @@ void NewFrameCallback(struct _ValueList * me)
|
|||||||
// send teleinfo full frame or only changed data
|
// send teleinfo full frame or only changed data
|
||||||
bool hasData = ResponseAppendTInfo(' ', Settings->teleinfo.raw_report_changed ? false : true );
|
bool hasData = ResponseAppendTInfo(' ', Settings->teleinfo.raw_report_changed ? false : true );
|
||||||
ResponseJsonEndEnd();
|
ResponseJsonEndEnd();
|
||||||
|
|
||||||
// Publish adding ADCO serial number into the topic
|
// Publish adding ADCO serial number into the topic
|
||||||
// Need setOption4 to be enabled
|
// Need setOption4 to be enabled
|
||||||
// No need to send empty payload
|
// No need to send empty payload
|
||||||
@ -643,7 +646,7 @@ void TInfoInit(void)
|
|||||||
AddLog(LOG_LEVEL_INFO, PSTR("TIC: Raw mode enabled"));
|
AddLog(LOG_LEVEL_INFO, PSTR("TIC: Raw mode enabled"));
|
||||||
if (raw_skip) {
|
if (raw_skip) {
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("TIC: Sending only one frame over %d "), raw_skip+1);
|
AddLog(LOG_LEVEL_INFO, PSTR("TIC: Sending only one frame over %d "), raw_skip+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -667,7 +670,7 @@ bool TInfoCmd(void) {
|
|||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: len %d, data '%s'"), XdrvMailbox.data_len, XdrvMailbox.data ? XdrvMailbox.data : "null" );
|
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: len %d, data '%s'"), XdrvMailbox.data_len, XdrvMailbox.data ? XdrvMailbox.data : "null" );
|
||||||
|
|
||||||
// Just "EnergyConfig" no more parameter
|
// Just "EnergyConfig" no more parameter
|
||||||
// Show Teleinfo configuration
|
// Show Teleinfo configuration
|
||||||
if (XdrvMailbox.data_len == 0) {
|
if (XdrvMailbox.data_len == 0) {
|
||||||
|
|
||||||
char mode_name[MAX_TINFO_COMMAND_NAME];
|
char mode_name[MAX_TINFO_COMMAND_NAME];
|
||||||
@ -676,7 +679,7 @@ bool TInfoCmd(void) {
|
|||||||
int index_raw = Settings->teleinfo.raw_send ? CMND_TELEINFO_RAW_FULL : CMND_TELEINFO_RAW_DISABLE;
|
int index_raw = Settings->teleinfo.raw_send ? CMND_TELEINFO_RAW_FULL : CMND_TELEINFO_RAW_DISABLE;
|
||||||
if (Settings->teleinfo.raw_send && Settings->teleinfo.raw_report_changed) {
|
if (Settings->teleinfo.raw_send && Settings->teleinfo.raw_report_changed) {
|
||||||
index_raw = CMND_TELEINFO_RAW_CHANGE;
|
index_raw = CMND_TELEINFO_RAW_CHANGE;
|
||||||
}
|
}
|
||||||
// Get the mode and raw name
|
// Get the mode and raw name
|
||||||
GetTextIndexed(mode_name, MAX_TINFO_COMMAND_NAME, index_mode, kTInfo_Commands);
|
GetTextIndexed(mode_name, MAX_TINFO_COMMAND_NAME, index_mode, kTInfo_Commands);
|
||||||
GetTextIndexed(raw_name, MAX_TINFO_COMMAND_NAME, index_raw, kTInfo_Commands);
|
GetTextIndexed(raw_name, MAX_TINFO_COMMAND_NAME, index_raw, kTInfo_Commands);
|
||||||
@ -685,7 +688,7 @@ bool TInfoCmd(void) {
|
|||||||
|
|
||||||
serviced = true;
|
serviced = true;
|
||||||
|
|
||||||
// At least "EnergyConfig xyz" plus one space and one (or more) char
|
// At least "EnergyConfig xyz" plus one space and one (or more) char
|
||||||
// so "EnergyConfig 0" or "EnergyConfig Teleinfo Standard"
|
// so "EnergyConfig 0" or "EnergyConfig Teleinfo Standard"
|
||||||
} else if (XdrvMailbox.data_len) {
|
} else if (XdrvMailbox.data_len) {
|
||||||
// Now point on parameter
|
// Now point on parameter
|
||||||
@ -722,7 +725,7 @@ bool TInfoCmd(void) {
|
|||||||
if ( (tinfo_mode==TINFO_MODE_STANDARD && command_code==CMND_TELEINFO_HISTORIQUE) ||
|
if ( (tinfo_mode==TINFO_MODE_STANDARD && command_code==CMND_TELEINFO_HISTORIQUE) ||
|
||||||
(tinfo_mode==TINFO_MODE_HISTORIQUE && command_code==CMND_TELEINFO_STANDARD) ) {
|
(tinfo_mode==TINFO_MODE_HISTORIQUE && command_code==CMND_TELEINFO_STANDARD) ) {
|
||||||
|
|
||||||
// Cleanup Serial not sure it will works since
|
// Cleanup Serial not sure it will works since
|
||||||
// there is no end() or close() on tasmotaserial class
|
// there is no end() or close() on tasmotaserial class
|
||||||
if (TInfoSerial) {
|
if (TInfoSerial) {
|
||||||
TInfoSerial->flush();
|
TInfoSerial->flush();
|
||||||
@ -730,7 +733,7 @@ bool TInfoCmd(void) {
|
|||||||
free(TInfoSerial);
|
free(TInfoSerial);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change mode
|
// Change mode
|
||||||
Settings->teleinfo.mode_standard = command_code == CMND_TELEINFO_STANDARD ? 1 : 0;
|
Settings->teleinfo.mode_standard = command_code == CMND_TELEINFO_STANDARD ? 1 : 0;
|
||||||
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("TIC: '%s' mode"), mode_name);
|
AddLog(LOG_LEVEL_INFO, PSTR("TIC: '%s' mode"), mode_name);
|
||||||
@ -746,10 +749,10 @@ bool TInfoCmd(void) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMND_TELEINFO_RAW_DISABLE:
|
case CMND_TELEINFO_RAW_DISABLE:
|
||||||
case CMND_TELEINFO_RAW_FULL:
|
case CMND_TELEINFO_RAW_FULL:
|
||||||
case CMND_TELEINFO_RAW_CHANGE: {
|
case CMND_TELEINFO_RAW_CHANGE: {
|
||||||
|
|
||||||
// Enable all RAW frame send
|
// Enable all RAW frame send
|
||||||
char raw_name[MAX_TINFO_COMMAND_NAME];
|
char raw_name[MAX_TINFO_COMMAND_NAME];
|
||||||
|
|
||||||
@ -899,7 +902,7 @@ void TInfoShow(bool json)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
char name[33];
|
char name[33];
|
||||||
char value[33];
|
char value[33];
|
||||||
int percent;
|
int percent;
|
||||||
|
|
||||||
if (isousc) {
|
if (isousc) {
|
||||||
@ -916,7 +919,7 @@ void TInfoShow(bool json)
|
|||||||
// Hue from 128 (green) to 0 (red) so reversed from percent
|
// Hue from 128 (green) to 0 (red) so reversed from percent
|
||||||
hue = changeUIntScale(100-percent, 0, 100, 0, 128);
|
hue = changeUIntScale(100-percent, 0, 100, 0, 128);
|
||||||
HsToRgb(hue, 128, &red, &green, &blue);
|
HsToRgb(hue, 128, &red, &green, &blue);
|
||||||
snprintf_P(phase_color, sizeof(phase_color), PSTR("#%02X%02X%02X"), red, green, blue);
|
snprintf_P(phase_color, sizeof(phase_color), PSTR("#%02X%02X%02X"), red, green, blue);
|
||||||
WSContentSend_P(HTTP_ENERGY_LOAD_BAR, phase_color, percent, percent);
|
WSContentSend_P(HTTP_ENERGY_LOAD_BAR, phase_color, percent, percent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,10 +166,11 @@ void IEM3000Every250ms(void)
|
|||||||
|
|
||||||
case 10:
|
case 10:
|
||||||
#ifdef IEM3000_IEM3155
|
#ifdef IEM3000_IEM3155
|
||||||
EnergyUpdateTotal(value, true);
|
Energy.import_active[0] = value;
|
||||||
#else
|
#else
|
||||||
EnergyUpdateTotal(value64 * 0.001f, true); // 1125 => 1.125
|
Energy.import_active[0] = value64 * 0.001f; // 1125 => 1.125
|
||||||
#endif
|
#endif
|
||||||
|
EnergyUpdateTotal();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +163,8 @@ void WE517Every250ms(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 16:
|
case 16:
|
||||||
EnergyUpdateTotal(value, true);
|
Energy.import_active[0] = value;
|
||||||
|
EnergyUpdateTotal();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,8 @@ void Sdm72Every250ms(void)
|
|||||||
|
|
||||||
++Sdm72.read_state %= nitems(sdm72_register);
|
++Sdm72.read_state %= nitems(sdm72_register);
|
||||||
if (0 == Sdm72.read_state && !isnan(Sdm72.total_active)) {
|
if (0 == Sdm72.read_state && !isnan(Sdm72.total_active)) {
|
||||||
EnergyUpdateTotal(Sdm72.total_active, true);
|
Energy.import_active[0] = Sdm72.total_active;
|
||||||
|
EnergyUpdateTotal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end data ready
|
} // end data ready
|
||||||
|
Loading…
x
Reference in New Issue
Block a user