From e24d71905bf19d747ac0d2827b4f0d0f0fe6ad10 Mon Sep 17 00:00:00 2001 From: Boernsman Date: Thu, 4 Feb 2021 18:34:53 +0100 Subject: [PATCH] added discovery on heos setup --- denon/integrationplugindenon.cpp | 64 +++++++++++++++++++++++-------- denon/integrationplugindenon.h | 1 + denon/integrationplugindenon.json | 8 ++-- 3 files changed, 54 insertions(+), 19 deletions(-) diff --git a/denon/integrationplugindenon.cpp b/denon/integrationplugindenon.cpp index 89b65a29..a4ad8ae1 100644 --- a/denon/integrationplugindenon.cpp +++ b/denon/integrationplugindenon.cpp @@ -84,7 +84,7 @@ void IntegrationPluginDenon::discoverThings(ThingDiscoveryInfo *info) QStringList discoveredIds; foreach (const ZeroConfServiceEntry &service, m_serviceBrowser->serviceEntries()) { - qCDebug(dcDenon()) << "mDNS service entry:" << service; + qCDebug(dcDenon()) << "mDNS service entry:" << service; if (service.txt().contains("am=AVRX1000")) { QString id = service.name().split("@").first(); @@ -235,32 +235,59 @@ void IntegrationPluginDenon::setupThing(ThingSetupInfo *info) denonConnection->connectDevice(); return; } else if (thing->thingClassId() == heosThingClassId) { - qCDebug(dcDenon) << "Setup Denon thing" << thing->paramValue(heosThingIpParamTypeId).toString(); - QHostAddress address(thing->paramValue(heosThingIpParamTypeId).toString()); - if (address.isNull()) { - qCWarning(dcDenon) << "Could not parse ip address" << thing->paramValue(heosThingIpParamTypeId).toString(); - info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The given IP address is not valid.")); + qCDebug(dcDenon) << "Setup Denon thing" << thing->name(); + QString serialnumber = thing->paramValue(heosThingSerialNumberParamTypeId).toString(); + if (serialnumber.isEmpty()) { + qCWarning(dcDenon) << "Serial number is empty"; + info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("Serial number is not set")); return; } - Heos *heos; + if (m_heosConnections.contains(thing->id())) { + qCDebug(dcDenon()) << "Setup after reconfiguration, cleaning up ..."; + m_heosConnections.take(thing->id())->deleteLater(); + } + if (m_unfinishedHeosConnections.contains(thing->id())) { - heos = m_unfinishedHeosConnections.take(thing->id()); + Heos *heos = m_unfinishedHeosConnections.take(thing->id()); m_heosConnections.insert(thing->id(), heos); info->finish(Thing::ThingErrorNoError); } else { - heos = createHeosConnection(address); - m_heosConnections.insert(thing->id(), heos); - m_asyncHeosSetups.insert(heos, info); - // In case the setup is cancelled before we finish it... - connect(info, &QObject::destroyed, this, [=]() {m_asyncHeosSetups.remove(heos);}); - heos->connectDevice(); + + UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices(); + connect(reply, &UpnpDiscoveryReply::finished, reply, &UpnpDiscoveryReply::deleteLater); + connect(reply, &UpnpDiscoveryReply::finished, info, [this, reply, info] { + if (reply->error() != UpnpDiscoveryReply::UpnpDiscoveryReplyErrorNoError) { + qCWarning(dcDenon()) << "Upnp discovery error" << reply->error(); + info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("UPnP discovery failed.")); + return; + } + + foreach (const UpnpDeviceDescriptor &upnpThing, reply->deviceDescriptors()) { + if (upnpThing.modelName().contains("HEOS", Qt::CaseSensitivity::CaseInsensitive)) { + QString serialNumber = info->thing()->paramValue(heosThingSerialNumberParamTypeId).toString(); + if (serialNumber == upnpThing.serialNumber()) { + ThingId thingId= info->thing()->id(); + info->thing()->setParamValue(heosThingIpParamTypeId, upnpThing.hostAddress().toString()); + Heos *heos = createHeosConnection(upnpThing.hostAddress()); + m_heosConnections.insert(thingId, heos); + m_asyncHeosSetups.insert(heos, info); + // In case the setup is cancelled before we finish it... + connect(info, &ThingSetupInfo::aborted, heos, &Heos::deleteLater); + connect(heos, &Heos::destroyed, this, [thingId, heos, this] { + m_asyncHeosSetups.remove(heos); + m_heosConnections.remove(thingId); + }); + heos->connectDevice(); + break; + } + } + } + }); } - return; } else if (thing->thingClassId() == heosPlayerThingClassId) { info->finish(Thing::ThingErrorNoError); - return; } else { info->finish(Thing::ThingErrorThingClassNotFound); } @@ -1416,3 +1443,8 @@ Heos *IntegrationPluginDenon::createHeosConnection(const QHostAddress &address) connect(heos, &Heos::userChanged, this, &IntegrationPluginDenon::onHeosUserChanged); return heos; } + +QHostAddress IntegrationPluginDenon::discoverHeos(const QString &serialnumber) +{ + +} diff --git a/denon/integrationplugindenon.h b/denon/integrationplugindenon.h index bcd8333f..2bfc1172 100644 --- a/denon/integrationplugindenon.h +++ b/denon/integrationplugindenon.h @@ -103,6 +103,7 @@ private: QHash m_playerBuffer; Heos *createHeosConnection(const QHostAddress &address); + QHostAddress discoverHeos(const QString &serialnumber); private slots: void onPluginTimer(); diff --git a/denon/integrationplugindenon.json b/denon/integrationplugindenon.json index 45b984fc..191017bb 100644 --- a/denon/integrationplugindenon.json +++ b/denon/integrationplugindenon.json @@ -324,19 +324,21 @@ "name": "ip", "displayName": "IPv4 address", "type" : "QString", - "inputType": "IPv4Address" + "readOnly": true }, { "id": "f796664d-6cb7-4f29-9d05-771968d82a32", "name": "serialNumber", "displayName": "Serial number", - "type" : "QString" + "type" : "QString", + "readOnly": true }, { "id": "ab1a0be8-e3a5-4f95-b9b7-893de1ca4cf7", "name": "modelName", "displayName": "Model name", - "type" : "QString" + "type" : "QString", + "readOnly": true } ], "stateTypes": [