Add energy logs support

This commit is contained in:
Michael Zanetti 2021-11-18 13:27:00 +01:00
parent 2d34f607d8
commit 64b31e7626
8 changed files with 422 additions and 4 deletions

View File

@ -0,0 +1,123 @@
#include "energylogs.h"
#include "powerbalancelogs.h"
#include <QMetaEnum>
#include "logging.h"
NYMEA_LOGGING_CATEGORY(dcEnergyLogs, "EnergyLogs")
EnergyLogs::EnergyLogs(QObject *parent) : QObject(parent)
{
m_powerBalanceLogs = new PowerBalanceLogs(this);
}
Engine *EnergyLogs::engine() const
{
return m_engine;
}
void EnergyLogs::setEngine(Engine *engine)
{
if (m_engine != engine) {
m_engine = engine;
emit engineChanged();
if (!m_engine) {
return;
}
qCDebug(dcEnergyLogs()) << "************* getting energylogs" << m_engine->jsonRpcClient()->experiences();
if (m_engine->jsonRpcClient()->experiences().value("Energy").toString() >= "1.0") {
QVariantMap params;
QMetaEnum metaEnum = QMetaEnum::fromType<SampleRate>();
params.insert("sampleRate", metaEnum.valueToKey(m_sampleRate));
m_engine->jsonRpcClient()->registerNotificationHandler(this, "Energy", "notificationReceived");
m_engine->jsonRpcClient()->sendCommand("Energy.GetPowerBalanceLogs", params, this, "powerBalanceLogsReceived");
// m_engine->jsonRpcClient()->sendCommand("Energy.GetThingPowerLogs", params, this, "thingPowerLogsReceived");
}
}
}
EnergyLogs::SampleRate EnergyLogs::sampleRate() const
{
return m_sampleRate;
}
void EnergyLogs::setSampleRate(SampleRate sampleRate)
{
if (m_sampleRate != sampleRate) {
m_sampleRate = sampleRate;
emit sampleRateChanged();
}
}
bool EnergyLogs::fetchPowerBalance() const
{
return m_fetchPowerBalance;
}
void EnergyLogs::setFetchPowerBalance(bool fetchPowerBalance)
{
if (m_fetchPowerBalance != fetchPowerBalance) {
m_fetchPowerBalance = fetchPowerBalance;
emit fetchPowerBalanceChanged();
}
}
QList<QUuid> EnergyLogs::thingIds() const
{
return m_thingIds;
}
void EnergyLogs::setThingIds(const QList<QUuid> &thingIds)
{
if (m_thingIds != thingIds) {
m_thingIds = thingIds;
emit thingIdsChanged();
}
}
PowerBalanceLogs *EnergyLogs::powerBalanceLogs() const
{
return m_powerBalanceLogs;
}
void EnergyLogs::powerBalanceLogsReceived(int commandId, const QVariantMap &params)
{
Q_UNUSED(commandId)
foreach (const QVariant &variant, params.value("powerBalanceLogEntries").toList()) {
QVariantMap map = variant.toMap();
QDateTime timestamp = QDateTime::fromSecsSinceEpoch(map.value("timestamp").toLongLong());
double consumption = map.value("consumption").toDouble();
double production = map.value("production").toDouble();
double acquisition = map.value("acquisition").toDouble();
double storage = map.value("storage").toDouble();
PowerBalanceLogEntry *entry = new PowerBalanceLogEntry(timestamp, consumption, production, acquisition, storage, this);
m_powerBalanceLogs->addEntry(entry);
}
}
void EnergyLogs::thingPowerLogsReceived(int commandId, const QVariantMap &params)
{
Q_UNUSED(commandId)
qCDebug(dcEnergyLogs) << "got energy logs";
}
void EnergyLogs::notificationReceived(const QVariantMap &data)
{
QString notification = data.value("notification").toString();
QVariantMap params = data.value("params").toMap();
if (notification == "Energy.PowerBalanceLogEntryAdded") {
QVariantMap map = data.value("powerBalanceLogEntry").toMap();
QDateTime timestamp = QDateTime::fromSecsSinceEpoch(map.value("timestamp").toLongLong());
double consumption = map.value("consumption").toDouble();
double production = map.value("production").toDouble();
double acquisition = map.value("acquisition").toDouble();
double storage = map.value("storage").toDouble();
PowerBalanceLogEntry *entry = new PowerBalanceLogEntry(timestamp, consumption, production, acquisition, storage, this);
m_powerBalanceLogs->addEntry(entry);
}
}

