diff --git a/CHANGELOG.md b/CHANGELOG.md index f36b48ae2..797e4303c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,9 @@ All notable changes to this project will be documented in this file. ### Changed - Consolidate three RTC chip drivers (DS3231, BM8563, PCF85363) into one driver updating RTC as soon as possible after restart - Removed command ``Sensor33`` and replaced by ``RtcNtpserver`` -- define ``USE_RTC_ADDR`` into ``DS3231_ADDRESS`` +- DS3231 I2C address define ``USE_RTC_ADDR`` into ``DS3231_ADDRESS`` - NeoPool remove ambiguous device color names +- Display of energy values in GUI use columns when define ``USE_ENERGY_COLUMN_GUI`` is enabled (default) ### Fixed - NeoPool NPBit and NPRead/NPReadL output diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2a305c6fc..1805121ce 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -132,7 +132,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Extent number of pulsetimers from 8 to 32 [#8266](https://github.com/arendst/Tasmota/issues/8266) - Consolidate three RTC chip drivers (DS3231, BM8563, PCF85363) into one driver updating RTC as soon as possible after restart - Removed command ``Sensor33`` and replaced by ``RtcNtpserver`` -- define ``USE_RTC_ADDR`` into ``DS3231_ADDRESS`` +- DS3231 I2C address define ``USE_RTC_ADDR`` into ``DS3231_ADDRESS`` +- Display of energy values in GUI use columns when define ``USE_ENERGY_COLUMN_GUI`` is enabled (default) - ESP32 Arduino core from v2.0.2.2 to v2.0.2.3 - ESP32 LVGL library from v8.1.0 to v8.2.0 - ESP32 NimBLE library from v1.3.3 to v1.3.6 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index bf8373714..50fdc7d81 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -775,6 +775,7 @@ // -- Power monitoring sensors -------------------- #define USE_ENERGY_SENSOR // Add support for Energy Monitors (+14k code) +#define USE_ENERGY_COLUMN_GUI // Add support for column display in GUI (+0k5 code) #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) #define USE_ENERGY_POWER_LIMIT // Add additional support for Energy Power Limit detection (+1k2 code) #define USE_ENERGY_DUMMY // Add support for dummy Energy monitor allowing user values (+0k7 code) diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index f5a3f2aaf..406aace85 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -370,7 +370,7 @@ enum LightTypes { LT_BASIC, LT_PWM1, LT_PWM2, LT_PWM3, LT_PWM4, LT enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_PIN_STATE, FUNC_MODULE_INIT, FUNC_PRE_INIT, FUNC_INIT, FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_100_MSECOND, FUNC_EVERY_200_MSECOND, FUNC_EVERY_250_MSECOND, FUNC_EVERY_SECOND, FUNC_SAVE_SETTINGS, FUNC_SAVE_AT_MIDNIGHT, FUNC_SAVE_BEFORE_RESTART, - FUNC_AFTER_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_SENSOR, FUNC_COMMAND, FUNC_COMMAND_SENSOR, FUNC_COMMAND_DRIVER, + FUNC_AFTER_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_SENSOR, FUNC_WEB_COL_SENSOR, FUNC_COMMAND, FUNC_COMMAND_SENSOR, FUNC_COMMAND_DRIVER, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SET_DEVICE_POWER, FUNC_SHOW_SENSOR, FUNC_ANY_KEY, FUNC_ENERGY_EVERY_SECOND, FUNC_ENERGY_RESET, diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index 515075157..d7b668d78 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -71,8 +71,6 @@ void (* const EnergyCommand[])(void) PROGMEM = { #endif // USE_ENERGY_MARGIN_DETECTION &CmndEnergyToday, &CmndEnergyYesterday, &CmndEnergyTotal, &CmndEnergyUsage, &CmndEnergyExport, &CmndTariff}; -const char kEnergyPhases[] PROGMEM = "|%*_f / %*_f|%*_f / %*_f / %*_f||[%*_f,%*_f]|[%*_f,%*_f,%*_f]"; - struct ENERGY { float voltage[ENERGY_MAX_PHASES]; // 123.1 V float current[ENERGY_MAX_PHASES]; // 123.123 A @@ -134,39 +132,68 @@ Ticker ticker_energy; /********************************************************************************************/ -char* EnergyFormatIndex(char* result, float* input, uint32_t resolution, bool json, uint32_t index, bool single = false) { - char layout[20]; - GetTextIndexed(layout, sizeof(layout), (index -1) + (ENERGY_MAX_PHASES * json), kEnergyPhases); - switch (index) { - case 2: - ext_snprintf_P(result, FLOATSZ * ENERGY_MAX_PHASES, layout, resolution, &input[0], resolution, &input[1]); - break; - case 3: - ext_snprintf_P(result, FLOATSZ * ENERGY_MAX_PHASES, layout, resolution, &input[0], resolution, &input[1], resolution, &input[2]); - break; - default: - ext_snprintf_P(result, FLOATSZ * ENERGY_MAX_PHASES, PSTR("%*_f"), resolution, &input[0]); +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) { + // 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 - 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] + uint32_t index = (single > 3) ? single &0x03 : (0 == single) ? Energy.phase_count : 1; // 1,2,3 + if (single > 2) { single = 0; } // 0,1,2 + if (single > 1) { + float input_sum = 0.0; + if (!Settings->flag5.energy_phase) { // SetOption129 - (Energy) Show phase information + for (uint32_t i = 0; i < Energy.phase_count; i++) { + input_sum += input[i]; + } + input = &input_sum; + } + } + result[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)?"":"]":""); } return result; } -char* EnergyFormat(char* result, float* input, uint32_t resolution, bool json, bool single = false) { - uint8_t index = (single) ? 1 : Energy.phase_count; // 1,2,3 - return EnergyFormatIndex(result, input, resolution, json, index, single); -} - -char* EnergyFormatSum(char* result, float* input, uint32_t resolution, bool json, bool single = false) { - uint8_t index = (single) ? 1 : Energy.phase_count; // 1,2,3 - float input_sum = 0.0; - if (!Settings->flag5.energy_phase) { - for (uint32_t i = 0; i < index; i++) { - input_sum += input[i]; +#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) { + // 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 - xx or single column using colspan (if needed) + if (single > 1) { // Sum and/or Single column + float input_sum = 0.0; + if (!Settings->flag5.energy_phase) { // SetOption129 - (Energy) Show phase information + for (uint32_t i = 0; i < Energy.phase_count; i++) { + input_sum += input[i]; + } + input = &input_sum; + } else { + single = 0; } - input = &input_sum; - index = 1; } - return EnergyFormatIndex(result, input, resolution, json, index, single); +#ifdef USE_ENERGY_COLUMN_GUI + if ((Energy.phase_count > 1) && single) { // Need to set colspan so need a new column + ext_snprintf_P(result, TOPSZ, PSTR("%*_f"), Energy.phase_count, resolution, &input[0]); + } else { + ext_snprintf_P(result, TOPSZ, PSTR("")); // Skip first column + for (uint32_t i = 0; i < Energy.phase_count; i++) { + ext_snprintf_P(result, TOPSZ, PSTR("%s%*_f"), result, resolution, &input[i]); + } + } +#else // not USE_ENERGY_COLUMN_GUI + uint32_t index = (single) ? 1 : Energy.phase_count; // 1,2,3 + result[0] = '\0'; + for (uint32_t i = 0; i < index; i++) { + ext_snprintf_P(result, TOPSZ, PSTR("%s%s%*_f"), result, (i)?" / ":"", resolution, &input[i]); + } +#endif // USE_ENERGY_COLUMN_GUI + return result; } +#endif // USE_WEBSERVER /********************************************************************************************/ @@ -398,20 +425,12 @@ void EnergyMarginCheck(void) Energy.power_history[phase][2] = active_power; } if (jsonflg) { -/* - char power_diff_chr[Energy.phase_count][FLOATSZ]; - for (uint32_t phase = 0; phase < Energy.phase_count; phase++) { - dtostrfd(power_diff[phase], 0, power_diff_chr[phase]); - } - char value_chr[FLOATSZ * ENERGY_MAX_PHASES]; - ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%s"), EnergyFormat(value_chr, power_diff_chr[0], 1)); -*/ float power_diff_f[Energy.phase_count]; for (uint32_t phase = 0; phase < Energy.phase_count; phase++) { power_diff_f[phase] = power_diff[phase]; } - char value_chr[FLOATSZ * ENERGY_MAX_PHASES]; - ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%s"), EnergyFormat(value_chr, power_diff_f, 0, 1)); + char value_chr[TOPSZ]; + ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%s"), EnergyFormat(value_chr, power_diff_f, 0)); } uint16_t energy_power_u = (uint16_t)(Energy.active_power[0]); @@ -590,9 +609,9 @@ void EnergyCommandCalResponse(uint32_t nvalue) { } void ResponseCmndEnergyTotalYesterdayToday(void) { - char value_chr[FLOATSZ * ENERGY_MAX_PHASES]; // Used by EnergyFormatIndex - char value2_chr[FLOATSZ * ENERGY_MAX_PHASES]; - char value3_chr[FLOATSZ * ENERGY_MAX_PHASES]; + 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++) { @@ -602,9 +621,9 @@ void ResponseCmndEnergyTotalYesterdayToday(void) { Response_P(PSTR("{\"%s\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s}}"), XdrvMailbox.command, - EnergyFormat(value_chr, Energy.total, Settings->flag2.energy_resolution, true), - EnergyFormat(value2_chr, energy_yesterday_ph, Settings->flag2.energy_resolution, true), - EnergyFormat(value3_chr, Energy.daily, Settings->flag2.energy_resolution, true)); + 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)); } void CmndEnergyTotal(void) { @@ -1089,34 +1108,34 @@ void EnergyShow(bool json) { energy_tariff = true; } - char value_chr[FLOATSZ * ENERGY_MAX_PHASES]; // Used by EnergyFormatIndex - char value2_chr[FLOATSZ * ENERGY_MAX_PHASES]; - char value3_chr[FLOATSZ * ENERGY_MAX_PHASES]; + char value_chr[TOPSZ]; // Used by EnergyFormatIndex + char value2_chr[TOPSZ]; + char value3_chr[TOPSZ]; 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(), - EnergyFormatSum(value_chr, Energy.total, Settings->flag2.energy_resolution, json)); + EnergyFormat(value_chr, Energy.total, Settings->flag2.energy_resolution, 2)); if (energy_tariff) { ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL D_CMND_TARIFF "\":%s"), - EnergyFormatIndex(value_chr, energy_usage, Settings->flag2.energy_resolution, json, 2)); + EnergyFormat(value_chr, energy_usage, Settings->flag2.energy_resolution, 6)); } ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"), - EnergyFormatSum(value_chr, energy_yesterday_ph, Settings->flag2.energy_resolution, json), - EnergyFormatSum(value2_chr, Energy.daily, Settings->flag2.energy_resolution, json)); + EnergyFormat(value_chr, energy_yesterday_ph, Settings->flag2.energy_resolution, 2), + EnergyFormat(value2_chr, 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, json)); + EnergyFormat(value_chr, Energy.import_active, Settings->flag2.energy_resolution)); if (energy_tariff) { ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT D_CMND_TARIFF "\":%s"), - EnergyFormatIndex(value_chr, energy_return, Settings->flag2.energy_resolution, json, 2)); + EnergyFormat(value_chr, energy_return, Settings->flag2.energy_resolution, 6)); } } #endif // SDM630_IMPORT || SDM72_IMPEXP @@ -1124,10 +1143,10 @@ void EnergyShow(bool json) { if (!isnan(Energy.export_active[0])) { ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"), - EnergyFormat(value_chr, Energy.export_active, Settings->flag2.energy_resolution, json)); + EnergyFormat(value_chr, Energy.export_active, Settings->flag2.energy_resolution)); if (energy_tariff) { ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT D_CMND_TARIFF "\":%s"), - EnergyFormatIndex(value_chr, energy_return, Settings->flag2.energy_resolution, json, 2)); + EnergyFormat(value_chr, energy_return, Settings->flag2.energy_resolution, 6)); } } @@ -1138,30 +1157,30 @@ 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, json)); + EnergyFormat(value_chr, energy_period, Settings->flag2.wattage_resolution)); } ResponseAppend_P(PSTR(",\"" D_JSON_POWERUSAGE "\":%s"), - EnergyFormat(value_chr, Energy.active_power, Settings->flag2.wattage_resolution, json)); + EnergyFormat(value_chr, 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, json), - EnergyFormat(value2_chr, reactive_power, Settings->flag2.wattage_resolution, json), - EnergyFormat(value3_chr, power_factor, 2, json)); + EnergyFormat(value_chr, apparent_power, Settings->flag2.wattage_resolution), + EnergyFormat(value2_chr, reactive_power, Settings->flag2.wattage_resolution), + EnergyFormat(value3_chr, power_factor, 2)); } if (!isnan(Energy.frequency[0])) { ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%s"), - EnergyFormat(value_chr, Energy.frequency, Settings->flag2.frequency_resolution, json, Energy.frequency_common)); + EnergyFormat(value_chr, Energy.frequency, Settings->flag2.frequency_resolution, Energy.frequency_common)); } } if (Energy.voltage_available) { ResponseAppend_P(PSTR(",\"" D_JSON_VOLTAGE "\":%s"), - EnergyFormat(value_chr, Energy.voltage, Settings->flag2.voltage_resolution, json, Energy.voltage_common)); + EnergyFormat(value_chr, Energy.voltage, Settings->flag2.voltage_resolution, Energy.voltage_common)); } if (Energy.current_available) { ResponseAppend_P(PSTR(",\"" D_JSON_CURRENT "\":%s"), - EnergyFormat(value_chr, Energy.current, Settings->flag2.current_resolution, json)); + EnergyFormat(value_chr, Energy.current, Settings->flag2.current_resolution)); } XnrgCall(FUNC_JSON_APPEND); ResponseJsonEnd(); @@ -1209,32 +1228,45 @@ void EnergyShow(bool json) { #endif // USE_KNX #ifdef USE_WEBSERVER } else { +#ifdef USE_ENERGY_COLUMN_GUI + // Need a new table supporting more columns + WSContentSend_P(PSTR("{t}{s}")); // First column is empty ({t} = , {s} = ) +#endif // USE_ENERGY_COLUMN_GUI if (Energy.voltage_available) { - WSContentSend_PD(HTTP_SNS_VOLTAGE, EnergyFormat(value_chr, Energy.voltage, Settings->flag2.voltage_resolution, json, Energy.voltage_common)); + WSContentSend_PD(HTTP_SNS_VOLTAGE, WebEnergyFormat(value_chr, Energy.voltage, Settings->flag2.voltage_resolution, Energy.voltage_common)); } if (!Energy.type_dc) { if (!isnan(Energy.frequency[0])) { WSContentSend_PD(PSTR("{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"), - EnergyFormat(value_chr, Energy.frequency, Settings->flag2.frequency_resolution, json, Energy.frequency_common)); + WebEnergyFormat(value_chr, Energy.frequency, Settings->flag2.frequency_resolution, Energy.frequency_common)); } } if (Energy.current_available) { - WSContentSend_PD(HTTP_SNS_CURRENT, EnergyFormat(value_chr, Energy.current, Settings->flag2.current_resolution, json)); + WSContentSend_PD(HTTP_SNS_CURRENT, WebEnergyFormat(value_chr, Energy.current, Settings->flag2.current_resolution)); } - WSContentSend_PD(HTTP_SNS_POWER, EnergyFormat(value_chr, Energy.active_power, Settings->flag2.wattage_resolution, json)); + WSContentSend_PD(HTTP_SNS_POWER, WebEnergyFormat(value_chr, Energy.active_power, Settings->flag2.wattage_resolution)); if (!Energy.type_dc) { if (Energy.current_available && Energy.voltage_available) { - WSContentSend_PD(HTTP_ENERGY_SNS1, EnergyFormat(value_chr, apparent_power, Settings->flag2.wattage_resolution, json), - EnergyFormat(value2_chr, reactive_power, Settings->flag2.wattage_resolution, json), - EnergyFormat(value3_chr, power_factor, 2, json)); + 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_SNS2, EnergyFormatSum(value_chr, Energy.daily, Settings->flag2.energy_resolution, json), - EnergyFormatSum(value2_chr, energy_yesterday_ph, Settings->flag2.energy_resolution, json), - EnergyFormatSum(value3_chr, Energy.total, Settings->flag2.energy_resolution, json)); + 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)); 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, WebEnergyFormat(value_chr, Energy.export_active, Settings->flag2.energy_resolution, 2)); } +#ifdef USE_ENERGY_COLUMN_GUI + XnrgCall(FUNC_WEB_COL_SENSOR); + WSContentSend_P(PSTR("
) + bool no_label = Energy.voltage_common || (1 == Energy.phase_count); + for (uint32_t i = 0; i < Energy.phase_count; i++) { + WSContentSend_P(PSTR("%s%s"), (no_label)?"":"L", (no_label)?"":itoa(i +1, value_chr, 10)); + } + WSContentSend_P(PSTR("{e}")); // Last column is units ({e} =
{t}")); // {t} = - Define for next FUNC_WEB_SENSOR +#endif // USE_ENERGY_COLUMN_GUI XnrgCall(FUNC_WEB_SENSOR); #endif // USE_WEBSERVER } diff --git a/tasmota/xnrg_08_sdm120.ino b/tasmota/xnrg_08_sdm120.ino index f67ec69d9..34649da13 100644 --- a/tasmota/xnrg_08_sdm120.ino +++ b/tasmota/xnrg_08_sdm120.ino @@ -210,8 +210,8 @@ const char HTTP_ENERGY_SDM220[] PROGMEM = "{s}" D_PHASE_ANGLE "{m}%s " D_UNIT_ANGLE "{e}"; #endif // USE_WEBSERVER -void Sdm220Show(bool json) -{ +/* +void Sdm220Show(bool json) { if (isnan(Sdm120.import_active)) { return; } char import_active_chr[FLOATSZ]; @@ -232,6 +232,30 @@ void Sdm220Show(bool json) #endif // USE_WEBSERVER } } +*/ + +void Sdm220Show(bool json) { + if (isnan(Sdm120.import_active)) { return; } + + char value_chr[TOPSZ]; + char value2_chr[TOPSZ]; + char value3_chr[TOPSZ]; + char value4_chr[TOPSZ]; + + 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 + } +} /*********************************************************************************************\ * Interface @@ -249,9 +273,15 @@ bool Xnrg08(uint8_t function) Sdm220Show(1); break; #ifdef USE_WEBSERVER +#ifdef USE_ENERGY_COLUMN_GUI + case FUNC_WEB_COL_SENSOR: + Sdm220Show(0); + break; +#else // not USE_ENERGY_COLUMN_GUI case FUNC_WEB_SENSOR: Sdm220Show(0); break; +#endif // USE_ENERGY_COLUMN_GUI #endif // USE_WEBSERVER case FUNC_ENERGY_RESET: Sdm220Reset();