Keba: Update to networkdevice interface
This commit is contained in:
parent
a35312b7f2
commit
047367180a
@ -50,6 +50,12 @@ void IntegrationPluginKeba::init()
|
|||||||
m_macAddressParamTypeIds.insert(kebaThingClassId, kebaThingMacAddressParamTypeId);
|
m_macAddressParamTypeIds.insert(kebaThingClassId, kebaThingMacAddressParamTypeId);
|
||||||
m_macAddressParamTypeIds.insert(kebaSimpleThingClassId, kebaSimpleThingMacAddressParamTypeId);
|
m_macAddressParamTypeIds.insert(kebaSimpleThingClassId, kebaSimpleThingMacAddressParamTypeId);
|
||||||
|
|
||||||
|
m_hostNameParamTypeIds.insert(kebaThingClassId, kebaThingHostNameParamTypeId);
|
||||||
|
m_hostNameParamTypeIds.insert(kebaSimpleThingClassId, kebaSimpleThingHostNameParamTypeId);
|
||||||
|
|
||||||
|
m_addressParamTypeIds.insert(kebaThingClassId, kebaThingAddressParamTypeId);
|
||||||
|
m_addressParamTypeIds.insert(kebaSimpleThingClassId, kebaSimpleThingAddressParamTypeId);
|
||||||
|
|
||||||
m_modelParamTypeIds.insert(kebaThingClassId, kebaThingModelParamTypeId);
|
m_modelParamTypeIds.insert(kebaThingClassId, kebaThingModelParamTypeId);
|
||||||
m_modelParamTypeIds.insert(kebaSimpleThingClassId, kebaSimpleThingModelParamTypeId);
|
m_modelParamTypeIds.insert(kebaSimpleThingClassId, kebaSimpleThingModelParamTypeId);
|
||||||
|
|
||||||
@ -104,14 +110,16 @@ void IntegrationPluginKeba::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
qCDebug(dcKeba()) << "Discovered:" << descriptor.title() << descriptor.description();
|
qCDebug(dcKeba()) << "Discovered:" << descriptor.title() << descriptor.description();
|
||||||
|
|
||||||
// Check if we already have set up this device
|
// Check if we already have set up this device
|
||||||
Things existingThings = myThings().filterByParam(m_macAddressParamTypeIds.value(discoveredThingClassId), result.networkDeviceInfo.macAddress());
|
Things existingThings = myThings().filterByParam(m_serialNumberParamTypeIds.value(discoveredThingClassId), result.serialNumber);
|
||||||
if (existingThings.count() == 1) {
|
if (existingThings.count() == 1) {
|
||||||
qCDebug(dcKeba()) << "This keba already exists in the system!" << result.networkDeviceInfo;
|
qCDebug(dcKeba()) << "This keba already exists in the system!" << result.networkDeviceInfo;
|
||||||
descriptor.setThingId(existingThings.first()->id());
|
descriptor.setThingId(existingThings.first()->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamList params;
|
ParamList params;
|
||||||
params << Param(m_macAddressParamTypeIds.value(discoveredThingClassId), result.networkDeviceInfo.macAddress());
|
params << Param(m_macAddressParamTypeIds.value(discoveredThingClassId), result.networkDeviceInfo.thingParamValueMacAddress());
|
||||||
|
params << Param(m_hostNameParamTypeIds.value(discoveredThingClassId), result.networkDeviceInfo.thingParamValueHostName());
|
||||||
|
params << Param(m_addressParamTypeIds.value(discoveredThingClassId), result.networkDeviceInfo.thingParamValueAddress());
|
||||||
params << Param(m_modelParamTypeIds.value(discoveredThingClassId), result.product);
|
params << Param(m_modelParamTypeIds.value(discoveredThingClassId), result.product);
|
||||||
params << Param(m_serialNumberParamTypeIds.value(discoveredThingClassId), result.serialNumber);
|
params << Param(m_serialNumberParamTypeIds.value(discoveredThingClassId), result.serialNumber);
|
||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
@ -156,16 +164,16 @@ void IntegrationPluginKeba::setupThing(ThingSetupInfo *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a monitor so we always get the correct IP in the network and see if the device is reachable without polling on our own
|
||||||
|
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(thing);
|
||||||
// Make sure we have a valid mac address, otherwise no monitor and not auto searching is possible
|
// Make sure we have a valid mac address, otherwise no monitor and not auto searching is possible
|
||||||
MacAddress macAddress = MacAddress(thing->paramValue(m_macAddressParamTypeIds.value(thing->thingClassId())).toString());
|
if (!monitor) {
|
||||||
if (macAddress.isNull()) {
|
qCWarning(dcKeba()) << "Can not set up connection monitor with the given parameters:" << thing->params();
|
||||||
qCWarning(dcKeba()) << "Failed to set up keba because the MAC address is not valid:" << thing->paramValue(m_macAddressParamTypeIds.value(thing->thingClassId())).toString() << macAddress.toString();
|
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("Unable to set up the connection with this configuration. Please reconfigure the connection."));
|
||||||
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The MAC address is not vaild. Please reconfigure the device to fix this."));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a monitor so we always get the correct IP in the network and see if the device is reachable without polling on our own
|
|
||||||
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(macAddress);
|
|
||||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){
|
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){
|
||||||
// Only if the setup has been finished
|
// Only if the setup has been finished
|
||||||
KeContact *keba = m_kebaDevices.value(thing->id());
|
KeContact *keba = m_kebaDevices.value(thing->id());
|
||||||
|
|||||||
@ -77,6 +77,8 @@ private:
|
|||||||
KebaDiscovery *m_runningDiscovery = nullptr;
|
KebaDiscovery *m_runningDiscovery = nullptr;
|
||||||
|
|
||||||
QHash<ThingClassId, ParamTypeId> m_macAddressParamTypeIds;
|
QHash<ThingClassId, ParamTypeId> m_macAddressParamTypeIds;
|
||||||
|
QHash<ThingClassId, ParamTypeId> m_hostNameParamTypeIds;
|
||||||
|
QHash<ThingClassId, ParamTypeId> m_addressParamTypeIds;
|
||||||
QHash<ThingClassId, ParamTypeId> m_modelParamTypeIds;
|
QHash<ThingClassId, ParamTypeId> m_modelParamTypeIds;
|
||||||
QHash<ThingClassId, ParamTypeId> m_serialNumberParamTypeIds;
|
QHash<ThingClassId, ParamTypeId> m_serialNumberParamTypeIds;
|
||||||
|
|
||||||
|
|||||||
@ -13,24 +13,40 @@
|
|||||||
"name": "keba",
|
"name": "keba",
|
||||||
"displayName": "Keba KeContact",
|
"displayName": "Keba KeContact",
|
||||||
"createMethods": ["discovery", "user"],
|
"createMethods": ["discovery", "user"],
|
||||||
"interfaces": ["evcharger", "smartmeterconsumer", "connectable"],
|
"interfaces": ["evcharger", "smartmeterconsumer", "connectable", "networkdevice"],
|
||||||
"paramTypes":[
|
"paramTypes":[
|
||||||
{
|
{
|
||||||
"id": "c2df921d-ff8b-411c-9b1d-04a437d7dfa6",
|
"id": "c2df921d-ff8b-411c-9b1d-04a437d7dfa6",
|
||||||
"name": "macAddress",
|
"name": "macAddress",
|
||||||
"displayName": "MAC address",
|
"displayName": "MAC address",
|
||||||
"type": "QString",
|
"type": "QString",
|
||||||
"inputType": "TextLine",
|
"inputType": "MacAddress",
|
||||||
"defaultValue":"",
|
"defaultValue": "",
|
||||||
"readOnly": true
|
"readOnly": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "0cc79bb7-3162-432c-a7bc-45f9b5542fbd",
|
||||||
|
"name": "hostName",
|
||||||
|
"displayName": "Host name",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextLine",
|
||||||
|
"defaultValue": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "22f70789-33c2-4183-8bca-0d3108b1c80b",
|
||||||
|
"name": "address",
|
||||||
|
"displayName": "IP address",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "IPv4Address",
|
||||||
|
"defaultValue": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "45255155-318b-4204-8ce6-2c106a56286d",
|
"id": "45255155-318b-4204-8ce6-2c106a56286d",
|
||||||
"name": "serialNumber",
|
"name": "serialNumber",
|
||||||
"displayName": "Serial number",
|
"displayName": "Serial number",
|
||||||
"type": "QString",
|
"type": "QString",
|
||||||
"inputType": "TextLine",
|
"inputType": "TextLine",
|
||||||
"defaultValue":"",
|
"defaultValue": "",
|
||||||
"readOnly": true
|
"readOnly": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -39,7 +55,7 @@
|
|||||||
"displayName": "Product name",
|
"displayName": "Product name",
|
||||||
"type": "QString",
|
"type": "QString",
|
||||||
"inputType": "TextLine",
|
"inputType": "TextLine",
|
||||||
"defaultValue":"",
|
"defaultValue": "",
|
||||||
"readOnly": true
|
"readOnly": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -410,6 +426,22 @@
|
|||||||
"defaultValue":"",
|
"defaultValue":"",
|
||||||
"readOnly": true
|
"readOnly": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "96104d2b-2fd3-4f20-bc8c-7b873d0b0f9e",
|
||||||
|
"name": "hostName",
|
||||||
|
"displayName": "Host name",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextLine",
|
||||||
|
"defaultValue": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a0c60511-4082-4109-9a9f-383076680c4f",
|
||||||
|
"name": "address",
|
||||||
|
"displayName": "IP address",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "IPv4Address",
|
||||||
|
"defaultValue": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "6f732eb9-1711-4da0-a9a4-abcfa19f5e34",
|
"id": "6f732eb9-1711-4da0-a9a4-abcfa19f5e34",
|
||||||
"name": "serialNumber",
|
"name": "serialNumber",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2021, 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.
|
||||||
@ -44,6 +44,12 @@ KebaDiscovery::KebaDiscovery(KeContactDataLayer *kebaDataLayer, NetworkDeviceDis
|
|||||||
m_responseTimer.setInterval(2000);
|
m_responseTimer.setInterval(2000);
|
||||||
m_responseTimer.setSingleShot(true);
|
m_responseTimer.setSingleShot(true);
|
||||||
connect(&m_responseTimer, &QTimer::timeout, this, [=](){
|
connect(&m_responseTimer, &QTimer::timeout, this, [=](){
|
||||||
|
|
||||||
|
// Fill in all network device infos we have
|
||||||
|
for (int i = 0; i < m_results.count(); i++) {
|
||||||
|
m_results[i].networkDeviceInfo = m_networkDeviceInfos.get(m_results.at(i).address);
|
||||||
|
}
|
||||||
|
|
||||||
qCInfo(dcKeba()) << "Discovery: Finished successfully. Found" << m_results.count() << "Keba Wallbox";
|
qCInfo(dcKeba()) << "Discovery: Finished successfully. Found" << m_results.count() << "Keba Wallbox";
|
||||||
emit discoveryFinished();
|
emit discoveryFinished();
|
||||||
});
|
});
|
||||||
@ -51,12 +57,6 @@ KebaDiscovery::KebaDiscovery(KeContactDataLayer *kebaDataLayer, NetworkDeviceDis
|
|||||||
// Read data from the keba data layer and verify if it is a keba report
|
// Read data from the keba data layer and verify if it is a keba report
|
||||||
connect (m_kebaDataLayer, &KeContactDataLayer::datagramReceived, this, [=](const QHostAddress &address, const QByteArray &datagram){
|
connect (m_kebaDataLayer, &KeContactDataLayer::datagramReceived, this, [=](const QHostAddress &address, const QByteArray &datagram){
|
||||||
|
|
||||||
// Just continue if this is a new address we have no result for
|
|
||||||
if (alreadyDiscovered(address)) {
|
|
||||||
qCDebug(dcKeba()) << "Discovery: Skipping datagram from already discovered Keba on" << address.toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to convert the received data to a json document
|
// Try to convert the received data to a json document
|
||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(datagram, &error);
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(datagram, &error);
|
||||||
@ -78,15 +78,23 @@ KebaDiscovery::KebaDiscovery(KeContactDataLayer *kebaDataLayer, NetworkDeviceDis
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We have received a report 1 datagram, let's add it to the result
|
// We have received a report 1 datagram, let's add it to the result
|
||||||
NetworkDeviceInfo networkDeviceInfo = m_verifiedNetworkDeviceInfos.get(address);
|
KebaDiscoveryResult result;
|
||||||
if (networkDeviceInfo.isValid()) {
|
result.address = address;
|
||||||
KebaDiscoveryResult result;
|
result.product = dataMap.value("Product").toString();
|
||||||
result.networkDeviceInfo = networkDeviceInfo;
|
result.serialNumber = dataMap.value("Serial").toString();
|
||||||
result.product = dataMap.value("Product").toString();
|
result.firmwareVersion = dataMap.value("Firmware").toString();
|
||||||
result.serialNumber = dataMap.value("Serial").toString();
|
|
||||||
result.firmwareVersion = dataMap.value("Firmware").toString();
|
bool alreadyDiscovered = false;
|
||||||
|
foreach (const KebaDiscoveryResult &r, m_results) {
|
||||||
|
if (r.serialNumber == result.serialNumber) {
|
||||||
|
alreadyDiscovered = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alreadyDiscovered) {
|
||||||
m_results.append(result);
|
m_results.append(result);
|
||||||
qCDebug(dcKeba()) << "Discovery: -->" << networkDeviceInfo << networkDeviceInfo.macAddress() << result.product << result.serialNumber << result.firmwareVersion;
|
qCDebug(dcKeba()) << "Discovery: -->" << address.toString() << result.product << result.serialNumber << result.firmwareVersion;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -104,26 +112,16 @@ void KebaDiscovery::startDiscovery()
|
|||||||
qCInfo(dcKeba()) << "Discovery: Start searching for Keba wallboxes in the network...";
|
qCInfo(dcKeba()) << "Discovery: Start searching for Keba wallboxes in the network...";
|
||||||
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
||||||
|
|
||||||
// Check any already discovered infos..
|
|
||||||
foreach (const NetworkDeviceInfo &networkDeviceInfo, discoveryReply->networkDeviceInfos()) {
|
|
||||||
sendReportRequest(networkDeviceInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Imedialty check any new device gets discovered
|
// Imedialty check any new device gets discovered
|
||||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &KebaDiscovery::sendReportRequest);
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &KebaDiscovery::sendReportRequest);
|
||||||
|
|
||||||
// Check what might be left on finished
|
// Check what might be left on finished
|
||||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater);
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater);
|
||||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
|
||||||
qCDebug(dcKeba()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices";
|
qCDebug(dcKeba()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices";
|
||||||
m_networkDeviceInfos = discoveryReply->networkDeviceInfos();
|
m_networkDeviceInfos = discoveryReply->networkDeviceInfos();
|
||||||
|
|
||||||
qCDebug(dcKeba()) << "Discovery: Network discovery finished. Start finishing discovery...";
|
qCDebug(dcKeba()) << "Discovery: Network discovery finished. Start finishing discovery...";
|
||||||
// Send a report request to nework device info not sent already...
|
|
||||||
foreach (const NetworkDeviceInfo &networkDeviceInfo, m_networkDeviceInfos) {
|
|
||||||
if (!m_verifiedNetworkDeviceInfos.contains(networkDeviceInfo)) {
|
|
||||||
sendReportRequest(networkDeviceInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_responseTimer.start();
|
m_responseTimer.start();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -133,27 +131,17 @@ QList<KebaDiscovery::KebaDiscoveryResult> KebaDiscovery::discoveryResults() cons
|
|||||||
return m_results;
|
return m_results;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KebaDiscovery::alreadyDiscovered(const QHostAddress &address)
|
void KebaDiscovery::sendReportRequest(const QHostAddress &address)
|
||||||
{
|
{
|
||||||
foreach (const KebaDiscoveryResult &result, m_results) {
|
m_verifiedAddresses.append(address);
|
||||||
if (result.networkDeviceInfo.address() == address) {
|
m_kebaDataLayer->write(address, QByteArray("report 1\n"));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KebaDiscovery::cleanup()
|
void KebaDiscovery::cleanup()
|
||||||
{
|
{
|
||||||
m_networkDeviceInfos.clear();
|
m_networkDeviceInfos.clear();
|
||||||
m_verifiedNetworkDeviceInfos.clear();
|
m_verifiedAddresses.clear();
|
||||||
m_results.clear();
|
m_results.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KebaDiscovery::sendReportRequest(const NetworkDeviceInfo &networkDeviceInfo)
|
|
||||||
{
|
|
||||||
m_verifiedNetworkDeviceInfos.append(networkDeviceInfo);
|
|
||||||
m_kebaDataLayer->write(networkDeviceInfo.address(), QByteArray("report 1\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2021, 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.
|
||||||
@ -47,6 +47,7 @@ public:
|
|||||||
QString product;
|
QString product;
|
||||||
QString serialNumber;
|
QString serialNumber;
|
||||||
QString firmwareVersion;
|
QString firmwareVersion;
|
||||||
|
QHostAddress address;
|
||||||
NetworkDeviceInfo networkDeviceInfo;
|
NetworkDeviceInfo networkDeviceInfo;
|
||||||
} KebaDiscoveryResult;
|
} KebaDiscoveryResult;
|
||||||
|
|
||||||
@ -60,22 +61,19 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void discoveryFinished();
|
void discoveryFinished();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void sendReportRequest(const QHostAddress &address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KeContactDataLayer *m_kebaDataLayer = nullptr;
|
KeContactDataLayer *m_kebaDataLayer = nullptr;
|
||||||
NetworkDeviceDiscovery *m_networkDeviceDiscovery = nullptr;
|
NetworkDeviceDiscovery *m_networkDeviceDiscovery = nullptr;
|
||||||
QTimer m_responseTimer;
|
QTimer m_responseTimer;
|
||||||
|
|
||||||
NetworkDeviceInfos m_networkDeviceInfos;
|
NetworkDeviceInfos m_networkDeviceInfos;
|
||||||
NetworkDeviceInfos m_verifiedNetworkDeviceInfos;
|
QList<QHostAddress> m_verifiedAddresses;
|
||||||
QList<KebaDiscoveryResult> m_results;
|
QList<KebaDiscoveryResult> m_results;
|
||||||
|
|
||||||
bool alreadyDiscovered(const QHostAddress &address);
|
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void sendReportRequest(const NetworkDeviceInfo &networkDeviceInfo);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEBADISCOVERY_H
|
#endif // KEBADISCOVERY_H
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user