diff --git a/fronius/fronius.pro b/fronius/fronius.pro
index e730ebf0..84e9ebd3 100644
--- a/fronius/fronius.pro
+++ b/fronius/fronius.pro
@@ -3,11 +3,13 @@ include(../plugins.pri)
QT += network
SOURCES += \
+ froniusdiscovery.cpp \
froniusnetworkreply.cpp \
froniussolarconnection.cpp \
integrationpluginfronius.cpp \
HEADERS += \
+ froniusdiscovery.h \
froniusnetworkreply.h \
froniussolarconnection.h \
integrationpluginfronius.h \
diff --git a/fronius/froniusdiscovery.cpp b/fronius/froniusdiscovery.cpp
new file mode 100644
index 00000000..997ce59b
--- /dev/null
+++ b/fronius/froniusdiscovery.cpp
@@ -0,0 +1,137 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* Copyright 2013 - 2023, 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 "froniusdiscovery.h"
+
+#include "extern-plugininfo.h"
+
+#include
+#include
+
+FroniusDiscovery::FroniusDiscovery(NetworkAccessManager *networkManager, NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent):
+ QObject(parent),
+ m_networkManager(networkManager),
+ m_networkDeviceDiscovery{networkDeviceDiscovery}
+{
+ m_gracePeriodTimer.setSingleShot(true);
+ m_gracePeriodTimer.setInterval(3000);
+ connect(&m_gracePeriodTimer, &QTimer::timeout, this, [this](){
+ qCDebug(dcFronius()) << "Discovery: Grace period timer triggered.";
+ finishDiscovery();
+ });
+
+}
+
+void FroniusDiscovery::startDiscovery()
+{
+ qCDebug(dcFronius()) << "Discovery: Searching for Fronius solar devices in the network...";
+ m_startDateTime = QDateTime::currentDateTime();
+
+ NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
+ connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &FroniusDiscovery::checkNetworkDevice);
+ connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
+ qCDebug(dcFronius()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices";
+ m_gracePeriodTimer.start();
+ discoveryReply->deleteLater();
+ });
+}
+
+QList FroniusDiscovery::discoveryResults() const
+{
+ return m_discoveryResults;
+}
+
+void FroniusDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
+{
+ qCDebug(dcFronius()) << "Discovery: Checking network device:" << networkDeviceInfo;
+
+ FroniusSolarConnection *connection = new FroniusSolarConnection(m_networkManager, networkDeviceInfo.address(), this);
+ m_connections.append(connection);
+
+ FroniusNetworkReply *reply = connection->getVersion();
+ connect(reply, &FroniusNetworkReply::finished, this, [=] {
+ QByteArray data = reply->networkReply()->readAll();
+ if (reply->networkReply()->error() != QNetworkReply::NoError) {
+ if (reply->networkReply()->error() == QNetworkReply::ContentNotFoundError) {
+ qCInfo(dcFronius()) << "Discovery: The device on" << networkDeviceInfo.address().toString() << "does not reply to our requests. Please verify that the Fronius Solar API is enabled on the device.";
+ } else {
+ qCDebug(dcFronius()) << "Discovery: Reply finished with error on" << networkDeviceInfo.address().toString() << reply->networkReply()->errorString();
+ }
+ cleanupConnection(connection);
+ return;
+ }
+
+ QJsonParseError error;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
+ if (error.error != QJsonParseError::NoError) {
+ qCDebug(dcFronius()) << "Discovery: Failed to parse JSON data from" << networkDeviceInfo.address().toString() << ":" << error.errorString() << data;
+ cleanupConnection(connection);
+ return;
+ }
+
+ QVariantMap versionResponseMap = jsonDoc.toVariant().toMap();
+ if (!versionResponseMap.contains("CompatibilityRange")) {
+ qCDebug(dcFronius()) << "Discovery: Unexpected JSON reply from" << networkDeviceInfo.address().toString() << "Probably not a Fronius device.";
+ cleanupConnection(connection);
+ return;
+ }
+ qCDebug(dcFronius()) << "Discovery: Compatibility version" << versionResponseMap.value("CompatibilityRange").toString();
+
+ // Knwon version with broken JSON API. Still allowing to discover so the user will get a proper error message during setup
+ if (versionResponseMap.value("CompatibilityRange").toString() == "1.6-2") {
+ qCWarning(dcFronius()) << "Discovery: The Fronius data logger has a version which is known to have a broken JSON API firmware.";
+ }
+
+ m_discoveryResults.append(networkDeviceInfo);
+ cleanupConnection(connection);
+ });
+}
+
+void FroniusDiscovery::cleanupConnection(FroniusSolarConnection *connection)
+{
+ m_connections.removeAll(connection);
+ connection->deleteLater();
+}
+
+void FroniusDiscovery::finishDiscovery()
+{
+ qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch();
+
+ foreach (FroniusSolarConnection *connection, m_connections) {
+ cleanupConnection(connection);
+ }
+
+ qCDebug(dcFronius()) << "Discovery: Finished the discovery process. Found" << m_discoveryResults.count()
+ << "Fronius devices in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
+ m_gracePeriodTimer.stop();
+
+ emit discoveryFinished();
+
+}
diff --git a/fronius/froniusdiscovery.h b/fronius/froniusdiscovery.h
new file mode 100644
index 00000000..6b7b3249
--- /dev/null
+++ b/fronius/froniusdiscovery.h
@@ -0,0 +1,70 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* Copyright 2013 - 2023, 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 FRONIUSDISCOVERY_H
+#define FRONIUSDISCOVERY_H
+
+#include
+#include
+
+#include
+#include "froniussolarconnection.h"
+
+class FroniusDiscovery : public QObject
+{
+ Q_OBJECT
+public:
+ explicit FroniusDiscovery(NetworkAccessManager *networkManager, NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent = nullptr);
+
+ void startDiscovery();
+
+ QList discoveryResults() const;
+
+signals:
+ void discoveryFinished();
+
+private:
+ NetworkAccessManager *m_networkManager = nullptr;
+ NetworkDeviceDiscovery *m_networkDeviceDiscovery = nullptr;
+
+ QTimer m_gracePeriodTimer;
+ QDateTime m_startDateTime;
+
+ QList m_connections;
+
+ QList m_discoveryResults;
+
+ void checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo);
+ void cleanupConnection(FroniusSolarConnection *connection);
+
+ void finishDiscovery();
+};
+
+#endif // FRONIUSDISCOVERY_H
diff --git a/fronius/froniussolarconnection.cpp b/fronius/froniussolarconnection.cpp
index d34bfe4d..1566eac9 100644
--- a/fronius/froniussolarconnection.cpp
+++ b/fronius/froniussolarconnection.cpp
@@ -46,6 +46,30 @@ QHostAddress FroniusSolarConnection::address() const
return m_address;
}
+void FroniusSolarConnection::setAddress(const QHostAddress &address)
+{
+ if (m_address == address)
+ return;
+
+ m_address = address;
+
+ // The address has changed, let's clean up any queue and refresh
+
+ // Note: the destructor will take care about the cleanup of any pending replies
+ qDeleteAll(m_requestQueue);
+ m_requestQueue.clear();
+
+ if (m_currentReply) {
+ m_currentReply->deleteLater();
+ m_currentReply = nullptr;
+ }
+
+ if (m_address.isNull()) {
+ m_available = false;
+ emit availableChanged(m_available);
+ }
+}
+
bool FroniusSolarConnection::available() const
{
return m_available;
diff --git a/fronius/froniussolarconnection.h b/fronius/froniussolarconnection.h
index e940a9be..df5bec99 100644
--- a/fronius/froniussolarconnection.h
+++ b/fronius/froniussolarconnection.h
@@ -32,7 +32,6 @@
#define FRONIUSSOLARCONNECTION_H
#include
-
#include
#include
@@ -47,6 +46,7 @@ public:
explicit FroniusSolarConnection(NetworkAccessManager *networkManager, const QHostAddress &address, QObject *parent = nullptr);
QHostAddress address() const;
+ void setAddress(const QHostAddress &address);
bool available() const;
diff --git a/fronius/integrationpluginfronius.cpp b/fronius/integrationpluginfronius.cpp
index f46949a9..6099c8d4 100644
--- a/fronius/integrationpluginfronius.cpp
+++ b/fronius/integrationpluginfronius.cpp
@@ -28,11 +28,11 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include "plugininfo.h"
-#include "plugintimer.h"
#include "integrationpluginfronius.h"
-#include "network/networkaccessmanager.h"
-#include "network/networkdevicediscovery.h"
+#include "froniusdiscovery.h"
+#include "plugininfo.h"
+
+#include
#include
#include
@@ -56,20 +56,15 @@ void IntegrationPluginFronius::discoverThings(ThingDiscoveryInfo *info)
}
qCInfo(dcFronius()) << "Starting network discovery...";
- NetworkDeviceDiscoveryReply *discoveryReply = hardwareManager()->networkDeviceDiscovery()->discover();
- connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater);
- connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, info, [=](){
+ FroniusDiscovery *discovery = new FroniusDiscovery(hardwareManager()->networkManager(), hardwareManager()->networkDeviceDiscovery(), info);
+ connect(discovery, &FroniusDiscovery::discoveryFinished, info, [=](){
ThingDescriptors descriptors;
- qCDebug(dcFronius()) << "Discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "devices";
- foreach (const NetworkDeviceInfo &networkDeviceInfo, discoveryReply->networkDeviceInfos()) {
- qCDebug(dcFronius()) << networkDeviceInfo;
+ qCInfo(dcFronius()) << "Discovery finished. Found" << discovery->discoveryResults().count() << "devices";
+ foreach (const NetworkDeviceInfo &networkDeviceInfo, discovery->discoveryResults()) {
+ qCInfo(dcFronius()) << "Discovered Fronius on" << networkDeviceInfo;
if (networkDeviceInfo.macAddress().isNull())
continue;
- // Hostname or MAC manufacturer must include Fronius
- if (!(networkDeviceInfo.macAddressManufacturer().toLower().contains("fronius") || networkDeviceInfo.hostName().toLower().contains("fronius")))
- continue;
-
QString title;
if (networkDeviceInfo.hostName().isEmpty()) {
title += "Fronius Solar";
@@ -94,13 +89,14 @@ void IntegrationPluginFronius::discoverThings(ThingDiscoveryInfo *info)
}
ParamList params;
- params << Param(connectionThingAddressParamTypeId, networkDeviceInfo.address().toString());
params << Param(connectionThingMacParamTypeId, networkDeviceInfo.macAddress());
descriptor.setParams(params);
info->addThingDescriptor(descriptor);
}
info->finish(Thing::ThingErrorNoError);
});
+
+ discovery->startDiscovery();
}
void IntegrationPluginFronius::setupThing(ThingSetupInfo *info)
@@ -110,8 +106,6 @@ void IntegrationPluginFronius::setupThing(ThingSetupInfo *info)
if (thing->thingClassId() == connectionThingClassId) {
- QHostAddress address(thing->paramValue(connectionThingAddressParamTypeId).toString());
-
// Handle reconfigure
if (m_froniusConnections.values().contains(thing)) {
FroniusSolarConnection *connection = m_froniusConnections.key(thing);
@@ -119,49 +113,41 @@ void IntegrationPluginFronius::setupThing(ThingSetupInfo *info)
connection->deleteLater();
}
+ if (m_monitors.contains(thing)) {
+ hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
+ }
+
+ // Set up depending on the available params, mac can only be filled in by discovery (ro param),
+ // the ip could be used as static manual config for VPN networks or WAN IP's
+ QHostAddress address(thing->paramValue(connectionThingAddressParamTypeId).toString());
+ MacAddress mac(thing->paramValue(connectionThingMacParamTypeId).toString());
+
// Create the connection
- FroniusSolarConnection *connection = new FroniusSolarConnection(hardwareManager()->networkManager(), address, thing);
+ FroniusSolarConnection *connection = nullptr;
- // Verify the version
- FroniusNetworkReply *reply = connection->getVersion();
- 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();
- if (reply->networkReply()->error() == QNetworkReply::ContentNotFoundError) {
- info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("The device does not reply to our requests. Please verify that the Fronius Solar API is enabled on the device."));
+ if (mac.isValid() && !mac.isNull()) {
+ qCInfo(dcFronius()) << "Setting up network device monitor for Fronius connection using MAC address" << mac.toString();
+ NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(mac);
+ m_monitors.insert(thing, monitor);
+
+ connection = new FroniusSolarConnection(hardwareManager()->networkManager(), monitor->networkDeviceInfo().address(), thing);
+ connect(monitor, &NetworkDeviceMonitor::networkDeviceInfoChanged, this, [=](const NetworkDeviceInfo &networkDeviceInfo){
+ qCDebug(dcFronius()) << "Network device info changed for" << thing << networkDeviceInfo;
+ if (networkDeviceInfo.isValid()) {
+ connection->setAddress(networkDeviceInfo.address());
+ refreshConnection(connection);
} else {
- info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("The device is not reachable."));
+ connection->setAddress(QHostAddress());
}
- return;
- }
-
- // Convert the rawdata to a JSON document
- QJsonParseError error;
- 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, QT_TR_NOOP("The data received from the device could not be processed because the format is unknown."));
- 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") {
- qCWarning(dcFronius()) << "The Fronius data logger has a version which is known to have a broken JSON API firmware.";
- info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("The firmware version 1.6-2 of this Fronius data logger contains errors preventing proper operation. Please update your Fronius device and try again."));
- return;
- }
-
- 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 (!address.isNull()) {
+ qCInfo(dcFronius()) << "Setting up Fronius connection based on IP address" << address.toString() << "without monitoring. Any IP changed will not be recognized and the device will be disconnected.";
+ connection = new FroniusSolarConnection(hardwareManager()->networkManager(), address, thing);
+ } else {
+ qCWarning(dcFronius()) << "Unable to set up thing" << thing << ", neither IP nor MAC is valid." << thing->params();
+ info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("Please reconfigure the device."));
+ return;
+ }
connect(connection, &FroniusSolarConnection::availableChanged, this, [=](bool available){
qCDebug(dcFronius()) << thing << "Available changed" << available;
@@ -182,6 +168,53 @@ void IntegrationPluginFronius::setupThing(ThingSetupInfo *info)
}
});
+
+ if (info->isInitialSetup()) {
+ // Verify the version
+ FroniusNetworkReply *reply = connection->getVersion();
+ 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();
+ if (reply->networkReply()->error() == QNetworkReply::ContentNotFoundError) {
+ info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("The device does not reply to our requests. Please verify that the Fronius Solar API is enabled on the device."));
+ } else {
+ info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("The device is not reachable."));
+ }
+ return;
+ }
+
+ // Convert the rawdata to a JSON document
+ QJsonParseError error;
+ 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, QT_TR_NOOP("The data received from the device could not be processed because the format is unknown."));
+ 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") {
+ qCWarning(dcFronius()) << "The Fronius data logger has a version which is known to have a broken JSON API firmware.";
+ info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("The firmware version 1.6-2 of this Fronius data logger contains errors preventing proper operation. Please update your Fronius device and try again."));
+ return;
+ }
+
+ 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 {
+ // Let the available state handle the connected state, this already worked once...
+ m_froniusConnections.insert(connection, thing);
+ info->finish(Thing::ThingErrorNoError);
+ }
} else if ((thing->thingClassId() == inverterThingClassId ||
thing->thingClassId() == meterThingClassId ||
thing->thingClassId() == storageThingClassId)) {
@@ -229,6 +262,7 @@ void IntegrationPluginFronius::postSetupThing(Thing *thing)
// Refresh now
FroniusSolarConnection *connection = m_froniusConnections.key(thing);
if (connection) {
+ thing->setStateValue("connected", connection->available());
refreshConnection(connection);
}
}
@@ -237,9 +271,15 @@ void IntegrationPluginFronius::postSetupThing(Thing *thing)
void IntegrationPluginFronius::thingRemoved(Thing *thing)
{
if (thing->thingClassId() == connectionThingClassId) {
- FroniusSolarConnection *connection = m_froniusConnections.key(thing);
- m_froniusConnections.remove(connection);
- connection->deleteLater();
+ if (m_froniusConnections.values().contains(thing)) {
+ FroniusSolarConnection *connection = m_froniusConnections.key(thing);
+ m_froniusConnections.remove(connection);
+ connection->deleteLater();
+ }
+
+ if (m_monitors.contains(thing)) {
+ hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
+ }
}
if (myThings().filterByThingClassId(connectionThingClassId).isEmpty()) {
@@ -248,7 +288,6 @@ void IntegrationPluginFronius::thingRemoved(Thing *thing)
}
}
-
void IntegrationPluginFronius::executeAction(ThingActionInfo *info)
{
Q_UNUSED(info)
@@ -261,6 +300,11 @@ void IntegrationPluginFronius::refreshConnection(FroniusSolarConnection *connect
return;
}
+ if (connection->address().isNull()) {
+ qCDebug(dcFronius()) << "Connection has no IP configured yet. Skipping refresh cycle until known";
+ return;
+ }
+
// Note: this call will be used to monitor the available state of the connection internally
FroniusNetworkReply *reply = connection->getActiveDevices();
connect(reply, &FroniusNetworkReply::finished, this, [=]() {
diff --git a/fronius/integrationpluginfronius.h b/fronius/integrationpluginfronius.h
index 70271bc0..07547ffc 100644
--- a/fronius/integrationpluginfronius.h
+++ b/fronius/integrationpluginfronius.h
@@ -31,13 +31,11 @@
#ifndef INTEGRATIONPLUGINFRONIUS_H
#define INTEGRATIONPLUGINFRONIUS_H
-#include "integrations/integrationplugin.h"
-#include "froniussolarconnection.h"
+#include
+#include
+#include
-#include
-#include
-#include
-#include
+#include "froniussolarconnection.h"
class PluginTimer;
@@ -60,6 +58,7 @@ private:
PluginTimer *m_connectionRefreshTimer = nullptr;
QHash m_froniusConnections;
+ QHash m_monitors;
void refreshConnection(FroniusSolarConnection *connection);
diff --git a/fronius/integrationpluginfronius.json b/fronius/integrationpluginfronius.json
index e2d041d0..ed0e5935 100644
--- a/fronius/integrationpluginfronius.json
+++ b/fronius/integrationpluginfronius.json
@@ -22,7 +22,7 @@
"displayName": "Host address",
"type": "QString",
"inputType": "IPv4Address",
- "defaultValue": "88.117.152.99"
+ "defaultValue": ""
},
{
"id": "2237972e-385b-4458-b5d3-1d1fb4ae8756",