added rediscovery, fixed browsing and added bluetooth icon
parent
568b7ffd31
commit
01d4096e9b
|
|
@ -11,7 +11,6 @@
|
||||||
* of use of nymea GmbH, available under https://nymea.io/license
|
* of use of nymea GmbH, available under https://nymea.io/license
|
||||||
*
|
*
|
||||||
* GNU Lesser General Public License Usage
|
* GNU Lesser General Public License Usage
|
||||||
* This project may also contain libraries licensed under the open source software license GNU GPL v.3.
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
* 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.
|
* 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;
|
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
|
@ -30,7 +29,6 @@
|
||||||
#include "devices/device.h"
|
#include "devices/device.h"
|
||||||
#include "plugininfo.h"
|
#include "plugininfo.h"
|
||||||
#include "platform/platformzeroconfcontroller.h"
|
#include "platform/platformzeroconfcontroller.h"
|
||||||
#include "network/zeroconf/zeroconfservicebrowser.h"
|
|
||||||
#include "network/zeroconf/zeroconfserviceentry.h"
|
#include "network/zeroconf/zeroconfserviceentry.h"
|
||||||
#include "types/mediabrowseritem.h"
|
#include "types/mediabrowseritem.h"
|
||||||
|
|
||||||
|
|
@ -45,14 +43,37 @@ DevicePluginBose::~DevicePluginBose()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DevicePluginBose::init()
|
||||||
|
{
|
||||||
|
m_serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_soundtouch._tcp");
|
||||||
|
}
|
||||||
|
|
||||||
void DevicePluginBose::setupDevice(DeviceSetupInfo *info)
|
void DevicePluginBose::setupDevice(DeviceSetupInfo *info)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (info->device()->deviceClassId() == soundtouchDeviceClassId) {
|
if (info->device()->deviceClassId() == soundtouchDeviceClassId) {
|
||||||
|
|
||||||
connect(info->device(), &Device::nameChanged, this, &DevicePluginBose::onDeviceNameChanged);
|
QString ipAddress;
|
||||||
|
QString playerId = info->device()->paramValue(soundtouchDevicePlayerIdParamTypeId).toString();
|
||||||
|
|
||||||
QString ipAddress = info->device()->paramValue(soundtouchDeviceIpParamTypeId).toString();
|
foreach (const ZeroConfServiceEntry avahiEntry, m_serviceBrowser->serviceEntries()) {
|
||||||
|
QString discoveredPlayerId = avahiEntry.hostName().split(".").first();
|
||||||
|
if (discoveredPlayerId == playerId) {
|
||||||
|
ipAddress = avahiEntry.hostAddress().toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipAddress.isEmpty()) {
|
||||||
|
// Ok, we could not find an ip on zeroconf... Let's try again in a second while setupInfo hasn't timed out.
|
||||||
|
qCDebug(dcBose()) << "Device not found via ZeroConf... Waiting for a second for it to appear...";
|
||||||
|
QTimer::singleShot(1000, info, [this, info](){
|
||||||
|
setupDevice(info);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->device()->setParamValue(soundtouchDeviceIpParamTypeId,ipAddress);
|
||||||
SoundTouch *soundTouch = new SoundTouch(hardwareManager()->networkManager(), ipAddress, this);
|
SoundTouch *soundTouch = new SoundTouch(hardwareManager()->networkManager(), ipAddress, this);
|
||||||
connect(soundTouch, &SoundTouch::connectionChanged, this, &DevicePluginBose::onConnectionChanged);
|
connect(soundTouch, &SoundTouch::connectionChanged, this, &DevicePluginBose::onConnectionChanged);
|
||||||
connect(soundTouch, &SoundTouch::infoReceived, this, &DevicePluginBose::onInfoObjectReceived);
|
connect(soundTouch, &SoundTouch::infoReceived, this, &DevicePluginBose::onInfoObjectReceived);
|
||||||
|
|
@ -75,6 +96,7 @@ void DevicePluginBose::setupDevice(DeviceSetupInfo *info)
|
||||||
void DevicePluginBose::postSetupDevice(Device *device)
|
void DevicePluginBose::postSetupDevice(Device *device)
|
||||||
{
|
{
|
||||||
if (device->deviceClassId() == soundtouchDeviceClassId) {
|
if (device->deviceClassId() == soundtouchDeviceClassId) {
|
||||||
|
connect(device, &Device::nameChanged, this, &DevicePluginBose::onDeviceNameChanged);
|
||||||
SoundTouch *soundTouch = m_soundTouch.value(device);
|
SoundTouch *soundTouch = m_soundTouch.value(device);
|
||||||
soundTouch->getInfo();
|
soundTouch->getInfo();
|
||||||
soundTouch->getNowPlaying();
|
soundTouch->getNowPlaying();
|
||||||
|
|
@ -105,10 +127,8 @@ void DevicePluginBose::deviceRemoved(Device *device)
|
||||||
|
|
||||||
void DevicePluginBose::discoverDevices(DeviceDiscoveryInfo *info)
|
void DevicePluginBose::discoverDevices(DeviceDiscoveryInfo *info)
|
||||||
{
|
{
|
||||||
ZeroConfServiceBrowser *serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_soundtouch._tcp");
|
QTimer::singleShot(5000, info, [this, info](){
|
||||||
|
foreach (const ZeroConfServiceEntry avahiEntry, m_serviceBrowser->serviceEntries()) {
|
||||||
QTimer::singleShot(5000, info, [this, serviceBrowser, info](){
|
|
||||||
foreach (const ZeroConfServiceEntry avahiEntry, serviceBrowser->serviceEntries()) {
|
|
||||||
qCDebug(dcBose) << "Zeroconf entry:" << avahiEntry;
|
qCDebug(dcBose) << "Zeroconf entry:" << avahiEntry;
|
||||||
|
|
||||||
QString playerId = avahiEntry.hostName().split(".").first();
|
QString playerId = avahiEntry.hostName().split(".").first();
|
||||||
|
|
@ -126,7 +146,6 @@ void DevicePluginBose::discoverDevices(DeviceDiscoveryInfo *info)
|
||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
info->addDeviceDescriptor(descriptor);
|
info->addDeviceDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
serviceBrowser->deleteLater();
|
|
||||||
info->finish(Device::DeviceErrorNoError);
|
info->finish(Device::DeviceErrorNoError);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -254,9 +273,10 @@ void DevicePluginBose::browserItem(BrowserItemResult *result)
|
||||||
{
|
{
|
||||||
Device *device = result->device();
|
Device *device = result->device();
|
||||||
if (device->deviceClassId() == soundtouchDeviceClassId) {
|
if (device->deviceClassId() == soundtouchDeviceClassId) {
|
||||||
//SoundTouch *soundTouch = m_soundTouch.value(device);
|
SoundTouch *soundTouch = m_soundTouch.value(device);
|
||||||
//QUuid requestId = soundTouch->getSources();
|
QUuid requestId = soundTouch->getSources();
|
||||||
//m_asyncBrowseResults.insert(requestId, result);
|
m_asyncBrowseItemResults.insert(requestId, result);
|
||||||
|
connect(result, &BrowserItemResult::aborted, this, [this, requestId]{m_asyncBrowseItemResults.remove(requestId);});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,8 +292,8 @@ void DevicePluginBose::executeBrowserItem(BrowserActionInfo *info)
|
||||||
contentItem.source = source.source;
|
contentItem.source = source.source;
|
||||||
contentItem.sourceAccount = source.sourceAccount;
|
contentItem.sourceAccount = source.sourceAccount;
|
||||||
QUuid requestId = soundTouch->setSource(contentItem);
|
QUuid requestId = soundTouch->setSource(contentItem);
|
||||||
m_asyncExecuteBroweItems.insert(requestId, info);
|
m_asyncExecuteBrowseItems.insert(requestId, info);
|
||||||
connect(info, &BrowserActionInfo::aborted, this, [this, requestId]{m_asyncExecuteBroweItems.remove(requestId);});
|
connect(info, &BrowserActionInfo::aborted, this, [this, requestId]{m_asyncExecuteBrowseItems.remove(requestId);});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -319,13 +339,18 @@ void DevicePluginBose::onRequestExecuted(QUuid requestId, bool success)
|
||||||
BrowseResult *result = m_asyncBrowseResults.take(requestId);
|
BrowseResult *result = m_asyncBrowseResults.take(requestId);
|
||||||
result->finish(Device::DeviceErrorHardwareFailure);
|
result->finish(Device::DeviceErrorHardwareFailure);
|
||||||
}
|
}
|
||||||
} else if (m_asyncExecuteBroweItems.contains(requestId)) {
|
} else if (m_asyncExecuteBrowseItems.contains(requestId)) {
|
||||||
BrowserActionInfo *info = m_asyncExecuteBroweItems.take(requestId);
|
BrowserActionInfo *info = m_asyncExecuteBrowseItems.take(requestId);
|
||||||
if (success) {
|
if (success) {
|
||||||
info->finish(Device::DeviceErrorNoError);
|
info->finish(Device::DeviceErrorNoError);
|
||||||
} else {
|
} else {
|
||||||
info->finish(Device::DeviceErrorHardwareFailure);
|
info->finish(Device::DeviceErrorHardwareFailure);
|
||||||
}
|
}
|
||||||
|
} else if (m_asyncBrowseItemResults.contains(requestId)) {
|
||||||
|
if (!success) {
|
||||||
|
BrowserItemResult *result = m_asyncBrowseItemResults.take(requestId);
|
||||||
|
result->finish(Device::DeviceErrorHardwareFailure);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//This request was not an action or browse request
|
//This request was not an action or browse request
|
||||||
}
|
}
|
||||||
|
|
@ -402,7 +427,7 @@ void DevicePluginBose::onSourcesObjectReceived(QUuid requestId, SourcesObject so
|
||||||
MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true);
|
MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true);
|
||||||
item.setDescription(sourceItem.sourceAccount);
|
item.setDescription(sourceItem.sourceAccount);
|
||||||
item.setIcon(BrowserItem::BrowserIcon::BrowserIconMusic);
|
item.setIcon(BrowserItem::BrowserIcon::BrowserIconMusic);
|
||||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIcon::MediaBrowserIconRecentlyPlayed);
|
item.setMediaIcon(MediaBrowserItem::MediaBrowserIcon::MediaBrowserIconBluetooth);
|
||||||
result->addItem(item);
|
result->addItem(item);
|
||||||
} else if (sourceItem.source == "AUX") {
|
} else if (sourceItem.source == "AUX") {
|
||||||
MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true);
|
MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true);
|
||||||
|
|
@ -418,7 +443,15 @@ void DevicePluginBose::onSourcesObjectReceived(QUuid requestId, SourcesObject so
|
||||||
result->addItem(item);
|
result->addItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result->finish(Device::DeviceErrorNoError);
|
return result->finish(Device::DeviceErrorNoError);
|
||||||
|
} else if (m_asyncBrowseItemResults.contains(requestId)) {
|
||||||
|
BrowserItemResult *result = m_asyncBrowseItemResults.value(requestId);
|
||||||
|
foreach (SourceItemObject sourceItem, sources.sourceItems) {
|
||||||
|
if (sourceItem.source == result->itemId()) {
|
||||||
|
return result->finish(Device::DeviceErrorNoError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result->finish(Device::DeviceErrorItemNotFound);
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcBose()) << "Received sources without an associated BrowseResult";
|
qCWarning(dcBose()) << "Received sources without an associated BrowseResult";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
* of use of nymea GmbH, available under https://nymea.io/license
|
* of use of nymea GmbH, available under https://nymea.io/license
|
||||||
*
|
*
|
||||||
* GNU Lesser General Public License Usage
|
* GNU Lesser General Public License Usage
|
||||||
* This project may also contain libraries licensed under the open source software license GNU GPL v.3.
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
* 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.
|
* 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;
|
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
|
@ -30,6 +29,7 @@
|
||||||
#define DEVICEPLUGINBOSE_H
|
#define DEVICEPLUGINBOSE_H
|
||||||
|
|
||||||
#include "devices/deviceplugin.h"
|
#include "devices/deviceplugin.h"
|
||||||
|
#include "network/zeroconf/zeroconfservicebrowser.h"
|
||||||
#include "plugintimer.h"
|
#include "plugintimer.h"
|
||||||
#include "soundtouch.h"
|
#include "soundtouch.h"
|
||||||
#include "soundtouchtypes.h"
|
#include "soundtouchtypes.h"
|
||||||
|
|
@ -48,6 +48,7 @@ public:
|
||||||
explicit DevicePluginBose();
|
explicit DevicePluginBose();
|
||||||
~DevicePluginBose() override;
|
~DevicePluginBose() override;
|
||||||
|
|
||||||
|
void init() override;
|
||||||
void discoverDevices(DeviceDiscoveryInfo *info) override;
|
void discoverDevices(DeviceDiscoveryInfo *info) override;
|
||||||
void setupDevice(DeviceSetupInfo *info) override;
|
void setupDevice(DeviceSetupInfo *info) override;
|
||||||
void postSetupDevice(Device *device) override;
|
void postSetupDevice(Device *device) override;
|
||||||
|
|
@ -59,12 +60,14 @@ public:
|
||||||
void executeBrowserItem(BrowserActionInfo *info) override;
|
void executeBrowserItem(BrowserActionInfo *info) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ZeroConfServiceBrowser *m_serviceBrowser = nullptr;
|
||||||
PluginTimer *m_pluginTimer = nullptr;
|
PluginTimer *m_pluginTimer = nullptr;
|
||||||
|
|
||||||
QHash<Device *, SoundTouch *> m_soundTouch;
|
QHash<Device *, SoundTouch *> m_soundTouch;
|
||||||
QHash<QUuid, DeviceActionInfo *> m_pendingActions;
|
QHash<QUuid, DeviceActionInfo *> m_pendingActions;
|
||||||
QHash<QUuid, BrowseResult *> m_asyncBrowseResults;
|
QHash<QUuid, BrowseResult *> m_asyncBrowseResults;
|
||||||
QHash<QUuid, BrowserActionInfo *> m_asyncExecuteBroweItems;
|
QHash<QUuid, BrowserActionInfo *> m_asyncExecuteBrowseItems;
|
||||||
|
QHash<QUuid, BrowserItemResult *> m_asyncBrowseItemResults;
|
||||||
QHash<Device *, SourcesObject> m_sourcesObjects;
|
QHash<Device *, SourcesObject> m_sourcesObjects;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
* of use of nymea GmbH, available under https://nymea.io/license
|
* of use of nymea GmbH, available under https://nymea.io/license
|
||||||
*
|
*
|
||||||
* GNU Lesser General Public License Usage
|
* GNU Lesser General Public License Usage
|
||||||
* This project may also contain libraries licensed under the open source software license GNU GPL v.3.
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
* 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.
|
* 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;
|
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
* of use of nymea GmbH, available under https://nymea.io/license
|
* of use of nymea GmbH, available under https://nymea.io/license
|
||||||
*
|
*
|
||||||
* GNU Lesser General Public License Usage
|
* GNU Lesser General Public License Usage
|
||||||
* This project may also contain libraries licensed under the open source software license GNU GPL v.3.
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
* 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.
|
* 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;
|
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
* of use of nymea GmbH, available under https://nymea.io/license
|
* of use of nymea GmbH, available under https://nymea.io/license
|
||||||
*
|
*
|
||||||
* GNU Lesser General Public License Usage
|
* GNU Lesser General Public License Usage
|
||||||
* This project may also contain libraries licensed under the open source software license GNU GPL v.3.
|
|
||||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
* 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.
|
* 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;
|
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue