From bdcedb949675704649d376d04c5bb1be9205e896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 21 Feb 2022 22:11:44 +0100 Subject: [PATCH 1/7] Rework and cleanup plugin entirely, queue request and simplify structure for new API version --- fronius/README.md | 3 +- fronius/fronius.pro | 17 +- fronius/froniusinverter.cpp | 137 ---- fronius/froniuslogger.cpp | 144 ---- fronius/froniuslogger.h | 53 -- fronius/froniusmeter.cpp | 153 ---- ...froniusmeter.h => froniusnetworkreply.cpp} | 61 +- ...roniusinverter.h => froniusnetworkreply.h} | 39 +- fronius/froniussolarconnection.cpp | 203 +++++ ...niusstorage.h => froniussolarconnection.h} | 56 +- fronius/froniusstorage.cpp | 136 ---- fronius/integrationpluginfronius.cpp | 708 +++++++++--------- fronius/integrationpluginfronius.h | 21 +- fronius/integrationpluginfronius.json | 315 +++----- ...02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts | 90 +-- ...19cfc-8b55-49ba-99bc-0588bbfab063-en_US.ts | 90 +-- 16 files changed, 888 insertions(+), 1338 deletions(-) delete mode 100644 fronius/froniusinverter.cpp delete mode 100644 fronius/froniuslogger.cpp delete mode 100644 fronius/froniuslogger.h delete mode 100644 fronius/froniusmeter.cpp rename fronius/{froniusmeter.h => froniusnetworkreply.cpp} (54%) rename fronius/{froniusinverter.h => froniusnetworkreply.h} (70%) create mode 100644 fronius/froniussolarconnection.cpp rename fronius/{froniusstorage.h => froniussolarconnection.h} (55%) delete mode 100644 fronius/froniusstorage.cpp 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 From 4c8ca076b7ab6ac148d4cda27869d7a68c6ffc37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 21 Feb 2022 22:12:32 +0100 Subject: [PATCH 2/7] Update translations --- ...02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts | 624 +++--------------- ...19cfc-8b55-49ba-99bc-0588bbfab063-en_US.ts | 614 +++-------------- 2 files changed, 163 insertions(+), 1075 deletions(-) diff --git a/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts b/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts index c6f52213..97b09daa 100644 --- a/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts +++ b/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-de.ts @@ -9,17 +9,17 @@ - - Device not reachable - Gerät nicht erreichbar + + The device is not reachable + - - Please try again - Bitte versuchen Sie es erneut + + Unable to read the data. Please try again. + - + The firmware version 1.6-2 of this Fronius data logger has a broken API. Please update your Fronius device. @@ -27,276 +27,96 @@ fronius - - + Battery level - The name of the ParamType (ThingClass: storage, EventType: batteryLevel, ID: {5c6da672-9662-41bc-8c8c-aa0f32481251}) ----------- -The name of the StateType ({5c6da672-9662-41bc-8c8c-aa0f32481251}) of ThingClass storage + The name of the StateType ({5c6da672-9662-41bc-8c8c-aa0f32481251}) of ThingClass storage Batteriestand - - Battery level changed - The name of the EventType ({5c6da672-9662-41bc-8c8c-aa0f32481251}) of ThingClass storage - Batteriestand geändert - - - - + Battery level critical - The name of the ParamType (ThingClass: storage, EventType: batteryCritical, ID: {e5396312-b50e-4d6f-b628-5b51448971d3}) ----------- -The name of the StateType ({e5396312-b50e-4d6f-b628-5b51448971d3}) of ThingClass storage + The name of the StateType ({e5396312-b50e-4d6f-b628-5b51448971d3}) of ThingClass storage Batteriestand kritisch - - Battery level critical changed - The name of the EventType ({e5396312-b50e-4d6f-b628-5b51448971d3}) of ThingClass storage - Batteriestand kritisch geändert - - - - - CO2 factor - 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 connection - CO2 Faktor - - - - CO2 factor changed - 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: connection, EventType: co2unit, ID: {b0e655f8-27d0-4add-918b-461cadc8efcc}) ----------- -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 connection - CO2-Einheit geändert - - - - + Capacity - The name of the ParamType (ThingClass: storage, EventType: capacity, ID: {3b163deb-67a2-41d1-8441-b2d53ad846ef}) ----------- -The name of the StateType ({3b163deb-67a2-41d1-8441-b2d53ad846ef}) of ThingClass storage + The name of the StateType ({3b163deb-67a2-41d1-8441-b2d53ad846ef}) of ThingClass storage - - Capacity changed - The name of the EventType ({3b163deb-67a2-41d1-8441-b2d53ad846ef}) of ThingClass storage - - - - - Cash Currency changed - 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: connection, EventType: cashcurrency, ID: {84da30c8-a7fb-49c6-884c-9521f9f62bbc}) ----------- -The name of the StateType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass connection - Bargeldwährung - - - - - Cash factor - 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 connection - Cash-Faktor - - - - Cash factor changed - The name of the EventType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass connection - Cash-Faktor geändert - - - - + Cell temperature - The name of the ParamType (ThingClass: storage, EventType: cellTemperature, ID: {4417499c-1757-4309-868a-be5cf3455c4a}) ----------- -The name of the StateType ({4417499c-1757-4309-868a-be5cf3455c4a}) of ThingClass storage + The name of the StateType ({4417499c-1757-4309-868a-be5cf3455c4a}) of ThingClass storage Zellentemperatur - - Cell temperature changed - The name of the EventType ({4417499c-1757-4309-868a-be5cf3455c4a}) of ThingClass storage - Zellentemperatur geändert - - - - + Current phase A - The name of the ParamType (ThingClass: meter, EventType: currentPhaseA, ID: {a9673688-d84a-4848-8583-a70739130252}) ----------- -The name of the StateType ({a9673688-d84a-4848-8583-a70739130252}) of ThingClass meter + The name of the StateType ({a9673688-d84a-4848-8583-a70739130252}) of ThingClass meter - - Current phase A changed - The name of the EventType ({a9673688-d84a-4848-8583-a70739130252}) of ThingClass meter - - - - - + Current phase B - The name of the ParamType (ThingClass: meter, EventType: currentPhaseB, ID: {15632e49-95f9-496d-830c-53a31ca6d98e}) ----------- -The name of the StateType ({15632e49-95f9-496d-830c-53a31ca6d98e}) of ThingClass meter + The name of the StateType ({15632e49-95f9-496d-830c-53a31ca6d98e}) of ThingClass meter - - Current phase B changed - The name of the EventType ({15632e49-95f9-496d-830c-53a31ca6d98e}) of ThingClass meter - - - - - + Current phase C - The name of the ParamType (ThingClass: meter, EventType: currentPhaseC, ID: {10a24ba9-a57a-48a9-98f3-52671c09e855}) ----------- -The name of the StateType ({10a24ba9-a57a-48a9-98f3-52671c09e855}) of ThingClass meter + The name of the StateType ({10a24ba9-a57a-48a9-98f3-52671c09e855}) of ThingClass meter - - Current phase C changed - The name of the EventType ({10a24ba9-a57a-48a9-98f3-52671c09e855}) of ThingClass meter - - - - - + Current power phase A - The name of the ParamType (ThingClass: meter, EventType: currentPowerPhaseA, ID: {6dbbb062-447b-47d6-b2e4-dceac9aff795}) ----------- -The name of the StateType ({6dbbb062-447b-47d6-b2e4-dceac9aff795}) of ThingClass meter + The name of the StateType ({6dbbb062-447b-47d6-b2e4-dceac9aff795}) of ThingClass meter - - Current power phase A changed - The name of the EventType ({6dbbb062-447b-47d6-b2e4-dceac9aff795}) of ThingClass meter - - - - - + Current power phase B - The name of the ParamType (ThingClass: meter, EventType: currentPowerPhaseB, ID: {f230e78e-15b0-47a4-b494-bae65be00755}) ----------- -The name of the StateType ({f230e78e-15b0-47a4-b494-bae65be00755}) of ThingClass meter + The name of the StateType ({f230e78e-15b0-47a4-b494-bae65be00755}) of ThingClass meter - - Current power phase B changed - The name of the EventType ({f230e78e-15b0-47a4-b494-bae65be00755}) of ThingClass meter - - - - - + Current power phase C - The name of the ParamType (ThingClass: meter, EventType: currentPowerPhaseC, ID: {56b5d550-d902-4c33-9288-8ee972735a75}) ----------- -The name of the StateType ({56b5d550-d902-4c33-9288-8ee972735a75}) of ThingClass meter + The name of the StateType ({56b5d550-d902-4c33-9288-8ee972735a75}) of ThingClass meter - - Current power phase C changed - The name of the EventType ({56b5d550-d902-4c33-9288-8ee972735a75}) of ThingClass meter - - - - - + Frequency - The name of the ParamType (ThingClass: meter, EventType: frequency, ID: {9ff64b29-e023-4395-abd4-b6c366acfd9e}) ----------- -The name of the StateType ({9ff64b29-e023-4395-abd4-b6c366acfd9e}) of ThingClass meter + The name of the StateType ({9ff64b29-e023-4395-abd4-b6c366acfd9e}) of ThingClass meter - - Frequency changed - The name of the EventType ({9ff64b29-e023-4395-abd4-b6c366acfd9e}) of ThingClass meter - - - - + Fronius smart meter The name of the ThingClass ({c3cb53a4-32dd-434d-9d9c-aada41f8129c}) - + Fronius solar storage The name of the ThingClass ({b00139fa-7386-48b1-8697-2fdd21a57ced}) - - - - + + Current power - The name of the ParamType (ThingClass: storage, EventType: currentPower, ID: {5a89cd3f-3abf-4f51-ab2b-4039f1d211d9}) ----------- -The name of the StateType ({5a89cd3f-3abf-4f51-ab2b-4039f1d211d9}) of ThingClass storage ----------- -The name of the ParamType (ThingClass: inverter, EventType: currentPower, ID: {788accbc-b86e-471b-b37f-14c9c6411526}) + The name of the StateType ({5a89cd3f-3abf-4f51-ab2b-4039f1d211d9}) of ThingClass storage ---------- The name of the StateType ({788accbc-b86e-471b-b37f-14c9c6411526}) of ThingClass inverter Aktuelle Leistung - - - Default language - 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 connection - Standardsprache - - - - Default language changed - The name of the EventType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass connection - Standardsprache geändert - - - - - + + + Device ID The name of the ParamType (ThingClass: storage, Type: thing, ID: {49087f31-abf5-4bb8-946b-a3626ee80566}) ---------- @@ -306,128 +126,50 @@ The name of the ParamType (ThingClass: inverter, Type: thing, ID: {f2f8c2f5-dd6a Geräte ID - - + Energy Consumed - The name of the ParamType (ThingClass: meter, EventType: totalEnergyConsumed, ID: {f3451818-48d2-42a5-94fd-ad094c06967f}) ----------- -The name of the StateType ({f3451818-48d2-42a5-94fd-ad094c06967f}) of ThingClass meter + The name of the StateType ({f3451818-48d2-42a5-94fd-ad094c06967f}) of ThingClass meter Energie verbraucht - - Energy consumption changed - The name of the EventType ({f3451818-48d2-42a5-94fd-ad094c06967f}) of ThingClass meter - Energieverbrauch geändert - - - - - Energy of current day - The name of the ParamType (ThingClass: inverter, EventType: eday, ID: {b6af1bf5-753d-47b6-a151-e4d801fe6ff8}) ----------- -The name of the StateType ({b6af1bf5-753d-47b6-a151-e4d801fe6ff8}) of ThingClass inverter - Energie dieses Tages - - - - - Energy of current year - The name of the ParamType (ThingClass: inverter, EventType: eyear, ID: {7fd2fa28-9bcc-4f01-a823-459437d185f6}) ----------- -The name of the StateType ({7fd2fa28-9bcc-4f01-a823-459437d185f6}) of ThingClass inverter - Energie dieses Jahres - - - - Energy of day changed - The name of the EventType ({b6af1bf5-753d-47b6-a151-e4d801fe6ff8}) of ThingClass inverter - Energie dieses Tages geändert - - - - Energy of year changed - The name of the EventType ({7fd2fa28-9bcc-4f01-a823-459437d185f6}) of ThingClass inverter - Energie dieses Jahres geändert - - - - + Energy produced - The name of the ParamType (ThingClass: meter, EventType: totalEnergyProduced, ID: {ca14cca5-d9f0-49c5-a8f7-907d4c0825f0}) ----------- -The name of the StateType ({ca14cca5-d9f0-49c5-a8f7-907d4c0825f0}) of ThingClass meter + The name of the StateType ({ca14cca5-d9f0-49c5-a8f7-907d4c0825f0}) of ThingClass meter - - Energy production changed - The name of the EventType ({ca14cca5-d9f0-49c5-a8f7-907d4c0825f0}) of ThingClass meter - Energieproduktion geändert - - - - - Charging - The name of the ParamType (ThingClass: storage, EventType: charging, ID: {2de34a1f-de2e-43ad-8998-8a5460dff9ae}) ----------- -The name of the StateType ({2de34a1f-de2e-43ad-8998-8a5460dff9ae}) of ThingClass storage - - - - - Charging changed - The name of the EventType ({2de34a1f-de2e-43ad-8998-8a5460dff9ae}) of ThingClass storage - - - - - - Current power changed - The name of the EventType ({5a89cd3f-3abf-4f51-ab2b-4039f1d211d9}) of ThingClass storage ----------- -The name of the EventType ({788accbc-b86e-471b-b37f-14c9c6411526}) of ThingClass inverter - - - - - + Current power usage - The name of the ParamType (ThingClass: meter, EventType: currentPower, ID: {e5056ea1-88a2-410b-9c5e-6322aca4cb17}) ----------- -The name of the StateType ({e5056ea1-88a2-410b-9c5e-6322aca4cb17}) of ThingClass meter + The name of the StateType ({e5056ea1-88a2-410b-9c5e-6322aca4cb17}) of ThingClass meter - - Current power usage changed - The name of the EventType ({e5056ea1-88a2-410b-9c5e-6322aca4cb17}) of ThingClass meter + + Charging state + The name of the StateType ({7a045257-d829-4e58-a769-047b3aeec7c5}) of ThingClass storage - - - Discharging - The name of the ParamType (ThingClass: storage, EventType: discharging, ID: {be90d35c-081c-485b-b4cc-8271e7da5796}) ----------- -The name of the StateType ({be90d35c-081c-485b-b4cc-8271e7da5796}) of ThingClass storage + + Energy produced today + The name of the StateType ({b6af1bf5-753d-47b6-a151-e4d801fe6ff8}) of ThingClass inverter - - Discharging changed - The name of the EventType ({be90d35c-081c-485b-b4cc-8271e7da5796}) of ThingClass storage + + Energy produced year + The name of the StateType ({7fd2fa28-9bcc-4f01-a823-459437d185f6}) of ThingClass inverter - + Fronius The name of the vendor ({2286fc38-afd9-4128-ab7e-0fba527d53ba}) Fronius - - + + Fronius Solar The name of the ThingClass ({4fd79fed-42f1-4df9-be64-3df7b2e0bda2}) ---------- @@ -435,277 +177,79 @@ The name of the plugin fronius ({02319cfc-8b55-49ba-99bc-0588bbfab063})Fronius Solar - + Fronius Solar Inverter The name of the ThingClass ({540aa956-8b8f-4982-9f58-343a76cea846}) Fronius Solar Inverter - - - Hardware version - 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 connection - Hardwareversion + + Mac address + The name of the ParamType (ThingClass: connection, Type: thing, ID: {2237972e-385b-4458-b5d3-1d1fb4ae8756}) + - - Hardware version changed - The name of the EventType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass connection - Hardwareversion geändert + + Version + The name of the StateType ({8fd0c0ed-af89-4887-bf0f-040b13c25268}) of ThingClass connection + - + Host address The name of the ParamType (ThingClass: connection, Type: thing, ID: {52da0197-4b78-4fec-aa72-70f949e26edc}) Adresse - - - Inverter active - The name of the ParamType (ThingClass: inverter, EventType: active, ID: {e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0}) ----------- -The name of the StateType ({e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0}) of ThingClass inverter - Inverter aktiv - - - - Inverter active changed - The name of the EventType ({e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0}) of ThingClass inverter - Inverter aktiv geändert - - - - MAC address - The name of the ParamType (ThingClass: connection, Type: thing, ID: {2237972e-385b-4458-b5d3-1d1fb4ae8756}) - - - - - - Platform ID - 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 connection - Plattform ID - - - - Platform ID changed - 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: connection, EventType: powerManagmentRelay, ID: {b217acf6-0c5e-4a3e-a50c-4c0133c871c2}) ----------- -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: connection, EventType: powerManagmentRelayReason, ID: {5650ce9b-0d7d-4c52-b410-ea618889b4bb}) ----------- -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 connection - Leistungsmanagement Relais Grund geändert - - - - Power management relay status changed - 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: connection, EventType: productid, ID: {b22052ef-14da-43d2-982b-f2c2d8c03206}) ----------- -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 connection - Produkt-ID geändert - - - - - - - - - - + + + + Reachable - The name of the ParamType (ThingClass: storage, EventType: connected, ID: {2f7e1267-b0be-4b78-9aa3-832b86c4efad}) ----------- -The name of the StateType ({2f7e1267-b0be-4b78-9aa3-832b86c4efad}) of ThingClass storage ----------- -The name of the ParamType (ThingClass: meter, EventType: connected, ID: {b70b61a4-54cb-47ec-b62a-b498eb1f650e}) + The name of the StateType ({2f7e1267-b0be-4b78-9aa3-832b86c4efad}) of ThingClass storage ---------- The name of the StateType ({b70b61a4-54cb-47ec-b62a-b498eb1f650e}) of ThingClass meter ---------- -The name of the ParamType (ThingClass: inverter, EventType: connected, ID: {eda29c50-73ac-40e0-9c92-26fee352e688}) ----------- The name of the StateType ({eda29c50-73ac-40e0-9c92-26fee352e688}) of ThingClass inverter ---------- -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 connection Erreichbar - - - - Reachable changed - The name of the EventType ({2f7e1267-b0be-4b78-9aa3-832b86c4efad}) of ThingClass storage ----------- -The name of the EventType ({b70b61a4-54cb-47ec-b62a-b498eb1f650e}) of ThingClass meter ----------- -The name of the EventType ({eda29c50-73ac-40e0-9c92-26fee352e688}) of ThingClass inverter - Erreichbar geändert - - - - Search new devices - The name of the ActionType ({c217fdc1-de18-41dc-b5d8-8072f84e7b6c}) of ThingClass connection - Suche neue Geräte - - - - + + + Serial number The name of the ParamType (ThingClass: storage, Type: thing, ID: {8b6c7053-5ba5-4808-8ff4-9024c624d77d}) ---------- -The name of the ParamType (ThingClass: meter, Type: thing, ID: {dfc2eeef-38b2-4089-9953-48186aaee060}) +The name of the ParamType (ThingClass: meter, Type: thing, ID: {dfc2eeef-38b2-4089-9953-48186aaee060}) +---------- +The name of the ParamType (ThingClass: inverter, Type: thing, ID: {5e073a9d-f2de-4ff4-95f1-065a0ef4d51b}) - - - Software version - 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 connection - Softwareversion - - - - Software version changed - The name of the EventType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass connection - Softwareversion geändert - - - - + Total produced energy - The name of the ParamType (ThingClass: inverter, EventType: totalEnergyProduced, ID: {d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) ----------- -The name of the StateType ({d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) of ThingClass inverter + The name of the StateType ({d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) of ThingClass inverter - - Total produced energy changed - The name of the EventType ({d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) of ThingClass inverter - - - - - - Time zone - 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 connection - Zeitzone - - - - Time zone changed - The name of the EventType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass connection - Zeitzone geändert - - - - - Timezone location - 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 connection - Zeitzone Ort - - - - Timezone location changed - The name of the EventType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass connection - Zeitzone Ort geändert - - - - + Voltage phase A - The name of the ParamType (ThingClass: meter, EventType: voltagePhaseA, ID: {267bc59f-1113-4aff-a502-4618a591aa16}) ----------- -The name of the StateType ({267bc59f-1113-4aff-a502-4618a591aa16}) of ThingClass meter + The name of the StateType ({267bc59f-1113-4aff-a502-4618a591aa16}) of ThingClass meter - - Voltage phase A changed - The name of the EventType ({267bc59f-1113-4aff-a502-4618a591aa16}) of ThingClass meter - - - - - + Voltage phase B - The name of the ParamType (ThingClass: meter, EventType: voltagePhaseB, ID: {bbcedb80-30f1-493e-81f0-5f77f2847353}) ----------- -The name of the StateType ({bbcedb80-30f1-493e-81f0-5f77f2847353}) of ThingClass meter + The name of the StateType ({bbcedb80-30f1-493e-81f0-5f77f2847353}) of ThingClass meter - - Voltage phase B changed - The name of the EventType ({bbcedb80-30f1-493e-81f0-5f77f2847353}) of ThingClass meter - - - - - + Voltage phase C - The name of the ParamType (ThingClass: meter, EventType: voltagePhaseC, ID: {8037557b-40dc-411b-8937-bcd1695f898a}) ----------- -The name of the StateType ({8037557b-40dc-411b-8937-bcd1695f898a}) of ThingClass meter + The name of the StateType ({8037557b-40dc-411b-8937-bcd1695f898a}) of ThingClass meter - - - Voltage phase C changed - The name of the EventType ({8037557b-40dc-411b-8937-bcd1695f898a}) of ThingClass meter - - - - - logger reachable changed - 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 c9159bc7..9d4703e6 100644 --- a/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-en_US.ts +++ b/fronius/translations/02319cfc-8b55-49ba-99bc-0588bbfab063-en_US.ts @@ -9,17 +9,17 @@ - - Device not reachable + + The device is not reachable - - Please try again + + Unable to read the data. Please try again. - + The firmware version 1.6-2 of this Fronius data logger has a broken API. Please update your Fronius device. @@ -27,276 +27,96 @@ fronius - - + Battery level - The name of the ParamType (ThingClass: storage, EventType: batteryLevel, ID: {5c6da672-9662-41bc-8c8c-aa0f32481251}) ----------- -The name of the StateType ({5c6da672-9662-41bc-8c8c-aa0f32481251}) of ThingClass storage + The name of the StateType ({5c6da672-9662-41bc-8c8c-aa0f32481251}) of ThingClass storage - - Battery level changed - The name of the EventType ({5c6da672-9662-41bc-8c8c-aa0f32481251}) of ThingClass storage - - - - - + Battery level critical - The name of the ParamType (ThingClass: storage, EventType: batteryCritical, ID: {e5396312-b50e-4d6f-b628-5b51448971d3}) ----------- -The name of the StateType ({e5396312-b50e-4d6f-b628-5b51448971d3}) of ThingClass storage + The name of the StateType ({e5396312-b50e-4d6f-b628-5b51448971d3}) of ThingClass storage - - Battery level critical changed - The name of the EventType ({e5396312-b50e-4d6f-b628-5b51448971d3}) of ThingClass storage - - - - - - CO2 factor - 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 connection - - - - - CO2 factor changed - The name of the EventType ({8ab01225-7be5-4482-a99b-314108ae0e2b}) of ThingClass connection - - - - - - CO2 unit - 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 connection - - - - - CO2 unit changed - The name of the EventType ({b0e655f8-27d0-4add-918b-461cadc8efcc}) of ThingClass connection - - - - - + Capacity - The name of the ParamType (ThingClass: storage, EventType: capacity, ID: {3b163deb-67a2-41d1-8441-b2d53ad846ef}) ----------- -The name of the StateType ({3b163deb-67a2-41d1-8441-b2d53ad846ef}) of ThingClass storage + The name of the StateType ({3b163deb-67a2-41d1-8441-b2d53ad846ef}) of ThingClass storage - - Capacity changed - The name of the EventType ({3b163deb-67a2-41d1-8441-b2d53ad846ef}) of ThingClass storage - - - - - Cash Currency changed - The name of the EventType ({84da30c8-a7fb-49c6-884c-9521f9f62bbc}) of ThingClass connection - - - - - - Cash currency - 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 connection - - - - - - Cash factor - 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 connection - - - - - Cash factor changed - The name of the EventType ({bc18595b-17c7-4a1f-8002-b908a3d9239d}) of ThingClass connection - - - - - + Cell temperature - The name of the ParamType (ThingClass: storage, EventType: cellTemperature, ID: {4417499c-1757-4309-868a-be5cf3455c4a}) ----------- -The name of the StateType ({4417499c-1757-4309-868a-be5cf3455c4a}) of ThingClass storage + The name of the StateType ({4417499c-1757-4309-868a-be5cf3455c4a}) of ThingClass storage - - Cell temperature changed - The name of the EventType ({4417499c-1757-4309-868a-be5cf3455c4a}) of ThingClass storage - - - - - + Current phase A - The name of the ParamType (ThingClass: meter, EventType: currentPhaseA, ID: {a9673688-d84a-4848-8583-a70739130252}) ----------- -The name of the StateType ({a9673688-d84a-4848-8583-a70739130252}) of ThingClass meter + The name of the StateType ({a9673688-d84a-4848-8583-a70739130252}) of ThingClass meter - - Current phase A changed - The name of the EventType ({a9673688-d84a-4848-8583-a70739130252}) of ThingClass meter - - - - - + Current phase B - The name of the ParamType (ThingClass: meter, EventType: currentPhaseB, ID: {15632e49-95f9-496d-830c-53a31ca6d98e}) ----------- -The name of the StateType ({15632e49-95f9-496d-830c-53a31ca6d98e}) of ThingClass meter + The name of the StateType ({15632e49-95f9-496d-830c-53a31ca6d98e}) of ThingClass meter - - Current phase B changed - The name of the EventType ({15632e49-95f9-496d-830c-53a31ca6d98e}) of ThingClass meter - - - - - + Current phase C - The name of the ParamType (ThingClass: meter, EventType: currentPhaseC, ID: {10a24ba9-a57a-48a9-98f3-52671c09e855}) ----------- -The name of the StateType ({10a24ba9-a57a-48a9-98f3-52671c09e855}) of ThingClass meter + The name of the StateType ({10a24ba9-a57a-48a9-98f3-52671c09e855}) of ThingClass meter - - Current phase C changed - The name of the EventType ({10a24ba9-a57a-48a9-98f3-52671c09e855}) of ThingClass meter - - - - - + Current power phase A - The name of the ParamType (ThingClass: meter, EventType: currentPowerPhaseA, ID: {6dbbb062-447b-47d6-b2e4-dceac9aff795}) ----------- -The name of the StateType ({6dbbb062-447b-47d6-b2e4-dceac9aff795}) of ThingClass meter + The name of the StateType ({6dbbb062-447b-47d6-b2e4-dceac9aff795}) of ThingClass meter - - Current power phase A changed - The name of the EventType ({6dbbb062-447b-47d6-b2e4-dceac9aff795}) of ThingClass meter - - - - - + Current power phase B - The name of the ParamType (ThingClass: meter, EventType: currentPowerPhaseB, ID: {f230e78e-15b0-47a4-b494-bae65be00755}) ----------- -The name of the StateType ({f230e78e-15b0-47a4-b494-bae65be00755}) of ThingClass meter + The name of the StateType ({f230e78e-15b0-47a4-b494-bae65be00755}) of ThingClass meter - - Current power phase B changed - The name of the EventType ({f230e78e-15b0-47a4-b494-bae65be00755}) of ThingClass meter - - - - - + Current power phase C - The name of the ParamType (ThingClass: meter, EventType: currentPowerPhaseC, ID: {56b5d550-d902-4c33-9288-8ee972735a75}) ----------- -The name of the StateType ({56b5d550-d902-4c33-9288-8ee972735a75}) of ThingClass meter + The name of the StateType ({56b5d550-d902-4c33-9288-8ee972735a75}) of ThingClass meter - - Current power phase C changed - The name of the EventType ({56b5d550-d902-4c33-9288-8ee972735a75}) of ThingClass meter - - - - - + Frequency - The name of the ParamType (ThingClass: meter, EventType: frequency, ID: {9ff64b29-e023-4395-abd4-b6c366acfd9e}) ----------- -The name of the StateType ({9ff64b29-e023-4395-abd4-b6c366acfd9e}) of ThingClass meter + The name of the StateType ({9ff64b29-e023-4395-abd4-b6c366acfd9e}) of ThingClass meter - - Frequency changed - The name of the EventType ({9ff64b29-e023-4395-abd4-b6c366acfd9e}) of ThingClass meter - - - - + Fronius smart meter The name of the ThingClass ({c3cb53a4-32dd-434d-9d9c-aada41f8129c}) - + Fronius solar storage The name of the ThingClass ({b00139fa-7386-48b1-8697-2fdd21a57ced}) - - - - + + Current power - The name of the ParamType (ThingClass: storage, EventType: currentPower, ID: {5a89cd3f-3abf-4f51-ab2b-4039f1d211d9}) ----------- -The name of the StateType ({5a89cd3f-3abf-4f51-ab2b-4039f1d211d9}) of ThingClass storage ----------- -The name of the ParamType (ThingClass: inverter, EventType: currentPower, ID: {788accbc-b86e-471b-b37f-14c9c6411526}) + The name of the StateType ({5a89cd3f-3abf-4f51-ab2b-4039f1d211d9}) of ThingClass storage ---------- The name of the StateType ({788accbc-b86e-471b-b37f-14c9c6411526}) of ThingClass inverter - - - Default language - 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 connection - - - - - Default language changed - The name of the EventType ({18b250e2-080a-4991-b368-177c4da83eca}) of ThingClass connection - - - - - - + + + Device ID The name of the ParamType (ThingClass: storage, Type: thing, ID: {49087f31-abf5-4bb8-946b-a3626ee80566}) ---------- @@ -306,128 +126,50 @@ The name of the ParamType (ThingClass: inverter, Type: thing, ID: {f2f8c2f5-dd6a - - + Energy Consumed - The name of the ParamType (ThingClass: meter, EventType: totalEnergyConsumed, ID: {f3451818-48d2-42a5-94fd-ad094c06967f}) ----------- -The name of the StateType ({f3451818-48d2-42a5-94fd-ad094c06967f}) of ThingClass meter + The name of the StateType ({f3451818-48d2-42a5-94fd-ad094c06967f}) of ThingClass meter - - Energy consumption changed - The name of the EventType ({f3451818-48d2-42a5-94fd-ad094c06967f}) of ThingClass meter - - - - - - Energy of current day - The name of the ParamType (ThingClass: inverter, EventType: eday, ID: {b6af1bf5-753d-47b6-a151-e4d801fe6ff8}) ----------- -The name of the StateType ({b6af1bf5-753d-47b6-a151-e4d801fe6ff8}) of ThingClass inverter - - - - - - Energy of current year - The name of the ParamType (ThingClass: inverter, EventType: eyear, ID: {7fd2fa28-9bcc-4f01-a823-459437d185f6}) ----------- -The name of the StateType ({7fd2fa28-9bcc-4f01-a823-459437d185f6}) of ThingClass inverter - - - - - Energy of day changed - The name of the EventType ({b6af1bf5-753d-47b6-a151-e4d801fe6ff8}) of ThingClass inverter - - - - - Energy of year changed - The name of the EventType ({7fd2fa28-9bcc-4f01-a823-459437d185f6}) of ThingClass inverter - - - - - + Energy produced - The name of the ParamType (ThingClass: meter, EventType: totalEnergyProduced, ID: {ca14cca5-d9f0-49c5-a8f7-907d4c0825f0}) ----------- -The name of the StateType ({ca14cca5-d9f0-49c5-a8f7-907d4c0825f0}) of ThingClass meter + The name of the StateType ({ca14cca5-d9f0-49c5-a8f7-907d4c0825f0}) of ThingClass meter - - Energy production changed - The name of the EventType ({ca14cca5-d9f0-49c5-a8f7-907d4c0825f0}) of ThingClass meter - - - - - - Charging - The name of the ParamType (ThingClass: storage, EventType: charging, ID: {2de34a1f-de2e-43ad-8998-8a5460dff9ae}) ----------- -The name of the StateType ({2de34a1f-de2e-43ad-8998-8a5460dff9ae}) of ThingClass storage - - - - - Charging changed - The name of the EventType ({2de34a1f-de2e-43ad-8998-8a5460dff9ae}) of ThingClass storage - - - - - - Current power changed - The name of the EventType ({5a89cd3f-3abf-4f51-ab2b-4039f1d211d9}) of ThingClass storage ----------- -The name of the EventType ({788accbc-b86e-471b-b37f-14c9c6411526}) of ThingClass inverter - - - - - + Current power usage - The name of the ParamType (ThingClass: meter, EventType: currentPower, ID: {e5056ea1-88a2-410b-9c5e-6322aca4cb17}) ----------- -The name of the StateType ({e5056ea1-88a2-410b-9c5e-6322aca4cb17}) of ThingClass meter + The name of the StateType ({e5056ea1-88a2-410b-9c5e-6322aca4cb17}) of ThingClass meter - - Current power usage changed - The name of the EventType ({e5056ea1-88a2-410b-9c5e-6322aca4cb17}) of ThingClass meter + + Charging state + The name of the StateType ({7a045257-d829-4e58-a769-047b3aeec7c5}) of ThingClass storage - - - Discharging - The name of the ParamType (ThingClass: storage, EventType: discharging, ID: {be90d35c-081c-485b-b4cc-8271e7da5796}) ----------- -The name of the StateType ({be90d35c-081c-485b-b4cc-8271e7da5796}) of ThingClass storage + + Energy produced today + The name of the StateType ({b6af1bf5-753d-47b6-a151-e4d801fe6ff8}) of ThingClass inverter - - Discharging changed - The name of the EventType ({be90d35c-081c-485b-b4cc-8271e7da5796}) of ThingClass storage + + Energy produced year + The name of the StateType ({7fd2fa28-9bcc-4f01-a823-459437d185f6}) of ThingClass inverter - + Fronius The name of the vendor ({2286fc38-afd9-4128-ab7e-0fba527d53ba}) - - + + Fronius Solar The name of the ThingClass ({4fd79fed-42f1-4df9-be64-3df7b2e0bda2}) ---------- @@ -435,276 +177,78 @@ The name of the plugin fronius ({02319cfc-8b55-49ba-99bc-0588bbfab063}) - + Fronius Solar Inverter The name of the ThingClass ({540aa956-8b8f-4982-9f58-343a76cea846}) - - - Hardware version - 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 connection + + Mac address + The name of the ParamType (ThingClass: connection, Type: thing, ID: {2237972e-385b-4458-b5d3-1d1fb4ae8756}) - - Hardware version changed - The name of the EventType ({3b4206e5-74c7-4708-96b8-2abfab0c41d6}) of ThingClass connection + + Version + The name of the StateType ({8fd0c0ed-af89-4887-bf0f-040b13c25268}) of ThingClass connection - + Host address The name of the ParamType (ThingClass: connection, Type: thing, ID: {52da0197-4b78-4fec-aa72-70f949e26edc}) - - - Inverter active - The name of the ParamType (ThingClass: inverter, EventType: active, ID: {e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0}) ----------- -The name of the StateType ({e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0}) of ThingClass inverter - - - - - Inverter active changed - The name of the EventType ({e763baa7-5eaf-438c-83f0-4fa6c0f7eeb0}) of ThingClass inverter - - - - - MAC address - The name of the ParamType (ThingClass: connection, Type: thing, ID: {2237972e-385b-4458-b5d3-1d1fb4ae8756}) - - - - - - Platform ID - 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 connection - - - - - Platform ID changed - The name of the EventType ({65c068e6-4a0b-4672-9724-ae95216c4c9c}) of ThingClass connection - - - - - - Power management relay - 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 connection - - - - - - Power management relay reason - 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 connection - - - - - Power management relay reason changed - 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 connection - - - - - - Product ID - 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 connection - - - - - Product ID changed - The name of the EventType ({b22052ef-14da-43d2-982b-f2c2d8c03206}) of ThingClass connection - - - - - - - - - - - + + + + Reachable - The name of the ParamType (ThingClass: storage, EventType: connected, ID: {2f7e1267-b0be-4b78-9aa3-832b86c4efad}) ----------- -The name of the StateType ({2f7e1267-b0be-4b78-9aa3-832b86c4efad}) of ThingClass storage ----------- -The name of the ParamType (ThingClass: meter, EventType: connected, ID: {b70b61a4-54cb-47ec-b62a-b498eb1f650e}) + The name of the StateType ({2f7e1267-b0be-4b78-9aa3-832b86c4efad}) of ThingClass storage ---------- The name of the StateType ({b70b61a4-54cb-47ec-b62a-b498eb1f650e}) of ThingClass meter ---------- -The name of the ParamType (ThingClass: inverter, EventType: connected, ID: {eda29c50-73ac-40e0-9c92-26fee352e688}) ----------- The name of the StateType ({eda29c50-73ac-40e0-9c92-26fee352e688}) of ThingClass inverter ---------- -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 connection - - - - Reachable changed - The name of the EventType ({2f7e1267-b0be-4b78-9aa3-832b86c4efad}) of ThingClass storage ----------- -The name of the EventType ({b70b61a4-54cb-47ec-b62a-b498eb1f650e}) of ThingClass meter ----------- -The name of the EventType ({eda29c50-73ac-40e0-9c92-26fee352e688}) of ThingClass inverter - - - - - Search new devices - The name of the ActionType ({c217fdc1-de18-41dc-b5d8-8072f84e7b6c}) of ThingClass connection - - - - - + + + Serial number The name of the ParamType (ThingClass: storage, Type: thing, ID: {8b6c7053-5ba5-4808-8ff4-9024c624d77d}) ---------- -The name of the ParamType (ThingClass: meter, Type: thing, ID: {dfc2eeef-38b2-4089-9953-48186aaee060}) - - - - - - Software version - The name of the ParamType (ThingClass: connection, EventType: swversion, ID: {31743ca5-4353-4f26-b2ad-5da43e5b9d86}) +The name of the ParamType (ThingClass: meter, Type: thing, ID: {dfc2eeef-38b2-4089-9953-48186aaee060}) ---------- -The name of the StateType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass connection +The name of the ParamType (ThingClass: inverter, Type: thing, ID: {5e073a9d-f2de-4ff4-95f1-065a0ef4d51b}) - - Software version changed - The name of the EventType ({31743ca5-4353-4f26-b2ad-5da43e5b9d86}) of ThingClass connection - - - - - + Total produced energy - The name of the ParamType (ThingClass: inverter, EventType: totalEnergyProduced, ID: {d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) ----------- -The name of the StateType ({d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) of ThingClass inverter + The name of the StateType ({d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) of ThingClass inverter - - Total produced energy changed - The name of the EventType ({d6dbb879-4cbc-4db3-830e-b92ba91a13e5}) of ThingClass inverter - - - - - - Time zone - 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 connection - - - - - Time zone changed - The name of the EventType ({6bdfeeda-7a47-4043-a011-5eb96308a7d6}) of ThingClass connection - - - - - - Timezone location - 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 connection - - - - - Timezone location changed - The name of the EventType ({d034f59d-dc34-450a-a6f3-68264767a3e4}) of ThingClass connection - - - - - + Voltage phase A - The name of the ParamType (ThingClass: meter, EventType: voltagePhaseA, ID: {267bc59f-1113-4aff-a502-4618a591aa16}) ----------- -The name of the StateType ({267bc59f-1113-4aff-a502-4618a591aa16}) of ThingClass meter + The name of the StateType ({267bc59f-1113-4aff-a502-4618a591aa16}) of ThingClass meter - - Voltage phase A changed - The name of the EventType ({267bc59f-1113-4aff-a502-4618a591aa16}) of ThingClass meter - - - - - + Voltage phase B - The name of the ParamType (ThingClass: meter, EventType: voltagePhaseB, ID: {bbcedb80-30f1-493e-81f0-5f77f2847353}) ----------- -The name of the StateType ({bbcedb80-30f1-493e-81f0-5f77f2847353}) of ThingClass meter + The name of the StateType ({bbcedb80-30f1-493e-81f0-5f77f2847353}) of ThingClass meter - - Voltage phase B changed - The name of the EventType ({bbcedb80-30f1-493e-81f0-5f77f2847353}) of ThingClass meter - - - - - + Voltage phase C - The name of the ParamType (ThingClass: meter, EventType: voltagePhaseC, ID: {8037557b-40dc-411b-8937-bcd1695f898a}) ----------- -The name of the StateType ({8037557b-40dc-411b-8937-bcd1695f898a}) of ThingClass meter - - - - - Voltage phase C changed - The name of the EventType ({8037557b-40dc-411b-8937-bcd1695f898a}) of ThingClass meter - - - - - logger reachable changed - The name of the EventType ({98e4476f-e745-4a7f-b795-19269cb70c40}) of ThingClass connection + The name of the StateType ({8037557b-40dc-411b-8937-bcd1695f898a}) of ThingClass meter From 04d1b826859e90a0514d6f93fd9b8ff232a20a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 2 Mar 2022 07:45:20 +0100 Subject: [PATCH 3/7] Fix refresh method --- fronius/integrationpluginfronius.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fronius/integrationpluginfronius.cpp b/fronius/integrationpluginfronius.cpp index 1bca7c19..829ca62f 100644 --- a/fronius/integrationpluginfronius.cpp +++ b/fronius/integrationpluginfronius.cpp @@ -114,7 +114,6 @@ void IntegrationPluginFronius::setupThing(ThingSetupInfo *info) // 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) { @@ -236,7 +235,7 @@ void IntegrationPluginFronius::executeAction(ThingActionInfo *info) void IntegrationPluginFronius::refreshConnection(FroniusSolarConnection *connection) { - if (!connection->busy()) { + if (connection->busy()) { qCWarning(dcFronius()) << "Connection busy. Skipping refresh cycle for host" << connection->address().toString(); return; } From c7edc3ccf83e30d316bbb1ac59fb311b5adc3df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 2 Mar 2022 09:40:06 +0100 Subject: [PATCH 4/7] Fix battery power and user total pv power for the inverter --- fronius/integrationpluginfronius.cpp | 106 ++++++++++++++++----------- fronius/integrationpluginfronius.h | 1 + 2 files changed, 65 insertions(+), 42 deletions(-) diff --git a/fronius/integrationpluginfronius.cpp b/fronius/integrationpluginfronius.cpp index 829ca62f..42e81798 100644 --- a/fronius/integrationpluginfronius.cpp +++ b/fronius/integrationpluginfronius.cpp @@ -394,13 +394,68 @@ void IntegrationPluginFronius::refreshConnection(FroniusSolarConnection *connect thingDescriptors.clear(); } - // Update the inverters + // All devices + updatePowerFlow(connection); updateInverters(connection); updateMeters(connection); updateStorages(connection); }); } +void IntegrationPluginFronius::updatePowerFlow(FroniusSolarConnection *connection) +{ + Thing *parentThing = m_froniusConnections.value(connection); + + // Get power flow realtime data and update storage and pv power values according to the total values + // The inverter details inform about the PV production after feeding the storage, but we should use the total + // to make sure the sum is correct. Battery seems to be feeded DC to DC before the AC power convertion + FroniusNetworkReply *powerFlowReply = connection->getPowerFlowRealtimeData(); + connect(powerFlowReply, &FroniusNetworkReply::finished, this, [=]() { + if (powerFlowReply->networkReply()->error() != QNetworkReply::NoError) { + 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(); + 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)); + + // Find the inverter for this connection and set the total power + Things availableInverters = myThings().filterByParentId(parentThing->id()).filterByThingClassId(inverterThingClassId); + if (availableInverters.count() == 1) { + Thing *inverterThing = availableInverters.first(); + double pvPower = dataMap.value("Site").toMap().value("P_PV").toDouble(); + inverterThing->setStateValue(inverterCurrentPowerStateTypeId, - pvPower); + } + + // Find the storage for this connection and update the current power + Things availableStorages = myThings().filterByParentId(parentThing->id()).filterByThingClassId(storageThingClassId); + if (availableStorages.count() == 1) { + Thing *storageThing = availableStorages.first(); + // Note: negative (charge), positiv (discharge) + double akkuPower = - dataMap.value("Site").toMap().value("P_Akku").toDouble(); + storageThing->setStateValue(storageCurrentPowerStateTypeId, akkuPower); + if (akkuPower < 0) { + storageThing->setStateValue(storageChargingStateStateTypeId, "discharging"); + } else if (akkuPower > 0) { + storageThing->setStateValue(storageChargingStateStateTypeId, "charging"); + } else { + storageThing->setStateValue(storageChargingStateStateTypeId, "idle"); + } + } + + }); +} + + void IntegrationPluginFronius::updateInverters(FroniusSolarConnection *connection) { Thing *parentThing = m_froniusConnections.value(connection); @@ -430,14 +485,15 @@ void IntegrationPluginFronius::updateInverters(FroniusSolarConnection *connectio QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap(); //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()); - } - } + // Note: this is the PV power after feeding the battery, we have to use the total PV production from the power flow + //if (dataMap.contains("PAC")) { + // QVariantMap map = dataMap.value("PAC").toMap(); + // if (map.value("Unit") == "W") { + // inverterThing->setStateValue(inverterCurrentPowerStateTypeId, - map.value("Value").toDouble()); + // } + //} + // Set the inverter device state if (dataMap.contains("DAY_ENERGY")) { QVariantMap map = dataMap.value("DAY_ENERGY").toMap(); if (map.value("Unit") == "Wh") { @@ -561,40 +617,6 @@ void IntegrationPluginFronius::updateStorages(FroniusSolarConnection *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, [=]() { diff --git a/fronius/integrationpluginfronius.h b/fronius/integrationpluginfronius.h index bb801962..8fec913b 100644 --- a/fronius/integrationpluginfronius.h +++ b/fronius/integrationpluginfronius.h @@ -63,6 +63,7 @@ private: void refreshConnection(FroniusSolarConnection *connection); + void updatePowerFlow(FroniusSolarConnection *connection); void updateInverters(FroniusSolarConnection *connection); void updateMeters(FroniusSolarConnection *connection); void updateStorages(FroniusSolarConnection *connection); From 9f1869462a2ef1395ba328be8318f9a9b50f982d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 7 Mar 2022 13:20:17 +0100 Subject: [PATCH 5/7] Fix battery name parsing during initial setup --- fronius/integrationpluginfronius.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fronius/integrationpluginfronius.cpp b/fronius/integrationpluginfronius.cpp index 42e81798..2613977a 100644 --- a/fronius/integrationpluginfronius.cpp +++ b/fronius/integrationpluginfronius.cpp @@ -352,7 +352,8 @@ void IntegrationPluginFronius::refreshConnection(FroniusSolarConnection *connect } // Parse the data and update the states of our device - QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap(); + QVariantMap dataMap = jsonDoc.toVariant().toMap().value("Body").toMap().value("Data").toMap().value("Controller").toMap(); + QString thingName; QString serialNumber; if (dataMap.contains("Details")) { From dba629b17386f757c5fcf34bfbed5c8f745ed374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 7 Mar 2022 14:47:54 +0100 Subject: [PATCH 6/7] Handle reconfigure --- fronius/froniusnetworkreply.cpp | 2 +- fronius/integrationpluginfronius.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fronius/froniusnetworkreply.cpp b/fronius/froniusnetworkreply.cpp index 13141ae4..34d0ab4c 100644 --- a/fronius/froniusnetworkreply.cpp +++ b/fronius/froniusnetworkreply.cpp @@ -71,7 +71,7 @@ void FroniusNetworkReply::setNetworkReply(QNetworkReply *networkReply) { m_networkReply = networkReply; - // The QNetworkReply will be deleted in the constructor if set + // The QNetworkReply will be deleted in the destructor if set connect(m_networkReply, &QNetworkReply::finished, this, &FroniusNetworkReply::finished); } diff --git a/fronius/integrationpluginfronius.cpp b/fronius/integrationpluginfronius.cpp index 2613977a..934ff50c 100644 --- a/fronius/integrationpluginfronius.cpp +++ b/fronius/integrationpluginfronius.cpp @@ -110,6 +110,15 @@ void IntegrationPluginFronius::setupThing(ThingSetupInfo *info) if (thing->thingClassId() == connectionThingClassId) { QHostAddress address(thing->paramValue(connectionThingAddressParamTypeId).toString()); + + // Handle reconfigure + if (m_froniusConnections.values().contains(thing)) { + FroniusSolarConnection *oldConnection = m_froniusConnections.key(thing); + m_froniusConnections.remove(oldConnection); + oldConnection->deleteLater(); + } + + // Create the connection FroniusSolarConnection *connection = new FroniusSolarConnection(hardwareManager()->networkManager(), address, thing); // Verify the version From 63311b338cd352c3601da9bdf4eea01c9484a003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 7 Mar 2022 14:55:55 +0100 Subject: [PATCH 7/7] Fix state caches --- fronius/integrationpluginfronius.cpp | 6 +++--- fronius/integrationpluginfronius.json | 30 +++++++++++---------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/fronius/integrationpluginfronius.cpp b/fronius/integrationpluginfronius.cpp index 934ff50c..232e9be8 100644 --- a/fronius/integrationpluginfronius.cpp +++ b/fronius/integrationpluginfronius.cpp @@ -113,9 +113,9 @@ void IntegrationPluginFronius::setupThing(ThingSetupInfo *info) // Handle reconfigure if (m_froniusConnections.values().contains(thing)) { - FroniusSolarConnection *oldConnection = m_froniusConnections.key(thing); - m_froniusConnections.remove(oldConnection); - oldConnection->deleteLater(); + FroniusSolarConnection *connection = m_froniusConnections.key(thing); + m_froniusConnections.remove(connection); + connection->deleteLater(); } // Create the connection diff --git a/fronius/integrationpluginfronius.json b/fronius/integrationpluginfronius.json index f4ea654d..e2d041d0 100644 --- a/fronius/integrationpluginfronius.json +++ b/fronius/integrationpluginfronius.json @@ -92,7 +92,8 @@ "displayNameEvent": "Current power changed", "type": "double", "unit": "Watt", - "defaultValue": 0 + "defaultValue": 0, + "cached": false }, { "id": "b6af1bf5-753d-47b6-a151-e4d801fe6ff8", @@ -101,8 +102,7 @@ "displayNameEvent": "Energy produced today changed", "type": "double", "unit": "KiloWattHour", - "defaultValue": 0, - "cached": false + "defaultValue": 0 }, { "id": "7fd2fa28-9bcc-4f01-a823-459437d185f6", @@ -111,8 +111,7 @@ "displayNameEvent": "Energy produced changed", "type": "int", "unit": "KiloWattHour", - "defaultValue": 0, - "cached": false + "defaultValue": 0 }, { "id": "d6dbb879-4cbc-4db3-830e-b92ba91a13e5", @@ -166,7 +165,8 @@ "displayNameEvent": "Current power usage changed", "type": "double", "unit": "Watt", - "defaultValue": "0" + "defaultValue": 0, + "cached": false }, { "id": "267bc59f-1113-4aff-a502-4618a591aa16", @@ -235,8 +235,7 @@ "displayNameEvent": "Energy production changed", "type": "double", "unit": "KiloWattHour", - "defaultValue": "0", - "cached": false + "defaultValue": 0 }, { "id": "f3451818-48d2-42a5-94fd-ad094c06967f", @@ -245,8 +244,7 @@ "displayNameEvent": "Energy consumption changed", "type": "double", "unit": "KiloWattHour", - "defaultValue": "0", - "cached": false + "defaultValue": 0 }, { "id": "6dbbb062-447b-47d6-b2e4-dceac9aff795", @@ -331,8 +329,7 @@ "displayNameEvent": "Charging state changed", "type": "QString", "possibleValues": ["idle", "charging", "discharging"], - "defaultValue": "idle", - "cached": false + "defaultValue": "idle" }, { "id": "5a89cd3f-3abf-4f51-ab2b-4039f1d211d9", @@ -351,8 +348,7 @@ "displayNameEvent": "Capacity changed", "type": "double", "unit": "KiloWattHour", - "defaultValue": 0, - "cached": false + "defaultValue": 0 }, { "id": "5c6da672-9662-41bc-8c8c-aa0f32481251", @@ -363,8 +359,7 @@ "unit": "Percentage", "defaultValue": "0", "minValue": 0, - "maxValue": 100, - "cached": false + "maxValue": 100 }, { "id": "4417499c-1757-4309-868a-be5cf3455c4a", @@ -382,8 +377,7 @@ "displayName": "Battery level critical", "displayNameEvent": "Battery level critical changed", "type": "bool", - "defaultValue": false, - "cached": false + "defaultValue": false } ] }