View File

@ -0,0 +1,69 @@
#ifndef ENERGYLOGS_H
#define ENERGYLOGS_H
#include "engine.h"
#include <QObject>
#include <QUuid>
class PowerBalanceLogs;
class EnergyLogs : public QObject
{
Q_OBJECT
Q_PROPERTY(Engine *engine READ engine WRITE setEngine NOTIFY engineChanged)
Q_PROPERTY(SampleRate sampleRate READ sampleRate WRITE setSampleRate NOTIFY sampleRateChanged)
Q_PROPERTY(bool fetchPowerBalance READ fetchPowerBalance WRITE setFetchPowerBalance NOTIFY fetchPowerBalanceChanged)
Q_PROPERTY(QList<QUuid> thingIds READ thingIds WRITE setThingIds NOTIFY thingIdsChanged)
Q_PROPERTY(PowerBalanceLogs *powerBalanceLogs READ powerBalanceLogs CONSTANT)
public:
enum SampleRate {
SampleRate1Min = 1,
SampleRate15Mins = 15,
SampleRate1Hour = 60,
SampleRate3Hours = 180,
SampleRate1Day = 1440,
SampleRate1Week = 10080,
SampleRate1Month = 43200,
SampleRate1Year = 525600
};
Q_ENUM(SampleRate)
explicit EnergyLogs(QObject *parent = nullptr);
Engine *engine() const;
void setEngine(Engine *engine);
SampleRate sampleRate() const;
void setSampleRate(SampleRate sampleRate);
bool fetchPowerBalance() const;
void setFetchPowerBalance(bool fetchPowerBalance);
QList<QUuid> thingIds() const;
void setThingIds(const QList<QUuid> &thingIds);
PowerBalanceLogs *powerBalanceLogs() const;
signals:
void engineChanged();
void sampleRateChanged();
void fetchPowerBalanceChanged();
void thingIdsChanged();
private slots:
void powerBalanceLogsReceived(int commandId, const QVariantMap &params);
void thingPowerLogsReceived(int commandId, const QVariantMap &params);
void notificationReceived(const QVariantMap &data);
private:
Engine *m_engine = nullptr;
SampleRate m_sampleRate = SampleRate15Mins;
bool m_fetchPowerBalance = true;
QList<QUuid> m_thingIds;
PowerBalanceLogs *m_powerBalanceLogs = nullptr;
};
#endif // ENERGYLOGS_H

View File

@ -73,18 +73,25 @@ double EnergyManager::currentPowerAcquisition() const
void EnergyManager::notificationReceived(const QVariantMap &data)
{
qCDebug(dcEnergyExperience()) << "Energy notification received" << data;
QString notification = data.value("notification").toString();
QVariantMap params = data.value("params").toMap();
if (notification == "Energy.RootMeterChanged") {
m_rootMeterId = params.value("rootMeterThingId").toUuid();
emit rootMeterIdChanged();
}
if (notification == "Energy.PowerBalanceChanged") {
} else if (notification == "Energy.PowerBalanceChanged") {
m_currentPowerConsumption = params.value("currentPowerConsumption").toDouble();
m_currentPowerProduction = params.value("currentPowerProduction").toDouble();
m_currentPowerAcquisition = params.value("currentPowerAcquisition").toDouble();
emit powerBalanceChanged();
} else if (notification == "Energy.PowerBalanceLogEntryAdded") {
// Handled in EnergyLogs
} else if (notification == "Energy.ThingPowerLogEntryAdded") {
// Handled in EnergyLogs
} else {
qCDebug(dcEnergyExperience()) << "Unhandled energy notification received" << data;
}
}

