Browse Source

Use energy data from HLW8012.

fastled
Hermann Kraus 7 years ago
parent
commit
b2cab9684f
3 changed files with 44 additions and 11 deletions
  1. +9
    -1
      code/espurna/config/general.h
  2. +21
    -3
      code/espurna/power.ino
  3. +14
    -7
      code/espurna/power_hlw8012.ino

+ 9
- 1
code/espurna/config/general.h View File

@ -430,6 +430,7 @@ PROGMEM const char* const custom_reset_string[] = {
#define MQTT_TOPIC_POWER_REACTIVE "reactive" #define MQTT_TOPIC_POWER_REACTIVE "reactive"
#define MQTT_TOPIC_POWER_FACTOR "factor" #define MQTT_TOPIC_POWER_FACTOR "factor"
#define MQTT_TOPIC_ENERGY "energy" #define MQTT_TOPIC_ENERGY "energy"
#define MQTT_TOPIC_ENERGY_TOTAL "energy_total"
// Light module // Light module
#define MQTT_TOPIC_CHANNEL "channel" #define MQTT_TOPIC_CHANNEL "channel"
@ -523,6 +524,12 @@ PROGMEM const char* const custom_reset_string[] = {
#define POWER_HAS_ACTIVE 0 #define POWER_HAS_ACTIVE 0
#endif #endif
#if (POWER_PROVIDER == POWER_PROVIDER_HLW8012)
#define POWER_HAS_ENERGY 1
#else
#define POWER_HAS_ENERGY 0
#endif
#define POWER_VOLTAGE 230 // Default voltage #define POWER_VOLTAGE 230 // Default voltage
#define POWER_READ_INTERVAL 6000 // Default reading interval (6 seconds) #define POWER_READ_INTERVAL 6000 // Default reading interval (6 seconds)
#define POWER_REPORT_INTERVAL 60000 // Default report interval (1 minute) #define POWER_REPORT_INTERVAL 60000 // Default report interval (1 minute)
@ -530,7 +537,8 @@ PROGMEM const char* const custom_reset_string[] = {
#define POWER_CURRENT_DECIMALS 2 // Decimals for current values #define POWER_CURRENT_DECIMALS 2 // Decimals for current values
#define POWER_VOLTAGE_DECIMALS 0 // Decimals for voltage values #define POWER_VOLTAGE_DECIMALS 0 // Decimals for voltage values
#define POWER_POWER_DECIMALS 0 // Decimals for power values #define POWER_POWER_DECIMALS 0 // Decimals for power values
#define POWER_ENERGY_FACTOR (POWER_REPORT_INTERVAL / 1000.0 / 3600.0)
#define POWER_ENERGY_DECIMALS 3 // Decimals for energy values
#define POWER_ENERGY_FACTOR (1. / 3600.0) // Ws => Wh
#if POWER_PROVIDER == POWER_PROVIDER_EMON_ANALOG #if POWER_PROVIDER == POWER_PROVIDER_EMON_ANALOG
#define EMON_CURRENT_RATIO 30 // Current ratio in the clamp (30V/1A) #define EMON_CURRENT_RATIO 30 // Current ratio in the clamp (30V/1A)


+ 21
- 3
code/espurna/power.ino View File

@ -23,6 +23,7 @@ bool _power_newdata = false;
double _power_current = 0; double _power_current = 0;
double _power_voltage = 0; double _power_voltage = 0;
double _power_apparent = 0; double _power_apparent = 0;
double _power_energy = 0;
MedianFilter _filter_current = MedianFilter(POWER_REPORT_BUFFER); MedianFilter _filter_current = MedianFilter(POWER_REPORT_BUFFER);
#if POWER_HAS_ACTIVE #if POWER_HAS_ACTIVE
@ -34,6 +35,10 @@ MedianFilter _filter_current = MedianFilter(POWER_REPORT_BUFFER);
MedianFilter _filter_apparent = MedianFilter(POWER_REPORT_BUFFER); MedianFilter _filter_apparent = MedianFilter(POWER_REPORT_BUFFER);
#endif #endif
#if POWER_HAS_ENERGY
double _power_last_energy = 0;
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// PRIVATE METHODS // PRIVATE METHODS
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -101,6 +106,9 @@ void _powerRead() {
double factor = (apparent > 0) ? active / apparent : 1; double factor = (apparent > 0) ? active / apparent : 1;
if (factor > 1) factor = 1; if (factor > 1) factor = 1;
#endif #endif
#if POWER_HAS_ENERGY
_power_energy = _powerEnergy(); //Due to its nature this value doesn't have to be filtered
#endif
// Filters // Filters
_filter_current.add(current); _filter_current.add(current);
@ -132,6 +140,7 @@ void _powerRead() {
root["pwrCurrent"] = roundTo(current, POWER_CURRENT_DECIMALS); root["pwrCurrent"] = roundTo(current, POWER_CURRENT_DECIMALS);
root["pwrVoltage"] = roundTo(voltage, POWER_VOLTAGE_DECIMALS); root["pwrVoltage"] = roundTo(voltage, POWER_VOLTAGE_DECIMALS);
root["pwrApparent"] = roundTo(apparent, POWER_POWER_DECIMALS); root["pwrApparent"] = roundTo(apparent, POWER_POWER_DECIMALS);
root["pwrEnergy"] = roundTo(_power_energy * POWER_ENERGY_FACTOR, POWER_ENERGY_DECIMALS);
#if POWER_HAS_ACTIVE #if POWER_HAS_ACTIVE
root["pwrActive"] = roundTo(active, POWER_POWER_DECIMALS); root["pwrActive"] = roundTo(active, POWER_POWER_DECIMALS);
root["pwrReactive"] = roundTo(reactive, POWER_POWER_DECIMALS); root["pwrReactive"] = roundTo(reactive, POWER_POWER_DECIMALS);
@ -174,18 +183,26 @@ void _powerReport() {
_power_apparent = _power_current * _power_voltage; _power_apparent = _power_current * _power_voltage;
double power = _power_apparent; double power = _power_apparent;
#endif #endif
double energy_delta = power * POWER_ENERGY_FACTOR;
#if POWER_HAS_ENERGY
double energy_delta = _power_energy - _power_last_energy;
_power_last_energy = _power_energy;
#else
double energy_delta = power * (POWER_REPORT_INTERVAL / 1000.);
_power_energy += energy_delta;
#endif
_power_ready = true; _power_ready = true;
char buf_current[10]; char buf_current[10];
char buf_energy[10]; char buf_energy[10];
char buf_energy_total[10];
dtostrf(_power_current, 1-sizeof(buf_current), POWER_CURRENT_DECIMALS, buf_current); dtostrf(_power_current, 1-sizeof(buf_current), POWER_CURRENT_DECIMALS, buf_current);
dtostrf(energy_delta, 1-sizeof(buf_energy), POWER_CURRENT_DECIMALS, buf_energy);
dtostrf(energy_delta * POWER_ENERGY_FACTOR, 1-sizeof(buf_energy), POWER_ENERGY_DECIMALS, buf_energy);
dtostrf(_power_energy * POWER_ENERGY_FACTOR, 1-sizeof(buf_energy_total), POWER_ENERGY_DECIMALS, buf_energy_total);
{ {
mqttSend(MQTT_TOPIC_CURRENT, buf_current); mqttSend(MQTT_TOPIC_CURRENT, buf_current);
mqttSend(MQTT_TOPIC_POWER_APPARENT, String((int) _power_apparent).c_str()); mqttSend(MQTT_TOPIC_POWER_APPARENT, String((int) _power_apparent).c_str());
mqttSend(MQTT_TOPIC_ENERGY, buf_energy); mqttSend(MQTT_TOPIC_ENERGY, buf_energy);
mqttSend(MQTT_TOPIC_ENERGY_TOTAL, buf_energy_total);
#if POWER_HAS_ACTIVE #if POWER_HAS_ACTIVE
mqttSend(MQTT_TOPIC_POWER_ACTIVE, String((int) _power_active).c_str()); mqttSend(MQTT_TOPIC_POWER_ACTIVE, String((int) _power_active).c_str());
mqttSend(MQTT_TOPIC_POWER_REACTIVE, String((int) _power_reactive).c_str()); mqttSend(MQTT_TOPIC_POWER_REACTIVE, String((int) _power_reactive).c_str());
@ -214,6 +231,7 @@ void _powerReport() {
influxDBSend(MQTT_TOPIC_CURRENT, buf_current); influxDBSend(MQTT_TOPIC_CURRENT, buf_current);
influxDBSend(MQTT_TOPIC_POWER_APPARENT, String((int) _power_apparent).c_str()); influxDBSend(MQTT_TOPIC_POWER_APPARENT, String((int) _power_apparent).c_str());
influxDBSend(MQTT_TOPIC_ENERGY, buf_energy); influxDBSend(MQTT_TOPIC_ENERGY, buf_energy);
influxDBSend(MQTT_TOPIC_ENERGY_TOTAL, buf_energy_total);
#if POWER_HAS_ACTIVE #if POWER_HAS_ACTIVE
influxDBSend(MQTT_TOPIC_POWER_ACTIVE, String((int) _power_active).c_str()); influxDBSend(MQTT_TOPIC_POWER_ACTIVE, String((int) _power_active).c_str());
influxDBSend(MQTT_TOPIC_POWER_REACTIVE, String((int) _power_reactive).c_str()); influxDBSend(MQTT_TOPIC_POWER_REACTIVE, String((int) _power_reactive).c_str());


+ 14
- 7
code/espurna/power_hlw8012.ino View File

@ -75,6 +75,10 @@ double _powerPowerFactor() {
return _hlw8012.getPowerFactor(); return _hlw8012.getPowerFactor();
} }
double _powerEnergy() {
return _hlw8012.getEnergy();
}
void _powerEnabledProvider() { void _powerEnabledProvider() {
if (_power_enabled) { if (_power_enabled) {
attachInterrupt(HLW8012_CF1_PIN, _hlw_cf1_isr, CHANGE); attachInterrupt(HLW8012_CF1_PIN, _hlw_cf1_isr, CHANGE);
@ -128,13 +132,16 @@ void _powerSetupProvider() {
_hlwRestoreCalibration(); _hlwRestoreCalibration();
_power_wifi_onconnect = WiFi.onStationModeGotIP([](WiFiEventStationModeGotIP ipInfo) {
powerEnabled(true);
});
_power_wifi_ondisconnect = WiFi.onStationModeDisconnected([](WiFiEventStationModeDisconnected ipInfo) {
powerEnabled(false);
});
#if HLW8012_USE_INTERRUPTS
powerEnabled(true); //Always keep measurement active to keep track of energy used
#else
_power_wifi_onconnect = WiFi.onStationModeGotIP([](WiFiEventStationModeGotIP ipInfo) {
powerEnabled(true);
});
_power_wifi_ondisconnect = WiFi.onStationModeDisconnected([](WiFiEventStationModeDisconnected ipInfo) {
powerEnabled(false);
});
#endif
} }
void _powerLoopProvider(bool before) { void _powerLoopProvider(bool before) {


Loading…
Cancel
Save