Add Energy Export if available

Add Energy Export if available (#6282)
This commit is contained in:
Theo Arends 2019-09-10 12:31:08 +02:00
parent b811956d2f
commit 0e3a88bbe2
3 changed files with 52 additions and 30 deletions

View File

@ -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;

View File

@ -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} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
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
}

View File

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