View File

@ -0,0 +1,129 @@
#include "powerbalancelogs.h"
PowerBalanceLogEntry::PowerBalanceLogEntry(const QDateTime &timestamp, double consumption, double production, double acquisition, double storage, QObject *parent):
QObject(parent),
m_timestamp(timestamp),
m_consumption(consumption),
m_production(production),
m_acquisition(acquisition),
m_storage(storage)
{
}
QDateTime PowerBalanceLogEntry::timestamp() const
{
return m_timestamp;
}
double PowerBalanceLogEntry::consumption() const
{
return m_consumption;
}
double PowerBalanceLogEntry::production() const
{
return m_production;
}
double PowerBalanceLogEntry::acquisition() const
{
return m_acquisition;
}
double PowerBalanceLogEntry::storage() const
{
return m_storage;
}
PowerBalanceLogs::PowerBalanceLogs(QObject *parent) : QAbstractListModel(parent)
{
}
int PowerBalanceLogs::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_list.count();
}
QVariant PowerBalanceLogs::data(const QModelIndex &index, int role) const
{
return QVariant();
}
QHash<int, QByteArray> PowerBalanceLogs::roleNames() const
{
QHash<int, QByteArray> roles;
return roles;
}
double PowerBalanceLogs::minValue() const
{
return m_minValue;
}
double PowerBalanceLogs::maxValue() const
{
return m_maxValue;
}
void PowerBalanceLogs::addEntry(PowerBalanceLogEntry *entry)
{
entry->setParent(this);
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
m_list.append(entry);
endInsertRows();
emit entryAdded(entry);
emit countChanged();
if (entry->consumption() < m_minValue) {
m_minValue = entry->consumption();
emit minValueChanged();
}
if (entry->consumption() > m_maxValue) {
m_maxValue = entry->consumption();
emit maxValueChanged();
}
if (entry->production() < m_minValue) {
m_minValue = entry->production();
emit minValueChanged();
}
if (entry->production() > m_maxValue) {
m_maxValue = entry->production();
emit maxValueChanged();
}
if (entry->acquisition() < m_minValue) {
m_minValue = entry->acquisition();
emit minValueChanged();
}
if (entry->acquisition() > m_maxValue) {
m_maxValue = entry->acquisition();
emit maxValueChanged();
}
if (entry->storage() < m_minValue) {
m_minValue = entry->storage();
emit minValueChanged();
}
if (entry->storage() > m_maxValue) {
m_maxValue = entry->storage();
emit maxValueChanged();
}
}
PowerBalanceLogs *PowerBalanceLogsProxy::powerBalanceLogs() const
{
return m_powerBalanceLogs;
}
void PowerBalanceLogsProxy::setPowerBalanceLogs(PowerBalanceLogs *powerBalanceLogs)
{
if (m_powerBalanceLogs != powerBalanceLogs) {
m_powerBalanceLogs = powerBalanceLogs;
setSourceModel(powerBalanceLogs);
emit powerBalanceLogsChanged();
}
}

View File

