mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Bump v12.4.0.3
- Bump v12.4.0.3 - Refactor energy monitoring reducing stack usage and solve inherent exceptions and watchdogs (#18164)
This commit is contained in:
parent
d0f4637611
commit
54a2688cbf
16
CHANGELOG.md
16
CHANGELOG.md
@ -3,7 +3,19 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased] - Development
|
||||
|
||||
## [12.4.0.2]
|
||||
## [12.4.0.3]
|
||||
### Added
|
||||
|
||||
### Breaking Changed
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
- Refactor energy monitoring reducing stack usage and solve inherent exceptions and watchdogs (#18164)
|
||||
|
||||
### Removed
|
||||
|
||||
## [12.4.0.2] 20230317
|
||||
### Added
|
||||
- Support for multiple MCP23008 as switch/button/relay
|
||||
- Support for multiple PCF8574 as switch/button/relay
|
||||
@ -32,8 +44,6 @@ All notable changes to this project will be documented in this file.
|
||||
- Rule topic comparison (#18144)
|
||||
- ESP32 energy period shows kWh value instead of Wh regression from v12.3.1.5 (#15856)
|
||||
|
||||
### Removed
|
||||
|
||||
## [12.4.0.1] 20230301
|
||||
### Added
|
||||
- Matter read/write and commands (#18000)
|
||||
|
@ -110,7 +110,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
||||
|
||||
[Complete list](BUILDS.md) of available feature and sensors.
|
||||
|
||||
## Changelog v12.4.0.2
|
||||
## Changelog v12.4.0.3
|
||||
### Added
|
||||
- Support for multiple MCP23008/MCP23017/MCP23S17 as switch/button/relay
|
||||
- Support for multiple PCF8574 as switch/button/relay
|
||||
@ -143,4 +143,5 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
||||
- TuyaMcu v1 timer integer overflow [#18048](https://github.com/arendst/Tasmota/issues/18048)
|
||||
- PZEM energy monitor stabilize period on larger configs [#18103](https://github.com/arendst/Tasmota/issues/18103)
|
||||
- Rule topic comparison [#18144](https://github.com/arendst/Tasmota/issues/18144)
|
||||
- Refactor energy monitoring reducing stack usage and solve inherent exceptions and watchdogs [#18164](https://github.com/arendst/Tasmota/issues/18164)
|
||||
- ESP32 energy period shows kWh value instead of Wh regression from v12.3.1.5 [#15856](https://github.com/arendst/Tasmota/issues/15856)
|
||||
|
@ -200,11 +200,6 @@ const uint16_t MAX_INPUT_BUFFER_SIZE = 2048; // Max number of characters in Ardu
|
||||
const uint16_t FLOATSZ = 16; // Max number of characters in float result from dtostrfd (max 32)
|
||||
const uint16_t CMDSZ = 24; // Max number of characters in command
|
||||
const uint16_t TOPSZ = 151; // Max number of characters in topic string
|
||||
#ifdef ESP8266
|
||||
const uint16_t GUISZ = 300; // Max number of characters in WebEnergyFormat string
|
||||
#else
|
||||
const uint16_t GUISZ = 600; // Max number of characters in WebEnergyFormat string
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
#ifdef PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED
|
||||
|
@ -20,6 +20,6 @@
|
||||
#ifndef _TASMOTA_VERSION_H_
|
||||
#define _TASMOTA_VERSION_H_
|
||||
|
||||
const uint32_t VERSION = 0x0C040002; // 12.4.0.2
|
||||
const uint32_t VERSION = 0x0C040003; // 12.4.0.3
|
||||
|
||||
#endif // _TASMOTA_VERSION_H_
|
||||
|
@ -101,6 +101,8 @@ typedef struct {
|
||||
int32_t kWhtoday[ENERGY_MAX_PHASES]; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = Energy->daily
|
||||
int32_t period[ENERGY_MAX_PHASES]; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = Energy->daily
|
||||
|
||||
char* value;
|
||||
|
||||
uint8_t fifth_second;
|
||||
uint8_t command_code;
|
||||
uint8_t data_valid[ENERGY_MAX_PHASES];
|
||||
@ -143,14 +145,32 @@ Ticker ticker_energy;
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
char* EnergyFormat(char* result, float* input, uint32_t resolution, uint32_t single = 0);
|
||||
char* EnergyFormat(char* result, float* input, uint32_t resolution, uint32_t single) {
|
||||
const uint16_t GUISZ = 300; // Max number of characters in WebEnergyFmt string
|
||||
|
||||
bool EnergyFmtMalloc(void) {
|
||||
if (Energy->value == nullptr) {
|
||||
Energy->value = (char*)malloc(GUISZ);
|
||||
if (!Energy->value) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void EnergyFmtFree(void) {
|
||||
free(Energy->value);
|
||||
Energy->value = nullptr;
|
||||
}
|
||||
|
||||
char* EnergyFmt(float* input, uint32_t resolution, uint32_t single = 0);
|
||||
char* EnergyFmt(float* input, uint32_t resolution, uint32_t single) {
|
||||
// single = 0 - Energy->phase_count - xx or [xx,xx] or [xx,xx,xx]
|
||||
// single = 1 - Energy->voltage_common or Energy->frequency_common - xx
|
||||
// single = 2 - Sum of Energy->phase_count if SO129 0 - xx or if SO129 1 - [xx,xx,xx]
|
||||
// single = 5 - single &0x03 = 1 - xx
|
||||
// single = 6 - single &0x03 = 2 - [xx,xx] - used by tarriff
|
||||
// single = 7 - single &0x03 = 3 - [xx,xx,xx]
|
||||
|
||||
if (!EnergyFmtMalloc()) { return EmptyStr; }
|
||||
|
||||
uint32_t index = (single > 3) ? single &0x03 : (0 == single) ? Energy->phase_count : 1; // 1,2,3
|
||||
if (single > 2) { single = 0; } // 0,1,2
|
||||
float input_sum = 0.0f;
|
||||
@ -166,19 +186,22 @@ char* EnergyFormat(char* result, float* input, uint32_t resolution, uint32_t sin
|
||||
index = Energy->phase_count;
|
||||
}
|
||||
}
|
||||
result[0] = '\0';
|
||||
Energy->value[0] = '\0';
|
||||
for (uint32_t i = 0; i < index; i++) {
|
||||
ext_snprintf_P(result, TOPSZ, PSTR("%s%s%*_f%s"), result, (0==i)?(1==index)?"":"[":",", resolution, &input[i], (index-1==i)?(1==index)?"":"]":"");
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s%s%*_f%s"), Energy->value, (0==i)?(1==index)?"":"[":",", resolution, &input[i], (index-1==i)?(1==index)?"":"]":"");
|
||||
}
|
||||
return result;
|
||||
return Energy->value;
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
char* WebEnergyFormat(char* result, float* input, uint32_t resolution, uint32_t single = 0);
|
||||
char* WebEnergyFormat(char* result, float* input, uint32_t resolution, uint32_t single) {
|
||||
char* WebEnergyFmt(float* input, uint32_t resolution, uint32_t single = 0);
|
||||
char* WebEnergyFmt(float* input, uint32_t resolution, uint32_t single) {
|
||||
// single = 0 - Energy->phase_count - xx / xx / xx or multi column
|
||||
// single = 1 - Energy->voltage_common or Energy->frequency_common - xx or single column using colspan (if needed)
|
||||
// single = 2 - Sum of Energy->phase_count if SO129 0 - xx or single column using colspan (if needed) or if SO129 1 - xx / xx / xx or multi column
|
||||
|
||||
if (!EnergyFmtMalloc()) { return EmptyStr; }
|
||||
|
||||
float input_sum = 0.0f;
|
||||
if (single > 1) { // Sum and/or Single column
|
||||
if (!Settings->flag5.energy_phase) { // SetOption129 - (Energy) Show phase information
|
||||
@ -193,32 +216,32 @@ char* WebEnergyFormat(char* result, float* input, uint32_t resolution, uint32_t
|
||||
}
|
||||
}
|
||||
#ifdef USE_ENERGY_COLUMN_GUI
|
||||
ext_snprintf_P(result, GUISZ, PSTR("</td>")); // Skip first column
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("</td>")); // Skip first column
|
||||
if ((Energy->phase_count > 1) && single) { // Need to set colspan so need new columns
|
||||
// </td><td colspan='3' style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td colspan='5' style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td colspan='7' style='text-align:right'>1.23</td><td> </td><td>
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s<td colspan='%d' style='text-align:%s'>%*_f</td><td> </td>"),
|
||||
result, (Energy->phase_count *2) -1, (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("center"), resolution, &input[0]);
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s<td colspan='%d' style='text-align:%s'>%*_f</td><td> </td>"),
|
||||
Energy->value, (Energy->phase_count *2) -1, (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("center"), resolution, &input[0]);
|
||||
} else {
|
||||
// </td><td style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td>
|
||||
for (uint32_t i = 0; i < Energy->phase_count; i++) {
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s<td style='text-align:%s'>%*_f</td><td> </td>"),
|
||||
result, (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("left"), resolution, &input[i]);
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s<td style='text-align:%s'>%*_f</td><td> </td>"),
|
||||
Energy->value, (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("left"), resolution, &input[i]);
|
||||
}
|
||||
}
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s<td>"), result);
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s<td>"), Energy->value);
|
||||
#else // not USE_ENERGY_COLUMN_GUI
|
||||
uint32_t index = (single) ? 1 : Energy->phase_count; // 1,2,3
|
||||
result[0] = '\0';
|
||||
Energy->value[vidx][0] = '\0';
|
||||
for (uint32_t i = 0; i < index; i++) {
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s%s%*_f"), result, (i)?" / ":"", resolution, &input[i]);
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s%s%*_f"), Energy->value, (i)?" / ":"", resolution, &input[i]);
|
||||
}
|
||||
#endif // USE_ENERGY_COLUMN_GUI
|
||||
return result;
|
||||
return Energy->value;
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
@ -495,8 +518,7 @@ void EnergyMarginCheck(void) {
|
||||
for (uint32_t phase = 0; phase < Energy->phase_count; phase++) {
|
||||
power_diff_f[phase] = power_diff[phase];
|
||||
}
|
||||
char value_chr[TOPSZ];
|
||||
ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%s"), EnergyFormat(value_chr, power_diff_f, 0));
|
||||
ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%s"), EnergyFmt(power_diff_f, 0));
|
||||
}
|
||||
|
||||
uint16_t energy_power_u = (uint16_t)(Energy->active_power[0]);
|
||||
@ -603,6 +625,7 @@ void EnergyMarginCheck(void) {
|
||||
}
|
||||
}
|
||||
#endif // USE_ENERGY_POWER_LIMIT
|
||||
EnergyFmtFree();
|
||||
}
|
||||
|
||||
void EnergyMqttShow(void) {
|
||||
@ -668,10 +691,6 @@ void EnergyEverySecond(void) {
|
||||
\*********************************************************************************************/
|
||||
|
||||
void ResponseCmndEnergyTotalYesterdayToday(void) {
|
||||
char value_chr[TOPSZ]; // Used by EnergyFormatIndex
|
||||
char value2_chr[TOPSZ];
|
||||
char value3_chr[TOPSZ];
|
||||
|
||||
float energy_yesterday_ph[3];
|
||||
for (uint32_t i = 0; i < Energy->phase_count; i++) {
|
||||
energy_yesterday_ph[i] = (float)Settings->energy_kWhyesterday_ph[i] / 100000;
|
||||
@ -681,16 +700,19 @@ void ResponseCmndEnergyTotalYesterdayToday(void) {
|
||||
}
|
||||
}
|
||||
|
||||
Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"),
|
||||
Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s"),
|
||||
XdrvMailbox.command,
|
||||
EnergyFormat(value_chr, Energy->total, Settings->flag2.energy_resolution),
|
||||
EnergyFormat(value2_chr, energy_yesterday_ph, Settings->flag2.energy_resolution),
|
||||
EnergyFormat(value3_chr, Energy->daily, Settings->flag2.energy_resolution));
|
||||
EnergyFmt(Energy->total, Settings->flag2.energy_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s"),
|
||||
EnergyFmt(energy_yesterday_ph, Settings->flag2.energy_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY "\":%s"),
|
||||
EnergyFmt(Energy->daily, Settings->flag2.energy_resolution));
|
||||
if (Energy->local_energy_active_export) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->export_active, Settings->flag2.energy_resolution));
|
||||
EnergyFmt(Energy->export_active, Settings->flag2.energy_resolution));
|
||||
}
|
||||
ResponseJsonEndEnd();
|
||||
EnergyFmtFree();
|
||||
}
|
||||
|
||||
void CmndEnergyTotal(void) {
|
||||
@ -1110,6 +1132,7 @@ void EnergyDrvInit(void) {
|
||||
Energy = (tEnergy*)calloc(sizeof(tEnergy), 1); // Need calloc to reset registers to 0/false
|
||||
if (!Energy) { return; }
|
||||
|
||||
EnergyFmtFree();
|
||||
// Energy->voltage_common = false;
|
||||
// Energy->frequency_common = false;
|
||||
// Energy->use_overtemp = false;
|
||||
@ -1165,17 +1188,19 @@ void EnergySnsInit(void)
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_ENERGY_SNS1[] PROGMEM =
|
||||
"{s}" D_POWERUSAGE_APPARENT "{m}%s " D_UNIT_VA "{e}"
|
||||
"{s}" D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}"
|
||||
const char HTTP_ENERGY_POWERUSAGE_APPARENT[] PROGMEM =
|
||||
"{s}" D_POWERUSAGE_APPARENT "{m}%s " D_UNIT_VA "{e}";
|
||||
const char HTTP_ENERGY_POWERUSAGE_REACTIVE[] PROGMEM =
|
||||
"{s}" D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}";
|
||||
const char HTTP_ENERGY_POWER_FACTOR[] PROGMEM =
|
||||
"{s}" D_POWER_FACTOR "{m}%s{e}";
|
||||
|
||||
const char HTTP_ENERGY_SNS2[] PROGMEM =
|
||||
"{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
|
||||
"{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
|
||||
const char HTTP_ENERGY_TODAY[] PROGMEM =
|
||||
"{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
const char HTTP_ENERGY_YESTERDAY[] PROGMEM =
|
||||
"{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
const char HTTP_ENERGY_TOTAL[] PROGMEM =
|
||||
"{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
|
||||
const char HTTP_ENERGY_SNS3[] PROGMEM =
|
||||
const char HTTP_ENERGY_EXPORT_ACTIVE[] PROGMEM =
|
||||
"{s}" D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
@ -1256,34 +1281,31 @@ void EnergyShow(bool json) {
|
||||
energy_tariff = true;
|
||||
}
|
||||
|
||||
char value_chr[GUISZ]; // Used by EnergyFormatIndex
|
||||
char value2_chr[GUISZ];
|
||||
char value3_chr[GUISZ];
|
||||
|
||||
if (json) {
|
||||
bool show_energy_period = (0 == TasmotaGlobal.tele_period);
|
||||
|
||||
ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s"),
|
||||
GetDateAndTime(DT_ENERGY).c_str(),
|
||||
EnergyFormat(value_chr, Energy->total, Settings->flag2.energy_resolution, 2));
|
||||
EnergyFmt(Energy->total, Settings->flag2.energy_resolution, 2));
|
||||
|
||||
if (energy_tariff) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL D_CMND_TARIFF "\":%s"),
|
||||
EnergyFormat(value_chr, energy_usage, Settings->flag2.energy_resolution, 6));
|
||||
EnergyFmt(energy_usage, Settings->flag2.energy_resolution, 6));
|
||||
}
|
||||
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"),
|
||||
EnergyFormat(value_chr, energy_yesterday_ph, Settings->flag2.energy_resolution, 2),
|
||||
EnergyFormat(value2_chr, Energy->daily, Settings->flag2.energy_resolution, 2));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s"),
|
||||
EnergyFmt(energy_yesterday_ph, Settings->flag2.energy_resolution, 2));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY "\":%s"),
|
||||
EnergyFmt(Energy->daily, Settings->flag2.energy_resolution, 2));
|
||||
|
||||
/*
|
||||
#if defined(SDM630_IMPORT) || defined(SDM72_IMPEXP)
|
||||
if (!isnan(Energy->import_active[0])) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_ACTIVE "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->import_active, Settings->flag2.energy_resolution));
|
||||
EnergyFmt(Energy->import_active, Settings->flag2.energy_resolution));
|
||||
if (energy_tariff) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT D_CMND_TARIFF "\":%s"),
|
||||
EnergyFormat(value_chr, energy_return, Settings->flag2.energy_resolution, 6));
|
||||
EnergyFmt(energy_return, Settings->flag2.energy_resolution, 6));
|
||||
}
|
||||
}
|
||||
#endif // SDM630_IMPORT || SDM72_IMPEXP
|
||||
@ -1291,13 +1313,16 @@ void EnergyShow(bool json) {
|
||||
|
||||
if (!isnan(Energy->export_active[0])) {
|
||||
uint32_t single = (!isnan(Energy->export_active[1]) && !isnan(Energy->export_active[2])) ? 0 : 1;
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY_SUM_IMPORT "\":%s,\"" D_JSON_TODAY_SUM_EXPORT "\":%s,\"" D_JSON_EXPORT_ACTIVE "\":%s"),
|
||||
EnergyFormat(value_chr, &Energy->daily_sum_import_balanced, Settings->flag2.energy_resolution, 1),
|
||||
EnergyFormat(value2_chr, &Energy->daily_sum_export_balanced, Settings->flag2.energy_resolution, 1),
|
||||
EnergyFormat(value3_chr, Energy->export_active, Settings->flag2.energy_resolution, single));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY_SUM_IMPORT "\":%s"),
|
||||
EnergyFmt(&Energy->daily_sum_import_balanced, Settings->flag2.energy_resolution, 1));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY_SUM_EXPORT "\":%s"),
|
||||
EnergyFmt(&Energy->daily_sum_export_balanced, Settings->flag2.energy_resolution, 1));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"),
|
||||
EnergyFmt(Energy->export_active, Settings->flag2.energy_resolution, single));
|
||||
|
||||
if (energy_tariff) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT D_CMND_TARIFF "\":%s"),
|
||||
EnergyFormat(value_chr, energy_return, Settings->flag2.energy_resolution, 6));
|
||||
EnergyFmt(energy_return, Settings->flag2.energy_resolution, 6));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1308,30 +1333,32 @@ void EnergyShow(bool json) {
|
||||
Energy->period[i] = RtcSettings.energy_kWhtoday_ph[i];
|
||||
}
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_PERIOD "\":%s"),
|
||||
EnergyFormat(value_chr, energy_period, Settings->flag2.wattage_resolution));
|
||||
EnergyFmt(energy_period, Settings->flag2.wattage_resolution));
|
||||
}
|
||||
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_POWERUSAGE "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->active_power, Settings->flag2.wattage_resolution));
|
||||
EnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution));
|
||||
if (!Energy->type_dc) {
|
||||
if (Energy->current_available && Energy->voltage_available) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_POWERFACTOR "\":%s"),
|
||||
EnergyFormat(value_chr, apparent_power, Settings->flag2.wattage_resolution),
|
||||
EnergyFormat(value2_chr, reactive_power, Settings->flag2.wattage_resolution),
|
||||
EnergyFormat(value3_chr, power_factor, 2));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_APPARENT_POWERUSAGE "\":%s"),
|
||||
EnergyFmt(apparent_power, Settings->flag2.wattage_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_REACTIVE_POWERUSAGE "\":%s"),
|
||||
EnergyFmt(reactive_power, Settings->flag2.wattage_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_POWERFACTOR "\":%s"),
|
||||
EnergyFmt(power_factor, 2));
|
||||
}
|
||||
if (!isnan(Energy->frequency[0])) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->frequency, Settings->flag2.frequency_resolution, frequency_common));
|
||||
EnergyFmt(Energy->frequency, Settings->flag2.frequency_resolution, frequency_common));
|
||||
}
|
||||
}
|
||||
if (Energy->voltage_available) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_VOLTAGE "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->voltage, Settings->flag2.voltage_resolution, voltage_common));
|
||||
EnergyFmt(Energy->voltage, Settings->flag2.voltage_resolution, voltage_common));
|
||||
}
|
||||
if (Energy->current_available) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_CURRENT "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->current, Settings->flag2.current_resolution));
|
||||
EnergyFmt(Energy->current, Settings->flag2.current_resolution));
|
||||
}
|
||||
XnrgCall(FUNC_JSON_APPEND);
|
||||
ResponseJsonEnd();
|
||||
@ -1388,37 +1415,38 @@ void EnergyShow(bool json) {
|
||||
WSContentSend_P(PSTR("</table><hr/>{t}{s}</th><th></th>")); // First column is empty ({t} = <table style='width:100%'>, {s} = <tr><th>)
|
||||
bool label_o = voltage_common;
|
||||
bool no_label = (1 == Energy->phase_count);
|
||||
char number[4];
|
||||
for (uint32_t i = 0; i < Energy->phase_count; i++) {
|
||||
WSContentSend_P(PSTR("<th style='text-align:center'>%s%s<th></th>"), (no_label)?"":(label_o)?"O":"L", (no_label)?"":itoa(i +1, value_chr, 10));
|
||||
WSContentSend_P(PSTR("<th style='text-align:center'>%s%s<th></th>"), (no_label)?"":(label_o)?"O":"L", (no_label)?"":itoa(i +1, number, 10));
|
||||
}
|
||||
WSContentSend_P(PSTR("<td>{e}")); // Last column is units ({e} = </td></tr>)
|
||||
#endif // USE_ENERGY_COLUMN_GUI
|
||||
if (Energy->voltage_available) {
|
||||
WSContentSend_PD(HTTP_SNS_VOLTAGE, WebEnergyFormat(value_chr, Energy->voltage, Settings->flag2.voltage_resolution, voltage_common));
|
||||
WSContentSend_PD(HTTP_SNS_VOLTAGE, WebEnergyFmt(Energy->voltage, Settings->flag2.voltage_resolution, voltage_common));
|
||||
}
|
||||
if (!Energy->type_dc) {
|
||||
if (!isnan(Energy->frequency[0])) {
|
||||
WSContentSend_PD(PSTR("{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"),
|
||||
WebEnergyFormat(value_chr, Energy->frequency, Settings->flag2.frequency_resolution, frequency_common));
|
||||
WebEnergyFmt(Energy->frequency, Settings->flag2.frequency_resolution, frequency_common));
|
||||
}
|
||||
}
|
||||
if (Energy->current_available) {
|
||||
WSContentSend_PD(HTTP_SNS_CURRENT, WebEnergyFormat(value_chr, Energy->current, Settings->flag2.current_resolution));
|
||||
WSContentSend_PD(HTTP_SNS_CURRENT, WebEnergyFmt(Energy->current, Settings->flag2.current_resolution));
|
||||
}
|
||||
WSContentSend_PD(HTTP_SNS_POWER, WebEnergyFormat(value_chr, Energy->active_power, Settings->flag2.wattage_resolution));
|
||||
WSContentSend_PD(HTTP_SNS_POWER, WebEnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution));
|
||||
if (!Energy->type_dc) {
|
||||
if (Energy->current_available && Energy->voltage_available) {
|
||||
WSContentSend_PD(HTTP_ENERGY_SNS1, WebEnergyFormat(value_chr, apparent_power, Settings->flag2.wattage_resolution),
|
||||
WebEnergyFormat(value2_chr, reactive_power, Settings->flag2.wattage_resolution),
|
||||
WebEnergyFormat(value3_chr, power_factor, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWERUSAGE_APPARENT, WebEnergyFmt(apparent_power, Settings->flag2.wattage_resolution));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWERUSAGE_REACTIVE, WebEnergyFmt(reactive_power, Settings->flag2.wattage_resolution));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWER_FACTOR, WebEnergyFmt(power_factor, 2));
|
||||
}
|
||||
}
|
||||
WSContentSend_PD(HTTP_ENERGY_SNS2, WebEnergyFormat(value_chr, Energy->daily, Settings->flag2.energy_resolution, 2),
|
||||
WebEnergyFormat(value2_chr, energy_yesterday_ph, Settings->flag2.energy_resolution, 2),
|
||||
WebEnergyFormat(value3_chr, Energy->total, Settings->flag2.energy_resolution, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_TODAY, WebEnergyFmt(Energy->daily, Settings->flag2.energy_resolution, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_YESTERDAY, WebEnergyFmt(energy_yesterday_ph, Settings->flag2.energy_resolution, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_TOTAL, WebEnergyFmt(Energy->total, Settings->flag2.energy_resolution, 2));
|
||||
if (!isnan(Energy->export_active[0])) {
|
||||
uint32_t single = (!isnan(Energy->export_active[1]) && !isnan(Energy->export_active[2])) ? 2 : 1;
|
||||
WSContentSend_PD(HTTP_ENERGY_SNS3, WebEnergyFormat(value_chr, Energy->export_active, Settings->flag2.energy_resolution, single));
|
||||
WSContentSend_PD(HTTP_ENERGY_EXPORT_ACTIVE, WebEnergyFmt(Energy->export_active, Settings->flag2.energy_resolution, single));
|
||||
}
|
||||
#ifdef USE_ENERGY_COLUMN_GUI
|
||||
XnrgCall(FUNC_WEB_COL_SENSOR);
|
||||
@ -1427,6 +1455,7 @@ void EnergyShow(bool json) {
|
||||
XnrgCall(FUNC_WEB_SENSOR);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
EnergyFmtFree();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -159,6 +159,8 @@ typedef struct {
|
||||
int32_t kWhtoday[ENERGY_MAX_PHASES]; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = Energy->daily
|
||||
|
||||
// Local only
|
||||
char* value;
|
||||
|
||||
float daily_kWh[ENERGY_MAX_PHASES]; // 123.123 kWh
|
||||
float energy_today_offset_kWh[ENERGY_MAX_PHASES]; // 123.12312 kWh = Energy->daily
|
||||
float period_kWh[ENERGY_MAX_PHASES]; // 123.12312 kWh = Energy->daily
|
||||
@ -370,14 +372,32 @@ void EnergySettingsSave(void) {
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
char* EnergyFormat(char* result, float* input, uint32_t resolution, uint32_t single = 0);
|
||||
char* EnergyFormat(char* result, float* input, uint32_t resolution, uint32_t single) {
|
||||
const uint16_t GUISZ = 600; // Max number of characters in WebEnergyFmt string
|
||||
|
||||
bool EnergyFmtMalloc(void) {
|
||||
if (Energy->value == nullptr) {
|
||||
Energy->value = (char*)malloc(GUISZ);
|
||||
if (!Energy->value) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void EnergyFmtFree(void) {
|
||||
free(Energy->value);
|
||||
Energy->value = nullptr;
|
||||
}
|
||||
|
||||
char* EnergyFmt(float* input, uint32_t resolution, uint32_t single = 0);
|
||||
char* EnergyFmt(float* input, uint32_t resolution, uint32_t single) {
|
||||
// single = 0 - Energy->phase_count - xx or [xx,xx] or [xx,xx,xx]
|
||||
// single = 1 - Energy->voltage_common or Energy->frequency_common - xx
|
||||
// single = 2 - Sum of Energy->phase_count if SO129 0 - xx or if SO129 1 - [xx,xx,xx]
|
||||
// single = 5 - single &0x03 = 1 - xx
|
||||
// single = 6 - single &0x03 = 2 - [xx,xx] - used by tarriff
|
||||
// single = 7 - single &0x03 = 3 - [xx,xx,xx]
|
||||
|
||||
if (!EnergyFmtMalloc()) { return EmptyStr; }
|
||||
|
||||
uint32_t index = (single > 3) ? single &0x03 : (0 == single) ? Energy->phase_count : 1; // 1,2,3
|
||||
if (single > 2) { single = 0; } // 0,1,2
|
||||
float input_sum = 0.0f;
|
||||
@ -393,19 +413,22 @@ char* EnergyFormat(char* result, float* input, uint32_t resolution, uint32_t sin
|
||||
index = Energy->phase_count;
|
||||
}
|
||||
}
|
||||
result[0] = '\0';
|
||||
Energy->value[0] = '\0';
|
||||
for (uint32_t i = 0; i < index; i++) {
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s%s%*_f%s"), result, (0==i)?(1==index)?"":"[":",", resolution, &input[i], (index-1==i)?(1==index)?"":"]":"");
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s%s%*_f%s"), Energy->value, (0==i)?(1==index)?"":"[":",", resolution, &input[i], (index-1==i)?(1==index)?"":"]":"");
|
||||
}
|
||||
return result;
|
||||
return Energy->value;
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
char* WebEnergyFormat(char* result, float* input, uint32_t resolution, uint32_t single = 0);
|
||||
char* WebEnergyFormat(char* result, float* input, uint32_t resolution, uint32_t single) {
|
||||
char* WebEnergyFmt(float* input, uint32_t resolution, uint32_t single = 0);
|
||||
char* WebEnergyFmt(float* input, uint32_t resolution, uint32_t single) {
|
||||
// single = 0 - Energy->phase_count - xx / xx / xx or multi column
|
||||
// single = 1 - Energy->voltage_common or Energy->frequency_common - xx or single column using colspan (if needed)
|
||||
// single = 2 - Sum of Energy->phase_count if SO129 0 - xx or single column using colspan (if needed) or if SO129 1 - xx / xx / xx or multi column
|
||||
|
||||
if (!EnergyFmtMalloc()) { return EmptyStr; }
|
||||
|
||||
float input_sum = 0.0f;
|
||||
if (single > 1) { // Sum and/or Single column
|
||||
if (!Settings->flag5.energy_phase) { // SetOption129 - (Energy) Show phase information
|
||||
@ -420,32 +443,32 @@ char* WebEnergyFormat(char* result, float* input, uint32_t resolution, uint32_t
|
||||
}
|
||||
}
|
||||
#ifdef USE_ENERGY_COLUMN_GUI
|
||||
ext_snprintf_P(result, GUISZ, PSTR("</td>")); // Skip first column
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("</td>")); // Skip first column
|
||||
if ((Energy->gui_count > 1) && single) { // Need to set colspan so need new columns
|
||||
// </td><td colspan='3' style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td colspan='5' style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td colspan='7' style='text-align:right'>1.23</td><td> </td><td>
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s<td colspan='%d' style='text-align:%s'>%*_f</td><td> </td>"),
|
||||
result, (Energy->gui_count *2) -1, (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("center"), resolution, &input[Energy->gui_indirect[0]]);
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s<td colspan='%d' style='text-align:%s'>%*_f</td><td> </td>"),
|
||||
Energy->value, (Energy->gui_count *2) -1, (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("center"), resolution, &input[Energy->gui_indirect[0]]);
|
||||
} else {
|
||||
// </td><td style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td>
|
||||
// </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td style='text-align:right'>1.23</td><td> </td><td>
|
||||
for (uint32_t i = 0; i < Energy->gui_count; i++) {
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s<td style='text-align:%s'>%*_f</td><td> </td>"),
|
||||
result, (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("left"), resolution, &input[Energy->gui_indirect[Energy->gui_offset +i]]);
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s<td style='text-align:%s'>%*_f</td><td> </td>"),
|
||||
Energy->value, (Settings->flag5.gui_table_align)?PSTR("right"):PSTR("left"), resolution, &input[Energy->gui_indirect[Energy->gui_offset +i]]);
|
||||
}
|
||||
}
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s<td>"), result);
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s<td>"), Energy->value);
|
||||
#else // not USE_ENERGY_COLUMN_GUI
|
||||
uint32_t index = (single) ? 1 : Energy->phase_count; // 1,2,3
|
||||
result[0] = '\0';
|
||||
Energy->value[0] = '\0';
|
||||
for (uint32_t i = 0; i < index; i++) {
|
||||
ext_snprintf_P(result, GUISZ, PSTR("%s%s%*_f"), result, (i)?" / ":"", resolution, &input[i]);
|
||||
ext_snprintf_P(Energy->value, GUISZ, PSTR("%s%s%*_f"), Energy->value, (i)?" / ":"", resolution, &input[i]);
|
||||
}
|
||||
#endif // USE_ENERGY_COLUMN_GUI
|
||||
return result;
|
||||
return Energy->value;
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
@ -717,8 +740,7 @@ void EnergyMarginCheck(void) {
|
||||
for (uint32_t phase = 0; phase < Energy->phase_count; phase++) {
|
||||
power_diff_f[phase] = power_diff[phase];
|
||||
}
|
||||
char value_chr[GUISZ];
|
||||
ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%s"), EnergyFormat(value_chr, power_diff_f, 0));
|
||||
ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%s"), EnergyFmt(power_diff_f, 0));
|
||||
}
|
||||
|
||||
uint16_t energy_power_u = (uint16_t)(Energy->active_power[0]);
|
||||
@ -823,6 +845,7 @@ void EnergyMarginCheck(void) {
|
||||
SetAllPower(POWER_ALL_OFF, SRC_MAXENERGY);
|
||||
}
|
||||
}
|
||||
EnergyFmtFree();
|
||||
}
|
||||
|
||||
void EnergyMqttShow(void) {
|
||||
@ -885,10 +908,6 @@ void EnergyEverySecond(void) {
|
||||
\*********************************************************************************************/
|
||||
|
||||
void ResponseCmndEnergyTotalYesterdayToday(void) {
|
||||
char value_chr[GUISZ]; // Used by EnergyFormatIndex
|
||||
char value2_chr[GUISZ];
|
||||
char value3_chr[GUISZ];
|
||||
|
||||
float energy_yesterday_kWh[3];
|
||||
for (uint32_t i = 0; i < Energy->phase_count; i++) {
|
||||
energy_yesterday_kWh[i] = Energy->Settings.energy_yesterday_kWh[i];
|
||||
@ -898,16 +917,19 @@ void ResponseCmndEnergyTotalYesterdayToday(void) {
|
||||
}
|
||||
}
|
||||
|
||||
Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"),
|
||||
Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s"),
|
||||
XdrvMailbox.command,
|
||||
EnergyFormat(value_chr, Energy->total, Settings->flag2.energy_resolution),
|
||||
EnergyFormat(value2_chr, energy_yesterday_kWh, Settings->flag2.energy_resolution),
|
||||
EnergyFormat(value3_chr, Energy->daily_kWh, Settings->flag2.energy_resolution));
|
||||
EnergyFmt(Energy->total, Settings->flag2.energy_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s"),
|
||||
EnergyFmt(energy_yesterday_kWh, Settings->flag2.energy_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY "\":%s"),
|
||||
EnergyFmt(Energy->daily_kWh, Settings->flag2.energy_resolution));
|
||||
if (Energy->local_energy_active_export) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->export_active, Settings->flag2.energy_resolution));
|
||||
EnergyFmt(Energy->export_active, Settings->flag2.energy_resolution));
|
||||
}
|
||||
ResponseJsonEndEnd();
|
||||
EnergyFmtFree();
|
||||
}
|
||||
|
||||
void CmndEnergyDisplay(void) {
|
||||
@ -1345,6 +1367,7 @@ void EnergyDrvInit(void) {
|
||||
EnergySettingsLoad(0);
|
||||
EnergyRtcSettingsLoad();
|
||||
|
||||
EnergyFmtFree();
|
||||
// Energy->voltage_common = false;
|
||||
// Energy->frequency_common = false;
|
||||
// Energy->use_overtemp = false;
|
||||
@ -1399,17 +1422,19 @@ void EnergySnsInit(void) {
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_ENERGY_SNS1[] PROGMEM =
|
||||
"{s}" D_POWERUSAGE_APPARENT "{m}%s " D_UNIT_VA "{e}"
|
||||
"{s}" D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}"
|
||||
const char HTTP_ENERGY_POWERUSAGE_APPARENT[] PROGMEM =
|
||||
"{s}" D_POWERUSAGE_APPARENT "{m}%s " D_UNIT_VA "{e}";
|
||||
const char HTTP_ENERGY_POWERUSAGE_REACTIVE[] PROGMEM =
|
||||
"{s}" D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}";
|
||||
const char HTTP_ENERGY_POWER_FACTOR[] PROGMEM =
|
||||
"{s}" D_POWER_FACTOR "{m}%s{e}";
|
||||
|
||||
const char HTTP_ENERGY_SNS2[] PROGMEM =
|
||||
"{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
|
||||
"{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
|
||||
const char HTTP_ENERGY_TODAY[] PROGMEM =
|
||||
"{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
const char HTTP_ENERGY_YESTERDAY[] PROGMEM =
|
||||
"{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
const char HTTP_ENERGY_TOTAL[] PROGMEM =
|
||||
"{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
|
||||
const char HTTP_ENERGY_SNS3[] PROGMEM =
|
||||
const char HTTP_ENERGY_EXPORT_ACTIVE[] PROGMEM =
|
||||
"{s}" D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
@ -1490,34 +1515,31 @@ void EnergyShow(bool json) {
|
||||
energy_tariff = true;
|
||||
}
|
||||
|
||||
char value_chr[GUISZ]; // Used by EnergyFormatIndex
|
||||
char value2_chr[GUISZ];
|
||||
char value3_chr[GUISZ];
|
||||
|
||||
if (json) {
|
||||
bool show_energy_period = (0 == TasmotaGlobal.tele_period);
|
||||
|
||||
ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s"),
|
||||
GetDateAndTime(DT_ENERGY).c_str(),
|
||||
EnergyFormat(value_chr, Energy->total, Settings->flag2.energy_resolution, 2));
|
||||
EnergyFmt(Energy->total, Settings->flag2.energy_resolution, 2));
|
||||
|
||||
if (energy_tariff) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL D_CMND_TARIFF "\":%s"),
|
||||
EnergyFormat(value_chr, energy_usage_kWh, Settings->flag2.energy_resolution, 6));
|
||||
EnergyFmt(energy_usage_kWh, Settings->flag2.energy_resolution, 6));
|
||||
}
|
||||
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"),
|
||||
EnergyFormat(value_chr, energy_yesterday_kWh, Settings->flag2.energy_resolution, 2),
|
||||
EnergyFormat(value2_chr, Energy->daily_kWh, Settings->flag2.energy_resolution, 2));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s"),
|
||||
EnergyFmt(energy_yesterday_kWh, Settings->flag2.energy_resolution, 2));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY "\":%s"),
|
||||
EnergyFmt(Energy->daily_kWh, Settings->flag2.energy_resolution, 2));
|
||||
|
||||
/*
|
||||
#if defined(SDM630_IMPORT) || defined(SDM72_IMPEXP)
|
||||
if (!isnan(Energy->import_active[0])) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_ACTIVE "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->import_active, Settings->flag2.energy_resolution));
|
||||
EnergyFmt(Energy->import_active, Settings->flag2.energy_resolution));
|
||||
if (energy_tariff) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT D_CMND_TARIFF "\":%s"),
|
||||
EnergyFormat(value_chr, energy_return_kWh, Settings->flag2.energy_resolution, 6));
|
||||
EnergyFmt(energy_return_kWh, Settings->flag2.energy_resolution, 6));
|
||||
}
|
||||
}
|
||||
#endif // SDM630_IMPORT || SDM72_IMPEXP
|
||||
@ -1525,13 +1547,15 @@ void EnergyShow(bool json) {
|
||||
|
||||
if (!isnan(Energy->export_active[0])) {
|
||||
uint32_t single = (!isnan(Energy->export_active[1]) && !isnan(Energy->export_active[2])) ? 0 : 1;
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY_SUM_IMPORT "\":%s,\"" D_JSON_TODAY_SUM_EXPORT "\":%s,\"" D_JSON_EXPORT_ACTIVE "\":%s"),
|
||||
EnergyFormat(value_chr, &Energy->daily_sum_import_balanced, Settings->flag2.energy_resolution, 1),
|
||||
EnergyFormat(value2_chr, &Energy->daily_sum_export_balanced, Settings->flag2.energy_resolution, 1),
|
||||
EnergyFormat(value3_chr, Energy->export_active, Settings->flag2.energy_resolution, single));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY_SUM_IMPORT "\":%s"),
|
||||
EnergyFmt(&Energy->daily_sum_import_balanced, Settings->flag2.energy_resolution, 1));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TODAY_SUM_EXPORT "\":%s"),
|
||||
EnergyFmt(&Energy->daily_sum_export_balanced, Settings->flag2.energy_resolution, 1));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"),
|
||||
EnergyFmt(Energy->export_active, Settings->flag2.energy_resolution, single));
|
||||
if (energy_tariff) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT D_CMND_TARIFF "\":%s"),
|
||||
EnergyFormat(value_chr, energy_return_kWh, Settings->flag2.energy_resolution, 6));
|
||||
EnergyFmt(energy_return_kWh, Settings->flag2.energy_resolution, 6));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1542,30 +1566,32 @@ void EnergyShow(bool json) {
|
||||
Energy->period_kWh[i] = RtcEnergySettings.energy_today_kWh[i];
|
||||
}
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_PERIOD "\":%s"),
|
||||
EnergyFormat(value_chr, energy_period, Settings->flag2.wattage_resolution));
|
||||
EnergyFmt(energy_period, Settings->flag2.wattage_resolution));
|
||||
}
|
||||
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_POWERUSAGE "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->active_power, Settings->flag2.wattage_resolution));
|
||||
EnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution));
|
||||
if (!Energy->type_dc) {
|
||||
if (Energy->current_available && Energy->voltage_available) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_POWERFACTOR "\":%s"),
|
||||
EnergyFormat(value_chr, apparent_power, Settings->flag2.wattage_resolution),
|
||||
EnergyFormat(value2_chr, reactive_power, Settings->flag2.wattage_resolution),
|
||||
EnergyFormat(value3_chr, power_factor, 2));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_APPARENT_POWERUSAGE "\":%s"),
|
||||
EnergyFmt(apparent_power, Settings->flag2.wattage_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_REACTIVE_POWERUSAGE "\":%s"),
|
||||
EnergyFmt(reactive_power, Settings->flag2.wattage_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_POWERFACTOR "\":%s"),
|
||||
EnergyFmt(power_factor, 2));
|
||||
}
|
||||
if (!isnan(Energy->frequency[0])) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->frequency, Settings->flag2.frequency_resolution, frequency_common));
|
||||
EnergyFmt(Energy->frequency, Settings->flag2.frequency_resolution, frequency_common));
|
||||
}
|
||||
}
|
||||
if (Energy->voltage_available) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_VOLTAGE "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->voltage, Settings->flag2.voltage_resolution, voltage_common));
|
||||
EnergyFmt(Energy->voltage, Settings->flag2.voltage_resolution, voltage_common));
|
||||
}
|
||||
if (Energy->current_available) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_CURRENT "\":%s"),
|
||||
EnergyFormat(value_chr, Energy->current, Settings->flag2.current_resolution));
|
||||
EnergyFmt(Energy->current, Settings->flag2.current_resolution));
|
||||
}
|
||||
XnrgCall(FUNC_JSON_APPEND);
|
||||
ResponseJsonEnd();
|
||||
@ -1667,39 +1693,40 @@ void EnergyShow(bool json) {
|
||||
// {s}</th><th></th><th>Head1</th><th></th><th>Head2</th><th></th><th>Head3</th><th></th><th>Head4</th><th></th><td>{e}
|
||||
WSContentSend_P(PSTR("{t}{s}</th><th></th>")); // First column is empty ({t} = <table style='width:100%'>, {s} = <tr><th>)
|
||||
bool no_label = (1 == Energy->phase_count);
|
||||
char number[4];
|
||||
for (uint32_t i = 0; i < Energy->gui_count; i++) {
|
||||
WSContentSend_P(PSTR("<th style='text-align:center'>%s%s<th></th>"),
|
||||
(no_label) ? "" : (label_o) ? "O" : "L",
|
||||
(no_label) ? "" : itoa(relays[Energy->gui_offset +i], value_chr, 10));
|
||||
(no_label) ? "" : itoa(relays[Energy->gui_offset +i], number, 10));
|
||||
}
|
||||
WSContentSend_P(PSTR("<td>{e}")); // Last column is units ({e} = </td></tr>)
|
||||
#endif // USE_ENERGY_COLUMN_GUI
|
||||
if (Energy->voltage_available) {
|
||||
WSContentSend_PD(HTTP_SNS_VOLTAGE, WebEnergyFormat(value_chr, Energy->voltage, Settings->flag2.voltage_resolution, voltage_common));
|
||||
WSContentSend_PD(HTTP_SNS_VOLTAGE, WebEnergyFmt(Energy->voltage, Settings->flag2.voltage_resolution, voltage_common));
|
||||
}
|
||||
if (!Energy->type_dc) {
|
||||
if (!isnan(Energy->frequency[0])) {
|
||||
WSContentSend_PD(PSTR("{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"),
|
||||
WebEnergyFormat(value_chr, Energy->frequency, Settings->flag2.frequency_resolution, frequency_common));
|
||||
WebEnergyFmt(Energy->frequency, Settings->flag2.frequency_resolution, frequency_common));
|
||||
}
|
||||
}
|
||||
if (Energy->current_available) {
|
||||
WSContentSend_PD(HTTP_SNS_CURRENT, WebEnergyFormat(value_chr, Energy->current, Settings->flag2.current_resolution));
|
||||
WSContentSend_PD(HTTP_SNS_CURRENT, WebEnergyFmt(Energy->current, Settings->flag2.current_resolution));
|
||||
}
|
||||
WSContentSend_PD(HTTP_SNS_POWER, WebEnergyFormat(value_chr, Energy->active_power, Settings->flag2.wattage_resolution));
|
||||
WSContentSend_PD(HTTP_SNS_POWER, WebEnergyFmt(Energy->active_power, Settings->flag2.wattage_resolution));
|
||||
if (!Energy->type_dc) {
|
||||
if (Energy->current_available && Energy->voltage_available) {
|
||||
WSContentSend_PD(HTTP_ENERGY_SNS1, WebEnergyFormat(value_chr, apparent_power, Settings->flag2.wattage_resolution),
|
||||
WebEnergyFormat(value2_chr, reactive_power, Settings->flag2.wattage_resolution),
|
||||
WebEnergyFormat(value3_chr, power_factor, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWERUSAGE_APPARENT, WebEnergyFmt(apparent_power, Settings->flag2.wattage_resolution));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWERUSAGE_REACTIVE, WebEnergyFmt(reactive_power, Settings->flag2.wattage_resolution));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWER_FACTOR, WebEnergyFmt(power_factor, 2));
|
||||
}
|
||||
}
|
||||
WSContentSend_PD(HTTP_ENERGY_SNS2, WebEnergyFormat(value_chr, Energy->daily_kWh, Settings->flag2.energy_resolution, 2),
|
||||
WebEnergyFormat(value2_chr, energy_yesterday_kWh, Settings->flag2.energy_resolution, 2),
|
||||
WebEnergyFormat(value3_chr, Energy->total, Settings->flag2.energy_resolution, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_TODAY, WebEnergyFmt(Energy->daily_kWh, Settings->flag2.energy_resolution, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_YESTERDAY, WebEnergyFmt(energy_yesterday_kWh, Settings->flag2.energy_resolution, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_TOTAL, WebEnergyFmt(Energy->total, Settings->flag2.energy_resolution, 2));
|
||||
if (!isnan(Energy->export_active[0])) {
|
||||
uint32_t single = (!isnan(Energy->export_active[1]) && !isnan(Energy->export_active[2])) ? 2 : 1;
|
||||
WSContentSend_PD(HTTP_ENERGY_SNS3, WebEnergyFormat(value_chr, Energy->export_active, Settings->flag2.energy_resolution, single));
|
||||
WSContentSend_PD(HTTP_ENERGY_EXPORT_ACTIVE, WebEnergyFmt(Energy->export_active, Settings->flag2.energy_resolution, single));
|
||||
}
|
||||
|
||||
#ifdef USE_ENERGY_COLUMN_GUI
|
||||
@ -1710,6 +1737,7 @@ void EnergyShow(bool json) {
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
EnergyFmtFree();
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
|
@ -60,6 +60,7 @@
|
||||
#define D_CMND_I2CSTRETCH "I2CStretch"
|
||||
#define D_CMND_I2CCLOCK "I2CClock"
|
||||
#define D_CMND_SERBUFF "SerBufSize"
|
||||
#define D_CMND_SOSET "SOSet"
|
||||
|
||||
const char kDebugCommands[] PROGMEM = "|" // No prefix
|
||||
D_CMND_MEMDUMP "|" D_CMND_CFGDUMP "|" D_CMND_CFGPEEK "|" D_CMND_CFGPOKE "|"
|
||||
@ -77,8 +78,9 @@ const char kDebugCommands[] PROGMEM = "|" // No prefix
|
||||
#endif
|
||||
D_CMND_FLASHDUMP "|" D_CMND_FLASHMODE "|" D_CMND_FREEMEM"|" D_CMND_HELP "|" D_CMND_RTCDUMP "|"
|
||||
#ifdef USE_I2C
|
||||
D_CMND_I2CWRITE "|" D_CMND_I2CREAD "|" D_CMND_I2CSTRETCH "|" D_CMND_I2CCLOCK
|
||||
D_CMND_I2CWRITE "|" D_CMND_I2CREAD "|" D_CMND_I2CSTRETCH "|" D_CMND_I2CCLOCK "|"
|
||||
#endif
|
||||
D_CMND_SOSET
|
||||
;
|
||||
|
||||
void (* const DebugCommand[])(void) PROGMEM = {
|
||||
@ -97,8 +99,9 @@ void (* const DebugCommand[])(void) PROGMEM = {
|
||||
#endif
|
||||
&CmndFlashDump, &CmndFlashMode, &CmndFreemem, &CmndHelp, &CmndRtcDump,
|
||||
#ifdef USE_I2C
|
||||
&CmndI2cWrite, &CmndI2cRead, &CmndI2cStretch, &CmndI2cClock
|
||||
&CmndI2cWrite, &CmndI2cRead, &CmndI2cStretch, &CmndI2cClock,
|
||||
#endif
|
||||
&CmndSoSet
|
||||
};
|
||||
|
||||
uint32_t CPU_loops = 0;
|
||||
@ -209,23 +212,41 @@ extern "C" {
|
||||
extern cont_t* g_pcont;
|
||||
}
|
||||
|
||||
void DebugFreeMem(void)
|
||||
{
|
||||
void DebugFreeMem(void) {
|
||||
register uint32_t *sp asm("a1");
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), ESP.getFreeHeap(), 4 * (sp - g_pcont->stack), XdrvMailbox.data);
|
||||
}
|
||||
|
||||
uint32_t FreeStack(void) {
|
||||
register uint32_t *sp asm("a1");
|
||||
return 4 * (sp - g_pcont->stack);
|
||||
}
|
||||
|
||||
void AddLogMem(const char* function) {
|
||||
register uint32_t *sp asm("a1");
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "== %s FreeRam %d, FreeStack %d"), function, ESP.getFreeHeap(), 4 * (sp - g_pcont->stack));
|
||||
}
|
||||
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
|
||||
void DebugFreeMem(void)
|
||||
{
|
||||
void DebugFreeMem(void) {
|
||||
register uint8_t *sp asm("a1");
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), ESP.getFreeHeap(), sp - pxTaskGetStackStart(NULL), XdrvMailbox.data);
|
||||
}
|
||||
|
||||
uint32_t FreeStack(void) {
|
||||
register uint8_t *sp asm("a1");
|
||||
return sp - pxTaskGetStackStart(NULL);
|
||||
}
|
||||
|
||||
void AddLogMem(const char* function) {
|
||||
register uint8_t *sp asm("a1");
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "== %s FreeRam %d, FreeStack %d"), function, ESP.getFreeHeap(), sp - pxTaskGetStackStart(NULL));
|
||||
}
|
||||
|
||||
#endif // ESP8266 - ESP32
|
||||
|
||||
/*******************************************************************************************/
|
||||
@ -724,6 +745,52 @@ void CmndI2cClock(void)
|
||||
}
|
||||
#endif // USE_I2C
|
||||
|
||||
void CmndSoSet(void) {
|
||||
// Set option data as 32-bit hex value
|
||||
// SoSet1 0x5400401B
|
||||
if ((XdrvMailbox.index >= 1) && (XdrvMailbox.index <= 5)) {
|
||||
uint32_t option = XdrvMailbox.index;
|
||||
uint32_t data;
|
||||
switch (option) {
|
||||
case 1:
|
||||
data = Settings->flag.data; // SetOption0 .. 31
|
||||
break;
|
||||
case 2:
|
||||
data = Settings->flag3.data; // SetOption50 .. 81
|
||||
break;
|
||||
case 3:
|
||||
data = Settings->flag4.data; // SetOption82 .. 113
|
||||
break;
|
||||
case 4:
|
||||
data = Settings->flag5.data; // SetOption114 .. 145
|
||||
break;
|
||||
case 5:
|
||||
data = Settings->flag6.data; // SetOption146 .. 177
|
||||
}
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
char *p;
|
||||
data = strtoul(XdrvMailbox.data, &p, 0); // decimal, octal (0) or hex (0x)
|
||||
switch (option) {
|
||||
case 1:
|
||||
Settings->flag.data = data; // SetOption0 .. 31
|
||||
break;
|
||||
case 2:
|
||||
Settings->flag3.data = data; // SetOption50 .. 81
|
||||
break;
|
||||
case 3:
|
||||
Settings->flag4.data = data; // SetOption82 .. 113
|
||||
break;
|
||||
case 4:
|
||||
Settings->flag5.data = data; // SetOption114 .. 145
|
||||
break;
|
||||
case 5: Settings->flag6.data = data; // SetOption146 .. 177
|
||||
}
|
||||
// TasmotaGlobal.restart_flag = 2; // Activate some SetOptions
|
||||
}
|
||||
Response_P(PSTR("{\"%s%d\":\"%08X\"}"), XdrvMailbox.command, XdrvMailbox.index, data);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
@ -2300,14 +2300,12 @@ void SSPMEnergyShow(bool json) {
|
||||
WSContentSend_PD(HTTP_SNS_VOLTAGE, SSPMEnergyFormat(value_chr, Sspm->voltage[0], Settings->flag2.voltage_resolution, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_SNS_CURRENT, SSPMEnergyFormat(value_chr, Sspm->current[0], Settings->flag2.current_resolution, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_SNS_POWER, SSPMEnergyFormat(value_chr, Sspm->active_power[0], Settings->flag2.wattage_resolution, indirect, offset, count));
|
||||
char valu2_chr[SSPM_SIZE];
|
||||
char valu3_chr[SSPM_SIZE];
|
||||
WSContentSend_PD(HTTP_ENERGY_SNS1, SSPMEnergyFormat(value_chr, Sspm->apparent_power[0], Settings->flag2.wattage_resolution, indirect, offset, count),
|
||||
SSPMEnergyFormat(valu2_chr, Sspm->reactive_power[0], Settings->flag2.wattage_resolution, indirect, offset, count),
|
||||
SSPMEnergyFormat(valu3_chr, Sspm->power_factor[0], 2, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_ENERGY_SNS2, SSPMEnergyFormat(value_chr, Sspm->energy_today[0], Settings->flag2.energy_resolution, indirect, offset, count),
|
||||
SSPMEnergyFormat(valu2_chr, Sspm->Settings.energy_yesterday[0], Settings->flag2.energy_resolution, indirect, offset, count),
|
||||
SSPMEnergyFormat(valu3_chr, Sspm->energy_total[0], Settings->flag2.energy_resolution, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWERUSAGE_APPARENT, SSPMEnergyFormat(value_chr, Sspm->apparent_power[0], Settings->flag2.wattage_resolution, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWERUSAGE_REACTIVE, SSPMEnergyFormat(value_chr, Sspm->reactive_power[0], Settings->flag2.wattage_resolution, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_ENERGY_POWER_FACTOR, SSPMEnergyFormat(value_chr, Sspm->power_factor[0], 2, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_ENERGY_TODAY, SSPMEnergyFormat(value_chr, Sspm->energy_today[0], Settings->flag2.energy_resolution, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_ENERGY_YESTERDAY, SSPMEnergyFormat(value_chr, Sspm->Settings.energy_yesterday[0], Settings->flag2.energy_resolution, indirect, offset, count));
|
||||
WSContentSend_PD(HTTP_ENERGY_TOTAL, SSPMEnergyFormat(value_chr, Sspm->energy_total[0], Settings->flag2.energy_resolution, indirect, offset, count));
|
||||
WSContentSend_P(PSTR("</table><hr/>{t}")); // {t} = <table style='width:100%'> - Define for next FUNC_WEB_SENSOR
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
@ -204,55 +204,32 @@ void Sdm220Reset(void)
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_ENERGY_SDM220[] PROGMEM =
|
||||
"{s}" D_IMPORT_REACTIVE "{m}%s " D_UNIT_KWARH "{e}"
|
||||
"{s}" D_EXPORT_REACTIVE "{m}%s " D_UNIT_KWARH "{e}"
|
||||
const char HTTP_ENERGY_SDM220_IMPORT_REACTIVE[] PROGMEM =
|
||||
"{s}" D_IMPORT_REACTIVE "{m}%s " D_UNIT_KWARH "{e}";
|
||||
const char HTTP_ENERGY_SDM220_EXPORT_REACTIVE[] PROGMEM =
|
||||
"{s}" D_EXPORT_REACTIVE "{m}%s " D_UNIT_KWARH "{e}";
|
||||
const char HTTP_ENERGY_SDM220_PHASE_ANGLE[] PROGMEM =
|
||||
"{s}" D_PHASE_ANGLE "{m}%s " D_UNIT_ANGLE "{e}";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
/*
|
||||
void Sdm220Show(bool json) {
|
||||
if (isnan(Sdm120.import_active)) { return; }
|
||||
|
||||
char import_active_chr[FLOATSZ];
|
||||
dtostrfd(Sdm120.import_active, Settings->flag2.energy_resolution, import_active_chr);
|
||||
char import_reactive_chr[FLOATSZ];
|
||||
dtostrfd(Sdm120.import_reactive, Settings->flag2.energy_resolution, import_reactive_chr);
|
||||
char export_reactive_chr[FLOATSZ];
|
||||
dtostrfd(Sdm120.export_reactive, Settings->flag2.energy_resolution, export_reactive_chr);
|
||||
char phase_angle_chr[FLOATSZ];
|
||||
dtostrfd(Sdm120.phase_angle, 2, phase_angle_chr);
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_ACTIVE "\":%s,\"" D_JSON_IMPORT_REACTIVE "\":%s,\"" D_JSON_EXPORT_REACTIVE "\":%s,\"" D_JSON_PHASE_ANGLE "\":%s"),
|
||||
import_active_chr, import_reactive_chr, export_reactive_chr, phase_angle_chr);
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_ACTIVE "\":%s"),
|
||||
EnergyFmt(&Sdm120.import_active, Settings->flag2.energy_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_REACTIVE "\":%s"),
|
||||
EnergyFmt(&Sdm120.import_reactive, Settings->flag2.energy_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_REACTIVE "\":%s"),
|
||||
EnergyFmt(&Sdm120.export_reactive, Settings->flag2.energy_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_PHASE_ANGLE "\":%s"),
|
||||
EnergyFmt(&Sdm120.phase_angle, 2));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM220, import_reactive_chr, export_reactive_chr, phase_angle_chr);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
*/
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM220_IMPORT_REACTIVE, WebEnergyFmt(&Sdm120.import_reactive, Settings->flag2.energy_resolution, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM220_EXPORT_REACTIVE, WebEnergyFmt(&Sdm120.export_reactive, Settings->flag2.energy_resolution, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM220_PHASE_ANGLE, WebEnergyFmt(&Sdm120.phase_angle, 2));
|
||||
|
||||
void Sdm220Show(bool json) {
|
||||
if (isnan(Sdm120.import_active)) { return; }
|
||||
|
||||
char value_chr[GUISZ];
|
||||
char value2_chr[GUISZ];
|
||||
char value3_chr[GUISZ];
|
||||
char value4_chr[GUISZ];
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_ACTIVE "\":%s,\"" D_JSON_IMPORT_REACTIVE "\":%s,\"" D_JSON_EXPORT_REACTIVE "\":%s,\"" D_JSON_PHASE_ANGLE "\":%s"),
|
||||
EnergyFormat(value_chr, &Sdm120.import_active, Settings->flag2.energy_resolution),
|
||||
EnergyFormat(value2_chr, &Sdm120.import_reactive, Settings->flag2.energy_resolution),
|
||||
EnergyFormat(value3_chr, &Sdm120.export_reactive, Settings->flag2.energy_resolution),
|
||||
EnergyFormat(value4_chr, &Sdm120.phase_angle, 2));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM220, WebEnergyFormat(value_chr, &Sdm120.import_reactive, Settings->flag2.energy_resolution, 2),
|
||||
WebEnergyFormat(value2_chr, &Sdm120.export_reactive, Settings->flag2.energy_resolution, 2),
|
||||
WebEnergyFormat(value3_chr, &Sdm120.phase_angle, 2));
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
|
@ -237,43 +237,22 @@ void FifLEReset(void)
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_ENERGY_LE01MR[] PROGMEM =
|
||||
"{s}" D_TOTAL_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
|
||||
"{s}" D_TOTAL_REACTIVE "{m}%s " D_UNIT_KWARH "{e}"
|
||||
;
|
||||
const char HTTP_ENERGY_LE01MR_TOTAL_ACTIVE[] PROGMEM =
|
||||
"{s}" D_TOTAL_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
const char HTTP_ENERGY_LE01MR_TOTAL_REACTIVE[] PROGMEM =
|
||||
"{s}" D_TOTAL_REACTIVE "{m}%s " D_UNIT_KWARH "{e}";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
/*
|
||||
void FifLEShow(bool json) {
|
||||
char total_reactive_chr[FLOATSZ];
|
||||
dtostrfd(Le01mr.total_reactive, Settings->flag2.energy_resolution, total_reactive_chr);
|
||||
char total_active_chr[FLOATSZ];
|
||||
dtostrfd(Le01mr.total_active, Settings->flag2.energy_resolution, total_active_chr);
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL_ACTIVE "\":%s,\"" D_JSON_TOTAL_REACTIVE "\":%s"),
|
||||
total_active_chr, total_reactive_chr);
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL_ACTIVE "\":%s"),
|
||||
EnergyFmt(&Le01mr.total_active, Settings->flag2.energy_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL_REACTIVE "\":%s"),
|
||||
EnergyFmt(&Le01mr.total_reactive, Settings->flag2.energy_resolution));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_ENERGY_LE01MR, total_active_chr, total_reactive_chr);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void FifLEShow(bool json) {
|
||||
char value_chr[GUISZ];
|
||||
char value2_chr[GUISZ];
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL_ACTIVE "\":%s,\"" D_JSON_TOTAL_REACTIVE "\":%s"),
|
||||
EnergyFormat(value_chr, &Le01mr.total_active, Settings->flag2.energy_resolution),
|
||||
EnergyFormat(value2_chr, &Le01mr.total_reactive, Settings->flag2.energy_resolution));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_ENERGY_LE01MR, WebEnergyFormat(value_chr, &Le01mr.total_active, Settings->flag2.energy_resolution),
|
||||
WebEnergyFormat(value2_chr, &Le01mr.total_reactive, Settings->flag2.energy_resolution));
|
||||
|
||||
WSContentSend_PD(HTTP_ENERGY_LE01MR_TOTAL_ACTIVE, WebEnergyFmt(&Le01mr.total_active, Settings->flag2.energy_resolution));
|
||||
WSContentSend_PD(HTTP_ENERGY_LE01MR_TOTAL_REACTIVE, WebEnergyFmt(&Le01mr.total_reactive, Settings->flag2.energy_resolution));
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
|
@ -177,26 +177,24 @@ void Sdm72Show(bool json) {
|
||||
*/
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_ENERGY_SDM72[] PROGMEM =
|
||||
"{s}" D_EXPORT_POWER "{m}%s" D_UNIT_WATT "{e}"
|
||||
const char HTTP_ENERGY_SDM72_EXPORT_POWER[] PROGMEM =
|
||||
"{s}" D_EXPORT_POWER "{m}%s" D_UNIT_WATT "{e}";
|
||||
const char HTTP_ENERGY_SDM72_IMPORT_POWER[] PROGMEM =
|
||||
"{s}" D_IMPORT_POWER "{m}%s" D_UNIT_WATT "{e}";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
void Sdm72Show(bool json) {
|
||||
if (isnan(Sdm72.total_active)) { return; }
|
||||
|
||||
char value_chr[GUISZ];
|
||||
char value2_chr[GUISZ];
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_POWER "\":%s,\"" D_JSON_IMPORT_POWER "\":%s"),
|
||||
EnergyFormat(value_chr, &Sdm72.export_power, Settings->flag2.wattage_resolution),
|
||||
EnergyFormat(value2_chr, &Sdm72.import_power, Settings->flag2.wattage_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_POWER "\":%s"),
|
||||
EnergyFmt(&Sdm72.export_power, Settings->flag2.wattage_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_POWER "\":%s"),
|
||||
EnergyFmt(&Sdm72.import_power, Settings->flag2.wattage_resolution));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM72, WebEnergyFormat(value_chr, &Sdm72.export_power, Settings->flag2.wattage_resolution),
|
||||
WebEnergyFormat(value2_chr, &Sdm72.import_power, Settings->flag2.wattage_resolution));
|
||||
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM72_EXPORT_POWER, WebEnergyFmt(&Sdm72.export_power, Settings->flag2.wattage_resolution));
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM72_IMPORT_POWER, WebEnergyFmt(&Sdm72.import_power, Settings->flag2.wattage_resolution));
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
|
@ -217,47 +217,27 @@ void Sdm230Reset(void)
|
||||
|
||||
#ifdef SDM230_MORE_REGS
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_ENERGY_SDM230[] PROGMEM =
|
||||
"{s}" D_PHASE_ANGLE "{m}%s " D_UNIT_ANGLE "{e}"
|
||||
"{s}" D_MAX_POWER "{m}%s " D_UNIT_WATT "{e}"
|
||||
const char HTTP_ENERGY_SDM230_PHASE_ANGLE[] PROGMEM =
|
||||
"{s}" D_PHASE_ANGLE "{m}%s " D_UNIT_ANGLE "{e}";
|
||||
const char HTTP_ENERGY_SDM230_MAX_POWER[] PROGMEM =
|
||||
"{s}" D_MAX_POWER "{m}%s " D_UNIT_WATT "{e}";
|
||||
const char HTTP_ENERGY_SDM230_RESETTABLE_TOTAL_ACTIVE[] PROGMEM =
|
||||
"{s}" D_RESETTABLE_TOTAL_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
/*
|
||||
void Sdm230Show(bool json) {
|
||||
char phase_angle_chr[FLOATSZ];
|
||||
dtostrfd(Sdm230.phase_angle, 2, phase_angle_chr);
|
||||
char maximum_demand_chr[FLOATSZ];
|
||||
dtostrfd(Sdm230.maximum_total_demand_power_active, Settings->flag2.wattage_resolution, maximum_demand_chr);
|
||||
char resettable_energy_chr[FLOATSZ];
|
||||
dtostrfd(Sdm230.resettable_total_energy, Settings->flag2.energy_resolution, resettable_energy_chr);
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_PHASE_ANGLE "\":%s,\"" D_JSON_POWERMAX "\":%s,\"" D_JSON_RESETTABLE_TOTAL_ACTIVE "\":%s"),
|
||||
phase_angle_chr, maximum_demand_chr, resettable_energy_chr);
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_PHASE_ANGLE "\":%s"),
|
||||
EnergyFmt(&Sdm230.phase_angle, 2));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_POWERMAX "\":%s"),
|
||||
EnergyFmt(&Sdm230.maximum_total_demand_power_active, Settings->flag2.wattage_resolution));
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_RESETTABLE_TOTAL_ACTIVE "\":%s"),
|
||||
EnergyFmt(&Sdm230.resettable_total_energy, Settings->flag2.energy_resolution));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM230, phase_angle_chr, maximum_demand_chr, resettable_energy_chr);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void Sdm230Show(bool json) {
|
||||
char value_chr[GUISZ];
|
||||
char value2_chr[GUISZ];
|
||||
char value3_chr[GUISZ];
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_PHASE_ANGLE "\":%s,\"" D_JSON_POWERMAX "\":%s,\"" D_JSON_RESETTABLE_TOTAL_ACTIVE "\":%s"),
|
||||
EnergyFormat(value_chr, &Sdm230.phase_angle, 2),
|
||||
EnergyFormat(value2_chr, &Sdm230.maximum_total_demand_power_active, Settings->flag2.wattage_resolution),
|
||||
EnergyFormat(value3_chr, &Sdm230.resettable_total_energy, Settings->flag2.energy_resolution));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM230, WebEnergyFormat(value_chr, &Sdm230.phase_angle, 2),
|
||||
WebEnergyFormat(value2_chr, &Sdm230.maximum_total_demand_power_active, Settings->flag2.wattage_resolution),
|
||||
WebEnergyFormat(value3_chr, &Sdm230.resettable_total_energy, Settings->flag2.energy_resolution));
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM230_PHASE_ANGLE, WebEnergyFmt(&Sdm230.phase_angle, 2));
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM230_MAX_POWER, WebEnergyFmt(&Sdm230.maximum_total_demand_power_active, Settings->flag2.wattage_resolution));
|
||||
WSContentSend_PD(HTTP_ENERGY_SDM230_RESETTABLE_TOTAL_ACTIVE, WebEnergyFmt(&Sdm230.resettable_total_energy, Settings->flag2.energy_resolution));
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
|
@ -746,14 +746,13 @@ const char HTTP_ADE7880_CURRENT[] PROGMEM = "{s}" D_CURRENT_NEUTRAL "{m}%s " D_U
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
void Ade7880Show(bool json) {
|
||||
char value_chr[GUISZ];
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"" D_JSON_CURRENT_NEUTRAL "\":%s"),
|
||||
EnergyFormat(value_chr, &Ade7880.neutral_current, Settings->flag2.current_resolution, 1));
|
||||
EnergyFmt(&Ade7880.neutral_current, Settings->flag2.current_resolution, 1));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
WSContentSend_PD(HTTP_ADE7880_CURRENT, WebEnergyFormat(value_chr, &Ade7880.neutral_current, Settings->flag2.current_resolution, 1));
|
||||
WSContentSend_PD(HTTP_ADE7880_CURRENT, WebEnergyFmt(&Ade7880.neutral_current, Settings->flag2.current_resolution, 1));
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
|
@ -799,7 +799,6 @@ uint32_t EnergyModbusResolution(uint32_t resolution) {
|
||||
}
|
||||
|
||||
void EnergyModbusShow(bool json) {
|
||||
char value_chr[GUISZ];
|
||||
float values[ENERGY_MAX_PHASES];
|
||||
for (uint32_t i = 0; i < NrgMbsParam.user_adds; i++) {
|
||||
uint32_t reg_index = NRG_MBS_MAX_REGS + i;
|
||||
@ -829,15 +828,14 @@ void EnergyModbusShow(bool json) {
|
||||
#ifdef ENERGY_MODBUS_DEBUG_SHOW
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: resolution %d -> %d"), NrgMbsUser[i].resolution, resolution);
|
||||
#endif
|
||||
|
||||
if (json) {
|
||||
ResponseAppend_P(PSTR(",\"%s\":%s"), NrgMbsUser[i].json_name, EnergyFormat(value_chr, values, resolution, single));
|
||||
ResponseAppend_P(PSTR(",\"%s\":%s"), NrgMbsUser[i].json_name, EnergyFmt(values, resolution, single));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
if (strlen(NrgMbsUser[i].gui_name)) { // Skip empty GUI names
|
||||
WSContentSend_PD(PSTR("{s}%s{m}%s %s{e}"),
|
||||
NrgMbsUser[i].gui_name,
|
||||
WebEnergyFormat(value_chr, values, resolution, single),
|
||||
WebEnergyFmt(values, resolution, single),
|
||||
NrgMbsUser[i].gui_unit);
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
|
Loading…
x
Reference in New Issue
Block a user