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

PC-Electric: Update to networkdevice interface #196

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
19 changes: 10 additions & 9 deletions pcelectric/integrationpluginpcelectric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,16 @@ void IntegrationPluginPcElectric::discoverThings(ThingDiscoveryInfo *info)
qCDebug(dcPcElectric()) << "Discovered:" << descriptor.title() << descriptor.description();

// Check if we already have set up this device
Things existingThings = myThings().filterByParam(ev11ThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress());
Things existingThings = myThings().filterByParam(ev11ThingSerialNumberParamTypeId, result.serialNumber);
if (existingThings.count() == 1) {
qCDebug(dcPcElectric()) << "This PCE wallbox already exists in the system:" << result.networkDeviceInfo;
qCDebug(dcPcElectric()) << "This PCE wallbox already exists in the system:" << result.serialNumber << result.networkDeviceInfo;
descriptor.setThingId(existingThings.first()->id());
}

ParamList params;
params << Param(ev11ThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress());
params << Param(ev11ThingMacAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress());
params << Param(ev11ThingHostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName());
params << Param(ev11ThingAddressParamTypeId, result.networkDeviceInfo.thingParamValueAddress());
params << Param(ev11ThingSerialNumberParamTypeId, result.serialNumber);
// Note: if we discover also the port and modbusaddress, we must fill them in from the discovery here, for now everywhere the defaults...
descriptor.setParams(params);
Expand Down Expand Up @@ -97,14 +99,13 @@ void IntegrationPluginPcElectric::setupThing(ThingSetupInfo *info)
}
}

