From 6f5850f7c61185086c56d0765861dbbe7d58a591 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Tue, 9 Nov 2021 14:03:19 +0100 Subject: [PATCH] Add energy manager class --- libnymea-app/energy/energymanager.cpp | 108 ++++++++++++++++++ libnymea-app/energy/energymanager.h | 53 +++++++++ libnymea-app/jsonrpc/jsonrpcclient.cpp | 4 +- libnymea-app/libnymea-app-core.h | 3 + libnymea-app/libnymea-app.pri | 2 + .../ui/devicepages/EvChargerThingPage.qml | 4 +- 6 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 libnymea-app/energy/energymanager.cpp create mode 100644 libnymea-app/energy/energymanager.h diff --git a/libnymea-app/energy/energymanager.cpp b/libnymea-app/energy/energymanager.cpp new file mode 100644 index 00000000..3d8de270 --- /dev/null +++ b/libnymea-app/energy/energymanager.cpp @@ -0,0 +1,108 @@ +#include "energymanager.h" + +#include "engine.h" + +#include "logging.h" + +NYMEA_LOGGING_CATEGORY(dcEnergyExperience, "EnergyExperience") + +EnergyManager::EnergyManager(QObject *parent) : QObject(parent) +{ + +} + +EnergyManager::~EnergyManager() +{ + if (m_engine) { + m_engine->jsonRpcClient()->unregisterNotificationHandler(this); + } +} + +Engine *EnergyManager::engine() const +{ + return m_engine; +} + +void EnergyManager::setEngine(Engine *engine) +{ + if (m_engine != engine) { + if (m_engine) { + m_engine->jsonRpcClient()->unregisterNotificationHandler(this); + } + + m_engine = engine; + emit engineChanged(); + + if (m_engine) { + m_engine->jsonRpcClient()->registerNotificationHandler(this, "Energy", "notificationReceived"); + m_engine->jsonRpcClient()->sendCommand("Energy.GetRootMeter", QVariantMap(), this, "getRootMeterResponse"); + m_engine->jsonRpcClient()->sendCommand("Energy.GetPowerBalance", QVariantMap(), this, "getPowerBalanceResponse"); + } + } +} + +QUuid EnergyManager::rootMeterId() const +{ + return m_rootMeterId; +} + +int EnergyManager::setRootMeterId(const QUuid &rootMeterId) +{ + if (!m_engine) { + return -1; + } + QVariantMap params; + params.insert("rootMeterThingId", rootMeterId); + return m_engine->jsonRpcClient()->sendCommand("Energy.SetRootMeter", params); +} + +double EnergyManager::currentPowerConsumption() const +{ + return m_currentPowerConsumption; +} + +double EnergyManager::currentPowerProduction() const +{ + return m_currentPowerProduction; +} + +double EnergyManager::currentPowerAcquisition() const +{ + return m_currentPowerAcquisition; +} + +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") { + m_currentPowerConsumption = params.value("currentPowerConsumption").toDouble(); + m_currentPowerProduction = params.value("currentPowerProduction").toDouble(); + m_currentPowerAcquisition = params.value("currentPowerAcquisition").toDouble(); + emit powerBalanceChanged(); + } +} + +void EnergyManager::getRootMeterResponse(int commandId, const QVariantMap ¶ms) +{ + Q_UNUSED(commandId) + qCDebug(dcEnergyExperience) << "RootMeter response:" << params; + m_rootMeterId = params.value("rootMeterThingId").toUuid(); + emit rootMeterIdChanged(); +} + +void EnergyManager::getPowerBalanceResponse(int commandId, const QVariantMap ¶ms) +{ + Q_UNUSED(commandId) + qCDebug(dcEnergyExperience()) << "Power balance response:" << params; + m_currentPowerConsumption = params.value("currentPowerConsumption").toDouble(); + m_currentPowerProduction = params.value("currentPowerProduction").toDouble(); + m_currentPowerAcquisition = params.value("currentPowerAcquisition").toDouble(); + emit powerBalanceChanged(); +} + diff --git a/libnymea-app/energy/energymanager.h b/libnymea-app/energy/energymanager.h new file mode 100644 index 00000000..23c98e21 --- /dev/null +++ b/libnymea-app/energy/energymanager.h @@ -0,0 +1,53 @@ +#ifndef ENERGYMANAGER_H +#define ENERGYMANAGER_H + +#include +#include + +class Engine; + +class EnergyManager : public QObject +{ + Q_OBJECT + Q_PROPERTY(Engine* engine READ engine WRITE setEngine NOTIFY engineChanged) + Q_PROPERTY(QUuid rootMeterId READ rootMeterId NOTIFY rootMeterIdChanged) + + Q_PROPERTY(double currentPowerConsumption READ currentPowerConsumption NOTIFY powerBalanceChanged) + Q_PROPERTY(double currentPowerProduction READ currentPowerProduction NOTIFY powerBalanceChanged) + Q_PROPERTY(double currentPowerAcquisition READ currentPowerAcquisition NOTIFY powerBalanceChanged) + +public: + explicit EnergyManager(QObject *parent = nullptr); + ~EnergyManager(); + + Engine* engine() const; + void setEngine(Engine *engine); + + QUuid rootMeterId() const; + Q_INVOKABLE int setRootMeterId(const QUuid &rootMeterId); + + double currentPowerConsumption() const; + double currentPowerProduction() const; + double currentPowerAcquisition() const; + +signals: + void engineChanged(); + void rootMeterIdChanged(); + void powerBalanceChanged(); + +private slots: + void notificationReceived(const QVariantMap &data); + void getRootMeterResponse(int commandId, const QVariantMap ¶ms); + void getPowerBalanceResponse(int commandId, const QVariantMap ¶ms); + +private: + Engine *m_engine = nullptr; + QUuid m_rootMeterId; + + double m_currentPowerConsumption = 0; + double m_currentPowerProduction = 0; + double m_currentPowerAcquisition = 0; + +}; + +#endif // ENERGYMANAGER_H diff --git a/libnymea-app/jsonrpc/jsonrpcclient.cpp b/libnymea-app/jsonrpc/jsonrpcclient.cpp index c491ad0a..c46c1dc2 100644 --- a/libnymea-app/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app/jsonrpc/jsonrpcclient.cpp @@ -74,8 +74,8 @@ JsonRpcClient::JsonRpcClient(QObject *parent) : void JsonRpcClient::registerNotificationHandler(QObject *handler, const QString &nameSpace, const QString &method) { - if (m_notificationHandlerMethods.contains(handler)) { - qWarning() << "Notification handler" << handler << " already registered"; + if (m_notificationHandlers.key(handler) == nameSpace) { + qWarning() << "Notification handler" << handler << " already registered for namespace" << nameSpace; return; } m_notificationHandlers.insert(nameSpace, handler); diff --git a/libnymea-app/libnymea-app-core.h b/libnymea-app/libnymea-app-core.h index e8909e8d..118b0523 100644 --- a/libnymea-app/libnymea-app-core.h +++ b/libnymea-app/libnymea-app-core.h @@ -135,6 +135,7 @@ #include "modbus/modbusrtumanager.h" #include "modbus/modbusrtumasters.h" #include "types/serialportsproxy.h" +#include "energy/energymanager.h" #include @@ -357,6 +358,8 @@ void registerQmlTypes() { qmlRegisterType(uri, 1, 0, "AppData"); + qmlRegisterType(uri, 1, 0, "EnergyManager"); + qmlRegisterType(uri, 1, 0, "SortFilterProxyModel"); } diff --git a/libnymea-app/libnymea-app.pri b/libnymea-app/libnymea-app.pri index dd779de7..9c8461cf 100644 --- a/libnymea-app/libnymea-app.pri +++ b/libnymea-app/libnymea-app.pri @@ -21,6 +21,7 @@ INCLUDEPATH += \ SOURCES += \ $$PWD/appdata.cpp \ + $$PWD/energy/energymanager.cpp \ $$PWD/models/scriptsproxymodel.cpp \ $$PWD/tagwatcher.cpp \ $$PWD/zigbee/zigbeenode.cpp \ @@ -177,6 +178,7 @@ SOURCES += \ HEADERS += \ $$PWD/appdata.h \ + $$PWD/energy/energymanager.h \ $$PWD/models/scriptsproxymodel.h \ $$PWD/tagwatcher.h \ $$PWD/zigbee/zigbeenode.h \ diff --git a/nymea-app/ui/devicepages/EvChargerThingPage.qml b/nymea-app/ui/devicepages/EvChargerThingPage.qml index f37ef188..b111ec60 100644 --- a/nymea-app/ui/devicepages/EvChargerThingPage.qml +++ b/nymea-app/ui/devicepages/EvChargerThingPage.qml @@ -58,7 +58,9 @@ ThingPageBase { id: background Layout.fillWidth: true Layout.fillHeight: true - Layout.margins: Style.hugeMargins + Layout.leftMargin: Style.hugeMargins + Layout.rightMargin: Style.hugeMargins + Layout.topMargin: Style.hugeMargins // iconSource: "ev-charger" onColor: app.interfaceToColor("evcharger") // on: (actionQueue.pendingValue || powerState.value) === true