Add totals to balance
parent
d684016498
commit
034f90d7a9
|
|
@ -12,12 +12,16 @@ PowerBalanceLogEntry::PowerBalanceLogEntry()
|
|||
|
||||
}
|
||||
|
||||
PowerBalanceLogEntry::PowerBalanceLogEntry(const QDateTime ×tamp, double consumption, double production, double acquisition, double storage):
|
||||
PowerBalanceLogEntry::PowerBalanceLogEntry(const QDateTime ×tamp, 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));
|
||||
|
|
|
|||
|
|
@ -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 ×tamp, double consumption, double production, double acquisition, double storage);
|
||||
PowerBalanceLogEntry(const QDateTime ×tamp, 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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ¶ms)
|
|||
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 ¶ms)
|
||||
{
|
||||
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)));
|
||||
|
|
|
|||
|
|
@ -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 ×tamp, SampleRate sampleRate, double consumption, double production, double acquisition, double storage)
|
||||
bool EnergyLogger::insertPowerBalance(const QDateTime ×tamp, 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());
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ×tamp, SampleRate sampleRate, double consumption, double production, double acquisition, double storage);
|
||||
bool insertPowerBalance(const QDateTime ×tamp, 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 ×tamp, 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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue