Vestel: Update to networkdevice interface
This commit is contained in:
parent
6c5b875d19
commit
ef86ece542
@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2023, nymea GmbH
|
* Copyright 2013 - 2024, nymea GmbH
|
||||||
* Contact: contact@nymea.io
|
* Contact: contact@nymea.io
|
||||||
*
|
*
|
||||||
* This file is part of nymea.
|
* This file is part of nymea.
|
||||||
@ -48,13 +48,14 @@ void EVC04Discovery::startDiscovery()
|
|||||||
{
|
{
|
||||||
qCInfo(m_dc()) << "Discovery: Searching for Vestel EVC04 wallboxes in the network...";
|
qCInfo(m_dc()) << "Discovery: Searching for Vestel EVC04 wallboxes in the network...";
|
||||||
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
||||||
|
m_startDateTime = QDateTime::currentDateTime();
|
||||||
|
|
||||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &EVC04Discovery::checkNetworkDevice);
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &EVC04Discovery::checkNetworkDevice);
|
||||||
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater);
|
||||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
|
||||||
qCDebug(m_dc()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices";
|
qCDebug(m_dc()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices";
|
||||||
|
m_networkDeviceInfos = discoveryReply->networkDeviceInfos();
|
||||||
m_gracePeriodTimer.start();
|
m_gracePeriodTimer.start();
|
||||||
discoveryReply->deleteLater();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,13 +64,13 @@ QList<EVC04Discovery::Result> EVC04Discovery::discoveryResults() const
|
|||||||
return m_discoveryResults;
|
return m_discoveryResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EVC04Discovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
|
void EVC04Discovery::checkNetworkDevice(const QHostAddress &address)
|
||||||
{
|
{
|
||||||
int port = 502;
|
int port = 502;
|
||||||
int slaveId = 0xff;
|
int slaveId = 0xff;
|
||||||
qCDebug(m_dc()) << "Checking network device:" << networkDeviceInfo << "Port:" << port << "Slave ID:" << slaveId;
|
qCDebug(m_dc()) << "Discovery: Checking network device:" << address << "Port:" << port << "Slave ID:" << slaveId;
|
||||||
|
|
||||||
EVC04ModbusTcpConnection *connection = new EVC04ModbusTcpConnection(networkDeviceInfo.address(), port, slaveId, this);
|
EVC04ModbusTcpConnection *connection = new EVC04ModbusTcpConnection(address, port, slaveId, this);
|
||||||
m_connections.append(connection);
|
m_connections.append(connection);
|
||||||
|
|
||||||
connect(connection, &EVC04ModbusTcpConnection::reachableChanged, this, [=](bool reachable){
|
connect(connection, &EVC04ModbusTcpConnection::reachableChanged, this, [=](bool reachable){
|
||||||
@ -79,10 +80,10 @@ void EVC04Discovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
connect(connection, &EVC04ModbusTcpConnection::initializationFinished, this, [=](bool success){
|
connect(connection, &EVC04ModbusTcpConnection::initializationFinished, this, [=](bool success){
|
||||||
qCDebug(m_dc()) << "Discovered device on" << networkDeviceInfo.address() << connection->brand() << connection->model() << connection->firmwareVersion();
|
qCDebug(m_dc()) << "Discovery: Discovered device on" << address.toString() << connection->brand() << connection->model() << connection->firmwareVersion();
|
||||||
qCDebug(m_dc()) << connection;
|
qCDebug(m_dc()) << connection;
|
||||||
if (!success) {
|
if (!success) {
|
||||||
qCDebug(m_dc()) << "Discovery: Initialization failed on" << networkDeviceInfo.address().toString();
|
qCDebug(m_dc()) << "Discovery: Initialization failed on" << address.toString();
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -92,29 +93,28 @@ void EVC04Discovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceIn
|
|||||||
result.brand = QString(QString::fromUtf16(connection->brand().data(), connection->brand().length()).toUtf8()).trimmed();
|
result.brand = QString(QString::fromUtf16(connection->brand().data(), connection->brand().length()).toUtf8()).trimmed();
|
||||||
result.model = QString(QString::fromUtf16(connection->model().data(), connection->model().length()).toUtf8()).trimmed();
|
result.model = QString(QString::fromUtf16(connection->model().data(), connection->model().length()).toUtf8()).trimmed();
|
||||||
result.firmwareVersion = QString(QString::fromUtf16(connection->firmwareVersion().data(), connection->firmwareVersion().length()).toUtf8()).trimmed();
|
result.firmwareVersion = QString(QString::fromUtf16(connection->firmwareVersion().data(), connection->firmwareVersion().length()).toUtf8()).trimmed();
|
||||||
result.networkDeviceInfo = networkDeviceInfo;
|
result.address = address;
|
||||||
|
|
||||||
if (result.chargepointId.isEmpty() && result.brand.isEmpty() && result.model.isEmpty() && result.firmwareVersion.isEmpty()) {
|
if (result.chargepointId.isEmpty() && result.brand.isEmpty() && result.model.isEmpty() && result.firmwareVersion.isEmpty()) {
|
||||||
qCDebug(m_dc()) << "Discovery: Found modbus device with valid register set (initialized successfully), but the information seem not to be valid. This is probably some other device. Ignoring" << result.networkDeviceInfo;
|
qCDebug(m_dc()) << "Discovery: Found modbus device with valid register set (initialized successfully), but the information seem not to be valid. "
|
||||||
|
"This is probably some other device. Ignoring" << address.toString();
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_discoveryResults.append(result);
|
m_discoveryResults.append(result);
|
||||||
|
qCDebug(m_dc()) << "Discovery: Found wallbox with firmware version:" << result.firmwareVersion << address.toString();
|
||||||
qCDebug(m_dc()) << "Discovery: Found wallbox with firmware version:" << result.firmwareVersion << result.networkDeviceInfo;
|
|
||||||
|
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!connection->initialize()) {
|
if (!connection->initialize()) {
|
||||||
qCDebug(m_dc()) << "Discovery: Unable to initialize connection on" << networkDeviceInfo.address().toString();
|
qCDebug(m_dc()) << "Discovery: Unable to initialize connection on" << address.toString();
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(connection, &EVC04ModbusTcpConnection::checkReachabilityFailed, this, [=](){
|
connect(connection, &EVC04ModbusTcpConnection::checkReachabilityFailed, this, [=](){
|
||||||
qCDebug(m_dc()) << "Discovery: Checking reachability failed on" << networkDeviceInfo.address().toString();
|
qCDebug(m_dc()) << "Discovery: Checking reachability failed on" << address.toString();
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -132,12 +132,16 @@ void EVC04Discovery::finishDiscovery()
|
|||||||
{
|
{
|
||||||
qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch();
|
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
|
// Cleanup any leftovers...we don't care any more
|
||||||
foreach (EVC04ModbusTcpConnection *connection, m_connections)
|
foreach (EVC04ModbusTcpConnection *connection, m_connections)
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
|
|
||||||
qCInfo(m_dc()) << "Discovery: Finished the discovery process. Found" << m_discoveryResults.count()
|
qCInfo(m_dc()) << "Discovery: Finished the discovery process. Found" << m_discoveryResults.count()
|
||||||
<< "Vestel EVC04 wallboxes in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
|
<< "EVC04 wallboxes in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
|
||||||
m_gracePeriodTimer.stop();
|
m_gracePeriodTimer.stop();
|
||||||
|
|
||||||
emit discoveryFinished();
|
emit discoveryFinished();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2022, nymea GmbH
|
* Copyright 2013 - 2024, nymea GmbH
|
||||||
* Contact: contact@nymea.io
|
* Contact: contact@nymea.io
|
||||||
*
|
*
|
||||||
* This file is part of nymea.
|
* This file is part of nymea.
|
||||||
@ -49,6 +49,7 @@ public:
|
|||||||
QString firmwareVersion;
|
QString firmwareVersion;
|
||||||
QString brand;
|
QString brand;
|
||||||
QString model;
|
QString model;
|
||||||
|
QHostAddress address;
|
||||||
NetworkDeviceInfo networkDeviceInfo;
|
NetworkDeviceInfo networkDeviceInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,11 +67,12 @@ private:
|
|||||||
QTimer m_gracePeriodTimer;
|
QTimer m_gracePeriodTimer;
|
||||||
QDateTime m_startDateTime;
|
QDateTime m_startDateTime;
|
||||||
|
|
||||||
QList<EVC04ModbusTcpConnection*> m_connections;
|
NetworkDeviceInfos m_networkDeviceInfos;
|
||||||
|
QList<EVC04ModbusTcpConnection *> m_connections;
|
||||||
|
|
||||||
QList<Result> m_discoveryResults;
|
QList<Result> m_discoveryResults;
|
||||||
|
|
||||||
void checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo);
|
void checkNetworkDevice(const QHostAddress &address);
|
||||||
void cleanupConnection(EVC04ModbusTcpConnection *connection);
|
void cleanupConnection(EVC04ModbusTcpConnection *connection);
|
||||||
|
|
||||||
void finishDiscovery();
|
void finishDiscovery();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2022, nymea GmbH
|
* Copyright 2013 - 2024, nymea GmbH
|
||||||
* Contact: contact@nymea.io
|
* Contact: contact@nymea.io
|
||||||
*
|
*
|
||||||
* This file is part of nymea.
|
* This file is part of nymea.
|
||||||
@ -58,21 +58,25 @@ void IntegrationPluginVestel::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
ThingDescriptor descriptor(evc04ThingClassId, name, description);
|
ThingDescriptor descriptor(evc04ThingClassId, name, description);
|
||||||
qCDebug(dcVestel()) << "Discovered:" << descriptor.title() << descriptor.description();
|
qCDebug(dcVestel()) << "Discovered:" << descriptor.title() << descriptor.description();
|
||||||
|
|
||||||
|
ParamList params;
|
||||||
|
params << Param(evc04ThingMacAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress());
|
||||||
|
params << Param(evc04ThingHostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName());
|
||||||
|
params << Param(evc04ThingAddressParamTypeId, result.networkDeviceInfo.thingParamValueAddress());
|
||||||
|
descriptor.setParams(params);
|
||||||
|
|
||||||
// Check if we already have set up this device
|
// Check if we already have set up this device
|
||||||
Things existingThings = myThings().filterByParam(evc04ThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress());
|
Thing *existingThing = myThings().findByParams(params);
|
||||||
if (existingThings.count() == 1) {
|
if (existingThing) {
|
||||||
qCDebug(dcVestel()) << "This wallbox already exists in the system:" << result.networkDeviceInfo;
|
qCDebug(dcVestel()) << "This thing already exists in the system:" << existingThing << existingThing->params();
|
||||||
descriptor.setThingId(existingThings.first()->id());
|
descriptor.setThingId(existingThing->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamList params;
|
|
||||||
params << Param(evc04ThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress());
|
|
||||||
descriptor.setParams(params);
|
|
||||||
info->addThingDescriptor(descriptor);
|
info->addThingDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
info->finish(Thing::ThingErrorNoError);
|
info->finish(Thing::ThingErrorNoError);
|
||||||
});
|
});
|
||||||
|
|
||||||
discovery->startDiscovery();
|
discovery->startDiscovery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +84,7 @@ void IntegrationPluginVestel::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
void IntegrationPluginVestel::setupThing(ThingSetupInfo *info)
|
void IntegrationPluginVestel::setupThing(ThingSetupInfo *info)
|
||||||
{
|
{
|
||||||
Thing *thing = info->thing();
|
Thing *thing = info->thing();
|
||||||
qCDebug(dcVestel()) << "Setup" << thing << thing->params();
|
qCDebug(dcVestel()) << "Setting up" << thing << thing->params();
|
||||||
|
|
||||||
if (thing->thingClassId() == evc04ThingClassId) {
|
if (thing->thingClassId() == evc04ThingClassId) {
|
||||||
|
|
||||||
@ -93,36 +97,45 @@ void IntegrationPluginVestel::setupThing(ThingSetupInfo *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MacAddress macAddress = MacAddress(thing->paramValue(evc04ThingMacAddressParamTypeId).toString());
|
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(thing);
|
||||||
if (!macAddress.isValid()) {
|
if (!monitor) {
|
||||||
qCWarning(dcVestel()) << "The configured mac address is not valid" << thing->params();
|
qCWarning(dcVestel()) << "Unable to register monitor with the given params" << thing->params();
|
||||||
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The MAC address is not known. Please reconfigure the thing."));
|
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("Unable to set up the connection with this configuration, please reconfigure the connection."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(macAddress);
|
|
||||||
m_monitors.insert(thing, monitor);
|
m_monitors.insert(thing, monitor);
|
||||||
|
|
||||||
connect(info, &ThingSetupInfo::aborted, monitor, [=](){
|
connect(info, &ThingSetupInfo::aborted, monitor, [this, thing](){
|
||||||
if (m_monitors.contains(thing)) {
|
if (m_monitors.contains(thing)) {
|
||||||
qCDebug(dcVestel()) << "Unregistering monitor because setup has been aborted.";
|
qCDebug(dcVestel()) << "Unregistering monitor because setup has been aborted.";
|
||||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_evc04Connections.contains(thing)) {
|
||||||
|
qCDebug(dcVestel()) << "Clean up connection because setup has been aborted.";
|
||||||
|
m_evc04Connections.take(thing)->deleteLater();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (monitor->reachable()) {
|
// If this is the initial setup, wait for the monitor to be reachable and make sure
|
||||||
setupEVC04Connection(info);
|
// we have an IP address, otherwise let the monitor do his work
|
||||||
|
if (info->isInitialSetup()) {
|
||||||
|
// Continue with setup only if we know that the network device is reachable
|
||||||
|
if (monitor->reachable()) {
|
||||||
|
setupEVC04Connection(info);
|
||||||
|
} else {
|
||||||
|
qCDebug(dcVestel()) << "Waiting for the network monitor to get reachable before continuing to set up the connection" << thing->name() << "...";
|
||||||
|
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [this, thing, info, monitor](bool reachable){
|
||||||
|
if (reachable) {
|
||||||
|
qCDebug(dcVestel()) << "The monitor for thing setup" << thing->name() << "is now reachable. Continuing setup on" << monitor->networkDeviceInfo().address().toString();
|
||||||
|
setupEVC04Connection(info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qCDebug(dcVestel()) << "Waiting for the network monitor to get reachable before continuing to set up the connection" << thing->name() << "...";
|
setupEVC04Connection(info);
|
||||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable){
|
|
||||||
if (reachable) {
|
|
||||||
qCDebug(dcVestel()) << "The monitor for thing setup" << thing->name() << "is now reachable. Continuing setup on" << monitor->networkDeviceInfo().address().toString();
|
|
||||||
setupEVC04Connection(info);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,15 +12,32 @@
|
|||||||
"name": "evc04",
|
"name": "evc04",
|
||||||
"displayName": "EVC04",
|
"displayName": "EVC04",
|
||||||
"id": "396de19c-ef2b-4f32-b551-9d0d153304a4",
|
"id": "396de19c-ef2b-4f32-b551-9d0d153304a4",
|
||||||
"createMethods": ["discovery", "user"],
|
"createMethods": [ "discovery", "user" ],
|
||||||
"interfaces": ["evcharger", "smartmeterconsumer", "connectable"],
|
"interfaces": [ "evcharger", "smartmeterconsumer", "connectable", "networkdevice" ],
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "e7413345-6c69-4e41-8522-e0795949ef79",
|
||||||
|
"name": "hostName",
|
||||||
|
"displayName": "Host name",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextLine",
|
||||||
|
"defaultValue": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "42a27ea2-e3dc-4568-bd17-f8779dc8c135",
|
||||||
|
"name": "address",
|
||||||
|
"displayName": "IP address",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "IPv4Address",
|
||||||
|
"defaultValue": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "afdc55b7-b509-4d0c-ab79-176f2edf8488",
|
"id": "afdc55b7-b509-4d0c-ab79-176f2edf8488",
|
||||||
"name":"macAddress",
|
"name":"macAddress",
|
||||||
"displayName": "MAC address",
|
"displayName": "MAC address",
|
||||||
"type": "QString",
|
"type": "QString",
|
||||||
"inputType": "MacAddress",
|
"inputType": "MacAddress",
|
||||||
|
"readOnly": true,
|
||||||
"defaultValue": ""
|
"defaultValue": ""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user