diff --git a/sonoff/settings.h b/sonoff/settings.h index a466f0a4d..eb58877cb 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -181,8 +181,8 @@ typedef struct { uint32_t usage1_kWhtoday; uint32_t return1_kWhtotal; uint32_t return2_kWhtotal; - uint32_t last_usage_kWhtotal; uint32_t last_return_kWhtotal; + uint32_t free; } EnergyUsage; diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index 89edd5981..007aa871f 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -82,6 +82,7 @@ struct ENERGY { float daily = 0; // 123.123 kWh float total = 0; // 12345.12345 kWh tariff 1 + 2 float total1 = 0; // 12345.12345 kWh tariff 1 - off-peak + float export_active = NAN; // 123.123 KWh unsigned long kWhtoday_delta = 0; // 1212312345 Wh 10^-5 (deca micro Watt hours) - Overflows to Energy.kWhtoday (HLW and CSE only) unsigned long kWhtoday_offset = 0; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = Energy.daily @@ -132,6 +133,12 @@ void EnergyUpdateToday(void) uint32_t energy_diff = Energy.kWhtoday_offset + Energy.kWhtoday - RtcSettings.energy_kWhtoday; + uint32_t return_diff = 0; + if (!isnan(Energy.export_active)) { + return_diff = (uint32_t)(Energy.export_active * 1000) - RtcSettings.energy_usage.last_return_kWhtotal; + RtcSettings.energy_usage.last_return_kWhtotal = (uint32_t)(Energy.export_active * 1000); + } + RtcSettings.energy_kWhtoday = Energy.kWhtoday_offset + Energy.kWhtoday; Energy.daily = (float)(RtcSettings.energy_kWhtoday) / 100000; Energy.total = (float)(RtcSettings.energy_kWhtotal + RtcSettings.energy_kWhtoday) / 100000; @@ -142,7 +149,10 @@ void EnergyUpdateToday(void) (RtcTime.day_of_week == 7))) ) { RtcSettings.energy_usage.usage1_kWhtoday += energy_diff; + RtcSettings.energy_usage.return1_kWhtotal += return_diff; Energy.total1 = (float)(RtcSettings.energy_usage.usage1_kWhtotal + RtcSettings.energy_usage.usage1_kWhtoday) / 100000; + } else { + RtcSettings.energy_usage.return2_kWhtotal += return_diff; } } @@ -216,8 +226,7 @@ void EnergySaveState(void) Settings.energy_kWhtoday = RtcSettings.energy_kWhtoday; Settings.energy_kWhtotal = RtcSettings.energy_kWhtotal; - Settings.energy_usage.usage1_kWhtoday = RtcSettings.energy_usage.usage1_kWhtoday; - Settings.energy_usage.usage1_kWhtotal = RtcSettings.energy_usage.usage1_kWhtotal; + Settings.energy_usage = RtcSettings.energy_usage; } #ifdef USE_ENERGY_MARGIN_DETECTION @@ -406,6 +415,7 @@ void EnergyOverTempCheck() if (!isnan(Energy.frequency)) { Energy.frequency = 0; } if (!isnan(Energy.power_factor)) { Energy.power_factor = 0; } Energy.start_energy = 0; + if (!isnan(Energy.export_active)) { Energy.export_active = 0; } XnrgCall(FUNC_ENERGY_RESET); } @@ -439,6 +449,7 @@ void CmndEnergyReset(void) if (p != XdrvMailbox.data) { switch (XdrvMailbox.index) { case 1: + // Reset Energy Today Energy.kWhtoday_offset = lnum *100; Energy.kWhtoday = 0; Energy.kWhtoday_delta = 0; @@ -451,9 +462,11 @@ void CmndEnergyReset(void) } break; case 2: + // Reset Energy Yesterday Settings.energy_kWhyesterday = lnum *100; break; case 3: + // Reset Energy Total RtcSettings.energy_kWhtotal = lnum *100; Settings.energy_kWhtotal = RtcSettings.energy_kWhtotal; Energy.total = (float)(RtcSettings.energy_kWhtotal + Energy.kWhtoday_offset + Energy.kWhtoday) / 100000; @@ -733,14 +746,13 @@ 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}" "{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = , {m} = , {e} = + +const char HTTP_ENERGY_SNS3[] PROGMEM = + "{s}" D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; #endif // USE_WEBSERVER void EnergyShow(bool json) { - char speriod[20]; - - bool show_energy_period = (0 == tele_period); - float power_factor = Energy.power_factor; char apparent_power_chr[FLOATSZ]; @@ -794,19 +806,28 @@ void EnergyShow(bool json) dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr); char energy_total_chr[FLOATSZ]; dtostrfd(Energy.total, Settings.flag2.energy_resolution, energy_total_chr); - - float energy = 0; - char energy_period_chr[FLOATSZ]; - if (show_energy_period) { - if (Energy.period) energy = (float)(RtcSettings.energy_kWhtoday - Energy.period) / 100; - Energy.period = RtcSettings.energy_kWhtoday; - dtostrfd(energy, Settings.flag2.wattage_resolution, energy_period_chr); - snprintf_P(speriod, sizeof(speriod), PSTR(",\"" D_JSON_PERIOD "\":%s"), energy_period_chr); - } + char export_active_chr[FLOATSZ]; + dtostrfd(Energy.export_active, Settings.flag2.energy_resolution, export_active_chr); if (json) { - ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s%s,\"" D_JSON_POWERUSAGE "\":%s"), - GetDateAndTime(DT_ENERGY).c_str(), energy_total_chr, energy_yesterday_chr, energy_daily_chr, (show_energy_period) ? speriod : "", active_power_chr); + bool show_energy_period = (0 == tele_period); + + ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"), + GetDateAndTime(DT_ENERGY).c_str(), energy_total_chr, energy_yesterday_chr, energy_daily_chr); + if (!isnan(Energy.export_active)) { + ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"), export_active_chr); + } + if (show_energy_period) { + float energy = 0; + if (Energy.period) { + energy = (float)(RtcSettings.energy_kWhtoday - Energy.period) / 100; + } + Energy.period = RtcSettings.energy_kWhtoday; + char energy_period_chr[FLOATSZ]; + dtostrfd(energy, Settings.flag2.wattage_resolution, energy_period_chr); + ResponseAppend_P(PSTR(",\"" D_JSON_PERIOD "\":%s"), energy_period_chr); + } + ResponseAppend_P(PSTR(",\"" D_JSON_POWERUSAGE "\":%s"), active_power_chr); 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"), @@ -833,8 +854,11 @@ void EnergyShow(bool json) dtostrfd((Energy.total - Energy.total1) * 1000, 1, energy_total_chr); // Tariff2 char energy_total1_chr[FLOATSZ]; dtostrfd(Energy.total1 * 1000, 1, energy_total1_chr); // Tariff1 - char energy_non[2] = "0"; - DomoticzSensorP1SmartMeter(energy_total1_chr, energy_total_chr, energy_non, energy_non, (int)Energy.active_power); + char return1_total_chr[FLOATSZ]; + dtostrfd(RtcSettings.energy_usage.return1_kWhtotal, 1, return1_total_chr); + char return2_total_chr[FLOATSZ]; + dtostrfd(RtcSettings.energy_usage.return2_kWhtotal, 1, return2_total_chr); + DomoticzSensorP1SmartMeter(energy_total1_chr, energy_total_chr, return1_total_chr, return2_total_chr, (int)Energy.active_power); if (Energy.voltage_available) { DomoticzSensor(DZ_VOLTAGE, voltage_chr); // Voltage @@ -877,6 +901,10 @@ void EnergyShow(bool json) } } WSContentSend_PD(HTTP_ENERGY_SNS2, energy_daily_chr, energy_yesterday_chr, energy_total_chr); + if (!isnan(Energy.export_active)) { + WSContentSend_PD(HTTP_ENERGY_SNS3, export_active_chr); + } + XnrgCall(FUNC_WEB_SENSOR); #endif // USE_WEBSERVER } diff --git a/sonoff/xnrg_08_sdm120.ino b/sonoff/xnrg_08_sdm120.ino index 3182ddfc1..472886442 100644 --- a/sonoff/xnrg_08_sdm120.ino +++ b/sonoff/xnrg_08_sdm120.ino @@ -62,7 +62,6 @@ const uint16_t sdm120_start_addresses[] { struct SDM120 { float total_active = 0; float import_active = NAN; - float export_active = 0; float import_reactive = 0; float export_reactive = 0; float phase_angle = 0; @@ -136,7 +135,7 @@ void SDM120Every250ms(void) break; case 9: - Sdm120.export_active = value; // 6.216 kWh + Energy.export_active = value; // 6.216 kWh break; case 10: @@ -199,7 +198,6 @@ void Sdm220Reset(void) if (isnan(Sdm120.import_active)) { return; } Sdm120.import_active = 0; - Sdm120.export_active = 0; Sdm120.import_reactive = 0; Sdm120.export_reactive = 0; Sdm120.phase_angle = 0; @@ -207,8 +205,6 @@ void Sdm220Reset(void) #ifdef USE_WEBSERVER const char HTTP_ENERGY_SDM220[] PROGMEM = - "{s}" D_IMPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}" - "{s}" D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}" "{s}" D_IMPORT_REACTIVE "{m}%s " D_UNIT_KWARH "{e}" "{s}" D_EXPORT_REACTIVE "{m}%s " D_UNIT_KWARH "{e}" "{s}" D_PHASE_ANGLE "{m}%s " D_UNIT_ANGLE "{e}"; @@ -220,8 +216,6 @@ void Sdm220Show(bool json) char import_active_chr[FLOATSZ]; dtostrfd(Sdm120.import_active, Settings.flag2.energy_resolution, import_active_chr); - char export_active_chr[FLOATSZ]; - dtostrfd(Sdm120.export_active, Settings.flag2.energy_resolution, export_active_chr); char import_reactive_chr[FLOATSZ]; dtostrfd(Sdm120.import_reactive, Settings.flag2.energy_resolution, import_reactive_chr); char export_reactive_chr[FLOATSZ]; @@ -230,11 +224,11 @@ void Sdm220Show(bool json) dtostrfd(Sdm120.phase_angle, 2, phase_angle_chr); if (json) { - ResponseAppend_P(PSTR(",\"" D_JSON_IMPORT_ACTIVE "\":%s,\"" D_JSON_EXPORT_ACTIVE "\":%s,\"" D_JSON_IMPORT_REACTIVE "\":%s,\"" D_JSON_EXPORT_REACTIVE "\":%s,\"" D_JSON_PHASE_ANGLE "\":%s"), - import_active_chr, export_active_chr, import_reactive_chr, export_reactive_chr, phase_angle_chr); + 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); #ifdef USE_WEBSERVER } else { - WSContentSend_PD(HTTP_ENERGY_SDM220, import_active_chr, export_active_chr, import_reactive_chr, export_reactive_chr, phase_angle_chr); + WSContentSend_PD(HTTP_ENERGY_SDM220, import_reactive_chr, export_reactive_chr, phase_angle_chr); #endif // USE_WEBSERVER } }