From d00c2b5eb3c91558a3bf801af3f3b8b925e04826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Mon, 8 Apr 2019 12:57:11 +0200 Subject: [PATCH] Fix energy storage when units different from joules --- code/espurna/sensor.ino | 65 +++++++++++++++++-------------- code/espurna/sensors/BaseSensor.h | 4 +- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/code/espurna/sensor.ino b/code/espurna/sensor.ino index eb7c6cbd..ab79a159 100644 --- a/code/espurna/sensor.ino +++ b/code/espurna/sensor.ino @@ -24,7 +24,7 @@ typedef struct { unsigned char type; // Type of measurement unsigned char decimals; // Number of decimals in textual representation unsigned char global; // Global index in its type - double current; // Current (last) value, unfiltered + double last; // Last raw value from sensor (unfiltered) double reported; // Last reported value double min_change; // Minimum value change to report double max_change; // Maximum value change to report @@ -62,6 +62,7 @@ unsigned char _magnitudeDecimals(unsigned char type) { if (type == MAGNITUDE_ANALOG) return ANALOG_DECIMALS; if (type == MAGNITUDE_ENERGY || type == MAGNITUDE_ENERGY_DELTA) { + _sensor_energy_units = getSetting("eneUnits", SENSOR_ENERGY_UNITS).toInt(); if (_sensor_energy_units == ENERGY_KWH) return 3; } if (type == MAGNITUDE_POWER_ACTIVE || @@ -162,8 +163,8 @@ void _sensorWebSocketSendData(JsonObject& root) { if (magnitude.type == MAGNITUDE_EVENT) continue; ++size; - unsigned char decimals = magnitude.decimals; - dtostrf(magnitude.current, 1-sizeof(buffer), decimals, buffer); + double value_show = _magnitudeProcess(magnitude.type, magnitude.decimals, magnitude.last); + dtostrf(value_show, 1-sizeof(buffer), magnitude.decimals, buffer); index.add(magnitude.global); type.add(magnitude.type); @@ -296,9 +297,8 @@ void _sensorAPISetup() { apiRegister(topic.c_str(), [magnitude_id](char * buffer, size_t len) { sensor_magnitude_t magnitude = _magnitudes[magnitude_id]; - unsigned char decimals = magnitude.decimals; - double value = _sensor_realtime ? magnitude.current : magnitude.reported; - dtostrf(value, 1-len, decimals, buffer); + double value = _sensor_realtime ? magnitude.last : magnitude.reported; + dtostrf(value, 1-len, magnitude.decimals, buffer); }); } @@ -859,16 +859,16 @@ void _sensorInit() { for (unsigned char k=0; k<_sensors[i]->count(); k++) { unsigned char type = _sensors[i]->type(k); - signed char decimals = _sensors[i]->decimals(type); - if (decimals < 0) decimals = _magnitudeDecimals(type); + signed char decimals = _sensors[i]->decimals(type); + if (decimals < 0) decimals = _magnitudeDecimals(type); sensor_magnitude_t new_magnitude; new_magnitude.sensor = _sensors[i]; new_magnitude.local = k; new_magnitude.type = type; - new_magnitude.decimals = (unsigned char) decimals; + new_magnitude.decimals = (unsigned char) decimals; new_magnitude.global = _counts[type]; - new_magnitude.current = 0; + new_magnitude.last = 0; new_magnitude.reported = 0; new_magnitude.min_change = 0; new_magnitude.max_change = 0; @@ -1303,7 +1303,7 @@ unsigned char magnitudeType(unsigned char index) { double magnitudeValue(unsigned char index) { if (index < _magnitudes.size()) { - return _sensor_realtime ? _magnitudes[index].current : _magnitudes[index].reported; + return _sensor_realtime ? _magnitudes[index].last : _magnitudes[index].reported; } return DBL_MIN; } @@ -1418,8 +1418,9 @@ void sensorLoop() { last_update = millis(); report_count = (report_count + 1) % _sensor_report_every; - double current; - double filtered; + double value_raw; // holds the raw value as the sensor returns it + double value_show; // holds the processed value applying units and decimals + double value_filtered; // holds the processed value applying filters, and the units and decimals // Pre-read hook _sensorPre(); @@ -1440,7 +1441,7 @@ void sensorLoop() { // Instant value // ------------------------------------------------------------- - current = magnitude.sensor->value(magnitude.local); + value_raw = magnitude.sensor->value(magnitude.local); // Completely remove spurious values if relay is OFF #if SENSOR_POWER_CHECK_STATUS @@ -1451,26 +1452,31 @@ void sensorLoop() { magnitude.type == MAGNITUDE_CURRENT || magnitude.type == MAGNITUDE_ENERGY_DELTA ) { - current = 0; + value_raw = 0; } } #endif + _magnitudes[i].last = value_raw; + // ------------------------------------------------------------- // Processing (filters) // ------------------------------------------------------------- - magnitude.filter->add(current); + magnitude.filter->add(value_raw); - // Special case for MovingAvergaeFilter + // Special case for MovingAverageFilter if (MAGNITUDE_COUNT == magnitude.type || MAGNITUDE_GEIGER_CPM ==magnitude. type || MAGNITUDE_GEIGER_SIEVERT == magnitude.type) { - current = magnitude.filter->result(); + value_raw = magnitude.filter->result(); } - current = _magnitudeProcess(magnitude.type, magnitude.decimals, current); - _magnitudes[i].current = current; + // ------------------------------------------------------------- + // Procesing (units and decimals) + // ------------------------------------------------------------- + + value_show = _magnitudeProcess(magnitude.type, magnitude.decimals, value_raw); // ------------------------------------------------------------- // Debug @@ -1479,7 +1485,7 @@ void sensorLoop() { #if SENSOR_DEBUG { char buffer[64]; - dtostrf(current, 1-sizeof(buffer), magnitude.decimals, buffer); + dtostrf(value_show, 1-sizeof(buffer), magnitude.decimals, buffer); DEBUG_MSG_P(PSTR("[SENSOR] %s - %s: %s%s\n"), magnitude.sensor->slot(magnitude.local).c_str(), magnitudeTopic(magnitude.type).c_str(), @@ -1497,21 +1503,20 @@ void sensorLoop() { bool report = (0 == report_count); if ((MAGNITUDE_ENERGY == magnitude.type) && (magnitude.max_change > 0)) { // for MAGNITUDE_ENERGY, filtered value is last value - double value = _magnitudeProcess(magnitude.type, magnitude.decimals, current); - report = (fabs(value - magnitude.reported) >= magnitude.max_change); + report = (fabs(value_show - magnitude.reported) >= magnitude.max_change); } // if ((MAGNITUDE_ENERGY == magnitude.type) && (magnitude.max_change > 0)) if (report) { - filtered = magnitude.filter->result(); - filtered = _magnitudeProcess(magnitude.type, magnitude.decimals, filtered); + value_filtered = magnitude.filter->result(); + value_filtered = _magnitudeProcess(magnitude.type, magnitude.decimals, value_filtered); magnitude.filter->reset(); // Check if there is a minimum change threshold to report - if (fabs(filtered - magnitude.reported) >= magnitude.min_change) { - _magnitudes[i].reported = filtered; - _sensorReport(i, filtered); - } // if (fabs(filtered - magnitude.reported) >= magnitude.min_change) + if (fabs(value_filtered - magnitude.reported) >= magnitude.min_change) { + _magnitudes[i].reported = value_filtered; + _sensorReport(i, value_filtered); + } // if (fabs(value_filtered - magnitude.reported) >= magnitude.min_change) // ------------------------------------------------------------- // Saving to EEPROM @@ -1524,7 +1529,7 @@ void sensorLoop() { if (0 == save_count) { if (MAGNITUDE_ENERGY == magnitude.type) { - setSetting("eneTotal", current); + setSetting("eneTotal", value_raw); saveSettings(); } } // if (0 == save_count) diff --git a/code/espurna/sensors/BaseSensor.h b/code/espurna/sensors/BaseSensor.h index 6608d015..b3f5408c 100644 --- a/code/espurna/sensors/BaseSensor.h +++ b/code/espurna/sensors/BaseSensor.h @@ -57,8 +57,8 @@ class BaseSensor { // Type for slot # index virtual unsigned char type(unsigned char index) = 0; - // Number of decimals for a magnitude (or -1 for default) - virtual signed char decimals(unsigned char type) { return -1; } + // Number of decimals for a magnitude (or -1 for default) + virtual signed char decimals(unsigned char type) { return -1; } // Current value for slot # index virtual double value(unsigned char index) = 0;