diff --git a/code/espurna/config/rtcmem.h b/code/espurna/config/rtcmem.h index ae58ae59..f5108257 100644 --- a/code/espurna/config/rtcmem.h +++ b/code/espurna/config/rtcmem.h @@ -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"); diff --git a/code/espurna/sensor.ino b/code/espurna/sensor.ino index ec6d4ae4..47a18df8 100644 --- a/code/espurna/sensor.ino +++ b/code/espurna/sensor.ino @@ -17,7 +17,7 @@ Copyright (C) 2016-2019 by Xose PĂ©rez #include -typedef struct { +struct sensor_magnitude_t { BaseSensor * sensor; // Sensor object BaseFilter * filter; // Filter object unsigned char local; // Local index in its provider @@ -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 _sensors; std::vector _magnitudes; @@ -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(); @@ -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; + } } // ----------------------------------------------------------------------------- @@ -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); @@ -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 @@ -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); } } @@ -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()); @@ -1352,7 +1338,7 @@ void _sensorConfigure() { if (getSetting("pwrResetE", 0).toInt() == 1) { sensor->resetEnergy(); - delSetting("eneTotal"); + delSetting("eneTotal", 0); _sensorResetTS(); } @@ -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(); } } @@ -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(); } } @@ -1409,7 +1395,7 @@ void _sensorConfigure() { if (getSetting("pwrResetE", 0).toInt() == 1) { sensor->resetEnergy(); - delSetting("eneTotal"); + delSetting("eneTotal", 0); _sensorResetTS(); } @@ -1448,7 +1434,7 @@ void _sensorConfigure() { if (getSetting("pwrResetE", 0).toInt() == 1) { sensor->resetEnergy(); - delSetting("eneTotal"); + delSetting("eneTotal", 0); _sensorResetTS(); } @@ -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(); } @@ -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(); } @@ -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(); @@ -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"); @@ -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(); @@ -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)