Skip to content

Commit

Permalink
Use indexed keys for energy saving (#1875)
Browse files Browse the repository at this point in the history
* Use indexed keys for energy saving

* match else even when rtcmem cannot fit the value

* fix energy reset placement

* fix rtcmem->energy size check

* revert to pre 62a2b9e value, handle update from 1.13.5
  • Loading branch information
mcspr authored Aug 27, 2019
1 parent d66b8a9 commit 58401c8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 66 deletions.
2 changes: 1 addition & 1 deletion code/espurna/config/rtcmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct RtcmemData {
uint32_t relay;
uint32_t mqtt;
uint64_t light;
double energy;
double energy[4];
};

static_assert(sizeof(RtcmemData) <= (RTCMEM_BLOCKS * 4u), "RTCMEM struct is too big");
Expand Down
109 changes: 44 additions & 65 deletions code/espurna/sensor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>

#include <float.h>

typedef struct {
struct sensor_magnitude_t {
BaseSensor * sensor; // Sensor object
BaseFilter * filter; // Filter object
unsigned char local; // Local index in its provider
Expand All @@ -28,7 +28,7 @@ typedef struct {
double reported; // Last reported value
double min_change; // Minimum value change to report
double max_change; // Maximum value change to report
} sensor_magnitude_t;
};

std::vector<BaseSensor *> _sensors;
std::vector<sensor_magnitude_t> _magnitudes;
Expand Down Expand Up @@ -393,7 +393,7 @@ void _sensorInitCommands() {
DEBUG_MSG_P(PSTR("[SENSOR] PZEM004T\n"));
for(unsigned char dev = init; dev < limit; dev++) {
float offset = pzem004t_sensor->resetEnergy(dev);
setSetting("pzemEneTotal", dev, offset);
_sensorEnergyTotal(dev, offset);
DEBUG_MSG_P(PSTR("Device %d/%s - Offset: %s\n"), dev, pzem004t_sensor->getAddress(dev).c_str(), String(offset).c_str());
}
terminalOK();
Expand Down Expand Up @@ -462,52 +462,38 @@ void _sensorResetTS() {
#endif
}

double _sensorEnergyTotal(unsigned int index = -1) {
double _sensorEnergyTotal(unsigned int index) {
double value = 0;

if (rtcmemStatus()) {
value = Rtcmem->energy;
} else {
if(index != -1) {
value = (_sensor_save_every > 0) ? getSetting("eneTotal", index, 0).toInt() : 0;
} else {
value = (_sensor_save_every > 0) ? getSetting("eneTotal", 0).toInt() : 0;
}
if (rtcmemStatus() && (index < (sizeof(Rtcmem->energy) / sizeof(*Rtcmem->energy)))) {
value = Rtcmem->energy[index];
} else {
value = (_sensor_save_every > 0) ? getSetting("eneTotal", index, 0).toInt() : 0;
}

return value;
}

void _sensorEnergyTotal(unsigned int index, double value) {
static unsigned long save_count = 0;

// Save to EEPROM every '_sensor_save_every' readings
if (_sensor_save_every > 0) {
save_count = (save_count + 1) % _sensor_save_every;
if (0 == save_count) {
setSetting("eneTotal", index, value);
saveSettings();
}
}

// Always save to RTCMEM
Rtcmem->energy = value;
double _sensorEnergyTotal() {
return _sensorEnergyTotal(0);
}

void _sensorEnergyTotal(double value) {
void _sensorEnergyTotal(unsigned int index, double value) {
static unsigned long save_count = 0;

// Save to EEPROM every '_sensor_save_every' readings
if (_sensor_save_every > 0) {
save_count = (save_count + 1) % _sensor_save_every;
if (0 == save_count) {
setSetting("eneTotal", value);
setSetting("eneTotal", index, value);
saveSettings();
}
}

// Always save to RTCMEM
Rtcmem->energy = value;
if (index < (sizeof(Rtcmem->energy) / sizeof(*Rtcmem->energy))) {
Rtcmem->energy[index] = value;
}
}

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -1001,7 +987,7 @@ void _sensorLoad() {
// Read saved energy offset
unsigned char dev_count = sensor->getAddressesCount();
for(unsigned char dev = 0; dev < dev_count; dev++) {
float value = getSetting("pzemEneTotal", dev, 0).toFloat();
float value = _sensorEnergyTotal(dev);
if (value > 0) sensor->resetEnergy(dev, value);
}
_sensors.push_back(sensor);
Expand Down Expand Up @@ -1100,7 +1086,7 @@ void _sensorLoad() {
#if ADE7953_SUPPORT
{
ADE7953Sensor * sensor = new ADE7953Sensor();
sensor->setAddress(ADE7953_ADDRESS);
sensor->setAddress(ADE7953_ADDRESS);
_sensors.push_back(sensor);
}
#endif
Expand Down Expand Up @@ -1245,12 +1231,12 @@ void _sensorInit() {

#if ADE7953_SUPPORT

if (_sensors[i]->getID() == SENSOR_ADE7953_ID) {
if (_sensors[i]->getID() == SENSOR_ADE7953_ID) {
ADE7953Sensor * sensor = (ADE7953Sensor *) _sensors[i];
unsigned int dev_count = sensor->getTotalDevices();
for(unsigned int dev = 0; dev < dev_count; dev++) {
for(unsigned char dev = 0; dev < dev_count; dev++) {
double value = _sensorEnergyTotal(dev);
if (value > 0) sensor->resetEnergy(dev, value);
if (value > 0) sensor->resetEnergy(dev, value);
}
}

Expand Down Expand Up @@ -1280,7 +1266,7 @@ void _sensorInit() {

#endif // CSE7766_SUPPORT

#if PULSEMETER_SUPPORT
#if PULSEMETER_SUPPORT
if (_sensors[i]->getID() == SENSOR_PULSEMETER_ID) {
PulseMeterSensor * sensor = (PulseMeterSensor *) _sensors[i];
sensor->setEnergyRatio(getSetting("pwrRatioE", sensor->getEnergyRatio()).toInt());
Expand Down Expand Up @@ -1352,7 +1338,7 @@ void _sensorConfigure() {

if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
delSetting("eneTotal");
delSetting("eneTotal", 0);
_sensorResetTS();
}

Expand All @@ -1367,7 +1353,7 @@ void _sensorConfigure() {
EmonADC121Sensor * sensor = (EmonADC121Sensor *) _sensors[i];
if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
delSetting("eneTotal");
delSetting("eneTotal", 0);
_sensorResetTS();
}
}
Expand All @@ -1378,7 +1364,7 @@ void _sensorConfigure() {
EmonADS1X15Sensor * sensor = (EmonADS1X15Sensor *) _sensors[i];
if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
delSetting("eneTotal");
delSetting("eneTotal", 0);
_sensorResetTS();
}
}
Expand Down Expand Up @@ -1409,7 +1395,7 @@ void _sensorConfigure() {

if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
delSetting("eneTotal");
delSetting("eneTotal", 0);
_sensorResetTS();
}

Expand Down Expand Up @@ -1448,7 +1434,7 @@ void _sensorConfigure() {

if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
delSetting("eneTotal");
delSetting("eneTotal", 0);
_sensorResetTS();
}

Expand All @@ -1468,7 +1454,7 @@ void _sensorConfigure() {
PulseMeterSensor * sensor = (PulseMeterSensor *) _sensors[i];
if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
delSetting("eneTotal");
delSetting("eneTotal", 0);
_sensorResetTS();
}

Expand All @@ -1484,7 +1470,7 @@ void _sensorConfigure() {
unsigned char dev_count = sensor->getAddressesCount();
for(unsigned char dev = 0; dev < dev_count; dev++) {
sensor->resetEnergy(dev, 0);
delSetting("pzemEneTotal", dev);
delSetting("eneTotal", dev);
}
_sensorResetTS();
}
Expand All @@ -1494,7 +1480,7 @@ void _sensorConfigure() {

#if ADE7953_SUPPORT

if (_sensors[i]->getID() == SENSOR_ADE7953_ID) {
if (_sensors[i]->getID() == SENSOR_ADE7953_ID) {
ADE7953Sensor * sensor = (ADE7953Sensor *) _sensors[i];
if (getSetting("pwrResetE", 0).toInt() == 1) {
unsigned char dev_count = sensor->getTotalDevices();
Expand All @@ -1510,17 +1496,19 @@ void _sensorConfigure() {

}

// Update filter sizes
for (unsigned char i=0; i<_magnitudes.size(); i++) {
_magnitudes[i].filter->resize(_sensor_report_every);
}

// General processing
if (0 == _sensor_save_every) {
delSetting("eneTotal");
// Update filter sizes and reset energy if needed
{
const bool reset_saved_energy = 0 == _sensor_save_every;
for (unsigned char i=0; i<_magnitudes.size(); i++) {
_magnitudes[i].filter->resize(_sensor_report_every);
if ((_magnitudes[i].type == MAGNITUDE_ENERGY) && reset_saved_energy) {
delSetting("eneTotal", _magnitudes[i].global);
}
}
}

// Save settings
// Remove calibration values
// TODO: do not use settings for one-shot calibration
delSetting("snsResetCalibration");
delSetting("pwrExpectedP");
delSetting("pwrExpectedC");
Expand Down Expand Up @@ -1678,11 +1666,12 @@ String magnitudeUnits(unsigned char type) {
void sensorSetup() {

// Backwards compatibility
moveSetting("eneTotal", "eneTotal0");
moveSetting("powerUnits", "pwrUnits");
moveSetting("energyUnits", "eneUnits");

// Update PZEM004T energy total across multiple devices
moveSettings("pzEneTotal", "pzemEneTotal");
moveSettings("pzEneTotal", "eneTotal");

// Load sensors
_sensorLoad();
Expand Down Expand Up @@ -1840,19 +1829,9 @@ void sensorLoop() {
_sensorReport(i, value_filtered);
} // if (fabs(value_filtered - magnitude.reported) >= magnitude.min_change)


// Persist total energy value
if (MAGNITUDE_ENERGY == magnitude.type) {
if (magnitude.sensor->getID() != SENSOR_ADE7953_ID) {
_sensorEnergyTotal(value_raw);
} else {
#if ADE7953_SUPPORT
ADE7953Sensor * sensor = (ADE7953Sensor *) magnitude.sensor;
unsigned int dev_count = sensor->getTotalDevices();
unsigned int dev = (magnitude.local / dev_count) - 1;
_sensorEnergyTotal(dev, value_raw);
#endif // ADE7953_SUPPORT
}
if (MAGNITUDE_ENERGY == magnitude.type) {
_sensorEnergyTotal(magnitude.global, value_raw);
}

} // if (report_count == 0)
Expand Down

0 comments on commit 58401c8

Please sign in to comment.