From 3b03ce0ce1ed7f69acb508eb377e7184e20f4349 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Wed, 15 Jun 2022 00:11:43 +0200 Subject: [PATCH] New plugin: powerfox --- debian/control | 9 + debian/nymea-plugin-powerfox.install.in | 2 + nymea-plugins.pro | 1 + powerfox/README.md | 13 + powerfox/integrationpluginpowerfox.cpp | 232 ++++++++++++++++++ powerfox/integrationpluginpowerfox.h | 77 ++++++ powerfox/integrationpluginpowerfox.json | 116 +++++++++ powerfox/meta.json | 13 + powerfox/powefox.jpeg | Bin 0 -> 4260 bytes powerfox/powerfox.pro | 7 + ...d8abd-1ff0-4156-87c5-7611153c3658-en_US.ts | 105 ++++++++ 11 files changed, 575 insertions(+) create mode 100644 debian/nymea-plugin-powerfox.install.in create mode 100644 powerfox/README.md create mode 100644 powerfox/integrationpluginpowerfox.cpp create mode 100644 powerfox/integrationpluginpowerfox.h create mode 100644 powerfox/integrationpluginpowerfox.json create mode 100644 powerfox/meta.json create mode 100644 powerfox/powefox.jpeg create mode 100644 powerfox/powerfox.pro create mode 100644 powerfox/translations/21cd8abd-1ff0-4156-87c5-7611153c3658-en_US.ts diff --git a/debian/control b/debian/control index f63e1acf..18285415 100644 --- a/debian/control +++ b/debian/control @@ -460,6 +460,15 @@ Description: nymea integration plugin for philipshue and connected devices to it. +Package: nymea-plugin-powerfox +Architecture: any +Depends: ${shlibs:Depends}, + ${misc:Depends}, +Description: nymea integration plugin for powerfox + This package contains the nymea integration plugin for the powerfox online service + to integrate energy meters. + + Package: nymea-plugin-pushbullet Architecture: any Depends: ${shlibs:Depends}, diff --git a/debian/nymea-plugin-powerfox.install.in b/debian/nymea-plugin-powerfox.install.in new file mode 100644 index 00000000..77faf19d --- /dev/null +++ b/debian/nymea-plugin-powerfox.install.in @@ -0,0 +1,2 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginpowerfox.so +powerfox/translations/*qm usr/share/nymea/translations/ diff --git a/nymea-plugins.pro b/nymea-plugins.pro index 6bd0c1c4..1054da3b 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -48,6 +48,7 @@ PLUGIN_DIRS = \ openweathermap \ osdomotics \ philipshue \ + powerfox \ pushbullet \ pushnotifications \ shelly \ diff --git a/powerfox/README.md b/powerfox/README.md new file mode 100644 index 00000000..12f5c5ce --- /dev/null +++ b/powerfox/README.md @@ -0,0 +1,13 @@ +# powerfox + +This integration connects to the powerfox online api to obtain information about power meters. +Currently only power meters are supported. + +## Requirements + +* A powerfox online account is required. +* The power meter devices need to be configured with the powerfox app and connected to powerfox + +## More + +More information [https://www.powerfox.energy/](https://www.powerfox.energy/). diff --git a/powerfox/integrationpluginpowerfox.cpp b/powerfox/integrationpluginpowerfox.cpp new file mode 100644 index 00000000..6334e2d5 --- /dev/null +++ b/powerfox/integrationpluginpowerfox.cpp @@ -0,0 +1,232 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2022, 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 Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* 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 "integrationpluginpowerfox.h" +#include "plugininfo.h" +#include "plugintimer.h" + +#include +#include +#include + +IntegrationPluginPowerfox::IntegrationPluginPowerfox() +{ + +} + +IntegrationPluginPowerfox::~IntegrationPluginPowerfox() +{ +} + +void IntegrationPluginPowerfox::startPairing(ThingPairingInfo *info) +{ + info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("Please enter the login credentials for your powerfox account.")); +} + +void IntegrationPluginPowerfox::confirmPairing(ThingPairingInfo *info, const QString &username, const QString &password) +{ + // Using /main/current as that one has the highest rate limit and we don't want to lock up the api for the following + // setupThing call as /all/devices can only be called once per minute. + QNetworkRequest request(QUrl("https://backend.powerfox.energy/api/2.0/my/main/current")); + QString concatenated = username + ":" + password; + QByteArray data = concatenated.toLocal8Bit().toBase64(); + QString headerData = "Basic " + data; + request.setRawHeader("Authorization", headerData.toLocal8Bit()); + qCDebug(dcPowerfox()) << "requesting:" << request.url().toString() << headerData; + QNetworkReply *reply = hardwareManager()->networkManager()->get(request); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, info, [info, reply, this, username, password](){ + if (reply->error() == QNetworkReply::AuthenticationRequiredError) { + qCWarning(dcPowerfox()) << "Error fetching devices from account"; + info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Error logging to powerfox. Please try again.")); + return; + } + if (reply->error() != QNetworkReply::NoError) { + qCWarning(dcPowerfox()) << "Error getting paired devices" << reply->error() << reply->errorString(); + info->finish(Thing::ThingErrorHardwareFailure, reply->errorString()); + return; + } + + qCDebug(dcPowerfox) << "Auth request succeeded"; + + pluginStorage()->beginGroup(info->thingId().toString()); + pluginStorage()->setValue("username", username); + pluginStorage()->setValue("password", password); + pluginStorage()->endGroup(); + info->finish(Thing::ThingErrorNoError); + }); +} + +void IntegrationPluginPowerfox::setupThing(ThingSetupInfo *info) +{ + if (info->thing()->thingClassId() == accountThingClassId) { + QNetworkReply *reply = request(info->thing(), "/all/devices"); // Max 1 per minute + connect(reply, &QNetworkReply::finished, info, [info, reply, this](){ + if (reply->error() == QNetworkReply::AuthenticationRequiredError) { + qCWarning(dcPowerfox()) << "Error fetching devices from account"; + info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Login error at powerfox.energy.")); + return; + } + if (reply->error() != QNetworkReply::NoError) { + qCWarning(dcPowerfox()) << "Error fetching devices from account" << reply->error(); + info->finish(Thing::ThingErrorAuthenticationFailure, reply->errorString()); + return; + } + + QByteArray data = reply->readAll(); + + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); + if (error.error != QJsonParseError::NoError) { + qCWarning(dcPowerfox()) << "JSON parse error in response from powerfox:" << error.error << error.errorString() << data; + info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Unable to process response from from server.")); + return; + } + + info->finish(Thing::ThingErrorNoError); + + info->thing()->setStateValue(accountConnectedStateTypeId, true); + info->thing()->setStateValue(accountLoggedInStateTypeId, true); + + foreach (const QVariant &entry, jsonDoc.toVariant().toList()) { + QVariantMap entryMap = entry.toMap(); + QString id = entryMap.value("DeviceId").toString(); + bool mainDevice = entryMap.value("MainDevice").toBool(); + Division division = static_cast(entryMap.value("Devision").toInt()); + + if (!mainDevice) { + qCDebug(dcPowerfox()) << "Skipping non-main device" << qUtf8Printable(QJsonDocument::fromVariant(entryMap).toJson()); + continue; + } + + if (division != DivisionPowerMeter) { + qCInfo(dcPowerfox()) << "Device type" << division << "is not yet supported."; + continue; + } + + Thing *child = myThings().filterByParentId(info->thing()->id()).findByParams({Param(powerMeterThingIdParamTypeId, id)}); + if (!child) { + qCDebug(dcPowerfox()) << "Found new power meter device:" << id; + ThingDescriptor descriptor(powerMeterThingClassId, "powerfox power meter", QString(), info->thing()->id()); + descriptor.setParams({Param(powerMeterThingIdParamTypeId, id)}); + emit autoThingsAppeared({descriptor}); + } + } + }); + + return; + } + + info->finish(Thing::ThingErrorNoError); +} + +void IntegrationPluginPowerfox::postSetupThing(Thing */*thing*/) +{ + if (!m_pollTimer) { + m_pollTimer = hardwareManager()->pluginTimerManager()->registerTimer(4); + connect(m_pollTimer, &PluginTimer::timeout, this, [this](){ + foreach (Thing *account, myThings().filterByInterface("account")) { + foreach (Thing *powerMeter, myThings().filterByParentId(account->id()).filterByInterface("energymeter")) { + QUrlQuery query; + query.addQueryItem("unit", "kWh"); + // Can be called at max once per 3 secs. Not sure if that's per account or per meter ID yet. Assuming per meter ID for now. + QNetworkReply *reply = request(account, "/" + powerMeter->paramValue(powerMeterThingIdParamTypeId).toString() + "/current", query); + connect(reply, &QNetworkReply::finished, powerMeter, [account, powerMeter, reply](){ + if (reply->error() == QNetworkReply::AuthenticationRequiredError) { + account->setStateValue(accountConnectedStateTypeId, false); + account->setStateValue(accountLoggedInStateTypeId, false); + } + if (reply->error() != QNetworkReply::NoError) { + qCWarning(dcPowerfox()) << "Failed to poll power meter:" << reply->error() << reply->errorString(); + powerMeter->setStateValue(powerMeterConnectedStateTypeId, false); + powerMeter->setStateValue(powerMeterCurrentPowerStateTypeId, 0); + powerMeter->setStateValue(powerMeterCurrentPhaseAStateTypeId, 0); + powerMeter->setStateValue(powerMeterVoltagePhaseAStateTypeId, 0); + return; + } + + QByteArray data = reply->readAll(); + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); + if (error.error != QJsonParseError::NoError) { + qCWarning(dcPowerfox()) << "Unable to parse reply from powerfox:" << error.error << error.errorString() << data; + return; + } + + account->setStateValue(accountConnectedStateTypeId, true); + + QVariantMap map = jsonDoc.toVariant().toMap(); + powerMeter->setStateValue(powerMeterConnectedStateTypeId, !map.value("Outdated").toBool()); + + powerMeter->setStateValue(powerMeterCurrentPowerStateTypeId, map.value("Watt").toDouble()); + powerMeter->setStateValue(powerMeterTotalEnergyConsumedStateTypeId, map.value("A_Plus").toDouble()); + powerMeter->setStateValue(powerMeterTotalEnergyProducedStateTypeId, map.value("A_Minus").toDouble()); + + // We don't get voltage/current from the API, let's assume 230V as powerfox is only available in Europe for now + powerMeter->setStateValue(powerMeterVoltagePhaseAStateTypeId, 230); + powerMeter->setStateValue(powerMeterCurrentPhaseAStateTypeId, powerMeter->stateValue(powerMeterCurrentPowerStateTypeId).toDouble() / powerMeter->stateValue(powerMeterVoltagePhaseAStateTypeId).toDouble()); + }); + } + } + }); + } +} + +void IntegrationPluginPowerfox::thingRemoved(Thing */*thing*/) +{ + if (myThings().isEmpty()) { + hardwareManager()->pluginTimerManager()->unregisterTimer(m_pollTimer); + m_pollTimer = nullptr; + } +} + +QNetworkReply *IntegrationPluginPowerfox::request(Thing *thing, const QString &path, const QUrlQuery &query) +{ + pluginStorage()->beginGroup(thing->id().toString()); + QString username = pluginStorage()->value("username").toString(); + QString password = pluginStorage()->value("password").toString(); + pluginStorage()->endGroup(); + + QUrl url; + url.setScheme("https"); + url.setHost("backend.powerfox.energy"); + url.setPath("/api/2.0/my" + path); + url.setQuery(query); + QNetworkRequest request(url); + QString concatenated = username + ":" + password; + QByteArray data = concatenated.toLocal8Bit().toBase64(); + QString headerData = "Basic " + data; + request.setRawHeader("Authorization", headerData.toLocal8Bit()); +// qCDebug(dcPowerfox()) << "requesting:" << url.toString() << headerData; + QNetworkReply *reply = hardwareManager()->networkManager()->get(request); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + return reply; +} + diff --git a/powerfox/integrationpluginpowerfox.h b/powerfox/integrationpluginpowerfox.h new file mode 100644 index 00000000..cf703002 --- /dev/null +++ b/powerfox/integrationpluginpowerfox.h @@ -0,0 +1,77 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2022, 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 Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* 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 INTEGRATIONPLUGINPOWERFOX_H +#define INTEGRATIONPLUGINPOWERFOX_H + +#include "integrations/integrationplugin.h" +#include "extern-plugininfo.h" + +#include + +class PluginTimer; +class QNetworkReply; + +class IntegrationPluginPowerfox: public IntegrationPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginpowerfox.json") + Q_INTERFACES(IntegrationPlugin) + +public: + enum Division { + DivisionUnknown = -1, + DivisionPowerMeter = 0, + DivisionColdWaterMeter = 1, + DivisionWarmWaterMeter = 2, + DivisionHeatMeter = 3, + DivisionGasMeter = 4, + DivisionColdAndWarmWaterMeter = 5 + }; + Q_ENUM(Division) + + explicit IntegrationPluginPowerfox(); + ~IntegrationPluginPowerfox(); + + void startPairing(ThingPairingInfo *info) override; + void confirmPairing(ThingPairingInfo *info, const QString &username, const QString &secret) override; + void setupThing(ThingSetupInfo *info) override; + void postSetupThing(Thing *thing) override; + void thingRemoved(Thing *thing) override; + +private: + QNetworkReply *request(Thing *thing, const QString &path, const QUrlQuery &query = QUrlQuery()); + +private: + PluginTimer *m_pollTimer = nullptr; +}; + +#endif // INTEGRATIONPLUGINPOWERFOX_H diff --git a/powerfox/integrationpluginpowerfox.json b/powerfox/integrationpluginpowerfox.json new file mode 100644 index 00000000..75202a6e --- /dev/null +++ b/powerfox/integrationpluginpowerfox.json @@ -0,0 +1,116 @@ +{ + "name": "powerfox", + "displayName": "powerfox", + "id": "21cd8abd-1ff0-4156-87c5-7611153c3658", + "vendors": [ + { + "name": "powerfox", + "displayName": "powerfox", + "id": "eb764f51-caff-481e-b008-56911f9f8446", + "thingClasses": [ + { + "id": "20d0fe05-ae1d-46c0-b34a-f00a121177f7", + "name": "account", + "displayName": "powerfox account", + "createMethods": ["user"], + "setupMethod": "userandpassword", + "interfaces": [ "account" ], + "stateTypes": [ + { + "id": "9cde6321-2abf-4a58-a1d6-c7418edb9747", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "defaultValue": false, + "cached": false + }, + { + "id": "634a43c1-e989-4bb2-b438-ea9aa0c2c33b", + "name": "loggedIn", + "displayName": "Logged in", + "displayNameEvent": "Logged in changed", + "type": "bool", + "defaultValue": false + } + ] + }, + { + "id": "b62c4e71-9e6e-4e7c-ae3c-79c96e4f8e27", + "name": "powerMeter", + "displayName": "powerfox smart meter", + "createMethods": ["auto"], + "interfaces": ["energymeter", "connectable"], + "paramTypes": [ + { + "id": "b58b5abd-c878-4c6a-be6e-58e08da76ba2", + "name": "id", + "displayName": "ID", + "type": "QString", + "defaultValue": "" + } + ], + "stateTypes": [ + { + "id": "3d674ba8-76ff-4025-a7ff-c64b5ffdc08a", + "name": "connected", + "displayName": "Reachable", + "displayNameEvent": "Reachable changed", + "type": "bool", + "defaultValue": false, + "cached": false + }, + { + "id": "50c0ac31-edc4-4374-b763-1cdebdc84ef2", + "name": "currentPower", + "displayName": "Current power consumption", + "displayNameEvent": "Currant power consumption changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0, + "cached": false + }, + { + "id": "3c82dd4e-9485-4c57-87dd-a82f98d4d5ab", + "name": "totalEnergyConsumed", + "displayName": "Total energy consumption", + "displayNameEvent": "Total consumed energy changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0 + }, + { + "id": "2c10f3e5-bc9f-4d65-b8d9-b1ff8db54751", + "name": "totalEnergyProduced", + "displayName": "Total energy production", + "displayNameEvent": "Total produced energy changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0 + }, + { + "id": "6b62d3f8-6b91-48fd-9bf0-4eca6fb06efb", + "name": "currentPhaseA", + "displayName": "Current", + "displayNameEvent": "Current changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0, + "cached": false + }, + { + "id": "dd8aeb79-606d-409a-9432-79a2fa7bad5c", + "name": "voltagePhaseA", + "displayName": "Voltage (Phase A)", + "displayNameEvent": "Voltage (Phase A) changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0, + "cached": false + } + ] + } + ] + } + ] +} diff --git a/powerfox/meta.json b/powerfox/meta.json new file mode 100644 index 00000000..fe35036e --- /dev/null +++ b/powerfox/meta.json @@ -0,0 +1,13 @@ +{ + "title": "powerfox", + "tagline": "Connects nymea to powerfox.", + "icon": "powerfox.jpeg", + "stability": "consumer", + "offline": false, + "technologies": [ + "cloud" + ], + "categories": [ + "energy" + ] +} diff --git a/powerfox/powefox.jpeg b/powerfox/powefox.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..908e991279e48c6f028eb26327857f094524e4fc GIT binary patch literal 4260 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 Fe*>wF&g=jH literal 0 HcmV?d00001 diff --git a/powerfox/powerfox.pro b/powerfox/powerfox.pro new file mode 100644 index 00000000..d112b2e1 --- /dev/null +++ b/powerfox/powerfox.pro @@ -0,0 +1,7 @@ +include(../plugins.pri) + +QT += network + +SOURCES += integrationpluginpowerfox.cpp + +HEADERS += integrationpluginpowerfox.h diff --git a/powerfox/translations/21cd8abd-1ff0-4156-87c5-7611153c3658-en_US.ts b/powerfox/translations/21cd8abd-1ff0-4156-87c5-7611153c3658-en_US.ts new file mode 100644 index 00000000..14a888ff --- /dev/null +++ b/powerfox/translations/21cd8abd-1ff0-4156-87c5-7611153c3658-en_US.ts @@ -0,0 +1,105 @@ + + + + + IntegrationPluginPowerfox + + + Please enter the login credentials for your Powerfox account. + + + + + Error logging to powerfox. Please try again. + + + + + Login error at powerfox.energy. + + + + + Unable to process response from from server. + + + + + powerfox + + + Connected + The name of the StateType ({9cde6321-2abf-4a58-a1d6-c7418edb9747}) of ThingClass account + + + + + Current + The name of the StateType ({6b62d3f8-6b91-48fd-9bf0-4eca6fb06efb}) of ThingClass powerMeter + + + + + Current power consumption + The name of the StateType ({50c0ac31-edc4-4374-b763-1cdebdc84ef2}) of ThingClass powerMeter + + + + + ID + The name of the ParamType (ThingClass: powerMeter, Type: thing, ID: {b58b5abd-c878-4c6a-be6e-58e08da76ba2}) + + + + + Logged in + The name of the StateType ({634a43c1-e989-4bb2-b438-ea9aa0c2c33b}) of ThingClass account + + + + + Reachable + The name of the StateType ({3d674ba8-76ff-4025-a7ff-c64b5ffdc08a}) of ThingClass powerMeter + + + + + Total energy consumption + The name of the StateType ({3c82dd4e-9485-4c57-87dd-a82f98d4d5ab}) of ThingClass powerMeter + + + + + Total energy production + The name of the StateType ({2c10f3e5-bc9f-4d65-b8d9-b1ff8db54751}) of ThingClass powerMeter + + + + + Voltage (Phase A) + The name of the StateType ({dd8aeb79-606d-409a-9432-79a2fa7bad5c}) of ThingClass powerMeter + + + + + + powerfox + The name of the vendor ({eb764f51-caff-481e-b008-56911f9f8446}) +---------- +The name of the plugin powerfox ({21cd8abd-1ff0-4156-87c5-7611153c3658}) + + + + + powerfox account + The name of the ThingClass ({20d0fe05-ae1d-46c0-b34a-f00a121177f7}) + + + + + powerfox smart meter + The name of the ThingClass ({b62c4e71-9e6e-4e7c-ae3c-79c96e4f8e27}) + + + +