Skip to content

Commit

Permalink
Merge PR #197: PhoenixConnect: Update to networkdevice interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jenkins committed Feb 5, 2025
2 parents fb9f36f + cfe4dc8 commit 720e528
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 46 deletions.
33 changes: 20 additions & 13 deletions phoenixconnect/integrationpluginphoenixconnect.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Copyright 2013 - 2024, nymea GmbH
* Contact: [email protected]
*
* This file is part of nymea.
Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion phoenixconnect/integrationpluginphoenixconnect.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Copyright 2013 - 2024, nymea GmbH
* Contact: [email protected]
*
* This file is part of nymea.
Expand Down
126 changes: 114 additions & 12 deletions phoenixconnect/integrationpluginphoenixconnect.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down Expand Up @@ -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":[
Expand Down Expand Up @@ -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": [
Expand Down Expand Up @@ -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":[
Expand Down Expand Up @@ -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": [
Expand Down Expand Up @@ -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":[
Expand Down
35 changes: 18 additions & 17 deletions phoenixconnect/phoenixdiscovery.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Copyright 2013 - 2024, nymea GmbH
* Contact: [email protected]
*
* This file is part of nymea.
Expand Down Expand Up @@ -46,14 +46,15 @@ PhoenixDiscovery::PhoenixDiscovery(NetworkDeviceDiscovery *networkDeviceDiscover
void PhoenixDiscovery::startDiscovery()
{
qCInfo(dcPhoenixConnect()) << "Discovery: Searching for PhoenixConnect wallboxes in the network...";
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();

connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &PhoenixDiscovery::checkNetworkDevice);
m_startDateTime = QDateTime::currentDateTime();

NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
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();
});
}

Expand All @@ -62,17 +63,14 @@ QList<PhoenixDiscovery::Result> 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){
Expand All @@ -83,15 +81,15 @@ 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;
}
Result result;
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;
Expand All @@ -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);
});

Expand All @@ -124,13 +122,16 @@ 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);

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();
}
Loading

0 comments on commit 720e528

Please sign in to comment.