Add nymea energy experience plugin

This commit is contained in:
Michael Zanetti 2021-11-08 18:31:07 +01:00
parent 38b43eecc9
commit 885fe9be3a
22 changed files with 900 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.pro.user
.crossbuilder/*

10
config.pri Normal file
View File

@ -0,0 +1,10 @@
gcc {
COMPILER_VERSION = $$system($$QMAKE_CXX " -dumpversion")
COMPILER_MAJOR_VERSION = $$str_member($$COMPILER_VERSION)
greaterThan(COMPILER_MAJOR_VERSION, 7): QMAKE_CXXFLAGS += -Wno-deprecated-copy
}
top_srcdir = $$PWD
top_builddir = $$shadowed($$PWD)
CONFIG += c++11

3
debian/changelog vendored Normal file
View File

@ -0,0 +1,3 @@
nymea-experience-plugin-energy (0.3) xenial; urgency=medium
-- Jenkins <jenkins@nymea.io> Tue, 05 Oct 2021 08:33:51 +0200

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
9

42
debian/control vendored Normal file
View File

@ -0,0 +1,42 @@
Source: nymea-experience-plugin-energy
Section: utils
Priority: optional
Maintainer: Michael Zanetti <michael.zanetti@nymea.io>
Standards-Version: 3.9.7
Homepage: https://nymea.io
Build-Depends: debhelper (>= 9.0.0),
dpkg-dev (>= 1.16.1~),
libnymea-dev (>= 0.17),
nymea-dev-tools:native,
qt5-qmake,
qtbase5-dev,
Package: nymea-experience-plugin-energy
Section: libs
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends},
${misc:Depends},
Description: nymea experiece plugin for energy related use cases
This nymea experience adds the support energy related use
caes to nymea.
Package: libnymea-energy
Section: libs
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends},
${misc:Depends},
Description: Library for nymea energy experience plugins
This library is used by plugins loaded by the nymea
energy experience.
Package: libnymea-energy-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends},
${misc:Depends},
libnymea-energy (= ${binary:Version}),
Description: Library for nymea expergy experience plugins - Development files

3
debian/libnymea-energy-dev.install.in vendored Normal file
View File

@ -0,0 +1,3 @@
usr/lib/@DEB_HOST_MULTIARCH@/libnymea-energy.so
usr/include/nymea-energy/*.h
usr/lib/@DEB_HOST_MULTIARCH@/pkgconfig/nymea-energy.pc

3
debian/libnymea-energy.install.in vendored Normal file
View File

@ -0,0 +1,3 @@
usr/lib/@DEB_HOST_MULTIARCH@/libnymea-energy.so.1
usr/lib/@DEB_HOST_MULTIARCH@/libnymea-energy.so.1.0
usr/lib/@DEB_HOST_MULTIARCH@/libnymea-energy.so.1.0.0

View File

@ -0,0 +1 @@
usr/lib/@DEB_HOST_MULTIARCH@/nymea/experiences/libnymea_experiencepluginenergy.so

27
debian/rules vendored Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/make -f
# -*- makefile -*-
export DH_VERBOSE=1
export QT_QPA_PLATFORM=minimal
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
PREPROCESS_FILES := $(wildcard debian/*.in)
$(PREPROCESS_FILES:.in=): %: %.in
sed 's,/@DEB_HOST_MULTIARCH@,$(DEB_HOST_MULTIARCH:%=/%),g' $< > $@
override_dh_install: $(PREPROCESS_FILES:.in=)
dh_install
override_dh_auto_clean:
dh_auto_clean
rm -rf $(PREPROCESS_FILES:.in=)
override_dh_auto_test:
override_dh_install: $(PREPROCESS_FILES:.in=)
dh_install --fail-missing
%:
dh $@ --buildsystem=qmake --parallel

View File

@ -0,0 +1,37 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "energymanager.h"
EnergyManager::EnergyManager(QObject *parent) : QObject(parent)
{
}

View File

@ -0,0 +1,65 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ENERGYMANAGER_H
#define ENERGYMANAGER_H
#include <QObject>
#include <integrations/thing.h>
class EnergyManager : public QObject
{
Q_OBJECT
public:
enum EnergyError {
EnergyErrorNoError,
EnergyErrorMissingParameter,
EnergyErrorInvalidParameter,
};
Q_ENUM(EnergyError)
explicit EnergyManager(QObject *parent = nullptr);
virtual ~EnergyManager() = default;
virtual EnergyError setRootMeter(const ThingId &rootMeterId) = 0;
virtual Thing *rootMeter() const = 0;
virtual double currentPowerConsumption() const = 0;
virtual double currentPowerProduction() const = 0;
virtual double currentPowerAcquisition() const = 0;
signals:
void rootMeterChanged();
void powerBalanceChanged();
};
#endif // ENERGYMANAGER_H

View File

@ -0,0 +1,61 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "energyplugin.h"
EnergyPlugin::EnergyPlugin(QObject *parent) : QObject(parent)
{
}
EnergyManager *EnergyPlugin::energyManager() const
{
return m_energyManager;
}
ThingManager *EnergyPlugin::thingManager() const
{
return m_thingManager;
}
JsonRPCServer *EnergyPlugin::jsonRpcServer() const
{
return m_jsonRpcServer;
}
void EnergyPlugin::initPlugin(EnergyManager *energyManager, ThingManager *thingManager, JsonRPCServer *jsonRPCServer)
{
m_energyManager = energyManager;
m_thingManager = thingManager;
m_jsonRpcServer = jsonRPCServer;
init();
}

View File

@ -0,0 +1,66 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ENERGYPLUGIN_H
#define ENERGYPLUGIN_H
#include <QObject>
#include <jsonrpc/jsonrpcserver.h>
#include <integrations/thingmanager.h>
#include "energymanager.h"
class EnergyPlugin : public QObject
{
Q_OBJECT
public:
explicit EnergyPlugin(QObject *parent = nullptr);
virtual ~EnergyPlugin() = default;
virtual void init() = 0;
protected:
EnergyManager* energyManager() const;
ThingManager* thingManager() const;
JsonRPCServer* jsonRpcServer() const;
private:
friend class ExperiencePluginEnergy;
void initPlugin(EnergyManager *energyManager, ThingManager *thingManager, JsonRPCServer *jsonRPCServer);
EnergyManager *m_energyManager = nullptr;
ThingManager *m_thingManager = nullptr;
JsonRPCServer *m_jsonRpcServer = nullptr;
};
Q_DECLARE_INTERFACE(EnergyPlugin, "io.nymea.EnergyPlugin")
#endif // ENERGYPLUGIN_H

View File

@ -0,0 +1,38 @@
TEMPLATE = lib
TARGET = $$qtLibraryTarget(nymea-energy)
include(../config.pri)
NYMEA_ENERGY_VERSION_STRING = "0.0.1"
CONFIG += link_pkgconfig
PKGCONFIG += nymea
HEADERS += \
energymanager.h \
energyplugin.h
SOURCES += \
energymanager.cpp \
energyplugin.cpp
target.path = $$[QT_INSTALL_LIBS]
INSTALLS += target
for(header, HEADERS) {
path = $$[QT_INSTALL_PREFIX]/include/nymea-energy/$${dirname(header)}
eval(headers_$${path}.files += $${header})
eval(headers_$${path}.path = $${path})
eval(INSTALLS *= headers_$${path})
}
CONFIG += create_pc create_prl no_install_prl
QMAKE_PKGCONFIG_NAME = libnymea-energy
QMAKE_PKGCONFIG_DESCRIPTION = nymea energy library
QMAKE_PKGCONFIG_PREFIX = $$[QT_INSTALL_PREFIX]
QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_PREFIX]/include/nymea-energy/
QMAKE_PKGCONFIG_LIBDIR = $$target.path
QMAKE_PKGCONFIG_VERSION = $$NYMEA_ENERGY_VERSION_STRING
QMAKE_PKGCONFIG_FILE = nymea-energy
QMAKE_PKGCONFIG_DESTDIR = pkgconfig

View File

@ -0,0 +1,7 @@
TEMPLATE = subdirs
SUBDIRS += libnymea-energy plugin
plugin.depends = libnymea-energy

View File

@ -0,0 +1,98 @@
#include "energyjsonhandler.h"
#include "energymanagerimpl.h"
Q_DECLARE_LOGGING_CATEGORY(dcEnergyExperience)
EnergyJsonHandler::EnergyJsonHandler(EnergyManager *energyManager, QObject *parent):
JsonHandler(parent),
m_energyManager(energyManager)
{
registerEnum<EnergyManager::EnergyError>();
QVariantMap params, returns;
QString description;
params.clear(); returns.clear();
description = "Get the root meter ID. If there is no root meter set, the params will be empty.";
returns.insert("o:rootMeterThingId", enumValueName(Uuid));
registerMethod("GetRootMeter", description, params, returns);
params.clear(); returns.clear();
description = "Set the root meter.";
params.insert("rootMeterThingId", enumValueName(Uuid));
returns.insert("energyError", enumRef<EnergyManager::EnergyError>());
registerMethod("SetRootMeter", description, params, returns);
params.clear(); returns.clear();
description = "Get the current power balance. That is, production, consumption and acquisition.";
returns.insert("currentPowerConsumption", enumValueName(Double));
returns.insert("currentPowerProduction", enumValueName(Double));
returns.insert("currentPowerAcquisition", enumValueName(Double));
registerMethod("GetPowerBalance", description, params, returns);
params.clear();
description = "Emitted whenever the root meter id changes. If the root meter has been unset, the params will be empty.";
params.insert("o:rootMeterThingId", enumValueName(Uuid));
registerNotification("RootMeterChanged", description, params);
params.clear();
description = "Emitted whenever the energy balance changes. That is, when the current consumption, production or acquisition changes. Typically they will all change at the same time.";
params.insert("currentPowerConsumption", enumValueName(Double));
params.insert("currentPowerProduction", enumValueName(Double));
params.insert("currentPowerAcquisition", enumValueName(Double));
registerNotification("PowerBalanceChanged", description, params);
connect(m_energyManager, &EnergyManager::rootMeterChanged, this, [=](){
QVariantMap params;
if (m_energyManager->rootMeter()) {
params.insert("rootMeterThingId", m_energyManager->rootMeter()->id());
}
emit RootMeterChanged(params);
});
connect(m_energyManager, &EnergyManager::powerBalanceChanged, this, [=](){
QVariantMap params;
params.insert("currentPowerConsumption", m_energyManager->currentPowerConsumption());
params.insert("currentPowerProduction", m_energyManager->currentPowerProduction());
params.insert("currentPowerAcquisition", m_energyManager->currentPowerAcquisition());
emit PowerBalanceChanged(params);
});
}
QString EnergyJsonHandler::name() const
{
return "Energy";
}
JsonReply *EnergyJsonHandler::GetRootMeter(const QVariantMap &params)
{
Q_UNUSED(params)
QVariantMap ret;
if (m_energyManager->rootMeter()) {
ret.insert("rootMeterThingId", m_energyManager->rootMeter()->id());
}
return createReply(ret);
}
JsonReply *EnergyJsonHandler::SetRootMeter(const QVariantMap &params)
{
QVariantMap returns;
if (!params.contains("rootMeterThingId")) {
returns.insert("energyError", enumValueName(EnergyManager::EnergyErrorMissingParameter));
return createReply(returns);
}
EnergyManager::EnergyError status = m_energyManager->setRootMeter(params.value("rootMeterThingId").toUuid());
returns.insert("energyError", enumValueName(status));
return createReply(returns);
}
JsonReply *EnergyJsonHandler::GetPowerBalance(const QVariantMap &params)
{
Q_UNUSED(params)
QVariantMap ret;
ret.insert("currentPowerConsumption", m_energyManager->currentPowerConsumption());
ret.insert("currentPowerProduction", m_energyManager->currentPowerProduction());
ret.insert("currentPowerAcquisition", m_energyManager->currentPowerAcquisition());
return createReply(ret);
}

View File

@ -0,0 +1,31 @@
#ifndef ENERGYJSONHANDLER_H
#define ENERGYJSONHANDLER_H
#include <QObject>
#include "jsonrpc/jsonhandler.h"
class EnergyManager;
class EnergyJsonHandler : public JsonHandler
{
Q_OBJECT
public:
explicit EnergyJsonHandler(EnergyManager *energyManager, QObject *parent = nullptr);
QString name() const override;
Q_INVOKABLE JsonReply* GetRootMeter(const QVariantMap &params);
Q_INVOKABLE JsonReply* SetRootMeter(const QVariantMap &params);
Q_INVOKABLE JsonReply* GetPowerBalance(const QVariantMap &params);
signals:
void RootMeterChanged(const QVariantMap &params);
void PowerBalanceChanged(const QVariantMap &params);
private:
EnergyManager *m_energyManager = nullptr;
};
#endif // ENERGYJSONHANDLER_H

View File

@ -0,0 +1,135 @@
#include "energymanagerimpl.h"
#include "nymeasettings.h"
#include <qmath.h>
Q_DECLARE_LOGGING_CATEGORY(dcEnergyExperience)
EnergyManagerImpl::EnergyManagerImpl(ThingManager *thingManager, QObject *parent):
EnergyManager(parent),
m_thingManager(thingManager)
{
// Most of the time we get a bunch of signals at the same time (root meter, producers, consumers etc)
// In order to decrease some load on the system, we'll wait for wee bit until we actually update to
// accumulate those changes and calculate the change in one go.
m_balanceUpdateTimer.setInterval(50);
m_balanceUpdateTimer.setSingleShot(true);
connect(&m_balanceUpdateTimer, &QTimer::timeout, this, &EnergyManagerImpl::updatePowerBalance);
QSettings settings(NymeaSettings::settingsPath() + "/energy.conf", QSettings::IniFormat);
ThingId rootMeterThingId = settings.value("rootMeterThingId").toUuid();
EnergyManagerImpl::setRootMeter(rootMeterThingId);
qCDebug(dcEnergyExperience()) << "Loaded root meter" << rootMeterThingId;
foreach (Thing *thing, m_thingManager->configuredThings()) {
watchThing(thing);
}
connect(thingManager, &ThingManager::thingAdded, this, &EnergyManagerImpl::watchThing);
connect(thingManager, &ThingManager::thingRemoved, this, &EnergyManagerImpl::unwatchThing);
}
Thing *EnergyManagerImpl::rootMeter() const
{
return m_rootMeter;
}
EnergyManager::EnergyError EnergyManagerImpl::setRootMeter(const ThingId &rootMeterId)
{
Thing *rootMeter = m_thingManager->findConfiguredThing(rootMeterId);
if (!rootMeter || !rootMeter->thingClass().interfaces().contains("energymeter")) {
return EnergyErrorInvalidParameter;
}
if (m_rootMeter != rootMeter) {
qCDebug(dcEnergyExperience()) << "Setting root meter to" << rootMeter->name();
m_rootMeter = rootMeter;
QSettings settings(NymeaSettings::settingsPath() + "/energy.conf", QSettings::IniFormat);
settings.setValue("rootMeterThingId", rootMeter->id());
emit rootMeterChanged();
}
return EnergyErrorNoError;
}
double EnergyManagerImpl::currentPowerConsumption() const
{
return m_currentPowerConsumption;
}
double EnergyManagerImpl::currentPowerProduction() const
{
return m_currentPowerProduction;
}
double EnergyManagerImpl::currentPowerAcquisition() const
{
return m_currentPowerAcquisition;
}
void EnergyManagerImpl::watchThing(Thing *thing)
{
// If we don't have a root meter yet, we'll be auto-setting the first energymeter that appears.
// It may be changed by the user through an API call later.
if (!m_rootMeter && thing->thingClass().interfaces().contains("energymeter")) {
setRootMeter(thing->id());
}
qCDebug(dcEnergyExperience()) << "Wathing thing:" << thing->name();
if (thing->thingClass().interfaces().contains("smartmeterproducer")
|| thing->thingClass().interfaces().contains("energymeter")
|| thing->thingClass().interfaces().contains("energystorage")) {
connect(thing, &Thing::stateValueChanged, this, [=](const StateTypeId &stateTypeId){
if (thing->thingClass().getStateType(stateTypeId).name() == "currentPower") {
m_balanceUpdateTimer.start();
}
});
}
}
void EnergyManagerImpl::unwatchThing(const ThingId &thingId)
{
if (m_rootMeter && m_rootMeter->id() == thingId) {
m_rootMeter = nullptr;
emit rootMeterChanged();
}
}
void EnergyManagerImpl::updatePowerBalance()
{
double currentPowerAcquisition = 0;
if (m_rootMeter) {
currentPowerAcquisition = m_rootMeter->stateValue("currentPower").toDouble();
}
double currentPowerProduction = 0;
foreach (Thing* thing, m_thingManager->configuredThings().filterByInterface("smartmeterproducer")) {
currentPowerProduction += thing->stateValue("currentPower").toDouble();
}
double currentBatteryBalance = 0;
foreach (Thing *thing, m_thingManager->configuredThings().filterByInterface("energystorage")) {
currentBatteryBalance += thing->stateValue("currentPower").toDouble();
}
double currentPowerConsumption = -currentPowerProduction + currentPowerAcquisition - currentBatteryBalance;
qCDebug(dcEnergyExperience()) << "Consumption:" << currentPowerConsumption << "Production:" << currentPowerProduction << "Acquisition:" << currentPowerAcquisition << "Battery:" << currentBatteryBalance;
if (currentPowerAcquisition != m_currentPowerAcquisition
|| currentPowerConsumption != m_currentPowerConsumption
|| currentPowerProduction != m_currentPowerProduction) {
m_currentPowerAcquisition = currentPowerAcquisition;
m_currentPowerProduction = currentPowerProduction;
m_currentPowerConsumption = currentPowerConsumption;
emit powerBalanceChanged();
}
}
void EnergyManagerImpl::logDumpConsumers()
{
foreach (Thing *consumer, m_thingManager->configuredThings().filterByInterface("smartmeterconsumer")) {
qCDebug(dcEnergyExperience()).nospace().noquote() << consumer->name() << ": " << (consumer->stateValue("currentPower").toDouble() / 230) << "A (" << consumer->stateValue("currentPower").toDouble() << "W)";
}
}

View File

@ -0,0 +1,45 @@
#ifndef ENERGYMANAGERIMPL_H
#define ENERGYMANAGERIMPL_H
#include <QObject>
#include <QHash>
#include <QTimer>
#include "integrations/thingmanager.h"
#include "energymanager.h"
class EnergyManagerImpl : public EnergyManager
{
Q_OBJECT
public:
explicit EnergyManagerImpl(ThingManager *thingManager, QObject *parent = nullptr);
Thing *rootMeter() const override;
EnergyError setRootMeter(const ThingId &rootMeterId) override;
double currentPowerConsumption() const override;
double currentPowerProduction() const override;
double currentPowerAcquisition() const override;
private:
void watchThing(Thing *thing);
void unwatchThing(const ThingId &thingId);
void updatePowerBalance();
private slots:
void logDumpConsumers();
private:
ThingManager *m_thingManager = nullptr;
Thing *m_rootMeter = nullptr;
QTimer m_balanceUpdateTimer;
double m_currentPowerConsumption;
double m_currentPowerProduction;
double m_currentPowerAcquisition;
};
#endif // ENERGYMANAGERIMPL_H

View File

@ -0,0 +1,119 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "experiencepluginenergy.h"
#include "energymanagerimpl.h"
#include "energyjsonhandler.h"
#include "energyplugin.h"
#include <jsonrpc/jsonrpcserver.h>
#include <loggingcategories.h>
#include <QDir>
#include <QCoreApplication>
#include <QPluginLoader>
NYMEA_LOGGING_CATEGORY(dcEnergyExperience, "EnergyExperience")
ExperiencePluginEnergy::ExperiencePluginEnergy()
{
}
void ExperiencePluginEnergy::init()
{
qCDebug(dcEnergyExperience()) << "Initializing energy experience";
m_energyManager = new EnergyManagerImpl(thingManager(), this);
jsonRpcServer()->registerExperienceHandler(new EnergyJsonHandler(m_energyManager, this), 1, 0);
loadPlugins();
}
void ExperiencePluginEnergy::loadPlugins()
{
foreach (const QString &path, pluginSearchDirs()) {
QDir dir(path);
qCDebug(dcEnergyExperience()) << "Loading energy plugins from:" << dir.absolutePath();
foreach (const QString &entry, dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot)) {
QFileInfo fi(path + "/" + entry);
if (fi.isFile()) {
if (entry.startsWith("libnymea_energyplugin") && entry.endsWith(".so")) {
loadEnergyPlugin(path + "/" + entry);
}
} else if (fi.isDir()) {
if (QFileInfo::exists(path + "/" + entry + "/libnymea_energyplugin" + entry + ".so")) {
loadEnergyPlugin(path + "/" + entry + "/libnymea_energyplugin" + entry + ".so");
}
}
}
}
}
QStringList ExperiencePluginEnergy::pluginSearchDirs() const
{
QStringList searchDirs;
QByteArray envPath = qgetenv("NYMEA_ENERGY_PLUGINS_PATH");
if (!envPath.isEmpty()) {
searchDirs << QString(envPath).split(':');
}
foreach (QString libraryPath, QCoreApplication::libraryPaths()) {
searchDirs << libraryPath.replace("qt5", "nymea").replace("plugins", "energy");
}
searchDirs << QCoreApplication::applicationDirPath() + "/../lib/nymea/energy";
searchDirs << QCoreApplication::applicationDirPath() + "/../energy/";
searchDirs << QCoreApplication::applicationDirPath() + "/../../../energy/";
return searchDirs;
}
void ExperiencePluginEnergy::loadEnergyPlugin(const QString &file)
{
QPluginLoader loader;
loader.setFileName(file);
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
if (!loader.load()) {
qCWarning(dcExperiences()) << loader.errorString();
return;
}
EnergyPlugin *plugin = qobject_cast<EnergyPlugin*>(loader.instance());
if (!plugin) {
qCWarning(dcEnergyExperience()) << "Could not get plugin instance of" << loader.fileName();
loader.unload();
return;
}
qCDebug(dcEnergyExperience()) << "Loaded energy plugin:" << loader.fileName();
m_plugins.append(plugin);
plugin->setParent(this);
plugin->initPlugin(m_energyManager, thingManager(), jsonRpcServer());
}

View File

@ -0,0 +1,64 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef EXPERIENCEPLUGINENERGY_H
#define EXPERIENCEPLUGINENERGY_H
#include <experiences/experienceplugin.h>
#include "energyplugin.h"
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(dcEnergyExperience)
class EnergyManagerImpl;
class ExperiencePluginEnergy: public ExperiencePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "io.nymea.ExperiencePlugin")
Q_INTERFACES(ExperiencePlugin)
public:
ExperiencePluginEnergy();
void init() override;
private:
QStringList pluginSearchDirs() const;
void loadPlugins();
void loadEnergyPlugin(const QString &file);
QList<EnergyPlugin*> m_plugins;
EnergyManagerImpl *m_energyManager = nullptr;
};
#endif // EXPERIENCEPLUGINENERGY_H

42
plugin/plugin.pro Normal file
View File

@ -0,0 +1,42 @@
TEMPLATE = lib
TARGET = $$qtLibraryTarget(nymea_experiencepluginenergy)
CONFIG += plugin link_pkgconfig c++11
PKGCONFIG += nymea
QT -= gui
QT += network
include(../config.pri)
INCLUDEPATH += $$top_srcdir/libnymea-energy
LIBS += -L$$top_builddir/libnymea-energy -lnymea-energy
HEADERS += experiencepluginenergy.h \
energyjsonhandler.h \
energymanagerimpl.h
SOURCES += experiencepluginenergy.cpp \
energyjsonhandler.cpp \
energymanagerimpl.cpp
target.path = $$[QT_INSTALL_LIBS]/nymea/experiences/
INSTALLS += target
# Install translation files
TRANSLATIONS *= $$files($${_PRO_FILE_PWD_}/translations/*ts, true)
lupdate.depends = FORCE
lupdate.depends += qmake_all
lupdate.commands = lupdate -recursive -no-obsolete $${_PRO_FILE_PWD_}/experience.pro
QMAKE_EXTRA_TARGETS += lupdate
# make lrelease to build .qm from .ts
lrelease.depends = FORCE
lrelease.commands += lrelease $$files($$_PRO_FILE_PWD_/translations/*.ts, true);
QMAKE_EXTRA_TARGETS += lrelease
translations.depends += lrelease
translations.path = /usr/share/nymea/translations
translations.files = $$[QT_SOURCE_TREE]/translations/*.qm
INSTALLS += translations