diff --git a/fronius/README.md b/fronius/README.md
index b0745868..3f41f5e4 100644
--- a/fronius/README.md
+++ b/fronius/README.md
@@ -5,9 +5,8 @@ nymea plug-in for Fronius solar devices.
## Supported Things
* PV-Inverter
-* Storage
-* Data Logger
* Smart Meter
+* Storage
## Requirements
diff --git a/fronius/fronius.pro b/fronius/fronius.pro
index 9dea299f..e730ebf0 100644
--- a/fronius/fronius.pro
+++ b/fronius/fronius.pro
@@ -1,20 +1,13 @@
include(../plugins.pri)
-QT += \
- network \
+QT += network
SOURCES += \
+ froniusnetworkreply.cpp \
+ froniussolarconnection.cpp \
integrationpluginfronius.cpp \
- froniusthing.cpp \
- froniuslogger.cpp \
- froniusinverter.cpp \
- froniusstorage.cpp \
- froniusmeter.cpp \
HEADERS += \
+ froniusnetworkreply.h \
+ froniussolarconnection.h \
integrationpluginfronius.h \
- froniusthing.h \
- froniuslogger.h \
- froniusinverter.h \
- froniusstorage.h \
- froniusmeter.h \
diff --git a/fronius/froniusinverter.cpp b/fronius/froniusinverter.cpp
deleted file mode 100644
index 9dd63109..00000000
--- a/fronius/froniusinverter.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-*
-* 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 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 "froniusinverter.h"
-#include
-#include "extern-plugininfo.h"
-#include
-
-FroniusInverter::FroniusInverter(Thing *thing, QObject *parent) : FroniusThing(thing, parent)
-{
-
-}
-
-QString FroniusInverter::activity() const
-{
- return m_activity;
-}
-
-void FroniusInverter::setActivity(const QString &activity)
-{
- m_activity = activity;
-}
-
-QUrl FroniusInverter::updateUrl()
-{
- QUrl requestUrl;
- requestUrl.setScheme("http");
- QUrlQuery query;
- requestUrl.setHost(hostAddress());
- requestUrl.setPath(baseUrl() + "GetInverterRealtimeData.cgi");
- query.addQueryItem("Scope", "Device");
- query.addQueryItem("DeviceId", deviceId());
- query.addQueryItem("DataCollection", "CommonInverterData");
- requestUrl.setQuery(query);
-
- return requestUrl;
-}
-
-void FroniusInverter::updateThingInfo(const QByteArray &data)
-{
- // Convert the rawdata to a JSON document
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
- if (error.error != QJsonParseError::NoError) {
- qCWarning(dcFronius()) << "FroniusInverter: Failed to parse JSON data" << data << ":" << error.errorString();
- pluginThing()->setStateValue(inverterConnectedStateTypeId,false);
- return;
- }
-
- // Parse the data and update the states of our device
- QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
- QVariantMap headMap = jsonDoc.toVariant().toMap().value("Head").toMap();
-
- qCDebug(dcFronius()) << "Inverter data" << qUtf8Printable(QJsonDocument::fromVariant(dataMap).toJson(QJsonDocument::Indented));
-
- // Set the inverter device state
- if (dataMap.contains("PAC")) {
- if(dataMap.value("PAC").toMap().values().at(0) == "W")
- pluginThing()->setStateValue(inverterCurrentPowerStateTypeId, -dataMap.value("PAC").toMap().values().at(1).toDouble());
- }
-
- if (dataMap.contains("DAY_ENERGY")) {
- if (dataMap.value("DAY_ENERGY").toMap().values().at(0) == "Wh")
- pluginThing()->setStateValue(inverterEdayStateTypeId, dataMap.value("DAY_ENERGY").toMap().values().at(1).toDouble()/1000);
- }
-
- if (dataMap.contains("YEAR_ENERGY")) {
- if(dataMap.value("YEAR_ENERGY").toMap().values().at(0) == "Wh")
- pluginThing()->setStateValue(inverterEyearStateTypeId, dataMap.value("YEAR_ENERGY").toMap().values().at(1).toInt()/1000);
- }
-
- if (dataMap.contains("TOTAL_ENERGY")) {
- if(dataMap.value("TOTAL_ENERGY").toMap().values().at(0) == "Wh")
- pluginThing()->setStateValue(inverterTotalEnergyProducedStateTypeId, dataMap.value("TOTAL_ENERGY").toMap().values().at(1).toInt()/1000);
- }
-
- //update successful
- pluginThing()->setStateValue(inverterConnectedStateTypeId,true);
-
-}
-
-QUrl FroniusInverter::activityUrl()
-{
- QUrl requestUrl;
- requestUrl.setScheme("http");
- requestUrl.setHost(hostAddress());
- requestUrl.setPath(baseUrl()+"GetPowerFlowRealtimeData.fcgi");
-
- return requestUrl;
-}
-
-void FroniusInverter::updateActivityInfo(const QByteArray &data)
-{
- // Convert the rawdata to a json document
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
- if(error.error != QJsonParseError::NoError) {
- qCWarning(dcFronius()) << "FroniusInverter: Failed to parse JSON data" << data << ":" << error.errorString();
- return;
- }
-
- // create StorageInfo list map
- QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
-
- if (dataMap.value("Site").toMap().value("P_PV").toFloat() > 0) {
- pluginThing()->setStateValue(inverterActiveStateTypeId, "production");
- } else {
- pluginThing()->setStateValue(inverterActiveStateTypeId, "inactive");
- }
-}
diff --git a/fronius/froniuslogger.cpp b/fronius/froniuslogger.cpp
deleted file mode 100644
index c03bd0d8..00000000
--- a/fronius/froniuslogger.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-*
-* 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 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 "froniuslogger.h"
-#include "extern-plugininfo.h"
-
-#include
-#include
-
-FroniusLogger::FroniusLogger(Thing *thing, QObject *parent) : FroniusThing(thing, parent)
-{
-
-}
-
-QUrl FroniusLogger::updateUrl()
-{
- QUrl requestUrl;
- requestUrl.setScheme("http");
- requestUrl.setHost(hostAddress());
- requestUrl.setPath(baseUrl() + "GetLoggerInfo.cgi");
-
- return requestUrl;
-}
-
-void FroniusLogger::updateThingInfo(const QByteArray &data)
-{
- // Convert the rawdata to a json document
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
- if (error.error != QJsonParseError::NoError) {
- // qCWarning(dcFroniusSolar()) << "Failed to parse JSON data" << data << ":" << error.errorString();
- pluginThing()->setStateValue(dataloggerConnectedStateTypeId,false);
- return;
- }
-
- // Parse the data and update the states of our device
- QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
- QVariantMap headMap = jsonDoc.toVariant().toMap().value("Head").toMap();
- QVariantMap bodyMap = jsonDoc.toVariant().toMap().value("Body").toMap();
-
- //qCDebug(dcFronius()) << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented));
-
- // create LoggerInfo list Map
- QVariantMap LoggerInfoMap = bodyMap.value("LoggerInfo").toMap();
-
- // copy retrieved information to device states
- if (LoggerInfoMap.contains("ProductID"))
- pluginThing()->setStateValue(dataloggerProductidStateTypeId, LoggerInfoMap.value("ProductID").toString());
-
- if (LoggerInfoMap.contains("PlatformID"))
- pluginThing()->setStateValue(dataloggerPlatformidStateTypeId, LoggerInfoMap.value("PlatformID").toString());
-
- if (LoggerInfoMap.contains("HWVersion"))
- pluginThing()->setStateValue(dataloggerHwversionStateTypeId, LoggerInfoMap.value("HWVersion").toString());
-
- if (LoggerInfoMap.contains("SWVersion"))
- pluginThing()->setStateValue(dataloggerSwversionStateTypeId, LoggerInfoMap.value("SWVersion").toString());
-
- if (LoggerInfoMap.contains("TimezoneLocation"))
- pluginThing()->setStateValue(dataloggerTzonelocStateTypeId, LoggerInfoMap.value("TimezoneLocation").toString());
-
- if (LoggerInfoMap.contains("TimezoneName"))
- pluginThing()->setStateValue(dataloggerTzoneStateTypeId, LoggerInfoMap.value("TimezoneName").toString());
-
- if (LoggerInfoMap.contains("DefaultLanguage"))
- pluginThing()->setStateValue(dataloggerDefaultlangStateTypeId, LoggerInfoMap.value("DefaultLanguage").toString());
-
- if (LoggerInfoMap.contains("CashFactor"))
- pluginThing()->setStateValue(dataloggerCashfactorStateTypeId, LoggerInfoMap.value("CashFactor").toDouble());
-
- if (LoggerInfoMap.contains("CashCurrency"))
- pluginThing()->setStateValue(dataloggerCashcurrencyStateTypeId, LoggerInfoMap.value("CashCurrency").toString());
-
- if (LoggerInfoMap.contains("CO2Factor"))
- pluginThing()->setStateValue(dataloggerCo2factorStateTypeId, LoggerInfoMap.value("CO2Factor").toDouble());
-
- if (LoggerInfoMap.contains("CO2Unit"))
- pluginThing()->setStateValue(dataloggerCo2unitStateTypeId, LoggerInfoMap.value("CO2Unit").toString());
-
- //update successful
- pluginThing()->setStateValue(dataloggerConnectedStateTypeId,true);
-}
-
-void FroniusLogger::updatePowerRelayState(const QByteArray &data)
-{
- // Convert the rawdata to a json document
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
- if (error.error != QJsonParseError::NoError) {
- // qCWarning(dcFroniusSolar()) << "Failed to parse JSON data" << data << ":" << error.errorString();
- pluginThing()->setStateValue(dataloggerConnectedStateTypeId,false);
- return;
- }
-
- // Parse the data and update the states of our device
- QVariantMap bodyMap = jsonDoc.toVariant().toMap().value("Body").toMap();
- QVariantMap dataMap = bodyMap.value("Data").toMap();
- QVariantMap emrsMap = dataMap.value("emrs").toMap();
-
- // create LoggerInfo list Map
- QVariantMap GpiosMap = emrsMap.value("gpios").toMap();
- //qCDebug(dcFroniusSolar()) << "Body: " << GpiosMap;
-
- // copy retrieved information to device states
- if (GpiosMap.contains("Reason")) {
- qCDebug(dcFronius()) << "Power Relay State Reason: " << GpiosMap.value("Reason").toString();
- pluginThing()->setStateValue(dataloggerPowerManagmentRelayReasonStateTypeId, GpiosMap.value("Reason").toString());
- }
-
- if (GpiosMap.contains("State")) {
- qCDebug(dcFronius()) << "Power Relay State: " << GpiosMap.value("State").toString();
- pluginThing()->setStateValue(dataloggerPowerManagmentRelayStateTypeId, GpiosMap.value("State").toBool());
- }
-
- //update successful
- pluginThing()->setStateValue(dataloggerConnectedStateTypeId,true);
-}
diff --git a/fronius/froniuslogger.h b/fronius/froniuslogger.h
deleted file mode 100644
index afb94a53..00000000
--- a/fronius/froniuslogger.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-*
-* 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 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 FRONIUSLOGGER_H
-#define FRONIUSLOGGER_H
-
-#include
-#include
-#include "froniusinverter.h"
-#include "froniusmeter.h"
-#include "froniusstorage.h"
-
-class FroniusLogger : public FroniusThing
-{
- Q_OBJECT
-
-public:
- explicit FroniusLogger(Thing *thing, QObject *parent = 0);
-
- QUrl updateUrl();
-
- void updateThingInfo(const QByteArray &data);
- void updatePowerRelayState(const QByteArray &data);
-};
-
-#endif // FRONIUSLOGGER_H
diff --git a/fronius/froniusmeter.cpp b/fronius/froniusmeter.cpp
deleted file mode 100644
index 0d767624..00000000
--- a/fronius/froniusmeter.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-*
-* 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 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 "froniusmeter.h"
-#include "extern-plugininfo.h"
-
-#include
-#include
-
-FroniusMeter::FroniusMeter(Thing* thing, QObject *parent) : FroniusThing(thing, parent)
-{
-
-}
-
-QString FroniusMeter::activity() const
-{
- return m_activity;
-}
-
-void FroniusMeter::setActivity(const QString &activity)
-{
- m_activity = activity;
-}
-
-QUrl FroniusMeter::updateUrl()
-{
- QUrl requestUrl;
- requestUrl.setScheme("http");
- QUrlQuery query;
- requestUrl.setHost(hostAddress());
- requestUrl.setPath(baseUrl() + "GetMeterRealtimeData.cgi");
- query.addQueryItem("Scope", "Device");
- query.addQueryItem("DeviceId", deviceId());
- requestUrl.setQuery(query);
- return requestUrl;
-}
-
-void FroniusMeter::updateThingInfo(const QByteArray &data)
-{
- // Convert the rawdata to a JSON document
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
- if (error.error != QJsonParseError::NoError) {
- qCWarning(dcFronius()) << "FroniusMeter: Failed to parse JSON data" << data << ":" << error.errorString();
- pluginThing()->setStateValue(meterConnectedStateTypeId, false);
- return;
- }
-
- // Parse the data and update the states of our thing
- QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
- //QVariantMap headMap = jsonDoc.toVariant().toMap().value("Head").toMap();
-
- //Add Smart meter with following states: „PowerReal_P_Sum“, „EnergyReal_WAC_Sum_Produced“, „EnergyReal_WAC_Sum_Consumed“
-
- qCDebug(dcFronius()) << "Meter data" << qUtf8Printable(QJsonDocument::fromVariant(dataMap).toJson(QJsonDocument::Indented));
-
- // Power
- if (dataMap.contains("PowerReal_P_Sum")) {
- pluginThing()->setStateValue(meterCurrentPowerStateTypeId, dataMap.value("PowerReal_P_Sum").toDouble());
- }
-
- if (dataMap.contains("PowerReal_P_Phase_1")) {
- pluginThing()->setStateValue(meterCurrentPowerPhaseAStateTypeId, dataMap.value("PowerReal_P_Phase_1").toDouble());
- }
-
- if (dataMap.contains("PowerReal_P_Phase_2")) {
- pluginThing()->setStateValue(meterCurrentPowerPhaseBStateTypeId, dataMap.value("PowerReal_P_Phase_2").toDouble());
- }
-
- if (dataMap.contains("PowerReal_P_Phase_3")) {
- pluginThing()->setStateValue(meterCurrentPowerPhaseCStateTypeId, dataMap.value("PowerReal_P_Phase_3").toDouble());
- }
-
- // Current
- if (dataMap.contains("Current_AC_Phase_1")) {
- pluginThing()->setStateValue(meterCurrentPhaseAStateTypeId, dataMap.value("Current_AC_Phase_1").toDouble());
- }
-
- if (dataMap.contains("Current_AC_Phase_2")) {
- pluginThing()->setStateValue(meterCurrentPhaseBStateTypeId, dataMap.value("Current_AC_Phase_2").toDouble());
- }
-
- if (dataMap.contains("Current_AC_Phase_3")) {
- pluginThing()->setStateValue(meterCurrentPhaseCStateTypeId, dataMap.value("Current_AC_Phase_3").toDouble());
- }
-
- // Voltage
- if (dataMap.contains("Voltage_AC_Phase_1")) {
- pluginThing()->setStateValue(meterVoltagePhaseAStateTypeId, dataMap.value("Voltage_AC_Phase_1").toDouble());
- }
-
- if (dataMap.contains("Voltage_AC_Phase_2")) {
- pluginThing()->setStateValue(meterVoltagePhaseBStateTypeId, dataMap.value("Voltage_AC_Phase_2").toDouble());
- }
-
- if (dataMap.contains("Voltage_AC_Phase_3")) {
- pluginThing()->setStateValue(meterVoltagePhaseCStateTypeId, dataMap.value("Voltage_AC_Phase_3").toDouble());
- }
-
- // Total energy
- if (dataMap.contains("EnergyReal_WAC_Sum_Produced")) {
- pluginThing()->setStateValue(meterTotalEnergyProducedStateTypeId, dataMap.value("EnergyReal_WAC_Sum_Produced").toInt()/1000.00);
- }
-
- if (dataMap.contains("EnergyReal_WAC_Sum_Consumed")) {
- pluginThing()->setStateValue(meterTotalEnergyConsumedStateTypeId, dataMap.value("EnergyReal_WAC_Sum_Consumed").toInt()/1000.00);
- }
-
- // Frequency
- if (dataMap.contains("Frequency_Phase_Average")) {
- pluginThing()->setStateValue(meterFrequencyStateTypeId, dataMap.value("Frequency_Phase_Average").toDouble());
- }
-
- //update successful
- pluginThing()->setStateValue(meterConnectedStateTypeId,true);
-}
-
-QUrl FroniusMeter::activityUrl()
-{
- QUrl requestUrl;
- requestUrl.setScheme("http");
- requestUrl.setHost(hostAddress());
- requestUrl.setPath(baseUrl()+"GetPowerFlowRealtimeData.fcgi");
-
- return requestUrl;
-}
diff --git a/fronius/froniusmeter.h b/fronius/froniusnetworkreply.cpp
similarity index 54%
rename from fronius/froniusmeter.h
rename to fronius/froniusnetworkreply.cpp
index 7f926a0c..13141ae4 100644
--- a/fronius/froniusmeter.h
+++ b/fronius/froniusnetworkreply.cpp
@@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
-* Copyright 2013 - 2020, nymea GmbH
+* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@@ -28,27 +28,50 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#ifndef FRONIUSMETER_H
-#define FRONIUSMETER_H
+#include "froniusnetworkreply.h"
-#include
-#include "froniusthing.h"
-
-class FroniusMeter : public FroniusThing
+FroniusNetworkReply::~FroniusNetworkReply()
{
- Q_OBJECT
-public:
- explicit FroniusMeter(Thing* thing, QObject *parent = 0);
+ if (m_networkReply) {
+ // We don't need the finished signal any more, object gets deleted
+ disconnect(m_networkReply, &QNetworkReply::finished, this, &FroniusNetworkReply::finished);
- QString activity() const;
- void setActivity(const QString &activity);
+ if (m_networkReply->isRunning()) {
+ // Abort the reply, we are not interested in it any more
+ m_networkReply->abort();
+ }
- QUrl updateUrl();
- void updateThingInfo(const QByteArray &data);
- QUrl activityUrl();
+ m_networkReply->deleteLater();
+ }
+}
-private:
- QString m_activity;
-};
+QUrl FroniusNetworkReply::requestUrl() const
+{
+ return m_request.url();
+}
+
+QNetworkRequest FroniusNetworkReply::request() const
+{
+ return m_request;
+}
+
+QNetworkReply *FroniusNetworkReply::networkReply() const
+{
+ return m_networkReply;
+}
+
+FroniusNetworkReply::FroniusNetworkReply(const QNetworkRequest &request, QObject *parent) :
+ QObject(parent),
+ m_request(request)
+{
+
+}
+
+void FroniusNetworkReply::setNetworkReply(QNetworkReply *networkReply)
+{
+ m_networkReply = networkReply;
+
+ // The QNetworkReply will be deleted in the constructor if set
+ connect(m_networkReply, &QNetworkReply::finished, this, &FroniusNetworkReply::finished);
+}
-#endif // FRONIUSMETER_H
diff --git a/fronius/froniusinverter.h b/fronius/froniusnetworkreply.h
similarity index 70%
rename from fronius/froniusinverter.h
rename to fronius/froniusnetworkreply.h
index 0b67e59a..5d03d36f 100644
--- a/fronius/froniusinverter.h
+++ b/fronius/froniusnetworkreply.h
@@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
-* Copyright 2013 - 2020, nymea GmbH
+* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@@ -28,29 +28,36 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#ifndef FRONIUSINVERTER_H
-#define FRONIUSINVERTER_H
+#ifndef FRONIUSNETWORKREPLY_H
+#define FRONIUSNETWORKREPLY_H
#include
-#include "froniusthing.h"
+#include
-class FroniusInverter : public FroniusThing
+class FroniusNetworkReply : public QObject
{
Q_OBJECT
-public:
- explicit FroniusInverter(Thing *thing, QObject *parent = 0);
+ friend class FroniusSolarConnection;
- QString activity() const;
- void setActivity(const QString &activity);
- Thing* inverterThing() const;
- QUrl updateUrl();
- void updateThingInfo(const QByteArray &data);
- QUrl activityUrl();
- void updateActivityInfo(const QByteArray &data);
+public:
+ ~FroniusNetworkReply();
+
+ QUrl requestUrl() const;
+
+ QNetworkRequest request() const;
+ QNetworkReply *networkReply() const;
+
+signals:
+ void finished();
private:
- QString m_activity;
+ explicit FroniusNetworkReply(const QNetworkRequest &request, QObject *parent = nullptr);
+
+ QNetworkRequest m_request;
+ QNetworkReply *m_networkReply = nullptr;
+
+ void setNetworkReply(QNetworkReply *networkReply);
};
-#endif // FRONIUSINVERTER_H
+#endif // FRONIUSNETWORKREPLY_H
diff --git a/fronius/froniussolarconnection.cpp b/fronius/froniussolarconnection.cpp
new file mode 100644
index 00000000..49d98d92
--- /dev/null
+++ b/fronius/froniussolarconnection.cpp
@@ -0,0 +1,203 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* 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 "froniussolarconnection.h"
+#include "extern-plugininfo.h"
+
+#include
+
+FroniusSolarConnection::FroniusSolarConnection(NetworkAccessManager *networkManager, const QHostAddress &address, QObject *parent) :
+ QObject(parent),
+ m_networkManager(networkManager),
+ m_address(address)
+{
+
+}
+
+QHostAddress FroniusSolarConnection::address() const
+{
+ return m_address;
+}
+
+bool FroniusSolarConnection::available() const
+{
+ return m_available;
+}
+
+bool FroniusSolarConnection::busy() const
+{
+ return m_requestQueue.count() > 1;
+}
+
+FroniusNetworkReply *FroniusSolarConnection::getVersion()
+{
+ QUrl requestUrl;
+ requestUrl.setScheme("http");
+ requestUrl.setHost(m_address.toString());
+ requestUrl.setPath("/solar_api/GetAPIVersion.cgi");
+
+ FroniusNetworkReply *reply = new FroniusNetworkReply(QNetworkRequest(requestUrl), this);
+ m_requestQueue.enqueue(reply);
+ sendNextRequest();
+ return reply;
+}
+
+FroniusNetworkReply *FroniusSolarConnection::getActiveDevices()
+{
+ QUrl requestUrl;
+ requestUrl.setScheme("http");
+ requestUrl.setHost(m_address.toString());
+ requestUrl.setPath("/solar_api/v1/GetActiveDeviceInfo.cgi");
+
+ QUrlQuery query;
+ query.addQueryItem("DeviceClass", "System");
+ requestUrl.setQuery(query);
+
+ FroniusNetworkReply *reply = new FroniusNetworkReply(QNetworkRequest(requestUrl), this);
+ m_requestQueue.enqueue(reply);
+
+ // Note: we use this request for detecting if the logger is available or not.
+ connect(reply, &FroniusNetworkReply::finished, this, [=](){
+ if (reply->networkReply()->error() == QNetworkReply::NoError) {
+ // Reply was successfully, we can communicate
+ if (!m_available) {
+ qCDebug(dcFronius()) << "Connection: the connection is now available";
+ m_available = true;
+ emit availableChanged(m_available);
+
+ // Destroy any pending requests
+ qDeleteAll(m_requestQueue);
+ m_requestQueue.clear();
+ }
+ } else {
+ // Ther have been errors, seems like we not available any more
+ if (m_available) {
+ qCDebug(dcFronius()) << "Connection: the connection is not available any more:" << reply->networkReply()->errorString();
+ m_available = false;
+ emit availableChanged(m_available);
+ }
+ }
+ });
+
+ sendNextRequest();
+ return reply;
+}
+
+FroniusNetworkReply *FroniusSolarConnection::getPowerFlowRealtimeData()
+{
+ QUrl requestUrl;
+ requestUrl.setScheme("http");
+ requestUrl.setHost(m_address.toString());
+ requestUrl.setPath("/solar_api/v1/GetPowerFlowRealtimeData.fcgi");
+
+ FroniusNetworkReply *reply = new FroniusNetworkReply(QNetworkRequest(requestUrl), this);
+ m_requestQueue.enqueue(reply);
+ sendNextRequest();
+ return reply;
+}
+
+FroniusNetworkReply *FroniusSolarConnection::getInverterRealtimeData(int inverterId)
+{
+ QUrl requestUrl;
+ requestUrl.setScheme("http");
+ requestUrl.setHost(m_address.toString());
+ requestUrl.setPath("/solar_api/v1/GetInverterRealtimeData.cgi");
+
+ QUrlQuery query;
+ query.addQueryItem("Scope", "Device");
+ query.addQueryItem("DeviceId", QString::number(inverterId));
+ query.addQueryItem("DataCollection", "CommonInverterData");
+ requestUrl.setQuery(query);
+
+ FroniusNetworkReply *reply = new FroniusNetworkReply(QNetworkRequest(requestUrl), this);
+ m_requestQueue.enqueue(reply);
+ sendNextRequest();
+ return reply;
+}
+
+FroniusNetworkReply *FroniusSolarConnection::getMeterRealtimeData(int meterId)
+{
+ QUrl requestUrl;
+ requestUrl.setScheme("http");
+ requestUrl.setHost(m_address.toString());
+ requestUrl.setPath("/solar_api/v1/GetMeterRealtimeData.cgi");
+
+ QUrlQuery query;
+ query.addQueryItem("Scope", "Device");
+ query.addQueryItem("DeviceId", QString::number(meterId));
+ requestUrl.setQuery(query);
+
+ FroniusNetworkReply *reply = new FroniusNetworkReply(QNetworkRequest(requestUrl), this);
+ m_requestQueue.enqueue(reply);
+ sendNextRequest();
+ return reply;
+}
+
+FroniusNetworkReply *FroniusSolarConnection::getStorageRealtimeData(int meterId)
+{
+ QUrl requestUrl;
+ requestUrl.setScheme("http");
+ requestUrl.setHost(m_address.toString());
+ requestUrl.setPath("/solar_api/v1/GetStorageRealtimeData.cgi");
+
+ QUrlQuery query;
+ query.addQueryItem("Scope", "Device");
+ query.addQueryItem("DeviceId", QString::number(meterId));
+ requestUrl.setQuery(query);
+
+ FroniusNetworkReply *reply = new FroniusNetworkReply(QNetworkRequest(requestUrl), this);
+ m_requestQueue.enqueue(reply);
+ sendNextRequest();
+ return reply;
+}
+
+void FroniusSolarConnection::sendNextRequest()
+{
+ if (m_currentReply)
+ return;
+
+ if (m_requestQueue.isEmpty())
+ return;
+
+ m_currentReply = m_requestQueue.dequeue();
+
+ qCDebug(dcFronius()) << "Connection: Sending request" << m_currentReply->request().url().toString();
+ m_currentReply->setNetworkReply(m_networkManager->get(m_currentReply->request()));
+
+ connect(m_currentReply, &FroniusNetworkReply::finished, this, [=](){
+ qCDebug(dcFronius()) << "Connection: Request finished" << m_currentReply->networkReply()->error();
+
+ // Note: the network reply will be deleted in the destructor
+ m_currentReply->deleteLater();
+
+ m_currentReply = nullptr;
+ sendNextRequest();
+ });
+}
diff --git a/fronius/froniusstorage.h b/fronius/froniussolarconnection.h
similarity index 55%
rename from fronius/froniusstorage.h
rename to fronius/froniussolarconnection.h
index 551d6044..e940a9be 100644
--- a/fronius/froniusstorage.h
+++ b/fronius/froniussolarconnection.h
@@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
-* Copyright 2013 - 2020, nymea GmbH
+* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@@ -28,29 +28,53 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#ifndef FRONIUSSTORAGE_H
-#define FRONIUSSTORAGE_H
+#ifndef FRONIUSSOLARCONNECTION_H
+#define FRONIUSSOLARCONNECTION_H
#include
-#include "froniusthing.h"
-class FroniusStorage : public FroniusThing
+#include
+#include
+
+#include
+
+#include "froniusnetworkreply.h"
+
+class FroniusSolarConnection : public QObject
{
Q_OBJECT
-
public:
- explicit FroniusStorage(Thing *thing, QObject *parent = 0);
+ explicit FroniusSolarConnection(NetworkAccessManager *networkManager, const QHostAddress &address, QObject *parent = nullptr);
- QString charging_state() const;
- void setChargingState(const QString &charging_state);
+ QHostAddress address() const;
- QUrl updateUrl();
- void updateThingInfo(const QByteArray &data);
- QUrl activityUrl();
- void updateActivityInfo(const QByteArray &data);
+ bool available() const;
+
+ bool busy() const;
+
+ FroniusNetworkReply *getVersion();
+ FroniusNetworkReply *getActiveDevices();
+ FroniusNetworkReply *getPowerFlowRealtimeData();
+
+ FroniusNetworkReply *getInverterRealtimeData(int inverterId);
+ FroniusNetworkReply *getMeterRealtimeData(int meterId);
+ FroniusNetworkReply *getStorageRealtimeData(int meterId);
+
+signals:
+ void availableChanged(bool available);
private:
- QString m_charging_state;
- int m_charge;
+ NetworkAccessManager *m_networkManager = nullptr;
+ QHostAddress m_address;
+
+ bool m_available = false;
+
+ // Request queue to prevent overloading the device with requests
+ FroniusNetworkReply *m_currentReply = nullptr;
+ QQueue m_requestQueue;
+
+ void sendNextRequest();
+
};
-#endif // FRONIUSSTORAGE_H
+
+#endif // FRONIUSSOLARCONNECTION_H
diff --git a/fronius/froniusstorage.cpp b/fronius/froniusstorage.cpp
deleted file mode 100644
index 2119c148..00000000
--- a/fronius/froniusstorage.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-*
-* 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 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 "froniusstorage.h"
-#include
-#include "extern-plugininfo.h"
-#include
-
-FroniusStorage::FroniusStorage(Thing* thing, QObject *parent) : FroniusThing(thing, parent)
-{
-
-}
-
-QString FroniusStorage::charging_state() const
-{
- return m_charging_state;
-}
-
-void FroniusStorage::setChargingState(const QString &charging_state)
-{
- m_charging_state = charging_state;
-}
-
-QUrl FroniusStorage::updateUrl()
-{
- QUrl requestUrl;
- requestUrl.setScheme("http");
- QUrlQuery query;
- requestUrl.setHost(hostAddress());
- requestUrl.setPath(baseUrl() + "GetStorageRealtimeData.cgi");
- query.addQueryItem("Scope", "Device");
- query.addQueryItem("DeviceId", deviceId());
- requestUrl.setQuery(query);
-
- return requestUrl;
-}
-
-void FroniusStorage::updateThingInfo(const QByteArray &data)
-{
- // Convert the rawdata to a JSON document
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
-
- if (error.error != QJsonParseError::NoError) {
- qCWarning(dcFronius()) << "FroniusStorage: Failed to parse JSON data" << data << ":" << error.errorString();
- pluginThing()->setStateValue(storageConnectedStateTypeId,false);
- return;
- }
-
- // Parse the data and update the states of our thing
- QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
- // QVariantMap headMap = jsonDoc.toVariant().toMap().value("Head").toMap();
-
- qCDebug(dcFronius()) << "Storage data" << qUtf8Printable(QJsonDocument::fromVariant(dataMap).toJson(QJsonDocument::Indented));
-
- // create StorageInfo list map
- QVariantMap storageInfoMap = dataMap.value("Controller").toMap();
-
- // copy retrieved information to thing states
- if (storageInfoMap.contains("StateOfCharge_Relative")) {
- pluginThing()->setStateValue(storageBatteryLevelStateTypeId, storageInfoMap.value("StateOfCharge_Relative").toInt());
- if (pluginThing()->stateValue(storageChargingStateStateTypeId).toString() == "charging" && (storageInfoMap.value("StateOfCharge_Relative").toInt() < 5)) {
- pluginThing()->setStateValue(storageBatteryCriticalStateTypeId, true);
- } else {
- pluginThing()->setStateValue(storageBatteryCriticalStateTypeId, false);
- }
- }
-
- if (storageInfoMap.contains("Temperature_Cell"))
- pluginThing()->setStateValue(storageCellTemperatureStateTypeId, storageInfoMap.value("Temperature_Cell").toDouble());
-
- if (storageInfoMap.contains("Capacity_Maximum"))
- pluginThing()->setStateValue(storageCapacityStateTypeId, storageInfoMap.value("Capacity_Maximum").toDouble());
-
- pluginThing()->setStateValue(storageConnectedStateTypeId,true);
-}
-
-QUrl FroniusStorage::activityUrl()
-{
- QUrl requestUrl;
- requestUrl.setScheme("http");
- requestUrl.setHost(hostAddress());
- requestUrl.setPath(baseUrl()+"GetPowerFlowRealtimeData.fcgi");
-
- return requestUrl;
-}
-
-void FroniusStorage::updateActivityInfo(const QByteArray &data)
-{
- // Convert the rawdata to a json document
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
- if(error.error != QJsonParseError::NoError) {
- qCWarning(dcFronius()) << "FroniusStorage: Failed to parse JSON data" << data << ":" << error.errorString();
- return;
- }
-
- // create StorageInfo list map
- QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
- float charge_akku = dataMap.value("Site").toMap().value("P_Akku").toFloat();
- pluginThing()->setStateValue(storageCurrentPowerStateTypeId, charge_akku);
- if (charge_akku < 0) {
- pluginThing()->setStateValue(storageChargingStateStateTypeId, "discharging");
- } else if (charge_akku > 0) {
- pluginThing()->setStateValue(storageChargingStateStateTypeId, "charging");
- } else {
- pluginThing()->setStateValue(storageChargingStateStateTypeId, "idle");
- }
-}
diff --git a/fronius/integrationpluginfronius.cpp b/fronius/integrationpluginfronius.cpp
index 5cb07ac4..1bca7c19 100644
--- a/fronius/integrationpluginfronius.cpp
+++ b/fronius/integrationpluginfronius.cpp
@@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
-* Copyright 2013 - 2020, nymea GmbH
+* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@@ -29,16 +29,16 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "plugininfo.h"
-#include "integrationpluginfronius.h"
#include "plugintimer.h"
+#include "integrationpluginfronius.h"
#include "network/networkaccessmanager.h"
#include "network/networkdevicediscovery.h"
#include
+#include
+#include
#include
#include
-#include
-#include
// Notes: Test IPs: 93.82.221.82 | 88.117.152.99
@@ -83,18 +83,18 @@ void IntegrationPluginFronius::discoverThings(ThingDiscoveryInfo *info)
description = networkDeviceInfo.macAddress() + " (" + networkDeviceInfo.macAddressManufacturer() + ")";
}
- ThingDescriptor descriptor(dataloggerThingClassId, title, description);
+ ThingDescriptor descriptor(connectionThingClassId, title, description);
// Check if we already have set up this device
- Things existingThings = myThings().filterByParam(dataloggerThingLoggerMacParamTypeId, networkDeviceInfo.macAddress());
+ Things existingThings = myThings().filterByParam(connectionThingMacParamTypeId, networkDeviceInfo.macAddress());
if (existingThings.count() == 1) {
qCDebug(dcFronius()) << "This thing already exists in the system." << existingThings.first() << networkDeviceInfo;
descriptor.setThingId(existingThings.first()->id());
}
ParamList params;
- params << Param(dataloggerThingLoggerHostParamTypeId, networkDeviceInfo.address().toString());
- params << Param(dataloggerThingLoggerMacParamTypeId, networkDeviceInfo.macAddress());
+ params << Param(connectionThingAddressParamTypeId, networkDeviceInfo.address().toString());
+ params << Param(connectionThingMacParamTypeId, networkDeviceInfo.macAddress());
descriptor.setParams(params);
info->addThingDescriptor(descriptor);
}
@@ -104,36 +104,22 @@ void IntegrationPluginFronius::discoverThings(ThingDiscoveryInfo *info)
void IntegrationPluginFronius::setupThing(ThingSetupInfo *info)
{
- qCDebug(dcFronius()) << "Setting up a new thing:" << info->thing()->name();
-
Thing *thing = info->thing();
+ qCDebug(dcFronius()) << "Setting up" << thing;
- if (thing->thingClassId() == dataloggerThingClassId) {
- //check if a data logger is already added with this IPv4Address
- foreach(FroniusLogger *logger, m_froniusLoggers.keys()){
- if(logger->hostAddress() == thing->paramValue(dataloggerThingLoggerHostParamTypeId).toString()){
- //this logger at this IPv4 address is already added
- qCWarning(dcFronius()) << "thing at " << thing->paramValue(dataloggerThingLoggerHostParamTypeId).toString() << " already added!";
- info->finish(Thing::ThingErrorThingInUse);
- return;
- }
- }
+ if (thing->thingClassId() == connectionThingClassId) {
- // Perform a HTTP request on the given IPv4Address to find things
- QUrl requestUrl;
- requestUrl.setScheme("http");
- requestUrl.setHost(thing->paramValue(dataloggerThingLoggerHostParamTypeId).toString());
- requestUrl.setPath("/solar_api/GetAPIVersion.cgi");
+ QHostAddress address(thing->paramValue(connectionThingAddressParamTypeId).toString());
+ FroniusSolarConnection *connection = new FroniusSolarConnection(hardwareManager()->networkManager(), address, thing);
- qCDebug(dcFronius()) << "Search at address" << requestUrl.toString();
-
- QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(requestUrl));
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, info, [this, info, thing, reply] {
- QByteArray data = reply->readAll();
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString() << reply->url();
- info->finish(Thing::ThingErrorHardwareNotAvailable, tr("Device not reachable"));
+ // Verify the version
+ FroniusNetworkReply *reply = connection->getVersion();
+ connect(reply, &FroniusNetworkReply::finished, reply, &QNetworkReply::deleteLater);
+ connect(reply, &FroniusNetworkReply::finished, info, [=] {
+ QByteArray data = reply->networkReply()->readAll();
+ if (reply->networkReply()->error() != QNetworkReply::NoError) {
+ qCWarning(dcFronius()) << "Network request error:" << reply->networkReply()->error() << reply->networkReply()->errorString() << reply->networkReply()->url();
+ info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("The device is not reachable"));
return;
}
@@ -142,11 +128,12 @@ void IntegrationPluginFronius::setupThing(ThingSetupInfo *info)
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcFronius()) << "Failed to parse JSON data" << data << ":" << error.errorString() << data;
- info->finish(Thing::ThingErrorHardwareFailure, tr("Please try again"));
+ info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Unable to read the data. Please try again."));
return;
}
QVariantMap versionResponseMap = jsonDoc.toVariant().toMap();
+ qCDebug(dcFronius()) << "Compatibility version" << versionResponseMap.value("CompatibilityRange").toString();
// Knwon version with broken JSON API
if (versionResponseMap.value("CompatibilityRange").toString() == "1.6-2") {
@@ -155,34 +142,47 @@ void IntegrationPluginFronius::setupThing(ThingSetupInfo *info)
return;
}
- FroniusLogger *newLogger = new FroniusLogger(thing, this);
- newLogger->setBaseUrl(versionResponseMap.value("BaseURL").toString());
- newLogger->setHostAddress(thing->paramValue(dataloggerThingLoggerHostParamTypeId).toString());
- m_froniusLoggers.insert(newLogger, thing);
-
+ m_froniusConnections.insert(connection, thing);
info->finish(Thing::ThingErrorNoError);
+
+ // Update the already known states
+ thing->setStateValue("connected", true);
+ thing->setStateValue(connectionVersionStateTypeId, versionResponseMap.value("CompatibilityRange").toString());
});
- } else if ((thing->thingClassId() == inverterThingClassId) ||
- (thing->thingClassId() == meterThingClassId) ||
- (thing->thingClassId() == storageThingClassId)) {
+ connect(connection, &FroniusSolarConnection::availableChanged, this, [=](bool available){
+ qCDebug(dcFronius()) << thing << "Available changed" << available;
+ thing->setStateValue("connected", available);
- Thing *loggerThing = myThings().findById(thing->parentId());
- if (!loggerThing) {
- qCWarning(dcFronius()) << "Could not find Logger Thing for thing " << thing->name();
- return info->finish(Thing::ThingErrorHardwareNotAvailable, "Please try again");
- }
-
- if (!loggerThing->setupComplete()) {
- //wait for the parent to finish the setup process
- connect(loggerThing, &Thing::setupStatusChanged, info, [this, info, loggerThing] {
- if (loggerThing->setupComplete()) {
- setupChild(info, loggerThing);
+ if (!available) {
+ // Update all child things, they will be set to available once the connection starts working again
+ foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
+ childThing->setStateValue("connected", false);
}
- });
+ }
+ });
+
+ } else if ((thing->thingClassId() == inverterThingClassId ||
+ thing->thingClassId() == meterThingClassId ||
+ thing->thingClassId() == storageThingClassId)) {
+
+ // Verify the parent connection
+ Thing *parentThing = myThings().findById(thing->parentId());
+ if (!parentThing) {
+ qCWarning(dcFronius()) << "Could not find the parent for" << thing;
+ info->finish(Thing::ThingErrorHardwareNotAvailable);
return;
}
- setupChild(info, loggerThing);
+
+ FroniusSolarConnection *connection = m_froniusConnections.key(parentThing);
+ if (!connection) {
+ qCWarning(dcFronius()) << "Could not find the parent connection for" << thing;
+ info->finish(Thing::ThingErrorHardwareNotAvailable);
+ return;
+ }
+
+ info->finish(Thing::ThingErrorNoError);
+
} else {
Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
}
@@ -192,206 +192,69 @@ void IntegrationPluginFronius::postSetupThing(Thing *thing)
{
qCDebug(dcFronius()) << "Post setup" << thing->name();
- if (!m_pluginTimer) {
- m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(2);
- connect(m_pluginTimer, &PluginTimer::timeout, this, [this]() {
- foreach (Thing *logger, m_froniusLoggers)
- updateThingStates(logger);
+ if (thing->thingClassId() == connectionThingClassId) {
- foreach (Thing *inverter, m_froniusInverters)
- updateThingStates(inverter);
+ // Create a refresh timer for monitoring the active devices
+ if (!m_connectionRefreshTimer) {
+ m_connectionRefreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(2);
+ connect(m_connectionRefreshTimer, &PluginTimer::timeout, this, [this]() {
+ foreach (FroniusSolarConnection *connection, m_froniusConnections.keys()) {
+ refreshConnection(connection);
+ }
+ });
- foreach (Thing *meter, m_froniusMeters)
- updateThingStates(meter);
+ m_connectionRefreshTimer->start();
+ }
- foreach (Thing *storage, m_froniusStorages)
- updateThingStates(storage);
- });
- }
-
- if (thing->thingClassId() == dataloggerThingClassId) {
- searchNewThings(m_froniusLoggers.key(thing));
- thing->setStateValue(dataloggerConnectedStateTypeId, true);
- updateThingStates(thing);
- } else if ((thing->thingClassId() == inverterThingClassId) ||
- (thing->thingClassId() == meterThingClassId) ||
- (thing->thingClassId() == storageThingClassId)) {
- updateThingStates(thing);
- } else {
- Q_ASSERT_X(false, "postSetupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
+ // Refresh now
+ FroniusSolarConnection *connection = m_froniusConnections.key(thing);
+ if (connection) {
+ refreshConnection(connection);
+ }
}
}
void IntegrationPluginFronius::thingRemoved(Thing *thing)
{
- if (thing->thingClassId() == dataloggerThingClassId) {
- FroniusLogger *logger = m_froniusLoggers.key(thing);
- m_froniusLoggers.remove(logger);
- logger->deleteLater();
- } else if (thing->thingClassId() == inverterThingClassId) {
- FroniusInverter *inverter = m_froniusInverters.key(thing);
- m_froniusInverters.remove(inverter);
- inverter->deleteLater();
- } else if (thing->thingClassId() == meterThingClassId) {
- FroniusMeter *meter = m_froniusMeters.key(thing);
- m_froniusMeters.remove(meter);
- meter->deleteLater();
- } else if (thing->thingClassId() == storageThingClassId) {
- FroniusStorage *storage = m_froniusStorages.key(thing);
- m_froniusStorages.remove(storage);
- storage->deleteLater();
- } else {
- Q_ASSERT_X(false, "thingRemoved", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
+ if (thing->thingClassId() == connectionThingClassId) {
+ FroniusSolarConnection *connection = m_froniusConnections.key(thing);
+ m_froniusConnections.remove(connection);
+ connection->deleteLater();
}
- if (myThings().isEmpty()) {
- hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
- m_pluginTimer = nullptr;
+ if (myThings().filterByThingClassId(connectionThingClassId).isEmpty()) {
+ hardwareManager()->pluginTimerManager()->unregisterTimer(m_connectionRefreshTimer);
+ m_connectionRefreshTimer = nullptr;
}
}
void IntegrationPluginFronius::executeAction(ThingActionInfo *info)
{
- Action action = info->action();
- Thing *thing = info->thing();
- qCDebug(dcFronius()) << "Execute action" << thing->name() << action.actionTypeId().toString();
-
- if (thing->thingClassId() == dataloggerThingClassId) {
- if (action.actionTypeId() == dataloggerSearchDevicesActionTypeId) {
- searchNewThings(m_froniusLoggers.key(thing));
- info->finish(Thing::ThingErrorNoError);
- } else {
- Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8());
- }
- } else {
- Q_ASSERT_X(false, "executeAction", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
- }
+ Q_UNUSED(info)
}
-void IntegrationPluginFronius::updateThingStates(Thing *thing)
+void IntegrationPluginFronius::refreshConnection(FroniusSolarConnection *connection)
{
- qCDebug(dcFronius()) << "Update thing values for" << thing->name();
-
- if (thing->thingClassId() == inverterThingClassId) {
- qCDebug(dcFronius()) << "Update inverter" << m_froniusInverters.key(thing)->updateUrl();
- QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(m_froniusInverters.key(thing)->updateUrl()));
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, thing, [this, thing, reply]() {
-
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString() << reply->request().url();
- return;
- }
- QByteArray data = reply->readAll();
- if (m_froniusInverters.values().contains(thing)){ // check if thing was not removed before reply was received
- m_froniusInverters.key(thing)->updateThingInfo(data);
- }
- });
- QNetworkReply *next_reply = hardwareManager()->networkManager()->get(QNetworkRequest(m_froniusInverters.key(thing)->activityUrl()));
- connect(next_reply, &QNetworkReply::finished, next_reply, &QNetworkReply::deleteLater);
- connect(next_reply, &QNetworkReply::finished, thing, [this, thing, next_reply] {
- if (next_reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << next_reply->error() << next_reply->errorString() << next_reply->request().url();
- return;
- }
- QByteArray data = next_reply->readAll();
- if (m_froniusInverters.values().contains(thing)){ // check if thing was not removed before reply was received
- m_froniusInverters.key(thing)->updateActivityInfo(data);
- }
- });
- } else if (thing->thingClassId() == dataloggerThingClassId) {
- qCDebug(dcFronius()) << "Update logger" << m_froniusLoggers.key(thing)->updateUrl();
- QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(m_froniusLoggers.key(thing)->updateUrl()));
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, thing, [this, thing, reply]() {
-
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString() << reply->request().url();
- return;
- }
- QByteArray data = reply->readAll();
- if (m_froniusLoggers.values().contains(thing)){ // check if thing was not removed before reply was received
- m_froniusLoggers.key(thing)->updateThingInfo(data);
- }
- });
-
- } else if (thing->thingClassId() == meterThingClassId) {
- qCDebug(dcFronius()) << "Update meter" << m_froniusMeters.key(thing)->updateUrl();
- QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(m_froniusMeters.key(thing)->updateUrl()));
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, thing, [this, thing, reply]() {
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString() << reply->request().url();
- return;
- }
- QByteArray data = reply->readAll();
- if (m_froniusMeters.values().contains(thing)){ // check if thing was not removed before reply was received
- m_froniusMeters.key(thing)->updateThingInfo(data);
- }
- });
-
- } else if (thing->thingClassId() == storageThingClassId) {
- qCDebug(dcFronius()) << "Update storage" << m_froniusStorages.key(thing)->updateUrl();
- QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(m_froniusStorages.key(thing)->updateUrl()));
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, thing, [this, thing, reply]() {
-
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString() << reply->request().url();
- return;
- }
- QByteArray data = reply->readAll();
- if (m_froniusStorages.values().contains(thing)){ // check if thing was not removed before reply was received
- m_froniusStorages.key(thing)->updateThingInfo(data);
- }
- });
- QNetworkReply *next_reply = hardwareManager()->networkManager()->get(QNetworkRequest(m_froniusStorages.key(thing)->activityUrl()));
- connect(next_reply, &QNetworkReply::finished, next_reply, &QNetworkReply::deleteLater);
- connect(next_reply, &QNetworkReply::finished, thing, [this, thing, next_reply]() {
-
- if (next_reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << next_reply->error() << next_reply->errorString() << next_reply->request().url();
- return;
- }
- QByteArray data = next_reply->readAll();
- if(m_froniusStorages.values().contains(thing)){ // check if thing was not removed before reply was received
- m_froniusStorages.key(thing)->updateActivityInfo(data);
- }
- });
- } else {
- Q_ASSERT_X(false, "updateThingState", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
+ if (!connection->busy()) {
+ qCWarning(dcFronius()) << "Connection busy. Skipping refresh cycle for host" << connection->address().toString();
+ return;
}
-}
-void IntegrationPluginFronius::searchNewThings(FroniusLogger *logger)
-{
- QUrl url; QUrlQuery query;
- query.addQueryItem("DeviceClass", "System");
- url.setScheme("http");
- url.setHost(logger->hostAddress());
- url.setPath(logger->baseUrl() + "GetActiveDeviceInfo.cgi");
- url.setQuery(query);
-
- qCDebug(dcFronius()) << "Searching new things at address" << url.toString();
- QNetworkRequest request = QNetworkRequest(url);
- request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
-
- QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, logger, [this, logger, reply]() {
-
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString() << reply->request().url();
+ // Note: this call will be used to monitor the available state of the connection internally
+ FroniusNetworkReply *reply = connection->getActiveDevices();
+ connect(reply, &FroniusNetworkReply::finished, this, [=]() {
+ if (reply->networkReply()->error() != QNetworkReply::NoError) {
+ // Note: the connection warns about any errors if available changed
return;
}
- Thing *loggerThing = m_froniusLoggers.value(logger);
- if (!loggerThing)
+ Thing *connectionThing = m_froniusConnections.value(connection);
+ if (!connectionThing)
return;
- // Convert the rawdata to a json document
- QByteArray data = reply->readAll();
+ QByteArray data = reply->networkReply()->readAll();
+
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) {
@@ -402,70 +265,62 @@ void IntegrationPluginFronius::searchNewThings(FroniusLogger *logger)
// Parse the data for thing information
QList thingDescriptors;
- // Check reply information
QVariantMap bodyMap = jsonDoc.toVariant().toMap().value("Body").toMap();
- qCDebug(dcFronius()) << "System:" << qUtf8Printable(QJsonDocument::fromVariant(bodyMap).toJson(QJsonDocument::Indented));
+ //qCDebug(dcFronius()) << "System:" << qUtf8Printable(QJsonDocument::fromVariant(bodyMap).toJson());
- // Parse reply for inverters at the host address
+ // Check if there are new inverters
QVariantMap inverterMap = bodyMap.value("Data").toMap().value("Inverter").toMap();
foreach (const QString &inverterId, inverterMap.keys()) {
- //check if thing already connected to logger
- if (!thingExists(inverterThingIdParamTypeId, inverterId)) {
- QString thingDescription = loggerThing->name();
- ThingDescriptor descriptor(inverterThingClassId, "Fronius Solar Inverter", thingDescription, loggerThing->id());
+ QVariantMap inverterInfo = inverterMap.value(inverterId).toMap();
+ const QString serialNumber = inverterInfo.value("Serial").toString();
+
+ // Note: we use the id to identify for backwards compatibility
+ if (myThings().filterByParam(inverterThingIdParamTypeId, inverterId).isEmpty()) {
+ QString thingDescription = connectionThing->name();
+ ThingDescriptor descriptor(inverterThingClassId, "Fronius Solar Inverter", thingDescription, connectionThing->id());
ParamList params;
params.append(Param(inverterThingIdParamTypeId, inverterId));
+ params.append(Param(inverterThingSerialNumberParamTypeId, serialNumber));
descriptor.setParams(params);
thingDescriptors.append(descriptor);
}
}
- // parse reply for meter things at the host address
+ // Check if there are new meters
QVariantMap meterMap = bodyMap.value("Data").toMap().value("Meter").toMap();
foreach (const QString &meterId, meterMap.keys()) {
- //check if thing already connected to logger
- if (!thingExists(meterThingIdParamTypeId, meterId)) {
- // get meter infos
- ///solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=0
- QUrl requestUrl;
- requestUrl.setScheme("http");
- requestUrl.setHost(logger->hostAddress());
- requestUrl.setPath(logger->baseUrl() + "GetMeterRealtimeData.cgi");
- QUrlQuery query;
- query.addQueryItem("Scope", "Device");
- query.addQueryItem("DeviceId", meterId);
- requestUrl.setQuery(query);
-
- qCDebug(dcFronius()) << "Get meter information before setup";
- QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(requestUrl));
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, this, [=]() {
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString();
+ // Note: we use the id to identify for backwards compatibility
+ if (myThings().filterByParam(meterThingIdParamTypeId, meterId).isEmpty()) {
+ // Get the meter realtime data for details
+ FroniusNetworkReply *realtimeDataReply = connection->getMeterRealtimeData(meterId.toInt());
+ connect(realtimeDataReply, &FroniusNetworkReply::finished, this, [=]() {
+ if (realtimeDataReply->networkReply()->error() != QNetworkReply::NoError) {
return;
}
- QByteArray data = reply->readAll();
+ QByteArray data = realtimeDataReply->networkReply()->readAll();
+
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) {
- qCWarning(dcFronius()) << "Failed to parse JSON data" << data << ":" << error.errorString();
+ qCWarning(dcFronius()) << "Meter: Failed to parse JSON data" << data << ":" << error.errorString();
return;
}
+ // Parse the data and update the states of our device
QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
-
QString thingName;
QString serialNumber;
+
if (dataMap.contains("Details")) {
QVariantMap details = dataMap.value("Details").toMap();
thingName = details.value("Manufacturer", "Fronius").toString() + " " + details.value("Model", "Smart Meter").toString();
serialNumber = details.value("Serial").toString();
} else {
- thingName = loggerThing->name() + " Meter " + meterId;
+ thingName = connectionThing->name() + " Meter " + meterId;
}
- ThingDescriptor descriptor(meterThingClassId, thingName, QString(), loggerThing->id());
+ ThingDescriptor descriptor(meterThingClassId, thingName, QString(), connectionThing->id());
ParamList params;
params.append(Param(meterThingIdParamTypeId, meterId));
params.append(Param(meterThingSerialNumberParamTypeId, serialNumber));
@@ -475,40 +330,30 @@ void IntegrationPluginFronius::searchNewThings(FroniusLogger *logger)
}
}
- // parse reply for storage things at the host address
+ // Check if there are new energy storages
QVariantMap storageMap = bodyMap.value("Data").toMap().value("Storage").toMap();
foreach (const QString &storageId, storageMap.keys()) {
- //check if thing already connected to logger
- if (!thingExists(storageThingIdParamTypeId, storageId)) {
- QUrlQuery query;
- QUrl requestUrl;
- requestUrl.setScheme("http");
- requestUrl.setHost(logger->hostAddress());
- requestUrl.setPath(logger->baseUrl() + "GetStorageRealtimeData.cgi");
- query.addQueryItem("Scope","Device");
- query.addQueryItem("DeviceId", storageId);
- requestUrl.setQuery(query);
+ // Note: we use the id to identify for backwards compatibility
+ if (myThings().filterByParam(storageThingIdParamTypeId, storageId).isEmpty()) {
- qCDebug(dcFronius()) << "Get storage information before setup" << requestUrl.toString();
- QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(requestUrl));
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, this, [=]() {
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString();
+ // Get the meter realtime data for details
+ FroniusNetworkReply *realtimeDataReply = connection->getStorageRealtimeData(storageId.toInt());
+ connect(realtimeDataReply, &FroniusNetworkReply::finished, this, [=]() {
+ if (realtimeDataReply->networkReply()->error() != QNetworkReply::NoError) {
return;
}
- // Convert the rawdata to a json document
- QByteArray data = reply->readAll();
+ QByteArray data = realtimeDataReply->networkReply()->readAll();
+
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) {
- qCWarning(dcFronius()) << "Failed to parse JSON data" << data << ":" << error.errorString();
+ qCWarning(dcFronius()) << "Storage: Failed to parse JSON data" << data << ":" << error.errorString();
return;
}
- QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap().value("Controller").toMap();
-
+ // Parse the data and update the states of our device
+ QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
QString thingName;
QString serialNumber;
if (dataMap.contains("Details")) {
@@ -516,20 +361,20 @@ void IntegrationPluginFronius::searchNewThings(FroniusLogger *logger)
thingName = details.value("Manufacturer", "Fronius").toString() + " " + details.value("Model", "Energy Storage").toString();
serialNumber = details.value("Serial").toString();
} else {
- thingName = loggerThing->name() + " Storage " + storageId;
+ thingName = connectionThing->name() + " Storage " + storageId;
}
- ThingDescriptor descriptor(storageThingClassId, thingName, QString(), loggerThing->id());
+ ThingDescriptor descriptor(storageThingClassId, thingName, QString(), connectionThing->id());
ParamList params;
params.append(Param(storageThingIdParamTypeId, storageId));
params.append(Param(storageThingSerialNumberParamTypeId, serialNumber));
descriptor.setParams(params);
emit autoThingsAppeared(ThingDescriptors() << descriptor);
-
});
}
}
+ // Inform about unhandled devices
QVariantMap ohmpilotMap = bodyMap.value("Data").toMap().value("Ohmpilot").toMap();
foreach (QString ohmpilotId, ohmpilotMap.keys()) {
qCDebug(dcFronius()) << "Unhandled device Ohmpilot" << ohmpilotId;
@@ -549,84 +394,251 @@ void IntegrationPluginFronius::searchNewThings(FroniusLogger *logger)
emit autoThingsAppeared(thingDescriptors);
thingDescriptors.clear();
}
+
+ // Update the inverters
+ updateInverters(connection);
+ updateMeters(connection);
+ updateStorages(connection);
});
}
-bool IntegrationPluginFronius::thingExists(const ParamTypeId &thingParamId, QString thingId)
+void IntegrationPluginFronius::updateInverters(FroniusSolarConnection *connection)
{
- foreach (Thing *thing, myThings()) {
- if (thing->paramValue(thingParamId).toString() == thingId) {
- return true;
- }
- }
- return false;
-}
+ Thing *parentThing = m_froniusConnections.value(connection);
+ foreach (Thing *inverterThing, myThings().filterByParentId(parentThing->id()).filterByThingClassId(inverterThingClassId)) {
+ int inverterId = inverterThing->paramValue(inverterThingIdParamTypeId).toInt();
-void IntegrationPluginFronius::setupChild(ThingSetupInfo *info, Thing *loggerThing)
-{
- Thing *thing = info->thing();
- if (thing->thingClassId() == inverterThingClassId) {
- FroniusInverter *newInverter = new FroniusInverter(thing,this);
- newInverter->setDeviceId(thing->paramValue(inverterThingIdParamTypeId).toString());
- newInverter->setBaseUrl(m_froniusLoggers.key(loggerThing)->baseUrl());
- newInverter->setHostAddress(m_froniusLoggers.key(loggerThing)->hostAddress());
-
- // Get inverter unique ID
- QUrl requestUrl;
- requestUrl.setScheme("http");
- requestUrl.setHost(newInverter->hostAddress());
- requestUrl.setPath(newInverter->baseUrl() + "GetInverterInfo.cgi");
-
- QNetworkReply *reply = hardwareManager()->networkManager()->get(QNetworkRequest(requestUrl));
- connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
- connect(reply, &QNetworkReply::finished, info, [this, info, newInverter, reply]() {
-
- QByteArray data = reply->readAll();
-
- if (reply->error() != QNetworkReply::NoError) {
- qCWarning(dcFronius()) << "Network request error:" << reply->error() << reply->errorString();
- info->finish(Thing::ThingErrorHardwareNotAvailable, "Device not reachable");
+ // Get the inverter realtime data
+ FroniusNetworkReply *realtimeDataReply = connection->getInverterRealtimeData(inverterId);
+ connect(realtimeDataReply, &FroniusNetworkReply::finished, this, [=]() {
+ if (realtimeDataReply->networkReply()->error() != QNetworkReply::NoError) {
+ // Thing does not seem to be reachable
+ inverterThing->setStateValue("connected", false);
return;
}
- // Convert the rawdata to a json document
+ QByteArray data = realtimeDataReply->networkReply()->readAll();
+
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
if (error.error != QJsonParseError::NoError) {
- qCWarning(dcFronius()) << "Failed to parse JSON data" << data << ":" << error.errorString();
- info->finish(Thing::ThingErrorHardwareNotAvailable, "Please try again");
+ qCWarning(dcFronius()) << "Inverter: Failed to parse JSON data" << data << ":" << error.errorString();
+ inverterThing->setStateValue("connected", false);
return;
}
- // Check reply information
+ // Parse the data and update the states of our device
QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
- // check for thing id in reply
- if (dataMap.contains(newInverter->deviceId())) {
- qCDebug(dcFronius()) << "Found Thing with unique:" << dataMap.value(newInverter->deviceId()).toMap().value("UniqueID").toString();
- newInverter->setUniqueId(dataMap.value(newInverter->deviceId()).toMap().value("UniqueID").toString());
- qCDebug(dcFronius()) << "Stored unique ID:" << newInverter->uniqueId();
+ //qCDebug(dcFronius()) << "Inverter data" << qUtf8Printable(QJsonDocument::fromVariant(dataMap).toJson(QJsonDocument::Indented));
+
+ // Set the inverter device state
+ if (dataMap.contains("PAC")) {
+ QVariantMap map = dataMap.value("PAC").toMap();
+ if (map.value("Unit") == "W") {
+ inverterThing->setStateValue(inverterCurrentPowerStateTypeId, - map.value("Value").toDouble());
+ }
}
- m_froniusInverters.insert(newInverter, info->thing());
- info->finish(Thing::ThingErrorNoError);
+ if (dataMap.contains("DAY_ENERGY")) {
+ QVariantMap map = dataMap.value("DAY_ENERGY").toMap();
+ if (map.value("Unit") == "Wh") {
+ inverterThing->setStateValue(inverterEnergyDayStateTypeId, map.value("Value").toDouble() / 1000);
+ }
+ }
+
+ if (dataMap.contains("YEAR_ENERGY")) {
+ QVariantMap map = dataMap.value("YEAR_ENERGY").toMap();
+ if (map.value("Unit") == "Wh") {
+ inverterThing->setStateValue(inverterEnergyYearStateTypeId, map.value("Value").toDouble() / 1000);
+ }
+ }
+
+ if (dataMap.contains("TOTAL_ENERGY")) {
+ QVariantMap map = dataMap.value("TOTAL_ENERGY").toMap();
+ if (map.value("Unit") == "Wh") {
+ inverterThing->setStateValue(inverterTotalEnergyProducedStateTypeId, map.value("Value").toDouble() / 1000);
+ }
+ }
+
+ inverterThing->setStateValue("connected", true);
+ });
+ }
+}
+
+void IntegrationPluginFronius::updateMeters(FroniusSolarConnection *connection)
+{
+ Thing *parentThing = m_froniusConnections.value(connection);
+ foreach (Thing *meterThing, myThings().filterByParentId(parentThing->id()).filterByThingClassId(meterThingClassId)) {
+ int meterId = meterThing->paramValue(inverterThingIdParamTypeId).toInt();
+
+ // Get the inverter realtime data
+ FroniusNetworkReply *realtimeDataReply = connection->getMeterRealtimeData(meterId);
+ connect(realtimeDataReply, &FroniusNetworkReply::finished, this, [=]() {
+ if (realtimeDataReply->networkReply()->error() != QNetworkReply::NoError) {
+ // Thing does not seem to be reachable
+ meterThing->setStateValue("connected", false);
+ return;
+ }
+
+ QByteArray data = realtimeDataReply->networkReply()->readAll();
+
+ QJsonParseError error;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
+ if (error.error != QJsonParseError::NoError) {
+ qCWarning(dcFronius()) << "Meter: Failed to parse JSON data" << data << ":" << error.errorString();
+ meterThing->setStateValue("connected", false);
+ return;
+ }
+
+ // Parse the data and update the states of our device
+ QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
+ //qCDebug(dcFronius()) << "Meter data" << qUtf8Printable(QJsonDocument::fromVariant(dataMap).toJson(QJsonDocument::Indented));
+
+ // Power
+ if (dataMap.contains("PowerReal_P_Sum")) {
+ meterThing->setStateValue(meterCurrentPowerStateTypeId, dataMap.value("PowerReal_P_Sum").toDouble());
+ }
+
+ if (dataMap.contains("PowerReal_P_Phase_1")) {
+ meterThing->setStateValue(meterCurrentPowerPhaseAStateTypeId, dataMap.value("PowerReal_P_Phase_1").toDouble());
+ }
+
+ if (dataMap.contains("PowerReal_P_Phase_2")) {
+ meterThing->setStateValue(meterCurrentPowerPhaseBStateTypeId, dataMap.value("PowerReal_P_Phase_2").toDouble());
+ }
+
+ if (dataMap.contains("PowerReal_P_Phase_3")) {
+ meterThing->setStateValue(meterCurrentPowerPhaseCStateTypeId, dataMap.value("PowerReal_P_Phase_3").toDouble());
+ }
+
+ // Current
+ if (dataMap.contains("Current_AC_Phase_1")) {
+ meterThing->setStateValue(meterCurrentPhaseAStateTypeId, dataMap.value("Current_AC_Phase_1").toDouble());
+ }
+
+ if (dataMap.contains("Current_AC_Phase_2")) {
+ meterThing->setStateValue(meterCurrentPhaseBStateTypeId, dataMap.value("Current_AC_Phase_2").toDouble());
+ }
+
+ if (dataMap.contains("Current_AC_Phase_3")) {
+ meterThing->setStateValue(meterCurrentPhaseCStateTypeId, dataMap.value("Current_AC_Phase_3").toDouble());
+ }
+
+ // Voltage
+ if (dataMap.contains("Voltage_AC_Phase_1")) {
+ meterThing->setStateValue(meterVoltagePhaseAStateTypeId, dataMap.value("Voltage_AC_Phase_1").toDouble());
+ }
+
+ if (dataMap.contains("Voltage_AC_Phase_2")) {
+ meterThing->setStateValue(meterVoltagePhaseBStateTypeId, dataMap.value("Voltage_AC_Phase_2").toDouble());
+ }
+
+ if (dataMap.contains("Voltage_AC_Phase_3")) {
+ meterThing->setStateValue(meterVoltagePhaseCStateTypeId, dataMap.value("Voltage_AC_Phase_3").toDouble());
+ }
+
+ // Total energy
+ if (dataMap.contains("EnergyReal_WAC_Sum_Produced")) {
+ meterThing->setStateValue(meterTotalEnergyProducedStateTypeId, dataMap.value("EnergyReal_WAC_Sum_Produced").toInt()/1000.00);
+ }
+
+ if (dataMap.contains("EnergyReal_WAC_Sum_Consumed")) {
+ meterThing->setStateValue(meterTotalEnergyConsumedStateTypeId, dataMap.value("EnergyReal_WAC_Sum_Consumed").toInt()/1000.00);
+ }
+
+ // Frequency
+ if (dataMap.contains("Frequency_Phase_Average")) {
+ meterThing->setStateValue(meterFrequencyStateTypeId, dataMap.value("Frequency_Phase_Average").toDouble());
+ }
+
+ meterThing->setStateValue("connected", true);
+ });
+ }
+}
+
+void IntegrationPluginFronius::updateStorages(FroniusSolarConnection *connection)
+{
+ Thing *parentThing = m_froniusConnections.value(connection);
+ foreach (Thing *storageThing, myThings().filterByParentId(parentThing->id()).filterByThingClassId(storageThingClassId)) {
+ int storageId = storageThing->paramValue(storageThingIdParamTypeId).toInt();
+
+ // Get power flow realtime data
+ FroniusNetworkReply *powerFlowReply = connection->getPowerFlowRealtimeData();
+ connect(powerFlowReply, &FroniusNetworkReply::finished, this, [=]() {
+ if (powerFlowReply->networkReply()->error() != QNetworkReply::NoError) {
+ // Thing does not seem to be reachable
+ storageThing->setStateValue("connected", false);
+ return;
+ }
+
+ QByteArray data = powerFlowReply->networkReply()->readAll();
+
+ QJsonParseError error;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
+ if (error.error != QJsonParseError::NoError) {
+ qCWarning(dcFronius()) << "Meter: Failed to parse JSON data" << data << ":" << error.errorString();
+ storageThing->setStateValue("connected", false);
+ return;
+ }
+
+ // Parse the data and update the states of our device
+ QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
+ //qCDebug(dcFronius()) << "Power flow data" << qUtf8Printable(QJsonDocument::fromVariant(dataMap).toJson(QJsonDocument::Indented));
+
+ float charge_akku = dataMap.value("Site").toMap().value("P_Akku").toFloat();
+ storageThing->setStateValue(storageCurrentPowerStateTypeId, charge_akku);
+ if (charge_akku < 0) {
+ storageThing->setStateValue(storageChargingStateStateTypeId, "discharging");
+ } else if (charge_akku > 0) {
+ storageThing->setStateValue(storageChargingStateStateTypeId, "charging");
+ } else {
+ storageThing->setStateValue(storageChargingStateStateTypeId, "idle");
+ }
+ });
+
+ // Get the storage realtime data
+ FroniusNetworkReply *realtimeDataReply = connection->getStorageRealtimeData(storageId);
+ connect(realtimeDataReply, &FroniusNetworkReply::finished, this, [=]() {
+ if (realtimeDataReply->networkReply()->error() != QNetworkReply::NoError) {
+ // Thing does not seem to be reachable
+ storageThing->setStateValue("connected", false);
+ return;
+ }
+
+ QByteArray data = realtimeDataReply->networkReply()->readAll();
+
+ QJsonParseError error;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
+ if (error.error != QJsonParseError::NoError) {
+ qCWarning(dcFronius()) << "Meter: Failed to parse JSON data" << data << ":" << error.errorString();
+ storageThing->setStateValue("connected", false);
+ return;
+ }
+
+ // Parse the data and update the states of our device
+ QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap();
+ //qCDebug(dcFronius()) << "Storage data" << qUtf8Printable(QJsonDocument::fromVariant(dataMap).toJson(QJsonDocument::Indented));
+
+ QVariantMap storageInfoMap = dataMap.value("Controller").toMap();
+
+ // copy retrieved information to thing states
+ if (storageInfoMap.contains("StateOfCharge_Relative")) {
+ storageThing->setStateValue(storageBatteryLevelStateTypeId, storageInfoMap.value("StateOfCharge_Relative").toInt());
+ if (storageThing->stateValue(storageChargingStateStateTypeId).toString() == "charging" && (storageInfoMap.value("StateOfCharge_Relative").toInt() < 5)) {
+ storageThing->setStateValue(storageBatteryCriticalStateTypeId, true);
+ } else {
+ storageThing->setStateValue(storageBatteryCriticalStateTypeId, false);
+ }
+ }
+
+ if (storageInfoMap.contains("Temperature_Cell"))
+ storageThing->setStateValue(storageCellTemperatureStateTypeId, storageInfoMap.value("Temperature_Cell").toDouble());
+
+ if (storageInfoMap.contains("Capacity_Maximum"))
+ storageThing->setStateValue(storageCapacityStateTypeId, storageInfoMap.value("Capacity_Maximum").toDouble());
+
+
+ storageThing->setStateValue("connected", true);
});
-
- } else if (thing->thingClassId() == meterThingClassId) {
- FroniusMeter *newMeter = new FroniusMeter(thing, this);;
- newMeter->setDeviceId(thing->paramValue(meterThingIdParamTypeId).toString());
- newMeter->setBaseUrl(m_froniusLoggers.key(loggerThing)->baseUrl());
- newMeter->setHostAddress(m_froniusLoggers.key(loggerThing)->hostAddress());
-
- m_froniusMeters.insert(newMeter, thing);
- info->finish(Thing::ThingErrorNoError);
-
- } else if (thing->thingClassId() == storageThingClassId) {
- FroniusStorage *newStorage = new FroniusStorage(thing, this);
- newStorage->setDeviceId(thing->paramValue(storageThingIdParamTypeId).toString());
- newStorage->setBaseUrl(m_froniusLoggers.key(loggerThing)->baseUrl());
- newStorage->setHostAddress(m_froniusLoggers.key(loggerThing)->hostAddress());
-
- m_froniusStorages.insert(newStorage, info->thing());
- info->finish(Thing::ThingErrorNoError);
}
}
diff --git a/fronius/integrationpluginfronius.h b/fronius/integrationpluginfronius.h
index 4662b8fd..bb801962 100644
--- a/fronius/integrationpluginfronius.h
+++ b/fronius/integrationpluginfronius.h
@@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
-* Copyright 2013 - 2020, nymea GmbH
+* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@@ -32,7 +32,7 @@
#define INTEGRATIONPLUGINFRONIUS_H
#include "integrations/integrationplugin.h"
-#include "froniuslogger.h"
+#include "froniussolarconnection.h"
#include
#include
@@ -57,21 +57,16 @@ public:
void thingRemoved(Thing* thing) override;
private:
- PluginTimer *m_pluginTimer = nullptr;
+ PluginTimer *m_connectionRefreshTimer = nullptr;
- QHash m_froniusLoggers;
- QHash m_froniusInverters;
- QHash m_froniusMeters;
- QHash m_froniusStorages;
+ QHash m_froniusConnections;
- QHash m_asyncActions;
+ void refreshConnection(FroniusSolarConnection *connection);
- void updateThingStates(Thing *thing);
+ void updateInverters(FroniusSolarConnection *connection);
+ void updateMeters(FroniusSolarConnection *connection);
+ void updateStorages(FroniusSolarConnection *connection);
- void searchNewThings(FroniusLogger *logger);
- bool thingExists(const ParamTypeId &thingParamId, QString thingId);
-
- void setupChild(ThingSetupInfo *info, Thing *parentThing);
};
#endif // INTEGRATIONPLUGINFRONIUS_H
diff --git a/fronius/integrationpluginfronius.json b/fronius/integrationpluginfronius.json
index 20558fb8..f4ea654d 100644
--- a/fronius/integrationpluginfronius.json
+++ b/fronius/integrationpluginfronius.json
@@ -10,7 +10,7 @@
"thingClasses": [
{
"id": "4fd79fed-42f1-4df9-be64-3df7b2e0bda2",
- "name": "datalogger",
+ "name": "connection",
"displayName": "Fronius Solar",
"createMethods": ["discovery", "user"],
"interfaces": ["gateway"],
@@ -18,7 +18,7 @@
"paramTypes": [
{
"id": "52da0197-4b78-4fec-aa72-70f949e26edc",
- "name": "loggerHost",
+ "name": "address",
"displayName": "Host address",
"type": "QString",
"inputType": "IPv4Address",
@@ -26,9 +26,10 @@
},
{
"id": "2237972e-385b-4458-b5d3-1d1fb4ae8756",
- "name": "loggerMac",
- "displayName": "MAC address",
+ "name": "mac",
+ "displayName": "Mac address",
"type": "QString",
+ "readOnly": true,
"defaultValue": "00:00:00:00:00:00"
}
],
@@ -37,127 +38,25 @@
"id": "98e4476f-e745-4a7f-b795-19269cb70c40",
"name": "connected",
"displayName": "Reachable",
- "displayNameEvent": "logger reachable changed",
+ "displayNameEvent": "Reachable changed",
"type": "bool",
"defaultValue": false
},
{
- "id": "b22052ef-14da-43d2-982b-f2c2d8c03206",
- "name": "productid",
- "displayName": "Product ID",
- "displayNameEvent": "Product ID changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "65c068e6-4a0b-4672-9724-ae95216c4c9c",
- "name": "platformid",
- "displayName": "Platform ID",
- "displayNameEvent": "Platform ID changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "3b4206e5-74c7-4708-96b8-2abfab0c41d6",
- "name": "hwversion",
- "displayName": "Hardware version",
- "displayNameEvent": "Hardware version changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "31743ca5-4353-4f26-b2ad-5da43e5b9d86",
- "name": "swversion",
- "displayName": "Software version",
- "displayNameEvent": "Software version changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "d034f59d-dc34-450a-a6f3-68264767a3e4",
- "name": "tzoneloc",
- "displayName": "Timezone location",
- "displayNameEvent": "Timezone location changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "6bdfeeda-7a47-4043-a011-5eb96308a7d6",
- "name": "tzone",
- "displayName": "Time zone",
- "displayNameEvent": "Time zone changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "18b250e2-080a-4991-b368-177c4da83eca",
- "name": "defaultlang",
- "displayName": "Default language",
- "displayNameEvent": "Default language changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "bc18595b-17c7-4a1f-8002-b908a3d9239d",
- "name": "cashfactor",
- "displayName": "Cash factor",
- "displayNameEvent": "Cash factor changed",
- "type": "double",
- "defaultValue": "-"
- },
- {
- "id": "84da30c8-a7fb-49c6-884c-9521f9f62bbc",
- "name": "cashcurrency",
- "displayName": "Cash currency",
- "displayNameEvent": "Cash Currency changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "8ab01225-7be5-4482-a99b-314108ae0e2b",
- "name": "co2factor",
- "displayName": "CO2 factor",
- "displayNameEvent": "CO2 factor changed",
- "type": "double",
- "defaultValue": "-"
- },
- {
- "id": "b0e655f8-27d0-4add-918b-461cadc8efcc",
- "name": "co2unit",
- "displayName": "CO2 unit",
- "displayNameEvent": "CO2 unit changed",
- "type": "QString",
- "defaultValue": "-"
- },
- {
- "id": "b217acf6-0c5e-4a3e-a50c-4c0133c871c2",
- "name": "powerManagmentRelay",
- "displayName": "Power management relay",
- "displayNameEvent": "Power management relay status changed",
- "type": "bool",
- "defaultValue": false
- },
- {
- "id": "5650ce9b-0d7d-4c52-b410-ea618889b4bb",
- "name": "powerManagmentRelayReason",
- "displayName": "Power management relay reason",
- "displayNameEvent": "Power management relay reason changed",
+ "id": "8fd0c0ed-af89-4887-bf0f-040b13c25268",
+ "name": "version",
+ "displayName": "Version",
+ "displayNameEvent": "Version changed",
"type": "QString",
"defaultValue": ""
}
],
- "actionTypes": [
- {
- "id": "c217fdc1-de18-41dc-b5d8-8072f84e7b6c",
- "name": "searchDevices",
- "displayName": "Search new devices"
- }
- ]
+ "actionTypes": [ ]
},
{
"id": "540aa956-8b8f-4982-9f58-343a76cea846",
"name": "inverter",
- "displayName": "Fronius Solar Inverter",
+ "displayName": "Fronius solar inverter",
"createMethods": ["auto"],
"interfaces" : ["solarinverter", "connectable"],
"paramTypes": [
@@ -166,8 +65,14 @@
"name": "id",
"displayName": "Device ID",
"type": "QString",
- "inputType": "TextLine",
- "readOnly": true
+ "readOnly": true
+ },
+ {
+ "id": "5e073a9d-f2de-4ff4-95f1-065a0ef4d51b",
+ "name": "serialNumber",
+ "displayName": "Serial number",
+ "type": "QString",
+ "readOnly": true
}
],
"stateTypes": [
@@ -180,14 +85,6 @@
"defaultValue": false,
"cached": false
},
- {
- "id": "e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0",
- "name": "active",
- "displayName": "Inverter active",
- "displayNameEvent": "Inverter active changed",
- "type": "QString",
- "defaultValue": "-"
- },
{
"id": "788accbc-b86e-471b-b37f-14c9c6411526",
"name": "currentPower",
@@ -195,25 +92,27 @@
"displayNameEvent": "Current power changed",
"type": "double",
"unit": "Watt",
- "defaultValue": "0"
+ "defaultValue": 0
},
{
"id": "b6af1bf5-753d-47b6-a151-e4d801fe6ff8",
- "name": "eday",
- "displayName": "Energy of current day",
- "displayNameEvent": "Energy of day changed",
+ "name": "energyDay",
+ "displayName": "Energy produced today",
+ "displayNameEvent": "Energy produced today changed",
"type": "double",
"unit": "KiloWattHour",
- "defaultValue": "0"
+ "defaultValue": 0,
+ "cached": false
},
{
"id": "7fd2fa28-9bcc-4f01-a823-459437d185f6",
- "name": "eyear",
- "displayName": "Energy of current year",
- "displayNameEvent": "Energy of year changed",
+ "name": "energyYear",
+ "displayName": "Energy produced year",
+ "displayNameEvent": "Energy produced changed",
"type": "int",
"unit": "KiloWattHour",
- "defaultValue": "0"
+ "defaultValue": 0,
+ "cached": false
},
{
"id": "d6dbb879-4cbc-4db3-830e-b92ba91a13e5",
@@ -222,7 +121,7 @@
"displayNameEvent": "Total produced energy changed",
"type": "double",
"unit": "KiloWattHour",
- "defaultValue": "0"
+ "defaultValue": 0
}
]
},
@@ -260,60 +159,6 @@
"defaultValue": false,
"cached": false
},
- {
- "id": "267bc59f-1113-4aff-a502-4618a591aa16",
- "name": "voltagePhaseA",
- "displayName": "Voltage phase A",
- "displayNameEvent": "Voltage phase A changed",
- "type": "double",
- "unit": "Volt",
- "defaultValue": 0
- },
- {
- "id": "bbcedb80-30f1-493e-81f0-5f77f2847353",
- "name": "voltagePhaseB",
- "displayName": "Voltage phase B",
- "displayNameEvent": "Voltage phase B changed",
- "type": "double",
- "unit": "Volt",
- "defaultValue": 0
- },
- {
- "id": "8037557b-40dc-411b-8937-bcd1695f898a",
- "name": "voltagePhaseC",
- "displayName": "Voltage phase C",
- "displayNameEvent": "Voltage phase C changed",
- "type": "double",
- "unit": "Volt",
- "defaultValue": 0
- },
- {
- "id": "a9673688-d84a-4848-8583-a70739130252",
- "name": "currentPhaseA",
- "displayName": "Current phase A",
- "displayNameEvent": "Current phase A changed",
- "type": "double",
- "unit": "Ampere",
- "defaultValue": 0
- },
- {
- "id": "15632e49-95f9-496d-830c-53a31ca6d98e",
- "name": "currentPhaseB",
- "displayName": "Current phase B",
- "displayNameEvent": "Current phase B changed",
- "type": "double",
- "unit": "Ampere",
- "defaultValue": 0
- },
- {
- "id": "10a24ba9-a57a-48a9-98f3-52671c09e855",
- "name": "currentPhaseC",
- "displayName": "Current phase C",
- "displayNameEvent": "Current phase C changed",
- "type": "double",
- "unit": "Ampere",
- "defaultValue": 0
- },
{
"id": "e5056ea1-88a2-410b-9c5e-6322aca4cb17",
"name": "currentPower",
@@ -323,6 +168,66 @@
"unit": "Watt",
"defaultValue": "0"
},
+ {
+ "id": "267bc59f-1113-4aff-a502-4618a591aa16",
+ "name": "voltagePhaseA",
+ "displayName": "Voltage phase A",
+ "displayNameEvent": "Voltage phase A changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0,
+ "cached": false
+ },
+ {
+ "id": "bbcedb80-30f1-493e-81f0-5f77f2847353",
+ "name": "voltagePhaseB",
+ "displayName": "Voltage phase B",
+ "displayNameEvent": "Voltage phase B changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0,
+ "cached": false
+ },
+ {
+ "id": "8037557b-40dc-411b-8937-bcd1695f898a",
+ "name": "voltagePhaseC",
+ "displayName": "Voltage phase C",
+ "displayNameEvent": "Voltage phase C changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0,
+ "cached": false
+ },
+ {
+ "id": "a9673688-d84a-4848-8583-a70739130252",
+ "name": "currentPhaseA",
+ "displayName": "Current phase A",
+ "displayNameEvent": "Current phase A changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0,
+ "cached": false
+ },
+ {
+ "id": "15632e49-95f9-496d-830c-53a31ca6d98e",
+ "name": "currentPhaseB",
+ "displayName": "Current phase B",
+ "displayNameEvent": "Current phase B changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0,
+ "cached": false
+ },
+ {
+ "id": "10a24ba9-a57a-48a9-98f3-52671c09e855",
+ "name": "currentPhaseC",
+ "displayName": "Current phase C",
+ "displayNameEvent": "Current phase C changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0,
+ "cached": false
+ },
{
"id": "ca14cca5-d9f0-49c5-a8f7-907d4c0825f0",
"name": "totalEnergyProduced",
@@ -330,7 +235,8 @@
"displayNameEvent": "Energy production changed",
"type": "double",
"unit": "KiloWattHour",
- "defaultValue": "0"
+ "defaultValue": "0",
+ "cached": false
},
{
"id": "f3451818-48d2-42a5-94fd-ad094c06967f",
@@ -339,7 +245,8 @@
"displayNameEvent": "Energy consumption changed",
"type": "double",
"unit": "KiloWattHour",
- "defaultValue": "0"
+ "defaultValue": "0",
+ "cached": false
},
{
"id": "6dbbb062-447b-47d6-b2e4-dceac9aff795",
@@ -348,7 +255,8 @@
"displayNameEvent": "Current power phase A changed",
"type": "double",
"unit": "Watt",
- "defaultValue": 0
+ "defaultValue": 0,
+ "cached": false
},
{
"id": "f230e78e-15b0-47a4-b494-bae65be00755",
@@ -357,7 +265,8 @@
"displayNameEvent": "Current power phase B changed",
"type": "double",
"unit": "Watt",
- "defaultValue": 0
+ "defaultValue": 0,
+ "cached": false
},
{
"id": "56b5d550-d902-4c33-9288-8ee972735a75",
@@ -366,7 +275,8 @@
"displayNameEvent": "Current power phase C changed",
"type": "double",
"unit": "Watt",
- "defaultValue": 0
+ "defaultValue": 0,
+ "cached": false
},
{
"id": "9ff64b29-e023-4395-abd4-b6c366acfd9e",
@@ -375,7 +285,8 @@
"displayNameEvent": "Frequency changed",
"type": "double",
"unit": "Hertz",
- "defaultValue": 0.00
+ "defaultValue": 0.00,
+ "cached": false
}
]
},
@@ -420,7 +331,8 @@
"displayNameEvent": "Charging state changed",
"type": "QString",
"possibleValues": ["idle", "charging", "discharging"],
- "defaultValue": "idle"
+ "defaultValue": "idle",
+ "cached": false
},
{
"id": "5a89cd3f-3abf-4f51-ab2b-4039f1d211d9",
@@ -429,7 +341,8 @@
"displayNameEvent": "Current power changed",
"type": "double",
"unit": "Watt",
- "defaultValue": 0
+ "defaultValue": 0,
+ "cached": false
},
{
"id": "3b163deb-67a2-41d1-8441-b2d53ad846ef",
@@ -438,7 +351,8 @@
"displayNameEvent": "Capacity changed",
"type": "double",
"unit": "KiloWattHour",
- "defaultValue": 0
+ "defaultValue": 0,
+ "cached": false
},
{
"id": "5c6da672-9662-41bc-8c8c-aa0f32481251",
@@ -449,7 +363,8 @@
"unit": "Percentage",
"defaultValue": "0",
"minValue": 0,
- "maxValue": 100
+ "maxValue": 100,
+ "cached": false
},
{
"id": "4417499c-1757-4309-868a-be5cf3455c4a",
@@ -458,7 +373,8 @@
"displayNameEvent": "Cell temperature changed",
"type": "double",
"unit": "DegreeCelsius",
- "defaultValue": "0"
+ "defaultValue": "0",
+ "cached": false
},
{
"id": "e5396312-b50e-4d6f-b628-5b51448971d3",
@@ -466,7 +382,8 @@
"displayName": "Battery level critical",
"displayNameEvent": "Battery level critical changed",
"type": "bool",
- "defaultValue": false
+ "defaultValue": false,
+ "cached": false
}
]
}
diff --git a/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts b/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts
index 598e3b0f..c6f52213 100644
--- a/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts
+++ b/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts
@@ -60,30 +60,30 @@ The name of the StateType ({e5396312-b50e-4d6f-b628-5b51448971d3}) of ThingClass
CO2 factor
- The name of the ParamType (ThingClass: datalogger, EventType: co2factor, ID: {8ab01225-7be5-4482-a99b-314108ae0e2b})
+ The name of the ParamType (ThingClass: connection, EventType: co2factor, ID: {8ab01225-7be5-4482-a99b-314108ae0e2b})
----------
-The name of the StateType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass datalogger
+The name of the StateType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass connection
CO2 Faktor
CO2 factor changed
- The name of the EventType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass datalogger
+ The name of the EventType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass connection
CO2 Faktor geändert
CO2 unit
- The name of the ParamType (ThingClass: datalogger, EventType: co2unit, ID: {b0e655f8-27d0-4add-918b-461cadc8efcc})
+ The name of the ParamType (ThingClass: connection, EventType: co2unit, ID: {b0e655f8-27d0-4add-918b-461cadc8efcc})
----------
-The name of the StateType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass datalogger
+The name of the StateType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass connection
CO2-Einheit
CO2 unit changed
- The name of the EventType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass datalogger
+ The name of the EventType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass connection
CO2-Einheit geändert
@@ -104,31 +104,31 @@ The name of the StateType ({3b163deb-67a2-41d1-8441-b2d53ad846ef}) of ThingClass
Cash Currency changed
- The name of the EventType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass datalogger
+ The name of the EventType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass connection
Bargeldwährung geändert
Cash currency
- The name of the ParamType (ThingClass: datalogger, EventType: cashcurrency, ID: {84da30c8-a7fb-49c6-884c-9521f9f62bbc})
+ The name of the ParamType (ThingClass: connection, EventType: cashcurrency, ID: {84da30c8-a7fb-49c6-884c-9521f9f62bbc})
----------
-The name of the StateType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass datalogger
+The name of the StateType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass connection
Bargeldwährung
Cash factor
- The name of the ParamType (ThingClass: datalogger, EventType: cashfactor, ID: {bc18595b-17c7-4a1f-8002-b908a3d9239d})
+ The name of the ParamType (ThingClass: connection, EventType: cashfactor, ID: {bc18595b-17c7-4a1f-8002-b908a3d9239d})
----------
-The name of the StateType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass datalogger
+The name of the StateType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass connection
Cash-Faktor
Cash factor changed
- The name of the EventType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass datalogger
+ The name of the EventType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass connection
Cash-Faktor geändert
@@ -282,15 +282,15 @@ The name of the StateType ({788accbc-b86e-471b-b37f-14c9c6411526}) of ThingClass
Default language
- The name of the ParamType (ThingClass: datalogger, EventType: defaultlang, ID: {18b250e2-080a-4991-b368-177c4da83eca})
+ The name of the ParamType (ThingClass: connection, EventType: defaultlang, ID: {18b250e2-080a-4991-b368-177c4da83eca})
----------
-The name of the StateType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass datalogger
+The name of the StateType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass connection
Standardsprache
Default language changed
- The name of the EventType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass datalogger
+ The name of the EventType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass connection
Standardsprache geändert
@@ -444,21 +444,21 @@ The name of the plugin fronius ({02319cfc-8b55-49ba-99bc-0588bbfab063})
Hardware version
- The name of the ParamType (ThingClass: datalogger, EventType: hwversion, ID: {3b4206e5-74c7-4708-96b8-2abfab0c41d6})
+ The name of the ParamType (ThingClass: connection, EventType: hwversion, ID: {3b4206e5-74c7-4708-96b8-2abfab0c41d6})
----------
-The name of the StateType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass datalogger
+The name of the StateType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass connection
Hardwareversion
Hardware version changed
- The name of the EventType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass datalogger
+ The name of the EventType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass connection
Hardwareversion geändert
Host address
- The name of the ParamType (ThingClass: datalogger, Type: thing, ID: {52da0197-4b78-4fec-aa72-70f949e26edc})
+ The name of the ParamType (ThingClass: connection, Type: thing, ID: {52da0197-4b78-4fec-aa72-70f949e26edc})
Adresse
@@ -479,67 +479,67 @@ The name of the StateType ({e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0}) of ThingClass
MAC address
- The name of the ParamType (ThingClass: datalogger, Type: thing, ID: {2237972e-385b-4458-b5d3-1d1fb4ae8756})
+ The name of the ParamType (ThingClass: connection, Type: thing, ID: {2237972e-385b-4458-b5d3-1d1fb4ae8756})
Platform ID
- The name of the ParamType (ThingClass: datalogger, EventType: platformid, ID: {65c068e6-4a0b-4672-9724-ae95216c4c9c})
+ The name of the ParamType (ThingClass: connection, EventType: platformid, ID: {65c068e6-4a0b-4672-9724-ae95216c4c9c})
----------
-The name of the StateType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass datalogger
+The name of the StateType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass connection
Plattform ID
Platform ID changed
- The name of the EventType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass datalogger
+ The name of the EventType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass connection
Plattform-ID geändert
Power management relay
- The name of the ParamType (ThingClass: datalogger, EventType: powerManagmentRelay, ID: {b217acf6-0c5e-4a3e-a50c-4c0133c871c2})
+ The name of the ParamType (ThingClass: connection, EventType: powerManagmentRelay, ID: {b217acf6-0c5e-4a3e-a50c-4c0133c871c2})
----------
-The name of the StateType ({b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) of ThingClass datalogger
+The name of the StateType ({b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) of ThingClass connection
Leistungsmanagement Relais
Power management relay reason
- The name of the ParamType (ThingClass: datalogger, EventType: powerManagmentRelayReason, ID: {5650ce9b-0d7d-4c52-b410-ea618889b4bb})
+ The name of the ParamType (ThingClass: connection, EventType: powerManagmentRelayReason, ID: {5650ce9b-0d7d-4c52-b410-ea618889b4bb})
----------
-The name of the StateType ({5650ce9b-0d7d-4c52-b410-ea618889b4bb}) of ThingClass datalogger
+The name of the StateType ({5650ce9b-0d7d-4c52-b410-ea618889b4bb}) of ThingClass connection
Leistungsmanagement Relais Grund
Power management relay reason changed
- The name of the EventType ({5650ce9b-0d7d-4c52-b410-ea618889b4bb}) of ThingClass datalogger
+ The name of the EventType ({5650ce9b-0d7d-4c52-b410-ea618889b4bb}) of ThingClass connection
Leistungsmanagement Relais Grund geändert
Power management relay status changed
- The name of the EventType ({b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) of ThingClass datalogger
+ The name of the EventType ({b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) of ThingClass connection
Leistungsmanagement Relais Status geändert
Product ID
- The name of the ParamType (ThingClass: datalogger, EventType: productid, ID: {b22052ef-14da-43d2-982b-f2c2d8c03206})
+ The name of the ParamType (ThingClass: connection, EventType: productid, ID: {b22052ef-14da-43d2-982b-f2c2d8c03206})
----------
-The name of the StateType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass datalogger
+The name of the StateType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass connection
Produkt-ID
Product ID changed
- The name of the EventType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass datalogger
+ The name of the EventType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass connection
Produkt-ID geändert
@@ -564,9 +564,9 @@ The name of the ParamType (ThingClass: inverter, EventType: connected, ID: {eda2
----------
The name of the StateType ({eda29c50-73ac-40e0-9c92-26fee352e688}) of ThingClass inverter
----------
-The name of the ParamType (ThingClass: datalogger, EventType: connected, ID: {98e4476f-e745-4a7f-b795-19269cb70c40})
+The name of the ParamType (ThingClass: connection, EventType: connected, ID: {98e4476f-e745-4a7f-b795-19269cb70c40})
----------
-The name of the StateType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass datalogger
+The name of the StateType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass connection
Erreichbar
@@ -584,7 +584,7 @@ The name of the EventType ({eda29c50-73ac-40e0-9c92-26fee352e688}) of ThingClass
Search new devices
- The name of the ActionType ({c217fdc1-de18-41dc-b5d8-8072f84e7b6c}) of ThingClass datalogger
+ The name of the ActionType ({c217fdc1-de18-41dc-b5d8-8072f84e7b6c}) of ThingClass connection
Suche neue Geräte
@@ -600,15 +600,15 @@ The name of the ParamType (ThingClass: meter, Type: thing, ID: {dfc2eeef-38b2-40
Software version
- The name of the ParamType (ThingClass: datalogger, EventType: swversion, ID: {31743ca5-4353-4f26-b2ad-5da43e5b9d86})
+ The name of the ParamType (ThingClass: connection, EventType: swversion, ID: {31743ca5-4353-4f26-b2ad-5da43e5b9d86})
----------
-The name of the StateType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass datalogger
+The name of the StateType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass connection
Softwareversion
Software version changed
- The name of the EventType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass datalogger
+ The name of the EventType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass connection
Softwareversion geändert
@@ -630,30 +630,30 @@ The name of the StateType ({d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) of ThingClass
Time zone
- The name of the ParamType (ThingClass: datalogger, EventType: tzone, ID: {6bdfeeda-7a47-4043-a011-5eb96308a7d6})
+ The name of the ParamType (ThingClass: connection, EventType: tzone, ID: {6bdfeeda-7a47-4043-a011-5eb96308a7d6})
----------
-The name of the StateType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass datalogger
+The name of the StateType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass connection
Zeitzone
Time zone changed
- The name of the EventType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass datalogger
+ The name of the EventType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass connection
Zeitzone geändert
Timezone location
- The name of the ParamType (ThingClass: datalogger, EventType: tzoneloc, ID: {d034f59d-dc34-450a-a6f3-68264767a3e4})
+ The name of the ParamType (ThingClass: connection, EventType: tzoneloc, ID: {d034f59d-dc34-450a-a6f3-68264767a3e4})
----------
-The name of the StateType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass datalogger
+The name of the StateType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass connection
Zeitzone Ort
Timezone location changed
- The name of the EventType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass datalogger
+ The name of the EventType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass connection
Zeitzone Ort geändert
@@ -704,7 +704,7 @@ The name of the StateType ({8037557b-40dc-411b-8937-bcd1695f898a}) of ThingClass
logger reachable changed
- The name of the EventType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass datalogger
+ The name of the EventType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass connection
Logger erriechbar geändert
diff --git a/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-en_US.ts b/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-en_US.ts
index 0df571b7..c9159bc7 100644
--- a/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-en_US.ts
+++ b/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-en_US.ts
@@ -60,30 +60,30 @@ The name of the StateType ({e5396312-b50e-4d6f-b628-5b51448971d3}) of ThingClass
CO2 factor
- The name of the ParamType (ThingClass: datalogger, EventType: co2factor, ID: {8ab01225-7be5-4482-a99b-314108ae0e2b})
+ The name of the ParamType (ThingClass: connection, EventType: co2factor, ID: {8ab01225-7be5-4482-a99b-314108ae0e2b})
----------
-The name of the StateType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass datalogger
+The name of the StateType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass connection
CO2 factor changed
- The name of the EventType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass datalogger
+ The name of the EventType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass connection
CO2 unit
- The name of the ParamType (ThingClass: datalogger, EventType: co2unit, ID: {b0e655f8-27d0-4add-918b-461cadc8efcc})
+ The name of the ParamType (ThingClass: connection, EventType: co2unit, ID: {b0e655f8-27d0-4add-918b-461cadc8efcc})
----------
-The name of the StateType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass datalogger
+The name of the StateType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass connection
CO2 unit changed
- The name of the EventType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass datalogger
+ The name of the EventType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass connection
@@ -104,31 +104,31 @@ The name of the StateType ({3b163deb-67a2-41d1-8441-b2d53ad846ef}) of ThingClass
Cash Currency changed
- The name of the EventType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass datalogger
+ The name of the EventType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass connection
Cash currency
- The name of the ParamType (ThingClass: datalogger, EventType: cashcurrency, ID: {84da30c8-a7fb-49c6-884c-9521f9f62bbc})
+ The name of the ParamType (ThingClass: connection, EventType: cashcurrency, ID: {84da30c8-a7fb-49c6-884c-9521f9f62bbc})
----------
-The name of the StateType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass datalogger
+The name of the StateType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass connection
Cash factor
- The name of the ParamType (ThingClass: datalogger, EventType: cashfactor, ID: {bc18595b-17c7-4a1f-8002-b908a3d9239d})
+ The name of the ParamType (ThingClass: connection, EventType: cashfactor, ID: {bc18595b-17c7-4a1f-8002-b908a3d9239d})
----------
-The name of the StateType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass datalogger
+The name of the StateType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass connection
Cash factor changed
- The name of the EventType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass datalogger
+ The name of the EventType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass connection
@@ -282,15 +282,15 @@ The name of the StateType ({788accbc-b86e-471b-b37f-14c9c6411526}) of ThingClass
Default language
- The name of the ParamType (ThingClass: datalogger, EventType: defaultlang, ID: {18b250e2-080a-4991-b368-177c4da83eca})
+ The name of the ParamType (ThingClass: connection, EventType: defaultlang, ID: {18b250e2-080a-4991-b368-177c4da83eca})
----------
-The name of the StateType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass datalogger
+The name of the StateType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass connection
Default language changed
- The name of the EventType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass datalogger
+ The name of the EventType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass connection
@@ -444,21 +444,21 @@ The name of the plugin fronius ({02319cfc-8b55-49ba-99bc-0588bbfab063})
Hardware version
- The name of the ParamType (ThingClass: datalogger, EventType: hwversion, ID: {3b4206e5-74c7-4708-96b8-2abfab0c41d6})
+ The name of the ParamType (ThingClass: connection, EventType: hwversion, ID: {3b4206e5-74c7-4708-96b8-2abfab0c41d6})
----------
-The name of the StateType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass datalogger
+The name of the StateType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass connection
Hardware version changed
- The name of the EventType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass datalogger
+ The name of the EventType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass connection
Host address
- The name of the ParamType (ThingClass: datalogger, Type: thing, ID: {52da0197-4b78-4fec-aa72-70f949e26edc})
+ The name of the ParamType (ThingClass: connection, Type: thing, ID: {52da0197-4b78-4fec-aa72-70f949e26edc})
@@ -479,67 +479,67 @@ The name of the StateType ({e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0}) of ThingClass
MAC address
- The name of the ParamType (ThingClass: datalogger, Type: thing, ID: {2237972e-385b-4458-b5d3-1d1fb4ae8756})
+ The name of the ParamType (ThingClass: connection, Type: thing, ID: {2237972e-385b-4458-b5d3-1d1fb4ae8756})
Platform ID
- The name of the ParamType (ThingClass: datalogger, EventType: platformid, ID: {65c068e6-4a0b-4672-9724-ae95216c4c9c})
+ The name of the ParamType (ThingClass: connection, EventType: platformid, ID: {65c068e6-4a0b-4672-9724-ae95216c4c9c})
----------
-The name of the StateType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass datalogger
+The name of the StateType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass connection
Platform ID changed
- The name of the EventType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass datalogger
+ The name of the EventType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass connection
Power management relay
- The name of the ParamType (ThingClass: datalogger, EventType: powerManagmentRelay, ID: {b217acf6-0c5e-4a3e-a50c-4c0133c871c2})
+ The name of the ParamType (ThingClass: connection, EventType: powerManagmentRelay, ID: {b217acf6-0c5e-4a3e-a50c-4c0133c871c2})
----------
-The name of the StateType ({b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) of ThingClass datalogger
+The name of the StateType ({b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) of ThingClass connection
Power management relay reason
- The name of the ParamType (ThingClass: datalogger, EventType: powerManagmentRelayReason, ID: {5650ce9b-0d7d-4c52-b410-ea618889b4bb})
+ The name of the ParamType (ThingClass: connection, EventType: powerManagmentRelayReason, ID: {5650ce9b-0d7d-4c52-b410-ea618889b4bb})
----------
-The name of the StateType ({5650ce9b-0d7d-4c52-b410-ea618889b4bb}) of ThingClass datalogger
+The name of the StateType ({5650ce9b-0d7d-4c52-b410-ea618889b4bb}) of ThingClass connection
Power management relay reason changed
- The name of the EventType ({5650ce9b-0d7d-4c52-b410-ea618889b4bb}) of ThingClass datalogger
+ The name of the EventType ({5650ce9b-0d7d-4c52-b410-ea618889b4bb}) of ThingClass connection
Power management relay status changed
- The name of the EventType ({b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) of ThingClass datalogger
+ The name of the EventType ({b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) of ThingClass connection
Product ID
- The name of the ParamType (ThingClass: datalogger, EventType: productid, ID: {b22052ef-14da-43d2-982b-f2c2d8c03206})
+ The name of the ParamType (ThingClass: connection, EventType: productid, ID: {b22052ef-14da-43d2-982b-f2c2d8c03206})
----------
-The name of the StateType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass datalogger
+The name of the StateType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass connection
Product ID changed
- The name of the EventType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass datalogger
+ The name of the EventType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass connection
@@ -564,9 +564,9 @@ The name of the ParamType (ThingClass: inverter, EventType: connected, ID: {eda2
----------
The name of the StateType ({eda29c50-73ac-40e0-9c92-26fee352e688}) of ThingClass inverter
----------
-The name of the ParamType (ThingClass: datalogger, EventType: connected, ID: {98e4476f-e745-4a7f-b795-19269cb70c40})
+The name of the ParamType (ThingClass: connection, EventType: connected, ID: {98e4476f-e745-4a7f-b795-19269cb70c40})
----------
-The name of the StateType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass datalogger
+The name of the StateType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass connection
@@ -584,7 +584,7 @@ The name of the EventType ({eda29c50-73ac-40e0-9c92-26fee352e688}) of ThingClass
Search new devices
- The name of the ActionType ({c217fdc1-de18-41dc-b5d8-8072f84e7b6c}) of ThingClass datalogger
+ The name of the ActionType ({c217fdc1-de18-41dc-b5d8-8072f84e7b6c}) of ThingClass connection
@@ -600,15 +600,15 @@ The name of the ParamType (ThingClass: meter, Type: thing, ID: {dfc2eeef-38b2-40
Software version
- The name of the ParamType (ThingClass: datalogger, EventType: swversion, ID: {31743ca5-4353-4f26-b2ad-5da43e5b9d86})
+ The name of the ParamType (ThingClass: connection, EventType: swversion, ID: {31743ca5-4353-4f26-b2ad-5da43e5b9d86})
----------
-The name of the StateType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass datalogger
+The name of the StateType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass connection
Software version changed
- The name of the EventType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass datalogger
+ The name of the EventType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass connection
@@ -630,30 +630,30 @@ The name of the StateType ({d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) of ThingClass
Time zone
- The name of the ParamType (ThingClass: datalogger, EventType: tzone, ID: {6bdfeeda-7a47-4043-a011-5eb96308a7d6})
+ The name of the ParamType (ThingClass: connection, EventType: tzone, ID: {6bdfeeda-7a47-4043-a011-5eb96308a7d6})
----------
-The name of the StateType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass datalogger
+The name of the StateType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass connection
Time zone changed
- The name of the EventType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass datalogger
+ The name of the EventType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass connection
Timezone location
- The name of the ParamType (ThingClass: datalogger, EventType: tzoneloc, ID: {d034f59d-dc34-450a-a6f3-68264767a3e4})
+ The name of the ParamType (ThingClass: connection, EventType: tzoneloc, ID: {d034f59d-dc34-450a-a6f3-68264767a3e4})
----------
-The name of the StateType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass datalogger
+The name of the StateType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass connection
Timezone location changed
- The name of the EventType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass datalogger
+ The name of the EventType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass connection
@@ -704,7 +704,7 @@ The name of the StateType ({8037557b-40dc-411b-8937-bcd1695f898a}) of ThingClass
logger reachable changed
- The name of the EventType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass datalogger
+ The name of the EventType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass connection