From cfe4dc84e561d2a9788b81814ad434654c653809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 18 Dec 2024 11:35:10 +0100 Subject: [PATCH] PhoenixConnect: Update to networkdevice interface --- .../integrationpluginphoenixconnect.cpp | 33 +++-- .../integrationpluginphoenixconnect.h | 2 +- .../integrationpluginphoenixconnect.json | 126 ++++++++++++++++-- phoenixconnect/phoenixdiscovery.cpp | 35 ++--- phoenixconnect/phoenixdiscovery.h | 7 +- 5 files changed, 157 insertions(+), 46 deletions(-) diff --git a/phoenixconnect/integrationpluginphoenixconnect.cpp b/phoenixconnect/integrationpluginphoenixconnect.cpp index 9e37ee9..33bace5 100644 --- a/phoenixconnect/integrationpluginphoenixconnect.cpp +++ b/phoenixconnect/integrationpluginphoenixconnect.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2024, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -66,16 +66,24 @@ void IntegrationPluginPhoenixConnect::discoverThings(ThingDiscoveryInfo *info) ThingDescriptor descriptor(info->thingClassId(), name, description); qCDebug(dcPhoenixConnect()) << "Discovered:" << descriptor.title() << descriptor.description(); - ParamTypeId macParamTypeId = supportedThings().findById(info->thingClassId()).paramTypes().findByName("mac").id(); - Things existingThings = myThings().filterByParam(macParamTypeId, result.networkDeviceInfo.macAddress()); - if (existingThings.count() == 1) { - qCDebug(dcPhoenixConnect()) << "This wallbox already exists in the system:" << result.networkDeviceInfo; - descriptor.setThingId(existingThings.first()->id()); - } + ParamTypeId macAddressParamTypeId = supportedThings().findById(info->thingClassId()).paramTypes().findByName("macAddress").id(); + ParamTypeId hostNameParamTypeId = supportedThings().findById(info->thingClassId()).paramTypes().findByName("hostName").id(); + ParamTypeId addressParamTypeId = supportedThings().findById(info->thingClassId()).paramTypes().findByName("address").id(); ParamList params; - params << Param(macParamTypeId, result.networkDeviceInfo.macAddress()); + params << Param(macAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress()); + params << Param(hostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName()); + params << Param(addressParamTypeId, result.networkDeviceInfo.thingParamValueAddress()); descriptor.setParams(params); + + // Check if we already have set up this device + // FIXME: maybe we should save the serialnumber as parameter in order to identify already known devices + Thing *existingThing = myThings().findByParams(params); + if (existingThing) { + qCDebug(dcPhoenixConnect()) << "This wallbox already exists in the system:" << result.networkDeviceInfo; + descriptor.setThingId(existingThing->id()); + } + info->addThingDescriptor(descriptor); } @@ -96,13 +104,12 @@ void IntegrationPluginPhoenixConnect::setupThing(ThingSetupInfo *info) qCDebug(dcPhoenixConnect()) << "Setting up a new device:" << thing->params(); } - - MacAddress mac = MacAddress(thing->paramValue("mac").toString()); - if (!mac.isValid()) { - info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The given MAC address is not valid.")); + NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(thing); + if (!monitor) { + qCWarning(dcPhoenixConnect()) << "Unable to create monitor with the given parameters" << thing->params(); + info->finish(Thing::ThingErrorInvalidParameter); return; } - NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(mac); PhoenixModbusTcpConnection *connection = new PhoenixModbusTcpConnection(monitor->networkDeviceInfo().address(), 502, 255, this); connect(info, &ThingSetupInfo::aborted, connection, &PhoenixModbusTcpConnection::deleteLater); diff --git a/phoenixconnect/integrationpluginphoenixconnect.h b/phoenixconnect/integrationpluginphoenixconnect.h index e44bf31..780fd0e 100644 --- a/phoenixconnect/integrationpluginphoenixconnect.h +++ b/phoenixconnect/integrationpluginphoenixconnect.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2022, nymea GmbH +* Copyright 2013 - 2024, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/phoenixconnect/integrationpluginphoenixconnect.json b/phoenixconnect/integrationpluginphoenixconnect.json index 8e86b93..ad92279 100644 --- a/phoenixconnect/integrationpluginphoenixconnect.json +++ b/phoenixconnect/integrationpluginphoenixconnect.json @@ -14,15 +14,32 @@ "name": "wallbeEco2", "createMethods": ["discovery", "user"], "discoveryType": "weak", - "interfaces": ["evcharger", "connectable"], + "interfaces": ["evcharger", "connectable", "networkdevice"], "paramTypes": [ { "id": "551b03f0-dd70-4463-929b-3668dbd3290f", "displayName": "MAC address", - "name": "mac", + "name": "macAddress", "type": "QString", + "inputType": "MacAddress", "defaultValue": "", "readOnly": true + }, + { + "id": "cdddb9c0-b243-4b51-8e27-7c323eb4866f", + "name": "address", + "displayName": "Host address", + "type": "QString", + "inputType": "IPv4Address", + "defaultValue": "" + }, + { + "id": "191faa5b-09dc-47ae-8ebe-39301ecdaf87", + "name": "hostName", + "displayName": "Host name", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "" } ], "settingsTypes": [ @@ -120,15 +137,32 @@ "name": "wallbePro", "createMethods": ["discovery", "user"], "discoveryType": "weak", - "interfaces": ["evcharger", "smartmeterconsumer", "connectable"], + "interfaces": ["evcharger", "smartmeterconsumer", "connectable", "networkdevice"], "paramTypes": [ { "id": "71a147c7-a87c-45e0-9e91-657d5c7fd0cd", "displayName": "MAC address", - "name": "mac", + "name": "macAddress", "type": "QString", + "inputType": "MacAddress", "defaultValue": "", "readOnly": true + }, + { + "id": "996dfe24-c15f-460d-ab83-cc924024171c", + "name": "address", + "displayName": "Host address", + "type": "QString", + "inputType": "IPv4Address", + "defaultValue": "" + }, + { + "id": "b142f726-8d1f-4e50-aee3-5725c1ddd4e0", + "name": "hostName", + "displayName": "Host name", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "" } ], "stateTypes":[ @@ -242,15 +276,32 @@ "name": "compleoEcoS", "createMethods": ["discovery", "user"], "discoveryType": "weak", - "interfaces": ["evcharger", "connectable"], + "interfaces": ["evcharger", "connectable", "networkdevice"], "paramTypes": [ { "id": "d65aa536-e60d-4e0d-986c-80c1023e0e81", "displayName": "MAC address", - "name": "mac", + "name": "macAddress", "type": "QString", + "inputType": "MacAddress", "defaultValue": "", "readOnly": true + }, + { + "id": "01eb59fd-7022-4511-999d-16b87e68b6b5", + "name": "address", + "displayName": "Host address", + "type": "QString", + "inputType": "IPv4Address", + "defaultValue": "" + }, + { + "id": "89d358bf-d072-4b83-92ff-c6a46a4b5e6d", + "name": "hostName", + "displayName": "Host name", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "" } ], "settingsTypes": [ @@ -348,15 +399,32 @@ "name": "compleoPro", "createMethods": ["discovery", "user"], "discoveryType": "weak", - "interfaces": ["evcharger", "smartmeterconsumer", "connectable"], + "interfaces": ["evcharger", "smartmeterconsumer", "connectable", "networkdevice"], "paramTypes": [ { "id": "e7ca8712-4a4a-44e8-a36b-233486acd687", "displayName": "MAC address", - "name": "mac", + "name": "macAddress", "type": "QString", + "inputType": "MacAddress", "defaultValue": "", "readOnly": true + }, + { + "id": "26769f5b-8c10-4bf1-a1e4-d20ef6ebd588", + "name": "address", + "displayName": "Host address", + "type": "QString", + "inputType": "IPv4Address", + "defaultValue": "" + }, + { + "id": "d4c00762-dd9b-43c9-8d8c-a1ffd435a46a", + "name": "hostName", + "displayName": "Host name", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "" } ], "stateTypes":[ @@ -470,15 +538,32 @@ "name": "scapoEco", "createMethods": ["discovery", "user"], "discoveryType": "weak", - "interfaces": ["evcharger", "connectable"], + "interfaces": ["evcharger", "connectable", "networkdevice"], "paramTypes": [ { "id": "2b544329-4d59-4974-8c3d-8b6aadf26c2c", "displayName": "MAC address", - "name": "mac", + "name": "macAddress", "type": "QString", + "inputType": "MacAddress", "defaultValue": "", "readOnly": true + }, + { + "id": "9a7bd593-c8c7-4108-816b-8122fca097dd", + "name": "address", + "displayName": "Host address", + "type": "QString", + "inputType": "IPv4Address", + "defaultValue": "" + }, + { + "id": "cbe4f47c-1fda-4283-a393-be479fd40caa", + "name": "hostName", + "displayName": "Host name", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "" } ], "settingsTypes": [ @@ -576,15 +661,32 @@ "name": "scapoVision", "createMethods": ["discovery", "user"], "discoveryType": "weak", - "interfaces": ["evcharger", "smartmeterconsumer", "connectable"], + "interfaces": ["evcharger", "smartmeterconsumer", "connectable", "networkdevice"], "paramTypes": [ { "id": "8a0a3c7c-1197-4c55-8a7d-ee87587235bd", "displayName": "MAC address", - "name": "mac", + "name": "macAddress", "type": "QString", + "inputType": "MacAddress", "defaultValue": "", "readOnly": true + }, + { + "id": "02e91e87-2509-4ae3-97ef-2d12280bab1b", + "name": "address", + "displayName": "Host address", + "type": "QString", + "inputType": "IPv4Address", + "defaultValue": "" + }, + { + "id": "7785006e-1fe0-450a-a10a-7f619c50b028", + "name": "hostName", + "displayName": "Host name", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "" } ], "stateTypes":[ diff --git a/phoenixconnect/phoenixdiscovery.cpp b/phoenixconnect/phoenixdiscovery.cpp index 4b67db4..93d2d37 100644 --- a/phoenixconnect/phoenixdiscovery.cpp +++ b/phoenixconnect/phoenixdiscovery.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2022, nymea GmbH +* Copyright 2013 - 2024, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -46,14 +46,15 @@ PhoenixDiscovery::PhoenixDiscovery(NetworkDeviceDiscovery *networkDeviceDiscover void PhoenixDiscovery::startDiscovery() { qCInfo(dcPhoenixConnect()) << "Discovery: Searching for PhoenixConnect wallboxes in the network..."; + m_startDateTime = QDateTime::currentDateTime(); + NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover(); - - connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &PhoenixDiscovery::checkNetworkDevice); - + connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &PhoenixDiscovery::checkNetworkDevice); connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){ qCDebug(dcPhoenixConnect()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices"; - m_gracePeriodTimer.start(); + m_networkDeviceInfos = discoveryReply->networkDeviceInfos(); discoveryReply->deleteLater(); + m_gracePeriodTimer.start(); }); } @@ -62,17 +63,14 @@ QList PhoenixDiscovery::discoveryResults() const return m_discoveryResults; } -void PhoenixDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo) +void PhoenixDiscovery::checkNetworkDevice(const QHostAddress &address) { -// if (networkDeviceInfo.macAddressManufacturer() != "wallbe GmbH" && networkDeviceInfo.macAddressManufacturer() != "Phoenix") { -// return; -// } - int port = 502; int slaveId = 0xff; - qCDebug(dcPhoenixConnect()) << "Checking network device:" << networkDeviceInfo << "Port:" << port << "Slave ID:" << slaveId; - PhoenixModbusTcpConnection *connection = new PhoenixModbusTcpConnection(networkDeviceInfo.address(), port, slaveId, this); + qCDebug(dcPhoenixConnect()) << "Discovery: Checking network device:" << address << "Port:" << port << "Slave ID:" << slaveId; + + PhoenixModbusTcpConnection *connection = new PhoenixModbusTcpConnection(address, port, slaveId, this); m_connections.append(connection); connect(connection, &PhoenixModbusTcpConnection::reachableChanged, this, [=](bool reachable){ @@ -83,7 +81,7 @@ void PhoenixDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevice connect(connection, &PhoenixModbusTcpConnection::initializationFinished, this, [=](bool success){ if (!success) { - qCDebug(dcPhoenixConnect()) << "Discovery: Initialization failed on" << networkDeviceInfo.address().toString(); + qCDebug(dcPhoenixConnect()) << "Discovery: Initialization failed on" << address.toString(); cleanupConnection(connection); return; } @@ -91,7 +89,7 @@ void PhoenixDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevice result.firmwareVersion = connection->firmwareVersion(); result.model = connection->deviceName(); result.serialNumber = connection->serial(); - result.networkDeviceInfo = networkDeviceInfo; + result.address = address; m_discoveryResults.append(result); qCDebug(dcPhoenixConnect()) << "Discovery: Found wallbox with firmware version:" << result.firmwareVersion << result.networkDeviceInfo; @@ -100,13 +98,13 @@ void PhoenixDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevice }); if (!connection->initialize()) { - qCDebug(dcPhoenixConnect()) << "Discovery: Unable to initialize connection on" << networkDeviceInfo.address().toString(); + qCDebug(dcPhoenixConnect()) << "Discovery: Unable to initialize connection on" << address.toString(); cleanupConnection(connection); } }); connect(connection, &PhoenixModbusTcpConnection::checkReachabilityFailed, this, [=](){ - qCDebug(dcPhoenixConnect()) << "Discovery: Checking reachability failed on" << networkDeviceInfo.address().toString(); + qCDebug(dcPhoenixConnect()) << "Discovery: Checking reachability failed on" << address.toString(); cleanupConnection(connection); }); @@ -124,6 +122,10 @@ void PhoenixDiscovery::finishDiscovery() { qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch(); + // Fill in all network device infos we have + for (int i = 0; i < m_discoveryResults.count(); i++) + m_discoveryResults[i].networkDeviceInfo = m_networkDeviceInfos.get(m_discoveryResults.at(i).address); + // Cleanup any leftovers...we don't care any more foreach (PhoenixModbusTcpConnection *connection, m_connections) cleanupConnection(connection); @@ -131,6 +133,5 @@ void PhoenixDiscovery::finishDiscovery() qCInfo(dcPhoenixConnect()) << "Discovery: Finished the discovery process. Found" << m_discoveryResults.count() << "Phoenix connect wallboxes in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz"); m_gracePeriodTimer.stop(); - emit discoveryFinished(); } diff --git a/phoenixconnect/phoenixdiscovery.h b/phoenixconnect/phoenixdiscovery.h index e5665f0..509fdeb 100644 --- a/phoenixconnect/phoenixdiscovery.h +++ b/phoenixconnect/phoenixdiscovery.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2022, nymea GmbH +* Copyright 2013 - 2024, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -47,6 +47,7 @@ public: QString firmwareVersion; QString model; QString serialNumber; + QHostAddress address; NetworkDeviceInfo networkDeviceInfo; }; @@ -62,12 +63,12 @@ private: QTimer m_gracePeriodTimer; QDateTime m_startDateTime; - + NetworkDeviceInfos m_networkDeviceInfos; QList m_connections; QList m_discoveryResults; - void checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo); + void checkNetworkDevice(const QHostAddress &address); void cleanupConnection(PhoenixModbusTcpConnection *connection); void finishDiscovery();