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
}
}