Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PhoenixConnect: Update to networkdevice interface #197

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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: contact@nymea.io
*
* 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: contact@nymea.io
*
* 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: contact@nymea.io
*
* 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