@ -0,0 +1,82 @@
#ifndef POWERBALANCELOGS_H
#define POWERBALANCELOGS_H
#include <QObject>
#include <QAbstractListModel>
#include <QDateTime>
#include <QSortFilterProxyModel>
class PowerBalanceLogEntry: public QObject
{
Q_OBJECT
Q_PROPERTY(QDateTime timestamp READ timestamp CONSTANT)
Q_PROPERTY(double consumption READ consumption CONSTANT)
Q_PROPERTY(double production READ production CONSTANT)
Q_PROPERTY(double acquisition READ acquisition CONSTANT)
Q_PROPERTY(double storage READ storage CONSTANT)
public:
PowerBalanceLogEntry() = default;
PowerBalanceLogEntry(const QDateTime &timestamp, double consumption, double production, double acquisition, double storage, QObject *parent);
QDateTime timestamp() const;
double consumption() const;
double production() const;
double acquisition() const;
double storage() const;
private:
QDateTime m_timestamp;
double m_consumption = 0;
double m_production = 0;
double m_acquisition = 0;
double m_storage = 0;
};
class PowerBalanceLogs : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(double minValue READ minValue NOTIFY minValueChanged)
Q_PROPERTY(double maxValue READ maxValue NOTIFY maxValueChanged)
public:
explicit PowerBalanceLogs(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
double minValue() const;
double maxValue() const;
void addEntry(PowerBalanceLogEntry *entry);
signals:
void countChanged();
void entryAdded(PowerBalanceLogEntry *entry);
void minValueChanged();
void maxValueChanged();
private:
QList<PowerBalanceLogEntry*> m_list;
double m_minValue = 0;
double m_maxValue = 0;
};
class PowerBalanceLogsProxy: public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(PowerBalanceLogs* powerBalanceLogs READ powerBalanceLogs WRITE setPowerBalanceLogs NOTIFY powerBalanceLogsChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
PowerBalanceLogsProxy(QObject *parent);
PowerBalanceLogs *powerBalanceLogs() const;
void setPowerBalanceLogs(PowerBalanceLogs *powerBalanceLogs);
signals:
void countChanged();
void powerBalanceLogsChanged();
private:
PowerBalanceLogs *m_powerBalanceLogs = nullptr;
};
#endif // POWERBALANCELOGS_H

View File

@ -136,6 +136,8 @@
#include "modbus/modbusrtumasters.h"
#include "types/serialportsproxy.h"
#include "energy/energymanager.h"
#include "energy/energylogs.h"
#include "energy/powerbalancelogs.h"
#include <QtQml/qqml.h>
@ -359,6 +361,9 @@ void registerQmlTypes() {
qmlRegisterType<AppData>(uri, 1, 0, "AppData");
qmlRegisterType<EnergyManager>(uri, 1, 0, "EnergyManager");
qmlRegisterType<EnergyLogs>(uri, 1, 0, "EnergyLogs");
qmlRegisterType<PowerBalanceLogs>(uri, 1, 0, "PowerBalanceLogs");
qmlRegisterType<PowerBalanceLogEntry>(uri, 1, 0, "PowerBalanceLogEntry");
qmlRegisterType<SortFilterProxyModel>(uri, 1, 0, "SortFilterProxyModel");
}

View File

@ -21,7 +21,9 @@ INCLUDEPATH += \
SOURCES += \
$$PWD/appdata.cpp \
$$PWD/energy/energylogs.cpp \
$$PWD/energy/energymanager.cpp \
$$PWD/energy/powerbalancelogs.cpp \
$$PWD/models/scriptsproxymodel.cpp \
$$PWD/tagwatcher.cpp \
$$PWD/zigbee/zigbeenode.cpp \
@ -178,7 +180,9 @@ SOURCES += \
HEADERS += \
$$PWD/appdata.h \
$$PWD/energy/energylogs.h \
$$PWD/energy/energymanager.h \
$$PWD/energy/powerbalancelogs.h \
$$PWD/models/scriptsproxymodel.h \
$$PWD/tagwatcher.h \
$$PWD/zigbee/zigbeenode.h \

View File

@ -217,7 +217,6 @@ void RuleManager::removeRuleResponse(int commandId, const QVariantMap &params)
qCDebug(dcRuleManager) << "Have remove rule reply" << commandId << params;
QMetaEnum metaEnum = QMetaEnum::fromType<RuleError>();
RuleError ruleError = static_cast<RuleError>(metaEnum.keyToValue(params.value("ruleError").toByteArray()));
qCritical() << "DAFUQQQ" << commandId << ruleError;
emit removeRuleReply(commandId, ruleError);
}