Merge PR #16: Fix occationally lost samples after startup
commit
e86d7e713b
|
|
@ -154,58 +154,11 @@ void EnergyManagerImpl::watchThing(Thing *thing)
|
||||||
m_thingsTotalEnergyProducedCache[thing] = qMakePair<double, double>(stateEntry.totalProduction(), entry.totalProduction());
|
m_thingsTotalEnergyProducedCache[thing] = qMakePair<double, double>(stateEntry.totalProduction(), entry.totalProduction());
|
||||||
qCDebug(dcEnergyExperience()) << "Loaded thing power totals for" << thing->name() << "Consumption:" << entry.totalConsumption() << "Production:" << entry.totalProduction() << "Last thing state consumption:" << stateEntry.totalConsumption() << "production:" << stateEntry.totalProduction();
|
qCDebug(dcEnergyExperience()) << "Loaded thing power totals for" << thing->name() << "Consumption:" << entry.totalConsumption() << "Production:" << entry.totalProduction() << "Last thing state consumption:" << stateEntry.totalConsumption() << "production:" << stateEntry.totalProduction();
|
||||||
|
|
||||||
|
updateThingPower(thing);
|
||||||
|
|
||||||
connect(thing, &Thing::stateValueChanged, this, [=](const StateTypeId &stateTypeId, const QVariant &/*value*/){
|
connect(thing, &Thing::stateValueChanged, this, [=](const StateTypeId &stateTypeId, const QVariant &/*value*/){
|
||||||
if (QStringList({"currentPower", "totalEnergyConsumed", "totalEnergyProduced"}).contains(thing->thingClass().getStateType(stateTypeId).name())) {
|
if (QStringList({"currentPower", "totalEnergyConsumed", "totalEnergyProduced"}).contains(thing->thingClass().getStateType(stateTypeId).name())) {
|
||||||
|
updateThingPower(thing);
|
||||||
// We'll be keeping our own counters, starting from 0 at the time they're added to nymea and increasing with the things counters.
|
|
||||||
// This way we'll have proper logs even if the thing counter is reset (some things may reset their counter on power loss, factory reset etc)
|
|
||||||
// and also won't start with huge values if the thing has been counting for a while and only added to nymea later on
|
|
||||||
|
|
||||||
|
|
||||||
// Consumption
|
|
||||||
double oldThingConsumptionState = m_thingsTotalEnergyConsumedCache.value(thing).first;
|
|
||||||
double oldThingConsumptionInternal = m_thingsTotalEnergyConsumedCache.value(thing).second;
|
|
||||||
double newThingConsumptionState = thing->stateValue("totalEnergyConsumed").toDouble();
|
|
||||||
// For the very first cycle (oldConsumption is 0) we'll sync up on the meter, without actually adding it to our diff
|
|
||||||
if (oldThingConsumptionState == 0 && newThingConsumptionState != 0) {
|
|
||||||
qInfo(dcEnergyExperience()) << "Don't have a consumption counter for" << thing->name() << "Synching internal counters to initial value:" << newThingConsumptionState;
|
|
||||||
oldThingConsumptionState = newThingConsumptionState;
|
|
||||||
}
|
|
||||||
// If the thing's meter has been reset in the meantime (newConsumption < oldConsumption) we'll sync down, taking the whole diff from 0 to new value
|
|
||||||
if (newThingConsumptionState < oldThingConsumptionState) {
|
|
||||||
qCInfo(dcEnergyExperience()).nospace() << "Thing meter for " << thing->name() << " seems to have been reset. Old value: " << oldThingConsumptionState << " New value: " << newThingConsumptionState << ". Re-synching internal consumption counter.";
|
|
||||||
oldThingConsumptionState = newThingConsumptionState;
|
|
||||||
}
|
|
||||||
double consumptionDiff = newThingConsumptionState - oldThingConsumptionState;
|
|
||||||
double newThingConsumptionInternal = oldThingConsumptionInternal + consumptionDiff;
|
|
||||||
m_thingsTotalEnergyConsumedCache[thing] = qMakePair<double, double>(newThingConsumptionState, newThingConsumptionInternal);
|
|
||||||
|
|
||||||
|
|
||||||
// Production
|
|
||||||
double oldThingProductionState = m_thingsTotalEnergyProducedCache.value(thing).first;
|
|
||||||
double oldThingProductionInternal = m_thingsTotalEnergyProducedCache.value(thing).second;
|
|
||||||
double newThingProductionState = thing->stateValue("totalEnergyProduced").toDouble();
|
|
||||||
// For the very first cycle (oldProductino is 0) we'll sync up on the meter, without actually adding it to our diff
|
|
||||||
if (oldThingProductionState == 0 && newThingProductionState != 0) {
|
|
||||||
qInfo(dcEnergyExperience()) << "Don't have a production counter for" << thing->name() << "Synching internal counter to initial value:" << newThingProductionState;
|
|
||||||
oldThingProductionState = newThingProductionState;
|
|
||||||
}
|
|
||||||
// If the thing's meter has been reset in the meantime (newProduction < oldProduction) we'll sync down, taking the whole diff from 0 to new value
|
|
||||||
if (newThingProductionState < oldThingProductionState) {
|
|
||||||
qCInfo(dcEnergyExperience()) << "Thing meter for" << thing->name() << "seems to have been reset. Re-synching internal production counter.";
|
|
||||||
oldThingProductionState = newThingProductionState;
|
|
||||||
}
|
|
||||||
double productionDiff = newThingProductionState - oldThingProductionState;
|
|
||||||
double newThingProductionInternal = oldThingProductionInternal + productionDiff;
|
|
||||||
m_thingsTotalEnergyProducedCache[thing] = qMakePair<double, double>(newThingProductionState, newThingProductionInternal);
|
|
||||||
|
|
||||||
|
|
||||||
// Write to log
|
|
||||||
qCDebug(dcEnergyExperience()) << "Logging thing" << thing->name() << "total consumption:" << newThingConsumptionInternal << "production:" << newThingProductionInternal;
|
|
||||||
m_logger->logThingPower(thing->id(), thing->state("currentPower").value().toDouble(), newThingConsumptionInternal, newThingProductionInternal);
|
|
||||||
|
|
||||||
// Cache the thing state values in case nymea is restarted
|
|
||||||
m_logger->cacheThingEntry(thing->id(), newThingConsumptionState, newThingProductionState);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -309,6 +262,60 @@ void EnergyManagerImpl::updatePowerBalance()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnergyManagerImpl::updateThingPower(Thing *thing)
|
||||||
|
{
|
||||||
|
// We'll be keeping our own counters, starting from 0 at the time they're added to nymea and increasing with the things counters.
|
||||||
|
// This way we'll have proper logs even if the thing counter is reset (some things may reset their counter on power loss, factory reset etc)
|
||||||
|
// and also won't start with huge values if the thing has been counting for a while and only added to nymea later on
|
||||||
|
|
||||||
|
|
||||||
|
// Consumption
|
||||||
|
double oldThingConsumptionState = m_thingsTotalEnergyConsumedCache.value(thing).first;
|
||||||
|
double oldThingConsumptionInternal = m_thingsTotalEnergyConsumedCache.value(thing).second;
|
||||||
|
double newThingConsumptionState = thing->stateValue("totalEnergyConsumed").toDouble();
|
||||||
|
// For the very first cycle (oldConsumption is 0) we'll sync up on the meter, without actually adding it to our diff
|
||||||
|
if (oldThingConsumptionState == 0 && newThingConsumptionState != 0) {
|
||||||
|
qInfo(dcEnergyExperience()) << "Don't have a consumption counter for" << thing->name() << "Synching internal counters to initial value:" << newThingConsumptionState;
|
||||||
|
oldThingConsumptionState = newThingConsumptionState;
|
||||||
|
}
|
||||||
|
// If the thing's meter has been reset in the meantime (newConsumption < oldConsumption) we'll sync down, taking the whole diff from 0 to new value
|
||||||
|
if (newThingConsumptionState < oldThingConsumptionState) {
|
||||||
|
qCInfo(dcEnergyExperience()).nospace() << "Thing meter for " << thing->name() << " seems to have been reset. Old value: " << oldThingConsumptionState << " New value: " << newThingConsumptionState << ". Re-synching internal consumption counter.";
|
||||||
|
oldThingConsumptionState = newThingConsumptionState;
|
||||||
|
}
|
||||||
|
double consumptionDiff = newThingConsumptionState - oldThingConsumptionState;
|
||||||
|
double newThingConsumptionInternal = oldThingConsumptionInternal + consumptionDiff;
|
||||||
|
m_thingsTotalEnergyConsumedCache[thing] = qMakePair<double, double>(newThingConsumptionState, newThingConsumptionInternal);
|
||||||
|
|
||||||
|
|
||||||
|
// Production
|
||||||
|
double oldThingProductionState = m_thingsTotalEnergyProducedCache.value(thing).first;
|
||||||
|
double oldThingProductionInternal = m_thingsTotalEnergyProducedCache.value(thing).second;
|
||||||
|
double newThingProductionState = thing->stateValue("totalEnergyProduced").toDouble();
|
||||||
|
// For the very first cycle (oldProductino is 0) we'll sync up on the meter, without actually adding it to our diff
|
||||||
|
if (oldThingProductionState == 0 && newThingProductionState != 0) {
|
||||||
|
qInfo(dcEnergyExperience()) << "Don't have a production counter for" << thing->name() << "Synching internal counter to initial value:" << newThingProductionState;
|
||||||
|
oldThingProductionState = newThingProductionState;
|
||||||
|
}
|
||||||
|
// If the thing's meter has been reset in the meantime (newProduction < oldProduction) we'll sync down, taking the whole diff from 0 to new value
|
||||||
|
if (newThingProductionState < oldThingProductionState) {
|
||||||
|
qCInfo(dcEnergyExperience()) << "Thing meter for" << thing->name() << "seems to have been reset. Re-synching internal production counter.";
|
||||||
|
oldThingProductionState = newThingProductionState;
|
||||||
|
}
|
||||||
|
double productionDiff = newThingProductionState - oldThingProductionState;
|
||||||
|
double newThingProductionInternal = oldThingProductionInternal + productionDiff;
|
||||||
|
m_thingsTotalEnergyProducedCache[thing] = qMakePair<double, double>(newThingProductionState, newThingProductionInternal);
|
||||||
|
|
||||||
|
|
||||||
|
// Write to log
|
||||||
|
qCDebug(dcEnergyExperience()) << "Logging thing" << thing->name() << "total consumption:" << newThingConsumptionInternal << "production:" << newThingProductionInternal;
|
||||||
|
m_logger->logThingPower(thing->id(), thing->state("currentPower").value().toDouble(), newThingConsumptionInternal, newThingProductionInternal);
|
||||||
|
|
||||||
|
// Cache the thing state values in case nymea is restarted
|
||||||
|
m_logger->cacheThingEntry(thing->id(), newThingConsumptionState, newThingProductionState);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void EnergyManagerImpl::logDumpConsumers()
|
void EnergyManagerImpl::logDumpConsumers()
|
||||||
{
|
{
|
||||||
foreach (Thing *consumer, m_thingManager->configuredThings().filterByInterface("smartmeterconsumer")) {
|
foreach (Thing *consumer, m_thingManager->configuredThings().filterByInterface("smartmeterconsumer")) {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ private:
|
||||||
void unwatchThing(const ThingId &thingId);
|
void unwatchThing(const ThingId &thingId);
|
||||||
|
|
||||||
void updatePowerBalance();
|
void updatePowerBalance();
|
||||||
|
void updateThingPower(Thing *thing);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void logDumpConsumers();
|
void logDumpConsumers();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue