From ffcab336abf084f86642e54b9f1693f234059297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 11 Dec 2024 16:56:37 +0100 Subject: [PATCH] Alphainnotec: Update to networkdevice interface --- .../integrationpluginalphainnotec.cpp | 145 +++++++++++------- alphainnotec/integrationpluginalphainnotec.h | 3 + .../integrationpluginalphainnotec.json | 13 +- 3 files changed, 102 insertions(+), 59 deletions(-) diff --git a/alphainnotec/integrationpluginalphainnotec.cpp b/alphainnotec/integrationpluginalphainnotec.cpp index cbdafcf8..6fd8611e 100644 --- a/alphainnotec/integrationpluginalphainnotec.cpp +++ b/alphainnotec/integrationpluginalphainnotec.cpp @@ -56,30 +56,45 @@ void IntegrationPluginAlphaInnotec::discoverThings(ThingDiscoveryInfo *info) qCDebug(dcAlphaInnotec()) << "Found" << networkDeviceInfo; QString title; - if (networkDeviceInfo.hostName().isEmpty()) { - title = networkDeviceInfo.address().toString(); - } else { - title = networkDeviceInfo.hostName() + " (" + networkDeviceInfo.address().toString() + ")"; - } - QString description; - if (networkDeviceInfo.macAddressManufacturer().isEmpty()) { - description = networkDeviceInfo.macAddress(); - } else { - description = networkDeviceInfo.macAddress() + " (" + networkDeviceInfo.macAddressManufacturer() + ")"; + + MacAddressInfo macInfo; + switch (networkDeviceInfo.monitorMode()) { + case NetworkDeviceInfo::MonitorModeMac: + macInfo = networkDeviceInfo.macAddressInfos().constFirst(); + description = networkDeviceInfo.address().toString(); + if (!macInfo.vendorName().isEmpty()) + description += " - " + networkDeviceInfo.macAddressInfos().constFirst().vendorName(); + + if (networkDeviceInfo.hostName().isEmpty()) { + title = macInfo.macAddress().toString(); + } else { + title = networkDeviceInfo.hostName() + " (" + macInfo.macAddress().toString() + ")"; + } + + break; + case NetworkDeviceInfo::MonitorModeHostName: + title = networkDeviceInfo.hostName(); + description = networkDeviceInfo.address().toString(); + break; + case NetworkDeviceInfo::MonitorModeIp: + title = networkDeviceInfo.address().toString(); + description = "Interface: " + networkDeviceInfo.networkInterface().name(); + break; } ThingDescriptor descriptor(alphaConnectThingClassId, title, description); ParamList params; - params << Param(alphaConnectThingIpAddressParamTypeId, networkDeviceInfo.address().toString()); - params << Param(alphaConnectThingMacAddressParamTypeId, networkDeviceInfo.macAddress()); + params << Param(alphaConnectThingMacAddressParamTypeId, networkDeviceInfo.thingParamValueMacAddress()); + params << Param(alphaConnectThingHostNameParamTypeId, networkDeviceInfo.thingParamValueHostName()); + params << Param(alphaConnectThingAddressParamTypeId, networkDeviceInfo.thingParamValueAddress()); descriptor.setParams(params); // Check if we already have set up this device - Things existingThings = myThings().filterByParam(alphaConnectThingMacAddressParamTypeId, networkDeviceInfo.macAddress()); - if (existingThings.count() == 1) { + Thing *existingThing = myThings().findByParams(params); + if (existingThing) { qCDebug(dcAlphaInnotec()) << "This connection already exists in the system:" << networkDeviceInfo; - descriptor.setThingId(existingThings.first()->id()); + descriptor.setThingId(existingThing->id()); } info->addThingDescriptor(descriptor); @@ -100,20 +115,35 @@ void IntegrationPluginAlphaInnotec::setupThing(ThingSetupInfo *info) qCDebug(dcAlphaInnotec()) << "Setup" << thing << thing->params(); if (thing->thingClassId() == alphaConnectThingClassId) { - QHostAddress hostAddress = QHostAddress(thing->paramValue(alphaConnectThingIpAddressParamTypeId).toString()); - if (hostAddress.isNull()) { - info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("No IP address given")); + + // Handle reconfigure + if (m_monitors.contains(thing)) + hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing)); + + NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(thing); + if (!monitor) { + info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("Unable to set up the connection with this configuration. Please reconfigure the connection.")); return; } uint port = thing->paramValue(alphaConnectThingPortParamTypeId).toUInt(); quint16 slaveId = thing->paramValue(alphaConnectThingSlaveIdParamTypeId).toUInt(); - AlphaInnotecModbusTcpConnection *alphaConnectTcpConnection = new AlphaInnotecModbusTcpConnection(hostAddress, port, slaveId, this); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::reachableChanged, this, [thing, alphaConnectTcpConnection](bool reachable){ + AlphaInnotecModbusTcpConnection *connection = new AlphaInnotecModbusTcpConnection(monitor->networkDeviceInfo().address(), port, slaveId, this); + + connect(monitor, &NetworkDeviceMonitor::networkDeviceInfoChanged, this, [=](const NetworkDeviceInfo &networkDeviceInfo){ + qCDebug(dcAlphaInnotec()) << "Network device info changed for" << thing << networkDeviceInfo; + if (networkDeviceInfo.isValid()) { + connection->modbusTcpMaster()->setHostAddress(networkDeviceInfo.address()); + } else { + connection->modbusTcpMaster()->setHostAddress(QHostAddress()); + } + }); + + connect(connection, &AlphaInnotecModbusTcpConnection::reachableChanged, this, [thing, connection](bool reachable){ qCDebug(dcAlphaInnotec()) << "Reachable changed to" << reachable << "for" << thing; if (reachable) { - alphaConnectTcpConnection->update(); + connection->update(); } thing->setStateValue(alphaConnectConnectedStateTypeId, reachable); @@ -121,92 +151,92 @@ void IntegrationPluginAlphaInnotec::setupThing(ThingSetupInfo *info) // Input registers -// connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::meanTemperatureChanged, this, [thing](float meanTemperature){ -// qCDebug(dcAlphaInnotec()) << thing << "mean temperature changed" << meanTemperature << "°C"; -// thing->setStateValue(alphaConnectMeanTemperatureStateTypeId, meanTemperature); -// }); + // connect(connection, &AlphaInnotecModbusTcpConnection::meanTemperatureChanged, this, [thing](float meanTemperature){ + // qCDebug(dcAlphaInnotec()) << thing << "mean temperature changed" << meanTemperature << "°C"; + // thing->setStateValue(alphaConnectMeanTemperatureStateTypeId, meanTemperature); + // }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::flowTemperatureChanged, this, [thing](float flowTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::flowTemperatureChanged, this, [thing](float flowTemperature){ qCDebug(dcAlphaInnotec()) << thing << "flow temperature changed" << flowTemperature << "°C"; thing->setStateValue(alphaConnectFlowTemperatureStateTypeId, flowTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::returnTemperatureChanged, this, [thing](float returnTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::returnTemperatureChanged, this, [thing](float returnTemperature){ qCDebug(dcAlphaInnotec()) << thing << "return temperature changed" << returnTemperature << "°C"; thing->setStateValue(alphaConnectReturnTemperatureStateTypeId, returnTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::externalReturnTemperatureChanged, this, [thing](float externalReturnTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::externalReturnTemperatureChanged, this, [thing](float externalReturnTemperature){ qCDebug(dcAlphaInnotec()) << thing << "external return temperature changed" << externalReturnTemperature << "°C"; thing->setStateValue(alphaConnectExternalReturnTemperatureStateTypeId, externalReturnTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::hotWaterTemperatureChanged, this, [thing](float hotWaterTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::hotWaterTemperatureChanged, this, [thing](float hotWaterTemperature){ qCDebug(dcAlphaInnotec()) << thing << "hot water temperature changed" << hotWaterTemperature << "°C"; thing->setStateValue(alphaConnectHotWaterTemperatureStateTypeId, hotWaterTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::hotGasTemperatureChanged, this, [thing](float hotGasTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::hotGasTemperatureChanged, this, [thing](float hotGasTemperature){ qCDebug(dcAlphaInnotec()) << thing << "hot gas temperature changed" << hotGasTemperature << "°C"; thing->setStateValue(alphaConnectHotGasTemperatureStateTypeId, hotGasTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::heatSourceInletTemperatureChanged, this, [thing](float heatSourceInletTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::heatSourceInletTemperatureChanged, this, [thing](float heatSourceInletTemperature){ qCDebug(dcAlphaInnotec()) << thing << "heat source inlet temperature changed" << heatSourceInletTemperature << "°C"; thing->setStateValue(alphaConnectHeatSourceInletTemperatureStateTypeId, heatSourceInletTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::heatSourceOutletTemperatureChanged, this, [thing](float heatSourceOutletTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::heatSourceOutletTemperatureChanged, this, [thing](float heatSourceOutletTemperature){ qCDebug(dcAlphaInnotec()) << thing << "heat source outlet temperature changed" << heatSourceOutletTemperature << "°C"; thing->setStateValue(alphaConnectHeatSourceOutletTemperatureStateTypeId, heatSourceOutletTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::roomTemperature1Changed, this, [thing](float roomTemperature1){ + connect(connection, &AlphaInnotecModbusTcpConnection::roomTemperature1Changed, this, [thing](float roomTemperature1){ qCDebug(dcAlphaInnotec()) << thing << "room remote adjuster 1 temperature changed" << roomTemperature1 << "°C"; thing->setStateValue(alphaConnectRoomTemperature1StateTypeId, roomTemperature1); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::roomTemperature2Changed, this, [thing](float roomTemperature2){ + connect(connection, &AlphaInnotecModbusTcpConnection::roomTemperature2Changed, this, [thing](float roomTemperature2){ qCDebug(dcAlphaInnotec()) << thing << "room remote adjuster 2 temperature changed" << roomTemperature2 << "°C"; thing->setStateValue(alphaConnectRoomTemperature2StateTypeId, roomTemperature2); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::roomTemperature3Changed, this, [thing](float roomTemperature3){ + connect(connection, &AlphaInnotecModbusTcpConnection::roomTemperature3Changed, this, [thing](float roomTemperature3){ qCDebug(dcAlphaInnotec()) << thing << "room remote adjuster 3 temperature changed" << roomTemperature3 << "°C"; thing->setStateValue(alphaConnectRoomTemperature2StateTypeId, roomTemperature3); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::solarCollectorTemperatureChanged, this, [thing](float solarCollectorTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::solarCollectorTemperatureChanged, this, [thing](float solarCollectorTemperature){ qCDebug(dcAlphaInnotec()) << thing << "solar collector temperature changed" << solarCollectorTemperature << "°C"; thing->setStateValue(alphaConnectSolarCollectorTemperatureStateTypeId, solarCollectorTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::solarStorageTankTemperatureChanged, this, [thing](float solarStorageTankTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::solarStorageTankTemperatureChanged, this, [thing](float solarStorageTankTemperature){ qCDebug(dcAlphaInnotec()) << thing << "solar storage tank temperature changed" << solarStorageTankTemperature << "°C"; thing->setStateValue(alphaConnectSolarCollectorTemperatureStateTypeId, solarStorageTankTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::externalEnergySourceTemperatureChanged, this, [thing](float externalEnergySourceTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::externalEnergySourceTemperatureChanged, this, [thing](float externalEnergySourceTemperature){ qCDebug(dcAlphaInnotec()) << thing << "external energy source temperature changed" << externalEnergySourceTemperature << "°C"; thing->setStateValue(alphaConnectExternalEnergySourceTemperatureStateTypeId, externalEnergySourceTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::supplyAirTemperatureChanged, this, [thing](float supplyAirTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::supplyAirTemperatureChanged, this, [thing](float supplyAirTemperature){ qCDebug(dcAlphaInnotec()) << thing << "supply air temperature changed" << supplyAirTemperature << "°C"; thing->setStateValue(alphaConnectSupplyAirTemperatureStateTypeId, supplyAirTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::externalAirTemperatureChanged, this, [thing](float externalAirTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::externalAirTemperatureChanged, this, [thing](float externalAirTemperature){ qCDebug(dcAlphaInnotec()) << thing << "external air temperature changed" << externalAirTemperature << "°C"; thing->setStateValue(alphaConnectExternalAirTemperatureStateTypeId, externalAirTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::heatingPumpOperatingHoursChanged, this, [thing](quint16 heatingPumpOperatingHours){ + connect(connection, &AlphaInnotecModbusTcpConnection::heatingPumpOperatingHoursChanged, this, [thing](quint16 heatingPumpOperatingHours){ qCDebug(dcAlphaInnotec()) << thing << "heating pump operating hours changed" << heatingPumpOperatingHours; thing->setStateValue(alphaConnectHeatingPumpOperatingHoursStateTypeId, heatingPumpOperatingHours); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::systemStatusChanged, this, [thing](AlphaInnotecModbusTcpConnection::SystemStatus systemStatus){ + connect(connection, &AlphaInnotecModbusTcpConnection::systemStatusChanged, this, [thing](AlphaInnotecModbusTcpConnection::SystemStatus systemStatus){ qCDebug(dcAlphaInnotec()) << thing << "system status changed" << systemStatus; switch (systemStatus) { case AlphaInnotecModbusTcpConnection::SystemStatusHeatingMode: @@ -241,43 +271,43 @@ void IntegrationPluginAlphaInnotec::setupThing(ThingSetupInfo *info) }); // Energy - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::totalHeatEnergyChanged, this, [thing](float totalHeatEnergy){ + connect(connection, &AlphaInnotecModbusTcpConnection::totalHeatEnergyChanged, this, [thing](float totalHeatEnergy){ qCDebug(dcAlphaInnotec()) << thing << "total heating energy changed" << totalHeatEnergy << "kWh"; thing->setStateValue(alphaConnectTotalEnergyStateTypeId, totalHeatEnergy); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::heatingEnergyChanged, this, [thing](float heatingEnergy){ + connect(connection, &AlphaInnotecModbusTcpConnection::heatingEnergyChanged, this, [thing](float heatingEnergy){ qCDebug(dcAlphaInnotec()) << thing << "heating energy changed" << heatingEnergy << "kWh"; thing->setStateValue(alphaConnectHeatingEnergyStateTypeId, heatingEnergy); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::waterHeatEnergyChanged, this, [thing](float waterHeatEnergy){ + connect(connection, &AlphaInnotecModbusTcpConnection::waterHeatEnergyChanged, this, [thing](float waterHeatEnergy){ qCDebug(dcAlphaInnotec()) << thing << "water heat energy changed" << waterHeatEnergy << "kWh"; thing->setStateValue(alphaConnectHotWaterEnergyStateTypeId, waterHeatEnergy); }); -// connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::swimmingPoolHeatEnergyChanged, this, [thing](float swimmingPoolHeatEnergy){ -// qCDebug(dcAlphaInnotec()) << thing << "swimming pool heat energy changed" << swimmingPoolHeatEnergy << "kWh"; -// thing->setStateValue(alphaConnectSwimmingPoolEnergyStateTypeId, swimmingPoolHeatEnergy); -// }); + // connect(connection, &AlphaInnotecModbusTcpConnection::swimmingPoolHeatEnergyChanged, this, [thing](float swimmingPoolHeatEnergy){ + // qCDebug(dcAlphaInnotec()) << thing << "swimming pool heat energy changed" << swimmingPoolHeatEnergy << "kWh"; + // thing->setStateValue(alphaConnectSwimmingPoolEnergyStateTypeId, swimmingPoolHeatEnergy); + // }); // Holding registers - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::outdoorTemperatureChanged, this, [thing](float outdoorTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::outdoorTemperatureChanged, this, [thing](float outdoorTemperature){ qCDebug(dcAlphaInnotec()) << thing << "outdoor temperature changed" << outdoorTemperature << "°C"; thing->setStateValue(alphaConnectOutdoorTemperatureStateTypeId, outdoorTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::returnSetpointTemperatureChanged, this, [thing](float returnSetpointTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::returnSetpointTemperatureChanged, this, [thing](float returnSetpointTemperature){ qCDebug(dcAlphaInnotec()) << thing << "return setpoint temperature changed" << returnSetpointTemperature << "°C"; thing->setStateValue(alphaConnectReturnSetpointTemperatureStateTypeId, returnSetpointTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::hotWaterSetpointTemperatureChanged, this, [thing](float hotWaterSetpointTemperature){ + connect(connection, &AlphaInnotecModbusTcpConnection::hotWaterSetpointTemperatureChanged, this, [thing](float hotWaterSetpointTemperature){ qCDebug(dcAlphaInnotec()) << thing << "hot water setpoint temperature changed" << hotWaterSetpointTemperature << "°C"; thing->setStateValue(alphaConnectHotWaterSetpointTemperatureStateTypeId, hotWaterSetpointTemperature); }); - connect(alphaConnectTcpConnection, &AlphaInnotecModbusTcpConnection::smartGridChanged, this, [thing](AlphaInnotecModbusTcpConnection::SmartGridState smartGridState){ + connect(connection, &AlphaInnotecModbusTcpConnection::smartGridChanged, this, [thing](AlphaInnotecModbusTcpConnection::SmartGridState smartGridState){ qCDebug(dcAlphaInnotec()) << thing << "smart grid state changed" << smartGridState; switch (smartGridState) { case AlphaInnotecModbusTcpConnection::SmartGridStateOff: @@ -295,8 +325,8 @@ void IntegrationPluginAlphaInnotec::setupThing(ThingSetupInfo *info) } }); - m_connections.insert(thing, alphaConnectTcpConnection); - alphaConnectTcpConnection->connectDevice(); + m_connections.insert(thing, connection); + connection->connectDevice(); // FIXME: make async and check if this is really an alpha connect info->finish(Thing::ThingErrorNoError); @@ -329,6 +359,9 @@ void IntegrationPluginAlphaInnotec::thingRemoved(Thing *thing) delete connection; } + if (m_monitors.contains(thing)) + hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing)); + if (myThings().isEmpty() && m_pluginTimer) { hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); m_pluginTimer = nullptr; @@ -347,7 +380,7 @@ void IntegrationPluginAlphaInnotec::executeAction(ThingActionInfo *info) } if (thing->thingClassId() == alphaConnectThingClassId) { - /* if (info->action().actionTypeId() == alphaConnectOutdoorTemperatureActionTypeId) { + /* if (info->action().actionTypeId() == alphaConnectOutdoorTemperatureActionTypeId) { double outdoorTemperature = info->action().paramValue(alphaConnectOutdoorTemperatureActionOutdoorTemperatureParamTypeId).toDouble(); qCDebug(dcAlphaInnotec()) << "Execute action" << info->action().actionTypeId().toString() << info->action().params(); QModbusReply *reply = connection->setOutdoorTemperature(outdoorTemperature); diff --git a/alphainnotec/integrationpluginalphainnotec.h b/alphainnotec/integrationpluginalphainnotec.h index 8f94c4a2..3db23e5a 100644 --- a/alphainnotec/integrationpluginalphainnotec.h +++ b/alphainnotec/integrationpluginalphainnotec.h @@ -36,6 +36,8 @@ #include "alphainnotecmodbustcpconnection.h" +class NetworkDeviceMonitor; + class IntegrationPluginAlphaInnotec: public IntegrationPlugin { Q_OBJECT @@ -56,6 +58,7 @@ class IntegrationPluginAlphaInnotec: public IntegrationPlugin private: PluginTimer *m_pluginTimer = nullptr; QHash m_connections; + QHash m_monitors; }; #endif // INTEGRATIONPLUGINALPHAINNOTEC_H diff --git a/alphainnotec/integrationpluginalphainnotec.json b/alphainnotec/integrationpluginalphainnotec.json index 14990a49..5399bdc9 100644 --- a/alphainnotec/integrationpluginalphainnotec.json +++ b/alphainnotec/integrationpluginalphainnotec.json @@ -13,15 +13,22 @@ "displayName": "alpha connect", "id": "c5437b68-cfd2-4ec8-bad6-006fb5e8a8da", "createMethods": ["discovery", "user"], - "interfaces": ["smartgridheatpump", "connectable"], + "interfaces": ["smartgridheatpump", "connectable", "networkdevice"], "paramTypes": [ { "id": "64a18910-9111-4eaf-986d-f7b64b03b99a", - "name": "ipAddress", + "name": "address", "displayName": "IP address", "type": "QString", "inputType": "IPv4Address", - "defaultValue": "127.0.0.1" + "defaultValue": "" + }, + { + "id": "f8d3b955-9560-492d-b32f-f89c69be1dec", + "name": "hostName", + "displayName": "Host name", + "type": "QString", + "defaultValue": "" }, { "id": "f791c219-98a5-41ee-8e5f-1bfb5136dc9c",