Keba: Update discovery mechanism
parent
9e1780c5c4
commit
e42322694f
|
|
@ -30,12 +30,13 @@
|
|||
|
||||
#include "plugininfo.h"
|
||||
#include "integrationpluginkeba.h"
|
||||
#include "network/networkdevicediscovery.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QUdpSocket>
|
||||
#include <QTimeZone>
|
||||
|
||||
#include "kebadiscovery.h"
|
||||
|
||||
IntegrationPluginKeba::IntegrationPluginKeba()
|
||||
{
|
||||
|
||||
|
|
@ -48,49 +49,50 @@ void IntegrationPluginKeba::init()
|
|||
|
||||
void IntegrationPluginKeba::discoverThings(ThingDiscoveryInfo *info)
|
||||
{
|
||||
|
||||
// Init data layer if not already created
|
||||
if (!m_kebaDataLayer){
|
||||
qCDebug(dcKeba()) << "Creating new Keba data layer...";
|
||||
m_kebaDataLayer= new KeContactDataLayer(this);
|
||||
if (!m_kebaDataLayer->init()) {
|
||||
m_kebaDataLayer->deleteLater();
|
||||
m_kebaDataLayer = nullptr;
|
||||
qCWarning(dcKeba()) << "Failed to create Keba data layer...";
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->thingClassId() == wallboxThingClassId) {
|
||||
qCDebug(dcKeba()) << "Discovering Keba Wallbox...";
|
||||
NetworkDeviceDiscoveryReply *discoveryReply = hardwareManager()->networkDeviceDiscovery()->discover();
|
||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
|
||||
ThingDescriptors descriptors;
|
||||
qCDebug(dcKeba()) << "Discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "devices";
|
||||
foreach (const NetworkDeviceInfo &networkDeviceInfo, discoveryReply->networkDeviceInfos()) {
|
||||
if (!networkDeviceInfo.macAddressManufacturer().contains("keba", Qt::CaseSensitivity::CaseInsensitive))
|
||||
continue;
|
||||
// Create a discovery with the info as parent for auto deleting the object
|
||||
KebaDiscovery *discovery = new KebaDiscovery(m_kebaDataLayer, hardwareManager()->networkDeviceDiscovery(), info);
|
||||
connect(discovery, &KebaDiscovery::discoveryFinished, info, [=](){
|
||||
foreach (const KebaDiscovery::KebaDiscoveryResult &result, discovery->discoveryResults()) {
|
||||
|
||||
qCDebug(dcKeba()) << " - Keba Wallbox" << networkDeviceInfo;
|
||||
QString title = "Keba Wallbox ";
|
||||
if (networkDeviceInfo.hostName().isEmpty()) {
|
||||
title += "(" + networkDeviceInfo.address().toString() + ")";
|
||||
} else {
|
||||
title += networkDeviceInfo.hostName() + " (" + networkDeviceInfo.address().toString() + ")";
|
||||
}
|
||||
|
||||
QString description;
|
||||
if (networkDeviceInfo.macAddressManufacturer().isEmpty()) {
|
||||
description = networkDeviceInfo.macAddress();
|
||||
} else {
|
||||
description = networkDeviceInfo.macAddress() + " (" + networkDeviceInfo.macAddressManufacturer() + ")";
|
||||
}
|
||||
|
||||
ThingDescriptor descriptor(wallboxThingClassId, title, description);
|
||||
ThingDescriptor descriptor(wallboxThingClassId, "Keba " + result.product, "Serial: " + result.serialNumber + " - " + result.networkDeviceInfo.address().toString());
|
||||
|
||||
// Check if we already have set up this device
|
||||
Things existingThings = myThings().filterByParam(wallboxThingMacAddressParamTypeId, networkDeviceInfo.macAddress());
|
||||
Things existingThings = myThings().filterByParam(wallboxThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress());
|
||||
if (existingThings.count() == 1) {
|
||||
qCDebug(dcKeba()) << "This wallbox already exists in the system!" << networkDeviceInfo;
|
||||
qCDebug(dcKeba()) << "This wallbox already exists in the system!" << result.networkDeviceInfo;
|
||||
descriptor.setThingId(existingThings.first()->id());
|
||||
}
|
||||
|
||||
ParamList params;
|
||||
params << Param(wallboxThingMacAddressParamTypeId, networkDeviceInfo.macAddress());
|
||||
params << Param(wallboxThingIpAddressParamTypeId, networkDeviceInfo.address().toString());
|
||||
params << Param(wallboxThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress());
|
||||
params << Param(wallboxThingIpAddressParamTypeId, result.networkDeviceInfo.address().toString());
|
||||
params << Param(wallboxThingModelParamTypeId, result.product);
|
||||
params << Param(wallboxThingSerialNumberParamTypeId, result.serialNumber);
|
||||
descriptor.setParams(params);
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
|
||||
// Start the discovery process
|
||||
discovery->startDiscovery();
|
||||
|
||||
} else {
|
||||
qCWarning(dcKeba()) << "Could not discover things because of unhandled thing class id" << info->thingClassId().toString();
|
||||
info->finish(Thing::ThingErrorThingClassNotFound);
|
||||
|
|
@ -143,6 +145,9 @@ void IntegrationPluginKeba::setupThing(ThingSetupInfo *info)
|
|||
connect(keba, &KeContact::report1XXReceived, this, &IntegrationPluginKeba::onReport1XXReceived);
|
||||
connect(keba, &KeContact::broadcastReceived, this, &IntegrationPluginKeba::onBroadcastReceived);
|
||||
|
||||
// TODO: first test the ip, verify serial number if responds
|
||||
// if no response, rediscover, reassign ip in case if changes
|
||||
|
||||
connect(keba, &KeContact::reportOneReceived, info, [info, this, keba] (const KeContact::ReportOne &report) {
|
||||
Thing *thing = info->thing();
|
||||
|
||||
|
|
@ -155,8 +160,6 @@ void IntegrationPluginKeba::setupThing(ThingSetupInfo *info)
|
|||
|
||||
thing->setStateValue(wallboxConnectedStateTypeId, true);
|
||||
thing->setStateValue(wallboxFirmwareStateTypeId, report.firmware);
|
||||
thing->setStateValue(wallboxSerialnumberStateTypeId, report.serialNumber);
|
||||
thing->setStateValue(wallboxModelStateTypeId, report.product);
|
||||
thing->setStateValue(wallboxUptimeStateTypeId, report.seconds / 60);
|
||||
|
||||
m_kebaDevices.insert(thing->id(), keba);
|
||||
|
|
@ -358,6 +361,11 @@ void IntegrationPluginKeba::searchNetworkDevices()
|
|||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginKeba::onDiscoveryWaitUpdResponseTimeout()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void IntegrationPluginKeba::onConnectionChanged(bool status)
|
||||
{
|
||||
KeContact *keba = static_cast<KeContact *>(sender());
|
||||
|
|
@ -402,7 +410,7 @@ void IntegrationPluginKeba::onReportTwoReceived(const KeContact::ReportTwo &repo
|
|||
if (!thing)
|
||||
return;
|
||||
|
||||
qCDebug(dcKeba()) << "Report 2 received for" << thing->name() << "Serial number:" << thing->stateValue(wallboxSerialnumberStateTypeId).toString();
|
||||
qCDebug(dcKeba()) << "Report 2 received for" << thing->name() << "Serial number:" << thing->paramValue(wallboxThingSerialNumberParamTypeId).toString();
|
||||
qCDebug(dcKeba()) << " - State:" << reportTwo.state;
|
||||
qCDebug(dcKeba()) << " - Error 1:" << reportTwo.error1;
|
||||
qCDebug(dcKeba()) << " - Error 2:" << reportTwo.error2;
|
||||
|
|
@ -422,7 +430,7 @@ void IntegrationPluginKeba::onReportTwoReceived(const KeContact::ReportTwo &repo
|
|||
qCDebug(dcKeba()) << " - Serial number:" << reportTwo.serialNumber;
|
||||
qCDebug(dcKeba()) << " - Uptime:" << reportTwo.seconds/60 << "[min]";
|
||||
|
||||
if (reportTwo.serialNumber == thing->stateValue(wallboxSerialnumberStateTypeId).toString()) {
|
||||
if (reportTwo.serialNumber == thing->paramValue(wallboxThingSerialNumberParamTypeId).toString()) {
|
||||
setDeviceState(thing, reportTwo.state);
|
||||
setDevicePlugState(thing, reportTwo.plugState);
|
||||
|
||||
|
|
@ -458,7 +466,7 @@ void IntegrationPluginKeba::onReportThreeReceived(const KeContact::ReportThree &
|
|||
if (!thing)
|
||||
return;
|
||||
|
||||
qCDebug(dcKeba()) << "Report 3 received for" << thing->name() << "Serial number:" << thing->stateValue(wallboxSerialnumberStateTypeId).toString();
|
||||
qCDebug(dcKeba()) << "Report 3 received for" << thing->name() << "Serial number:" << thing->paramValue(wallboxThingSerialNumberParamTypeId).toString();
|
||||
qCDebug(dcKeba()) << " - Current phase 1:" << reportThree.currentPhase1 << "[A]";
|
||||
qCDebug(dcKeba()) << " - Current phase 2:" << reportThree.currentPhase2 << "[A]";
|
||||
qCDebug(dcKeba()) << " - Current phase 3:" << reportThree.currentPhase3 << "[A]";
|
||||
|
|
@ -471,7 +479,7 @@ void IntegrationPluginKeba::onReportThreeReceived(const KeContact::ReportThree &
|
|||
qCDebug(dcKeba()) << " - Serial number" << reportThree.serialNumber;
|
||||
qCDebug(dcKeba()) << " - Uptime" << reportThree.seconds / 60 << "[min]";
|
||||
|
||||
if (reportThree.serialNumber == thing->stateValue(wallboxSerialnumberStateTypeId).toString()) {
|
||||
if (reportThree.serialNumber == thing->paramValue(wallboxThingSerialNumberParamTypeId).toString()) {
|
||||
thing->setStateValue(wallboxCurrentPhaseAEventTypeId, reportThree.currentPhase1);
|
||||
thing->setStateValue(wallboxCurrentPhaseBEventTypeId, reportThree.currentPhase2);
|
||||
thing->setStateValue(wallboxCurrentPhaseCEventTypeId, reportThree.currentPhase3);
|
||||
|
|
@ -509,7 +517,7 @@ void IntegrationPluginKeba::onReport1XXReceived(int reportNumber, const KeContac
|
|||
if (!thing)
|
||||
return;
|
||||
|
||||
qCDebug(dcKeba()) << "Report" << reportNumber << "received for" << thing->name() << "Serial number:" << thing->stateValue(wallboxSerialnumberStateTypeId).toString();
|
||||
qCDebug(dcKeba()) << "Report" << reportNumber << "received for" << thing->name() << "Serial number:" << thing->paramValue(wallboxThingSerialNumberParamTypeId).toString();
|
||||
qCDebug(dcKeba()) << " - Session Id" << report.sessionId;
|
||||
qCDebug(dcKeba()) << " - Curr HW" << report.currHW;
|
||||
qCDebug(dcKeba()) << " - Energy start" << report.startEnergy;
|
||||
|
|
@ -534,7 +542,7 @@ void IntegrationPluginKeba::onReport1XXReceived(int reportNumber, const KeContac
|
|||
|
||||
} else if (reportNumber == 101) {
|
||||
// Report 101 is the lastest finished session
|
||||
if (report.serialNumber == thing->stateValue(wallboxSerialnumberStateTypeId).toString()) {
|
||||
if (report.serialNumber == thing->paramValue(wallboxThingSerialNumberParamTypeId).toString()) {
|
||||
if (!m_lastSessionId.contains(thing->id())) {
|
||||
// This happens after reboot
|
||||
m_lastSessionId.insert(thing->id(), report.sessionId);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,10 @@
|
|||
#ifndef INTEGRATIONPLUGINKEBA_H
|
||||
#define INTEGRATIONPLUGINKEBA_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "plugintimer.h"
|
||||
#include <integrations/integrationplugin.h>
|
||||
#include <plugintimer.h>
|
||||
#include <network/networkdevicediscovery.h>
|
||||
|
||||
#include "kecontact.h"
|
||||
#include "kecontactdatalayer.h"
|
||||
|
||||
|
|
@ -41,6 +43,7 @@
|
|||
#include <QDateTime>
|
||||
#include <QUdpSocket>
|
||||
|
||||
|
||||
class IntegrationPluginKeba : public IntegrationPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -64,12 +67,10 @@ public:
|
|||
private:
|
||||
PluginTimer *m_updateTimer = nullptr;
|
||||
PluginTimer *m_reconnectTimer = nullptr;
|
||||
|
||||
KeContactDataLayer *m_kebaDataLayer = nullptr;
|
||||
|
||||
QHash<ThingId, KeContact *> m_kebaDevices;
|
||||
QHash<ThingId, int> m_lastSessionId;
|
||||
|
||||
QHash<QUuid, ThingActionInfo *> m_asyncActions;
|
||||
|
||||
void setDeviceState(Thing *device, KeContact::State state);
|
||||
|
|
@ -78,6 +79,8 @@ private:
|
|||
void searchNetworkDevices();
|
||||
|
||||
private slots:
|
||||
void onDiscoveryWaitUpdResponseTimeout();
|
||||
|
||||
void onConnectionChanged(bool status);
|
||||
void onCommandExecuted(QUuid requestId, bool success);
|
||||
void onReportTwoReceived(const KeContact::ReportTwo &reportTwo);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,24 @@
|
|||
"inputType": "TextLine",
|
||||
"defaultValue":"",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"id": "45255155-318b-4204-8ce6-2c106a56286d",
|
||||
"name": "serialNumber",
|
||||
"displayName": "Serial number",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"defaultValue":"",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"id": "a996c698-4831-4977-8979-f76f78ac7da8",
|
||||
"name": "model",
|
||||
"displayName": "Product name",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"defaultValue":"",
|
||||
"readOnly": true
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
|
|
@ -43,30 +61,6 @@
|
|||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "c3fca233-95b9-4948-88c6-4c0f13cf53b1",
|
||||
"name": "model",
|
||||
"displayName": "Model",
|
||||
"displayNameEvent": "Model changed",
|
||||
"type": "QString",
|
||||
"defaultValue": "Unknown"
|
||||
},
|
||||
{
|
||||
"id": "e941ace5-fb7f-4dc2-b3f2-188233f4e934",
|
||||
"name": "firmware",
|
||||
"displayName": "Firmware",
|
||||
"displayNameEvent": "Firmware changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "9a1b4316-ce01-4cd3-890f-a8c94b8b5029",
|
||||
"name": "serialnumber",
|
||||
"displayName": "Serial number",
|
||||
"displayNameEvent": "Serial number changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "83ed0774-2a91-434d-b03c-d920d02f2981",
|
||||
"name": "power",
|
||||
|
|
@ -328,6 +322,14 @@
|
|||
"writable": true,
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "e941ace5-fb7f-4dc2-b3f2-188233f4e934",
|
||||
"name": "firmware",
|
||||
"displayName": "Firmware",
|
||||
"displayNameEvent": "Firmware changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ TARGET = $$qtLibraryTarget(nymea_integrationpluginkeba)
|
|||
|
||||
SOURCES += \
|
||||
integrationpluginkeba.cpp \
|
||||
kebadiscovery.cpp \
|
||||
kecontact.cpp \
|
||||
kecontactdatalayer.cpp
|
||||
|
||||
HEADERS += \
|
||||
integrationpluginkeba.h \
|
||||
kebadiscovery.h \
|
||||
kecontact.h \
|
||||
kecontactdatalayer.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project is distributed in the hope that
|
||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "kebadiscovery.h"
|
||||
#include "kecontactdatalayer.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <network/networkdevicediscovery.h>
|
||||
|
||||
KebaDiscovery::KebaDiscovery(KeContactDataLayer *kebaDataLayer, NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_kebaDataLayer(kebaDataLayer),
|
||||
m_networkDeviceDiscovery(networkDeviceDiscovery)
|
||||
{
|
||||
// Timer for waiting if network devices responded to the "report 1 request"
|
||||
m_responseTimer.setInterval(5000);
|
||||
m_responseTimer.setSingleShot(true);
|
||||
connect(&m_responseTimer, &QTimer::timeout, this, [=](){
|
||||
qCDebug(dcKeba()) << "Discovery: Report response timeout. Found" << m_results.count() << "Keba Wallbox";
|
||||
emit discoveryFinished();
|
||||
});
|
||||
|
||||
// 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){
|
||||
|
||||
// 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
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(datagram, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcKeba()) << "Discovery: Received data from the keba data link but failed to parse the data as JSON:" << datagram << ":" << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify JSON data
|
||||
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
||||
if (!dataMap.contains("ID") || !dataMap.contains("Serial") || !dataMap.contains("Product") || !dataMap.contains("Firmware")) {
|
||||
qCDebug(dcKeba()) << "Discovery: Received valid JSON data on data layer but they don't seem to be what we are listening for:" << qUtf8Printable(jsonDoc.toJson());
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataMap.value("ID").toInt() != 1) {
|
||||
qCDebug(dcKeba()) << "Discovery: Received valid Keba JSON data on data layer but this is not a report 1 message:" << qUtf8Printable(jsonDoc.toJson());
|
||||
return;
|
||||
}
|
||||
|
||||
// We have received a report 1 datagram, let's add it to the result
|
||||
foreach (const NetworkDeviceInfo &networkDeviceInfo, m_networkDeviceInfos) {
|
||||
if (networkDeviceInfo.address() == address) {
|
||||
KebaDiscoveryResult result;
|
||||
result.networkDeviceInfo = networkDeviceInfo;
|
||||
result.product = dataMap.value("Product").toString();
|
||||
result.serialNumber = dataMap.value("Serial").toString();
|
||||
result.firmwareVersion = dataMap.value("Firmware").toString();
|
||||
m_results.append(result);
|
||||
qCDebug(dcKeba()) << "Discovery: -->" << networkDeviceInfo.address().toString() << networkDeviceInfo.macAddress() << result.product << result.serialNumber << result.firmwareVersion;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
KebaDiscovery::~KebaDiscovery()
|
||||
{
|
||||
qCDebug(dcKeba()) << "Discovery: Destroying object.";
|
||||
}
|
||||
|
||||
void KebaDiscovery::startDiscovery()
|
||||
{
|
||||
// Clean up
|
||||
m_networkDeviceInfos.clear();
|
||||
m_results.clear();
|
||||
|
||||
qCDebug(dcKeba()) << "Discovery: Start discovering Keba Wallboxs...";
|
||||
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
|
||||
qCDebug(dcKeba()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices";
|
||||
m_networkDeviceInfos = discoveryReply->networkDeviceInfos();
|
||||
|
||||
// Send a report 1 request to all discovered network devices and see which one responds
|
||||
qCDebug(dcKeba()) << "Discovery: Start sending \"report 1\" request to all discovered network devices";
|
||||
foreach (const NetworkDeviceInfo &networkDeviceInfo, m_networkDeviceInfos)
|
||||
m_kebaDataLayer->write(networkDeviceInfo.address(), QByteArray("report 1\n"));
|
||||
|
||||
m_responseTimer.start();
|
||||
});
|
||||
}
|
||||
|
||||
QList<KebaDiscovery::KebaDiscoveryResult> KebaDiscovery::discoveryResults() const
|
||||
{
|
||||
return m_results;
|
||||
}
|
||||
|
||||
bool KebaDiscovery::alreadyDiscovered(const QHostAddress &address)
|
||||
{
|
||||
foreach (const KebaDiscoveryResult &result, m_results) {
|
||||
if (result.networkDeviceInfo.address() == address) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project is distributed in the hope that
|
||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef KEBADISCOVERY_H
|
||||
#define KEBADISCOVERY_H
|
||||
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
|
||||
#include <network/networkdeviceinfos.h>
|
||||
|
||||
class KeContactDataLayer;
|
||||
class NetworkDeviceDiscovery;
|
||||
|
||||
class KebaDiscovery : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef struct KebaDiscoveryResult {
|
||||
QString product;
|
||||
QString serialNumber;
|
||||
QString firmwareVersion;
|
||||
NetworkDeviceInfo networkDeviceInfo;
|
||||
} KebaDiscoveryResult;
|
||||
|
||||
explicit KebaDiscovery(KeContactDataLayer *kebaDataLayer, NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent = nullptr);
|
||||
~KebaDiscovery();
|
||||
|
||||
void startDiscovery();
|
||||
|
||||
QList<KebaDiscoveryResult> discoveryResults() const;
|
||||
|
||||
signals:
|
||||
void discoveryFinished();
|
||||
|
||||
private:
|
||||
KeContactDataLayer *m_kebaDataLayer = nullptr;
|
||||
NetworkDeviceDiscovery *m_networkDeviceDiscovery = nullptr;
|
||||
QTimer m_responseTimer;
|
||||
NetworkDeviceInfos m_networkDeviceInfos;
|
||||
QList<KebaDiscoveryResult> m_results;
|
||||
|
||||
bool alreadyDiscovered(const QHostAddress &address);
|
||||
};
|
||||
|
||||
#endif // KEBADISCOVERY_H
|
||||
Loading…
Reference in New Issue