Browse Source

Fix energy storage when units different from joules

rules-rpn
Xose Pérez 5 years ago
parent
commit
d00c2b5eb3
2 changed files with 37 additions and 32 deletions
  1. +35
    -30
      code/espurna/sensor.ino
  2. +2
    -2
      code/espurna/sensors/BaseSensor.h

+ 35
- 30
code/espurna/sensor.ino View File

@ -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<uint8_t>(magnitude.global);
type.add<uint8_t>(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)


+ 2
- 2
code/espurna/sensors/BaseSensor.h View File

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


Loading…
Cancel
Save