Add nymea energy experience plugin
This commit is contained in:
parent
38b43eecc9
commit
885fe9be3a
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.pro.user
|
||||
.crossbuilder/*
|
||||
10
config.pri
Normal file
10
config.pri
Normal 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
3
debian/changelog
vendored
Normal 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
1
debian/compat
vendored
Normal file
@ -0,0 +1 @@
|
||||
9
|
||||
42
debian/control
vendored
Normal file
42
debian/control
vendored
Normal 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
3
debian/libnymea-energy-dev.install.in
vendored
Normal 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
3
debian/libnymea-energy.install.in
vendored
Normal 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
|
||||
1
debian/nymea-experience-plugin-energy.install.in
vendored
Normal file
1
debian/nymea-experience-plugin-energy.install.in
vendored
Normal file
@ -0,0 +1 @@
|
||||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/experiences/libnymea_experiencepluginenergy.so
|
||||
27
debian/rules
vendored
Executable file
27
debian/rules
vendored
Executable 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
|
||||
37
libnymea-energy/energymanager.cpp
Normal file
37
libnymea-energy/energymanager.cpp
Normal 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)
|
||||
{
|
||||
|
||||
}
|
||||
65
libnymea-energy/energymanager.h
Normal file
65
libnymea-energy/energymanager.h
Normal 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
|
||||
61
libnymea-energy/energyplugin.cpp
Normal file
61
libnymea-energy/energyplugin.cpp
Normal 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();
|
||||
}
|
||||
|
||||
66
libnymea-energy/energyplugin.h
Normal file
66
libnymea-energy/energyplugin.h
Normal 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
|
||||
38
libnymea-energy/libnymea-energy.pro
Normal file
38
libnymea-energy/libnymea-energy.pro
Normal 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
|
||||
|
||||
7
nymea-experience-plugin-energy.pro
Normal file
7
nymea-experience-plugin-energy.pro
Normal file
@ -0,0 +1,7 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += libnymea-energy plugin
|
||||
|
||||
plugin.depends = libnymea-energy
|
||||
|
||||
|
||||
98
plugin/energyjsonhandler.cpp
Normal file
98
plugin/energyjsonhandler.cpp
Normal 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 ¶ms)
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
QVariantMap ret;
|
||||
if (m_energyManager->rootMeter()) {
|
||||
ret.insert("rootMeterThingId", m_energyManager->rootMeter()->id());
|
||||
}
|
||||
return createReply(ret);
|
||||
}
|
||||
|
||||
JsonReply *EnergyJsonHandler::SetRootMeter(const QVariantMap ¶ms)
|
||||
{
|
||||
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 ¶ms)
|
||||
{
|
||||
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);
|
||||
}
|
||||
31
plugin/energyjsonhandler.h
Normal file
31
plugin/energyjsonhandler.h
Normal 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 ¶ms);
|
||||
Q_INVOKABLE JsonReply* SetRootMeter(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply* GetPowerBalance(const QVariantMap ¶ms);
|
||||
|
||||
signals:
|
||||
void RootMeterChanged(const QVariantMap ¶ms);
|
||||
|
||||
void PowerBalanceChanged(const QVariantMap ¶ms);
|
||||
|
||||
private:
|
||||
EnergyManager *m_energyManager = nullptr;
|
||||
|
||||
};
|
||||
|
||||
#endif // ENERGYJSONHANDLER_H
|
||||
135
plugin/energymanagerimpl.cpp
Normal file
135
plugin/energymanagerimpl.cpp
Normal 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)";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
45
plugin/energymanagerimpl.h
Normal file
45
plugin/energymanagerimpl.h
Normal 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
|
||||
119
plugin/experiencepluginenergy.cpp
Normal file
119
plugin/experiencepluginenergy.cpp
Normal 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());
|
||||
|
||||
}
|
||||
64
plugin/experiencepluginenergy.h
Normal file
64
plugin/experiencepluginenergy.h
Normal 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
42
plugin/plugin.pro
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user