Add totals to balance

master
Michael Zanetti 2021-11-22 00:43:36 +01:00
parent d684016498
commit 034f90d7a9
8 changed files with 239 additions and 39 deletions

View File

@ -12,12 +12,16 @@ PowerBalanceLogEntry::PowerBalanceLogEntry()
}
PowerBalanceLogEntry::PowerBalanceLogEntry(const QDateTime &timestamp, double consumption, double production, double acquisition, double storage):
PowerBalanceLogEntry::PowerBalanceLogEntry(const QDateTime &timestamp, double consumption, double production, double acquisition, double storage, double totalConsumption, double totalProduction, double totalAcquisition, double totalReturn):
m_timestamp(timestamp),
m_consumption(consumption),
m_production(production),
m_acquisition(acquisition),
m_storage(storage)
m_storage(storage),
m_totalConsumption(totalConsumption),
m_totalProduction(totalProduction),
m_totalAcquisition(totalAcquisition),
m_totalReturn(totalReturn)
{
}
@ -47,6 +51,26 @@ double PowerBalanceLogEntry::storage() const
return m_storage;
}
double PowerBalanceLogEntry::totalConsumption() const
{
return m_totalConsumption;
}
double PowerBalanceLogEntry::totalProduction() const
{
return m_totalProduction;
}
double PowerBalanceLogEntry::totalAcquisition() const
{
return m_totalAcquisition;
}
double PowerBalanceLogEntry::totalReturn() const
{
return m_totalReturn;
}
QVariant PowerBalanceLogEntries::get(int index) const
{
return QVariant::fromValue(at(index));

View File

@ -20,6 +20,7 @@ public:
virtual ~EnergyLogs() = default;
enum SampleRate {
SampleRateAny = 0,
SampleRate1Min = 1,
SampleRate15Mins = 15,
SampleRate1Hour = 60,
@ -57,20 +58,33 @@ class PowerBalanceLogEntry
Q_PROPERTY(double production READ production)
Q_PROPERTY(double acquisition READ acquisition)
Q_PROPERTY(double storage READ storage)
Q_PROPERTY(double totalConsumption READ totalConsumption)
Q_PROPERTY(double totalProduction READ totalProduction)
Q_PROPERTY(double totalAcquisition READ totalAcquisition)
Q_PROPERTY(double totalReturn READ totalReturn)
public:
PowerBalanceLogEntry();
PowerBalanceLogEntry(const QDateTime &timestamp, double consumption, double production, double acquisition, double storage);
PowerBalanceLogEntry(const QDateTime &timestamp, double consumption, double production, double acquisition, double storage, double totalConsumption, double totalProduction, double totalAcquisition, double totalReturn);
QDateTime timestamp() const;
double consumption() const;
double production() const;
double acquisition() const;
double storage() const;
double totalConsumption() const;
double totalProduction() const;
double totalAcquisition() const;
double totalReturn() const;
private:
QDateTime m_timestamp;
double m_consumption = 0;
double m_production = 0;
double m_acquisition = 0;
double m_storage = 0;
double m_totalConsumption = 0;
double m_totalProduction = 0;
double m_totalAcquisition = 0;
double m_totalReturn = 0;
};
Q_DECLARE_METATYPE(PowerBalanceLogEntry)

View File

@ -61,6 +61,10 @@ public:
virtual double currentPowerProduction() const = 0;
virtual double currentPowerAcquisition() const = 0;
virtual double currentPowerStorage() const = 0;
virtual double totalConsumption() const = 0;
virtual double totalProduction() const = 0;
virtual double totalAcquisition() const = 0;
virtual double totalReturn() const = 0;
virtual EnergyLogs* logs() const = 0;

View File

@ -33,6 +33,10 @@ EnergyJsonHandler::EnergyJsonHandler(EnergyManager *energyManager, QObject *pare
returns.insert("currentPowerProduction", enumValueName(Double));
returns.insert("currentPowerAcquisition", enumValueName(Double));
returns.insert("currentPowerStorage", enumValueName(Double));
returns.insert("totalConsumption", enumValueName(Double));
returns.insert("totalProduction", enumValueName(Double));
returns.insert("totalAcquisition", enumValueName(Double));
returns.insert("totalReturn", enumValueName(Double));
registerMethod("GetPowerBalance", description, params, returns);
params.clear(); returns.clear();
@ -67,6 +71,10 @@ EnergyJsonHandler::EnergyJsonHandler(EnergyManager *energyManager, QObject *pare
params.insert("currentPowerProduction", enumValueName(Double));
params.insert("currentPowerAcquisition", enumValueName(Double));
params.insert("currentPowerStorage", enumValueName(Double));
params.insert("totalConsumption", enumValueName(Double));
params.insert("totalProduction", enumValueName(Double));
params.insert("totalAcquisition", enumValueName(Double));
params.insert("totalReturn", enumValueName(Double));
registerNotification("PowerBalanceChanged", description, params);
params.clear();
@ -95,6 +103,10 @@ EnergyJsonHandler::EnergyJsonHandler(EnergyManager *energyManager, QObject *pare
params.insert("currentPowerProduction", m_energyManager->currentPowerProduction());
params.insert("currentPowerAcquisition", m_energyManager->currentPowerAcquisition());
params.insert("currentPowerStorage", m_energyManager->currentPowerStorage());
params.insert("totalConsumption", m_energyManager->totalConsumption());
params.insert("totalProduction", m_energyManager->totalProduction());
params.insert("totalAcquisition", m_energyManager->totalAcquisition());
params.insert("totalReturn", m_energyManager->totalReturn());
emit PowerBalanceChanged(params);
});
@ -149,16 +161,17 @@ JsonReply *EnergyJsonHandler::GetPowerBalance(const QVariantMap &params)
ret.insert("currentPowerProduction", m_energyManager->currentPowerProduction());
ret.insert("currentPowerAcquisition", m_energyManager->currentPowerAcquisition());
ret.insert("currentPowerStorage", m_energyManager->currentPowerStorage());
ret.insert("totalConsumption", m_energyManager->totalConsumption());
ret.insert("totalProduction", m_energyManager->totalProduction());
ret.insert("totalAcquisition", m_energyManager->totalAcquisition());
ret.insert("totalReturn", m_energyManager->totalReturn());
return createReply(ret);
}
JsonReply *EnergyJsonHandler::GetPowerBalanceLogs(const QVariantMap &params)
{
qCDebug(dcEnergyExperience()) << "params" << params;
qCDebug(dcEnergyExperience()) << "from" << params.value("from");
EnergyLogs::SampleRate sampleRate = enumNameToValue<EnergyLogs::SampleRate>(params.value("sampleRate").toString());
QDateTime from = params.contains("from") ? QDateTime::fromMSecsSinceEpoch(params.value("from").toLongLong() * 1000) : QDateTime();
qCDebug(dcEnergyExperience()) << "from2" << from;
QDateTime to = params.contains("to") ? QDateTime::fromMSecsSinceEpoch(params.value("to").toLongLong() * 1000) : QDateTime();
QVariantMap returns;
returns.insert("powerBalanceLogEntries", pack(m_energyManager->logs()->powerBalanceLogs(sampleRate, from, to)));

View File

@ -6,6 +6,7 @@
#include <QDir>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
#include <QSettings>
#include <QLoggingCategory>
@ -53,7 +54,6 @@ EnergyLogger::EnergyLogger(QObject *parent) : EnergyLogs(parent)
}
// Start the scheduling
scheduleNextSample(SampleRate1Min);
foreach (SampleRate sampleRate, m_configs.keys()) {
scheduleNextSample(sampleRate);
@ -71,9 +71,9 @@ EnergyLogger::EnergyLogger(QObject *parent) : EnergyLogs(parent)
m_sampleTimer.start(1000);
}
void EnergyLogger::logPowerBalance(double consumption, double production, double acquisition, double storage)
void EnergyLogger::logPowerBalance(double consumption, double production, double acquisition, double storage, double totalConsumption, double totalProduction, double totalAcquisition, double totalReturn)
{
PowerBalanceLogEntry entry(QDateTime::currentDateTime(), consumption, production, acquisition, storage);
PowerBalanceLogEntry entry(QDateTime::currentDateTime(), consumption, production, acquisition, storage, totalConsumption, totalProduction, totalAcquisition, totalReturn);
// Add everything to livelog, keep that for one day, in memory only
m_balanceLiveLog.prepend(entry);
@ -124,8 +124,8 @@ PowerBalanceLogEntries EnergyLogger::powerBalanceLogs(SampleRate sampleRate, con
}
while (query.next()) {
qCDebug(dcEnergyExperience()) << "Adding result";
result.append(PowerBalanceLogEntry(QDateTime::fromMSecsSinceEpoch(query.value("timestamp").toLongLong()), query.value("consumption").toDouble(), query.value("production").toDouble(), query.value("acquisition").toDouble(), query.value("storage").toDouble()));
// qCDebug(dcEnergyExperience()) << "Adding result";
result.append(queryResultToBalanceLogEntry(query.record()));
}
return result;
}
@ -178,6 +178,33 @@ ThingPowerLogEntries EnergyLogger::thingPowerLogs(SampleRate sampleRate, const Q
}
PowerBalanceLogEntry EnergyLogger::latestLogEntry(SampleRate sampleRate)
{
QSqlQuery query(m_db);
QString queryString = "SELECT MAX(timestamp), consumption, production, acquisition, storage, totalConsumption, totalProduction, totalAcquisition, totalReturn FROM powerBalance";
QVariantList bindValues;
if (sampleRate != SampleRateAny) {
queryString += " WHERE sampleRate = ?";
bindValues.append(sampleRate);
}
queryString += ";";
query.prepare(queryString);
foreach (const QVariant &value, bindValues) {
query.addBindValue(value);
}
query.exec();
if (query.lastError().isValid()) {
qCWarning(dcEnergyExperience()) << "Error obtaining latest log entry from DB:" << query.lastError() << query.executedQuery();
return PowerBalanceLogEntry();
}
if (!query.next()) {
qCDebug(dcEnergyExperience()) << "No power balance log entry in DB for sample rate:" << sampleRate;
return PowerBalanceLogEntry();
}
qCDebug(dcEnergyExperience()) << "Loaded latest log entry:" << query.record();
return queryResultToBalanceLogEntry(query.record());
}
void EnergyLogger::sample()
{
QDateTime now = QDateTime::currentDateTime();
@ -210,8 +237,19 @@ void EnergyLogger::sample()
medianProduction /= sampleStart.msecsTo(sampleEnd);
medianAcquisition /= sampleStart.msecsTo(sampleEnd);
medianStorage /= sampleStart.msecsTo(sampleEnd);
PowerBalanceLogEntry newest = m_balanceLiveLog.count() > 0 ? m_balanceLiveLog.at(0) : PowerBalanceLogEntry();
double totalConsumption = newest.totalConsumption();
double totalProduction = newest.totalProduction();
double totalAcquisition = newest.totalAcquisition();
double totalReturn = newest.totalReturn();
qCDebug(dcEnergyExperience()) << "Power balance for sample:" << medianConsumption << medianProduction << medianAcquisition << medianStorage << "duration:" << sampleStart.msecsTo(sampleEnd);
insertPowerBalance(sampleEnd, SampleRate1Min, medianConsumption, medianProduction, medianAcquisition, medianStorage);
insertPowerBalance(sampleEnd, SampleRate1Min, medianConsumption, medianProduction, medianAcquisition, medianStorage, totalConsumption, totalProduction, totalAcquisition, totalReturn);
m_lastSampleTotalConsumption = totalConsumption;
m_lastSampleTotalProducation = totalProduction;
m_lastSampleTotalAcquisition = totalAcquisition;
m_lastSampleTotalReturn = totalReturn;
foreach (const ThingId &thingId, m_thingsPowerLiveLogs.keys()) {
medianConsumption = 0;
@ -307,7 +345,11 @@ bool EnergyLogger::initDB()
"consumption FLOAT,"
"production FLOAT,"
"acquisition FLOAT,"
"storage FLOAT"
"storage FLOAT,"
"totalConsumption FLOAT,"
"totalProduction FLOAT,"
"totalAcquisition FLOAT,"
"totalReturn FLOAT"
");");
if (m_db.lastError().isValid()) {
@ -333,7 +375,7 @@ bool EnergyLogger::initDB()
}
}
qCDebug(dcEnergyExperience()) << "Initialized logging DB successfully.";
qCDebug(dcEnergyExperience()) << "Initialized logging DB successfully." << m_db.databaseName();
return true;
}
@ -412,16 +454,16 @@ void EnergyLogger::rectifySamples(SampleRate sampleRate, SampleRate baseSampleRa
QDateTime newestSample = getNewestPowerBalanceSampleTimestamp(sampleRate);
qCDebug(dcEnergyExperience()) << "Checking for missing samples for" << sampleRate;
qCDebug(dcEnergyExperience()) << "Newest sample:" << newestSample.toString() << "Oldest base sample:" << oldestBaseSample.toString();
// qCDebug(dcEnergyExperience()) << "Newest sample:" << newestSample.toString() << "Oldest base sample:" << oldestBaseSample.toString();
if (newestSample.isNull()) {
qCDebug(dcEnergyExperience()) << "No sample at all so far. Using base as starting point.";
// qCDebug(dcEnergyExperience()) << "No sample at all so far. Using base as starting point.";
newestSample = oldestBaseSample;
}
qCDebug(dcEnergyExperience()) << "next sample after last in series:" << nextSampleTimestamp(sampleRate, newestSample).toString();
qCDebug(dcEnergyExperience()) << "next scheduled sample:" << m_nextSamples.value(sampleRate).toString();
// qCDebug(dcEnergyExperience()) << "next sample after last in series:" << nextSampleTimestamp(sampleRate, newestSample).toString();
// qCDebug(dcEnergyExperience()) << "next scheduled sample:" << m_nextSamples.value(sampleRate).toString();
while (!newestSample.isNull() && nextSampleTimestamp(sampleRate, newestSample) < m_nextSamples[sampleRate]) {
QDateTime nextSample = nextSampleTimestamp(sampleRate, newestSample.addMSecs(1000));
qCDebug(dcEnergyExperience()) << "Rectifying missed sample for" << sampleRate << "from" << nextSample.toString();
// qCDebug(dcEnergyExperience()) << "Rectifying missed sample for" << sampleRate << "from" << nextSample.toString();
samplePowerBalance(sampleRate, baseSampleRate, nextSample);
newestSample = nextSample;
}
@ -430,17 +472,17 @@ void EnergyLogger::rectifySamples(SampleRate sampleRate, SampleRate baseSampleRa
QDateTime oldestBaseSample = getOldestThingPowerSampleTimestamp(thingId, baseSampleRate);
QDateTime newestSample = getNewestThingPowerSampleTimestamp(thingId, sampleRate);
qCDebug(dcEnergyExperience()) << "T Checking for missing samples for" << sampleRate;
qCDebug(dcEnergyExperience()) << "T Newest sample:" << newestSample.toString() << "Oldest base sample:" << oldestBaseSample.toString();
// qCDebug(dcEnergyExperience()) << "T Checking for missing samples for" << sampleRate;
// qCDebug(dcEnergyExperience()) << "T Newest sample:" << newestSample.toString() << "Oldest base sample:" << oldestBaseSample.toString();
if (newestSample.isNull()) {
qCDebug(dcEnergyExperience()) << "T No sample at all so far. Using base as starting point.";
// qCDebug(dcEnergyExperience()) << "T No sample at all so far. Using base as starting point.";
newestSample = oldestBaseSample;
}
qCDebug(dcEnergyExperience()) << "T next sample after last in series:" << nextSampleTimestamp(sampleRate, newestSample).toString();
qCDebug(dcEnergyExperience()) << "T next scheduled sample:" << m_nextSamples.value(sampleRate).toString();
// qCDebug(dcEnergyExperience()) << "T next sample after last in series:" << nextSampleTimestamp(sampleRate, newestSample).toString();
// qCDebug(dcEnergyExperience()) << "T next scheduled sample:" << m_nextSamples.value(sampleRate).toString();
while (!newestSample.isNull() && nextSampleTimestamp(sampleRate, newestSample) < m_nextSamples[sampleRate]) {
QDateTime nextSample = nextSampleTimestamp(sampleRate, newestSample.addMSecs(1000));
qCDebug(dcEnergyExperience()) << "T Rectifying missed sample for" << sampleRate << "from" << nextSample.toString();
// qCDebug(dcEnergyExperience()) << "T Rectifying missed sample for" << sampleRate << "from" << nextSample.toString();
sampleThingPower(thingId, sampleRate, baseSampleRate, nextSample);
newestSample = nextSample;
}
@ -453,6 +495,9 @@ QDateTime EnergyLogger::nextSampleTimestamp(SampleRate sampleRate, const QDateTi
QDate date = dateTime.date();
QDateTime next;
switch (sampleRate) {
case SampleRateAny:
qCWarning(dcEnergyExperience()) << "Cannot calculate next sample timestamp without a sample rate";
return QDateTime();
case SampleRate1Min:
time.setHMS(time.hour(), time.minute(), 0);
next = QDateTime(date, time).addMSecs(60 * 1000);
@ -512,12 +557,20 @@ bool EnergyLogger::samplePowerBalance(SampleRate sampleRate, SampleRate baseSamp
double medianProduction = 0;
double medianAcquisition = 0;
double medianStorage = 0;
double totalConsumption = 0;
double totalProduction = 0;
double totalAcquisition = 0;
double totalReturn = 0;
while (query.next()) {
qCDebug(dcEnergyExperience()) << "Frame:" << query.value("consumption").toDouble() << query.value("production").toDouble() << query.value("acquisition").toDouble() << QDateTime::fromMSecsSinceEpoch(query.value("timestamp").toLongLong()).toString();
medianConsumption += query.value("consumption").toDouble();
medianProduction += query.value("production").toDouble();
medianAcquisition += query.value("acquisition").toDouble();
medianStorage += query.value("storage").toDouble();
totalConsumption = query.value("totalConsumption").toDouble();
totalProduction = query.value("totalProduction").toDouble();
totalAcquisition = query.value("totalAcquisition").toDouble();
totalReturn = query.value("totalReturn").toDouble();
}
qCDebug(dcEnergyExperience()) << "Totals:" << medianConsumption << medianProduction << medianAcquisition << medianStorage << "base samplerate" << baseSampleRate << "samplerate:" << sampleRate;
medianConsumption = medianConsumption * baseSampleRate / sampleRate;
@ -526,25 +579,29 @@ bool EnergyLogger::samplePowerBalance(SampleRate sampleRate, SampleRate baseSamp
medianStorage = medianStorage * baseSampleRate / sampleRate;
qCDebug(dcEnergyExperience()) << "Sampled:" << medianConsumption << medianProduction << medianAcquisition << medianStorage;
return insertPowerBalance(sampleEnd, sampleRate, medianConsumption, medianProduction, medianAcquisition, medianStorage);
return insertPowerBalance(sampleEnd, sampleRate, medianConsumption, medianProduction, medianAcquisition, medianStorage, totalConsumption, totalProduction, totalAcquisition, totalReturn);
}
bool EnergyLogger::insertPowerBalance(const QDateTime &timestamp, SampleRate sampleRate, double consumption, double production, double acquisition, double storage)
bool EnergyLogger::insertPowerBalance(const QDateTime &timestamp, SampleRate sampleRate, double consumption, double production, double acquisition, double storage, double totalConsumption, double totalProduction, double totalAcquisition, double totalReturn)
{
QSqlQuery query = QSqlQuery(m_db);
query.prepare("INSERT INTO powerBalance (timestamp, sampleRate, consumption, production, acquisition, storage) values (?, ?, ?, ?, ?, ?);");
query.prepare("INSERT INTO powerBalance (timestamp, sampleRate, consumption, production, acquisition, storage, totalConsumption, totalProduction, totalAcquisition, totalReturn) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
query.addBindValue(timestamp.toMSecsSinceEpoch());
query.addBindValue(sampleRate);
query.addBindValue(consumption);
query.addBindValue(production);
query.addBindValue(acquisition);
query.addBindValue(storage);
query.addBindValue(totalConsumption);
query.addBindValue(totalProduction);
query.addBindValue(totalAcquisition);
query.addBindValue(totalReturn);
query.exec();
if (query.lastError().isValid()) {
qCWarning(dcEnergyExperience()) << "Error logging consumption sample:" << query.lastError();
return false;
}
emit powerBalanceEntryAdded(sampleRate, PowerBalanceLogEntry(timestamp, consumption, production, acquisition, storage));
emit powerBalanceEntryAdded(sampleRate, PowerBalanceLogEntry(timestamp, consumption, production, acquisition, storage, totalConsumption, totalProduction, totalAcquisition, totalReturn));
return true;
}
@ -635,3 +692,17 @@ void EnergyLogger::trimThingPower(const ThingId &thingId, SampleRate sampleRate,
qCDebug(dcEnergyExperience()).nospace() << "Trimmed " << query.numRowsAffected() << " from thing power series for: " << thingId << sampleRate << " (Older than: " << beforeTime.toString() << ")";
}
}
PowerBalanceLogEntry EnergyLogger::queryResultToBalanceLogEntry(const QSqlRecord &record) const
{
return PowerBalanceLogEntry(QDateTime::fromMSecsSinceEpoch(record.value("timestamp").toLongLong()),
record.value("consumption").toDouble(),
record.value("production").toDouble(),
record.value("acquisition").toDouble(),
record.value("storage").toDouble(),
record.value("totalConsumption").toDouble(),
record.value("totalProduction").toDouble(),
record.value("totalAcquisition").toDouble(),
record.value("totalReturn").toDouble());
}

View File

@ -8,6 +8,7 @@
#include <QObject>
#include <QDateTime>
#include <QSqlDatabase>
#include <QSqlResult>
#include <QTimer>
#include <QMap>
@ -17,12 +18,14 @@ class EnergyLogger : public EnergyLogs
public:
explicit EnergyLogger(QObject *parent = nullptr);
void logPowerBalance(double consumption, double production, double acquisition, double storage);
void logPowerBalance(double consumption, double production, double acquisition, double storage, double totalConsumption, double totalProduction, double totalAcquisition, double totalReturn);
void logThingPower(const ThingId &thingId, double currentPower, double totalConsumption, double totalProduction);
PowerBalanceLogEntries powerBalanceLogs(SampleRate sampleRate, const QDateTime &from = QDateTime(), const QDateTime &to = QDateTime()) const override;
ThingPowerLogEntries thingPowerLogs(SampleRate sampleRate, const QList<ThingId> &thingIds, const QDateTime &from = QDateTime(), const QDateTime &to = QDateTime()) const override;
PowerBalanceLogEntry latestLogEntry(SampleRate sampleRate);
private slots:
void sample();
@ -40,13 +43,15 @@ private:
void rectifySamples(SampleRate sampleRate, EnergyLogger::SampleRate baseSampleRate);
bool samplePowerBalance(SampleRate sampleRate, SampleRate baseSampleRate, const QDateTime &sampleEnd);
bool insertPowerBalance(const QDateTime &timestamp, SampleRate sampleRate, double consumption, double production, double acquisition, double storage);
bool insertPowerBalance(const QDateTime &timestamp, SampleRate sampleRate, double consumption, double production, double acquisition, double storage, double totalConsumption, double totalProduction, double totalAcquisition, double totalReturn);
bool sampleThingsPower(SampleRate sampleRate, SampleRate baseSampleRate, const QDateTime &sampleEnd);
bool sampleThingPower(const ThingId &thingId, SampleRate sampleRate, SampleRate baseSampleRate, const QDateTime &sampleEnd);
bool insertThingPower(const QDateTime &timestamp, SampleRate sampleRate, const ThingId &thingId, double currentPower, double totalConsumption, double totalProduction);
void trimPowerBalance(SampleRate sampleRate, const QDateTime &beforeTime);
void trimThingPower(const ThingId &thingId, SampleRate sampleRate, const QDateTime &beforeTime);
PowerBalanceLogEntry queryResultToBalanceLogEntry(const QSqlRecord &record) const;
private:
struct SampleConfig {
SampleRate baseSampleRate;
@ -59,6 +64,11 @@ private:
QTimer m_sampleTimer;
QHash<SampleRate, QDateTime> m_nextSamples;
double m_lastSampleTotalConsumption = 0;
double m_lastSampleTotalProducation = 0;
double m_lastSampleTotalAcquisition = 0;
double m_lastSampleTotalReturn = 0;
QSqlDatabase m_db;
int m_maxMinuteSamples = 0;

View File

@ -24,6 +24,13 @@ EnergyManagerImpl::EnergyManagerImpl(ThingManager *thingManager, QObject *parent
EnergyManagerImpl::setRootMeter(rootMeterThingId);
qCDebug(dcEnergyExperience()) << "Loaded root meter" << rootMeterThingId;
PowerBalanceLogEntry latestEntry = m_logger->latestLogEntry(EnergyLogs::SampleRateAny);
m_totalConsumption = latestEntry.totalConsumption();
m_totalProduction = latestEntry.totalProduction();
m_totalAcquisition = latestEntry.totalAcquisition();
m_totalReturn = latestEntry.totalReturn();
qCDebug(dcEnergyExperience()) << "Loader power balance totals. Consumption:" << m_totalConsumption << "Production:" << m_totalProduction << "Acquisition:" << m_totalAcquisition << "Return:" << m_totalReturn;
foreach (Thing *thing, m_thingManager->configuredThings()) {
watchThing(thing);
}
@ -75,6 +82,26 @@ double EnergyManagerImpl::currentPowerStorage() const
return m_currentPowerStorage;
}
double EnergyManagerImpl::totalConsumption() const
{
return m_totalConsumption;
}
double EnergyManagerImpl::totalProduction() const
{
return m_totalProduction;
}
double EnergyManagerImpl::totalAcquisition() const
{
return m_totalAcquisition;
}
double EnergyManagerImpl::totalReturn() const
{
return m_totalReturn;
}
EnergyLogs *EnergyManagerImpl::logs() const
{
return m_logger;
@ -106,6 +133,10 @@ void EnergyManagerImpl::watchThing(Thing *thing)
|| thing->thingClass().interfaces().contains("smartmeterconsumer")
|| thing->thingClass().interfaces().contains("smartmeterproducer")
|| thing->thingClass().interfaces().contains("energystorage")) {
m_totalEnergyConsumedCache[thing] = thing->stateValue("totalEnergyConsumed").toDouble();
m_totalEnergyProducedCache[thing] = thing->stateValue("totalEnergyProduced").toDouble();
connect(thing, &Thing::stateValueChanged, this, [=](const StateTypeId &stateTypeId, const QVariant &value){
if (thing->thingClass().getStateType(stateTypeId).name() == "currentPower") {
m_logger->logThingPower(thing->id(), value.toDouble(), thing->state("totalEnergyConsumed").value().toDouble(), thing->state("totalEnergyProduced").value().toDouble());
@ -127,22 +158,44 @@ void EnergyManagerImpl::updatePowerBalance()
double currentPowerAcquisition = 0;
if (m_rootMeter) {
currentPowerAcquisition = m_rootMeter->stateValue("currentPower").toDouble();
double oldAcquisition = m_totalEnergyConsumedCache.value(m_rootMeter);
double newAcquisition = m_rootMeter->stateValue("totalEnergyConsumed").toDouble();
qCDebug(dcEnergyExperience()) << "Root meteter total consumption diff" << "old" << oldAcquisition << " new" << newAcquisition << (newAcquisition -oldAcquisition);
m_totalAcquisition += newAcquisition - oldAcquisition;
m_totalEnergyConsumedCache[m_rootMeter] = newAcquisition;
double oldReturn = m_totalEnergyProducedCache.value(m_rootMeter);
double newReturn = m_rootMeter->stateValue("totalEnergyProduced").toDouble();
qCDebug(dcEnergyExperience()) << "Root meteter total return diff" << "old" << oldReturn << " new" << newReturn << (newReturn - oldReturn);
m_totalReturn += newReturn - oldReturn;
m_totalEnergyProducedCache[m_rootMeter] = newReturn;
}
double currentPowerProduction = 0;
foreach (Thing* thing, m_thingManager->configuredThings().filterByInterface("smartmeterproducer")) {
currentPowerProduction += thing->stateValue("currentPower").toDouble();
double oldProduction = m_totalEnergyProducedCache.value(thing);
double newProduction = thing->stateValue("totalEnergyProduced").toDouble();
qCDebug(dcEnergyExperience()) << "inverter total production diff" << "old" << oldProduction << " new" << newProduction << (newProduction - oldProduction);
m_totalProduction += newProduction - oldProduction;
m_totalEnergyProducedCache[thing] = newProduction;
}
double currentPowerStorage = 0;
double totalFromStorage = 0;
foreach (Thing *thing, m_thingManager->configuredThings().filterByInterface("energystorage")) {
currentPowerStorage += thing->stateValue("currentPower").toDouble();
double oldProduction = m_totalEnergyProducedCache.value(thing);
double newProduction = thing->stateValue("totalEnergyProduced").toDouble();
totalFromStorage += newProduction - oldProduction;
m_totalEnergyProducedCache[thing] = newProduction;
}
double currentPowerConsumption = -currentPowerProduction + currentPowerAcquisition - currentPowerStorage;
double currentPowerConsumption = currentPowerAcquisition + qAbs(qMin(0.0, currentPowerProduction)) - currentPowerStorage;
m_totalConsumption = m_totalAcquisition + m_totalProduction + totalFromStorage;
qCDebug(dcEnergyExperience()) << "Consumption:" << currentPowerConsumption << "Production:" << currentPowerProduction << "Acquisition:" << currentPowerAcquisition << "Storage:" << currentPowerStorage;
qCDebug(dcEnergyExperience()).noquote().nospace() << "Power balance: " << "🔥: " << currentPowerConsumption << " W, 🌞: " << currentPowerProduction << " W, 💵: " << currentPowerAcquisition << " W, 🔋: " << currentPowerStorage << " W. Totals: 🔥: " << m_totalConsumption << " kWh, 🌞: " << m_totalProduction << " kWh, 💵↓: " << m_totalAcquisition << " kWh, 💵↑: " << m_totalReturn << " kWh";
if (currentPowerAcquisition != m_currentPowerAcquisition
|| currentPowerConsumption != m_currentPowerConsumption
|| currentPowerProduction != m_currentPowerProduction
@ -152,7 +205,7 @@ void EnergyManagerImpl::updatePowerBalance()
m_currentPowerConsumption = currentPowerConsumption;
m_currentPowerStorage = currentPowerStorage;
emit powerBalanceChanged();
m_logger->logPowerBalance(m_currentPowerConsumption, m_currentPowerProduction, m_currentPowerAcquisition, m_currentPowerStorage);
m_logger->logPowerBalance(m_currentPowerConsumption, m_currentPowerProduction, m_currentPowerAcquisition, m_currentPowerStorage, m_totalConsumption, m_totalProduction, m_totalAcquisition, m_totalReturn);
}
}

View File

@ -24,6 +24,10 @@ public:
double currentPowerProduction() const override;
double currentPowerAcquisition() const override;
double currentPowerStorage() const override;
double totalConsumption() const override;
double totalProduction() const override;
double totalAcquisition() const override;
double totalReturn() const override;
EnergyLogs* logs() const override;
@ -42,12 +46,19 @@ private:
Thing *m_rootMeter = nullptr;
QTimer m_balanceUpdateTimer;
double m_currentPowerConsumption;
double m_currentPowerProduction;
double m_currentPowerAcquisition;
double m_currentPowerStorage;
double m_currentPowerConsumption = 0;
double m_currentPowerProduction = 0;
double m_currentPowerAcquisition = 0;
double m_currentPowerStorage = 0;
double m_totalConsumption = 0;
double m_totalProduction = 0;
double m_totalAcquisition = 0;
double m_totalReturn = 0;
EnergyLogger *m_logger = nullptr;
QHash<Thing*, double> m_totalEnergyConsumedCache;
QHash<Thing*, double> m_totalEnergyProducedCache;
};
#endif // ENERGYMANAGERIMPL_H