MacAddress macAddress = MacAddress(thing->paramValue(ev11ThingMacAddressParamTypeId).toString());
if (!macAddress.isValid()) {
qCWarning(dcPcElectric()) << "The configured mac address is not valid" << thing->params();
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The MAC address is not known. Please reconfigure the thing."));
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(thing);
if (!monitor) {
qCWarning(dcPcElectric()) << "Could not create a valid network device monitor for the given parameters" << thing->params();
info->finish(Thing::ThingErrorInvalidParameter);
return;
}

NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(macAddress);
m_monitors.insert(thing, monitor);

connect(info, &ThingSetupInfo::aborted, monitor, [=](){
Expand Down Expand Up @@ -285,7 +286,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
Thing *thing = info->thing();
NetworkDeviceMonitor *monitor = m_monitors.value(thing);

qCDebug(dcPcElectric()) << "Setting up PCE wallbox finished successfully" << monitor->networkDeviceInfo().address().toString();
qCDebug(dcPcElectric()) << "Setting up PCE wallbox using" << monitor->networkDeviceInfo().address().toString();

PceWallbox *connection = new PceWallbox(monitor->networkDeviceInfo().address(), 502, 1, this);
connect(info, &ThingSetupInfo::aborted, connection, &PceWallbox::deleteLater);
Expand Down
18 changes: 17 additions & 1 deletion pcelectric/integrationpluginpcelectric.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,24 @@
"displayName": "PCE EV11.3",
"id": "88d96940-a940-4a07-8176-5e6aba7ca832",
"createMethods": ["discovery", "user"],
"interfaces": ["evcharger", "connectable"],
"interfaces": ["evcharger", "connectable", "networkdevice"],
"paramTypes": [
{
"id": "aa18f1ae-e2d5-4918-9230-ab3f6fb49010",
"name": "address",
"displayName": "Host address",
"type": "QString",
"inputType": "IPv4Address",
"defaultValue": ""
},
{
"id": "a8b81e4a-f4ec-479b-9cb8-19147759c4cc",
"name": "hostName",
"displayName": "Host name",
"type": "QString",
"inputType": "TextLine",
"defaultValue": ""
},
{
"id": "0a3f8d12-9d33-4ae2-b763-9568f32e8da1",
"name":"macAddress",
Expand Down
51 changes: 36 additions & 15 deletions pcelectric/pcelectricdiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@ void PcElectricDiscovery::startDiscovery()
m_startDateTime = QDateTime::currentDateTime();

NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &PcElectricDiscovery::checkNetworkDevice);
connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &PcElectricDiscovery::checkNetworkDevice);
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater);
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){

m_networkDeviceInfos = discoveryReply->networkDeviceInfos();

// Finish with some delay so the last added network device information objects still can be checked.
QTimer::singleShot(3000, this, [this](){
qCDebug(dcPcElectric()) << "Discovery: Grace period timer triggered.";
Expand All @@ -63,9 +66,9 @@ void PcElectricDiscovery::startDiscovery()
});
}

void PcElectricDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address)
{
EV11ModbusTcpConnection *connection = new EV11ModbusTcpConnection(networkDeviceInfo.address(), m_port, m_modbusAddress, this);
EV11ModbusTcpConnection *connection = new EV11ModbusTcpConnection(address, m_port, m_modbusAddress, this);
m_connections.append(connection);

connect(connection, &EV11ModbusTcpConnection::reachableChanged, this, [=](bool reachable){
Expand All @@ -78,7 +81,7 @@ void PcElectricDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDev
// Modbus TCP connected...ok, let's try to initialize it!
connect(connection, &EV11ModbusTcpConnection::initializationFinished, this, [=](bool success){
if (!success) {
qCDebug(dcPcElectric()) << "Discovery: Initialization failed on" << networkDeviceInfo.address().toString() << "Continue...";;
qCDebug(dcPcElectric()) << "Discovery: Initialization failed on" << address.toString() << "Continue...";;
cleanupConnection(connection);
return;
}
Expand All @@ -95,7 +98,7 @@ void PcElectricDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDev
qCDebug(dcPcElectric()) << "Fetched mac address" << macRawData.toHex() << registerMacAddress;

// According to PCE the HW revision must be 0
if (registerMacAddress == MacAddress(networkDeviceInfo.macAddress()) && connection->hardwareRevision() == 0) {
if (!registerMacAddress.isNull() && connection->hardwareRevision() == 0) {

// Parse the serial number
QByteArray serialRawData;
Expand All @@ -110,13 +113,9 @@ void PcElectricDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDev
Result result;
result.serialNumber = QString::number(serialNumber);
result.firmwareRevision = connection->firmwareRevision();
result.networkDeviceInfo = networkDeviceInfo;
m_results.append(result);

qCInfo(dcPcElectric()) << "Discovery: --> Found"
<< "Serial number:" << result.serialNumber
<< "Firmware revision:" << result.firmwareRevision
<< result.networkDeviceInfo;
result.address = address;
result.registerMacAddress = registerMacAddress;
m_potentialResults.append(result);
}

// Done with this connection
Expand All @@ -125,22 +124,22 @@ void PcElectricDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDev

// Initializing...
if (!connection->initialize()) {
qCDebug(dcPcElectric()) << "Discovery: Unable to initialize connection on" << networkDeviceInfo.address().toString() << "Continue...";;
qCDebug(dcPcElectric()) << "Discovery: Unable to initialize connection on" << address.toString() << "Continue...";;
cleanupConnection(connection);
}
});

// If we get any error...skip this host...
connect(connection->modbusTcpMaster(), &ModbusTcpMaster::connectionErrorOccurred, this, [=](QModbusDevice::Error error){
if (error != QModbusDevice::NoError) {
qCDebug(dcPcElectric()) << "Discovery: Connection error on" << networkDeviceInfo.address().toString() << "Continue...";;
qCDebug(dcPcElectric()) << "Discovery: Connection error on" << address.toString() << "Continue...";;
cleanupConnection(connection);
}
});

// If check reachability failed...skip this host...
connect(connection, &EV11ModbusTcpConnection::checkReachabilityFailed, this, [=](){
qCDebug(dcPcElectric()) << "Discovery: Check reachability failed on" << networkDeviceInfo.address().toString() << "Continue...";;
qCDebug(dcPcElectric()) << "Discovery: Check reachability failed on" << address.toString() << "Continue...";;
cleanupConnection(connection);
});

Expand All @@ -159,6 +158,28 @@ void PcElectricDiscovery::finishDiscovery()
{
qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch();

for (int i = 0; i < m_potentialResults.count(); i++) {
const NetworkDeviceInfo networkDeviceInfo = m_networkDeviceInfos.get(m_potentialResults.at(i).address);
m_potentialResults[i].networkDeviceInfo = networkDeviceInfo;

Result result = m_potentialResults.at(i);
if (networkDeviceInfo.macAddressInfos().hasMacAddress(result.registerMacAddress)) {
qCInfo(dcPcElectric()) << "Discovery: --> Found EV11.3"
<< "Serial number:" << result.serialNumber
<< "Firmware revision:" << result.firmwareRevision
<< result.networkDeviceInfo;
m_results.append(result);
} else {
qCWarning(dcPcElectric()) << "Discovery: --> Found potential EV11.3, but not adding to the results due to imcomplete MAC address check:"
<< "Serial number:" << result.serialNumber
<< "Firmware revision:" << result.firmwareRevision
<< result.networkDeviceInfo;
}
}

m_potentialResults.clear();
m_networkDeviceInfos.clear();

// Cleanup any leftovers...we don't care any more
foreach (EV11ModbusTcpConnection *connection, m_connections)
cleanupConnection(connection);
Expand Down
6 changes: 5 additions & 1 deletion pcelectric/pcelectricdiscovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class PcElectricDiscovery : public QObject
typedef struct Result {
QString serialNumber;
QString firmwareRevision;
QHostAddress address;
MacAddress registerMacAddress;
NetworkDeviceInfo networkDeviceInfo;
} Result;

Expand All @@ -64,10 +66,12 @@ public slots:
QDateTime m_startDateTime;

QList<EV11ModbusTcpConnection *> m_connections;
NetworkDeviceInfos m_networkDeviceInfos;
QList<Result> m_potentialResults;

QList<Result> m_results;

void checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo);
void checkNetworkDevice(const QHostAddress &address);
void cleanupConnection(EV11ModbusTcpConnection *connection);

void finishDiscovery();
Expand Down