added source browsing

master
Boernsman 2020-01-16 12:35:01 +01:00
parent fe916126f6
commit 568b7ffd31
3 changed files with 96 additions and 50 deletions

View File

@ -32,6 +32,7 @@
#include "platform/platformzeroconfcontroller.h" #include "platform/platformzeroconfcontroller.h"
#include "network/zeroconf/zeroconfservicebrowser.h" #include "network/zeroconf/zeroconfservicebrowser.h"
#include "network/zeroconf/zeroconfserviceentry.h" #include "network/zeroconf/zeroconfserviceentry.h"
#include "types/mediabrowseritem.h"
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QNetworkReply> #include <QNetworkReply>
@ -44,10 +45,6 @@ DevicePluginBose::~DevicePluginBose()
{ {
} }
void DevicePluginBose::init()
{
}
void DevicePluginBose::setupDevice(DeviceSetupInfo *info) void DevicePluginBose::setupDevice(DeviceSetupInfo *info)
{ {
@ -67,11 +64,12 @@ void DevicePluginBose::setupDevice(DeviceSetupInfo *info)
connect(soundTouch, &SoundTouch::zoneReceived, this, &DevicePluginBose::onZoneObjectReceived); connect(soundTouch, &SoundTouch::zoneReceived, this, &DevicePluginBose::onZoneObjectReceived);
connect(soundTouch, &SoundTouch::requestExecuted, this, &DevicePluginBose::onRequestExecuted); connect(soundTouch, &SoundTouch::requestExecuted, this, &DevicePluginBose::onRequestExecuted);
m_soundTouch.insert(info->device(), soundTouch); m_soundTouch.insert(info->device(), soundTouch);
return info->finish(Device::DeviceErrorNoError);
info->finish(Device::DeviceErrorNoError); } else {
return; qCWarning(dcBose()) << "DeviceClassId not found" << info->device()->deviceClassId();
return info->finish(Device::DeviceErrorDeviceClassNotFound);
} }
info->finish(Device::DeviceErrorDeviceClassNotFound);
} }
void DevicePluginBose::postSetupDevice(Device *device) void DevicePluginBose::postSetupDevice(Device *device)
@ -81,7 +79,6 @@ void DevicePluginBose::postSetupDevice(Device *device)
soundTouch->getInfo(); soundTouch->getInfo();
soundTouch->getNowPlaying(); soundTouch->getNowPlaying();
soundTouch->getVolume(); soundTouch->getVolume();
soundTouch->getSources();
soundTouch->getBass(); soundTouch->getBass();
soundTouch->getBassCapabilities(); soundTouch->getBassCapabilities();
soundTouch->getZone(); soundTouch->getZone();
@ -102,6 +99,7 @@ void DevicePluginBose::deviceRemoved(Device *device)
if (m_pluginTimer && myDevices().isEmpty()) { if (m_pluginTimer && myDevices().isEmpty()) {
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
m_pluginTimer = nullptr;
} }
} }
@ -232,11 +230,12 @@ void DevicePluginBose::executeAction(DeviceActionInfo *info)
connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_pendingActions.remove(requestId);}); connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_pendingActions.remove(requestId);});
} else { } else {
info->finish(Device::DeviceErrorActionTypeNotFound); qCWarning(dcBose()) << "ActionTypeId not found" << action.actionTypeId();
return; return info->finish(Device::DeviceErrorActionTypeNotFound);
} }
} else { } else {
info->finish(Device::DeviceErrorDeviceClassNotFound); qCWarning(dcBose()) << "DeviceClassId not found" << device->deviceClassId();
return info->finish(Device::DeviceErrorDeviceClassNotFound);
} }
} }
@ -247,6 +246,7 @@ void DevicePluginBose::browseDevice(BrowseResult *result)
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_asyncBrowseResults.insert(requestId, result);
connect(result, &BrowseResult::aborted, this, [this, requestId]{m_asyncBrowseResults.remove(requestId);});
} }
} }
@ -265,11 +265,18 @@ void DevicePluginBose::executeBrowserItem(BrowserActionInfo *info)
Device *device = info->device(); Device *device = info->device();
if (device->deviceClassId() == soundtouchDeviceClassId) { if (device->deviceClassId() == soundtouchDeviceClassId) {
SoundTouch *soundTouch = m_soundTouch.value(device); SoundTouch *soundTouch = m_soundTouch.value(device);
ContentItemObject contentItem; SourcesObject sources = m_sourcesObjects.value(device);
contentItem.source = info->browserAction().itemId(); foreach (SourceItemObject source, sources.sourceItems) {
QUuid requestId = soundTouch->setSource(contentItem); if (source.source == info->browserAction().itemId()) {
m_asyncExecuteBroweItems.insert(requestId, info); ContentItemObject contentItem;
connect(info, &BrowserActionInfo::aborted, this, [this, requestId]{m_asyncExecuteBroweItems.remove(requestId);}); contentItem.source = source.source;
contentItem.sourceAccount = source.sourceAccount;
QUuid requestId = soundTouch->setSource(contentItem);
m_asyncExecuteBroweItems.insert(requestId, info);
connect(info, &BrowserActionInfo::aborted, this, [this, requestId]{m_asyncExecuteBroweItems.remove(requestId);});
break;
}
}
} }
} }
@ -312,6 +319,13 @@ 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)) {
BrowserActionInfo *info = m_asyncExecuteBroweItems.take(requestId);
if (success) {
info->finish(Device::DeviceErrorNoError);
} else {
info->finish(Device::DeviceErrorHardwareFailure);
}
} else { } else {
//This request was not an action or browse request //This request was not an action or browse request
} }
@ -376,12 +390,33 @@ void DevicePluginBose::onVolumeObjectReceived(QUuid requestId, VolumeObject volu
void DevicePluginBose::onSourcesObjectReceived(QUuid requestId, SourcesObject sources) void DevicePluginBose::onSourcesObjectReceived(QUuid requestId, SourcesObject sources)
{ {
SoundTouch *soundtouch = static_cast<SoundTouch *>(sender());
Device *device = m_soundTouch.key(soundtouch);
m_sourcesObjects.insert(device, sources);
if (m_asyncBrowseResults.contains(requestId)) { if (m_asyncBrowseResults.contains(requestId)) {
BrowseResult *result = m_asyncBrowseResults.value(requestId); BrowseResult *result = m_asyncBrowseResults.value(requestId);
foreach (SourceItemObject sourceItem, sources.sourceItems) { foreach (SourceItemObject sourceItem, sources.sourceItems) {
qDebug(dcBose()) << "Source:" << sources.deviceId << sourceItem.source << sourceItem.displayName; qDebug(dcBose()) << "Source:" << sourceItem.source;
BrowserItem item("sources"+sourceItem.source, sourceItem.displayName, false, true); if (sourceItem.source == "BLUETOOTH") {
result->addItem(item); MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true);
item.setDescription(sourceItem.sourceAccount);
item.setIcon(BrowserItem::BrowserIcon::BrowserIconMusic);
item.setMediaIcon(MediaBrowserItem::MediaBrowserIcon::MediaBrowserIconRecentlyPlayed);
result->addItem(item);
} else if (sourceItem.source == "AUX") {
MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true);
item.setDescription(sourceItem.sourceAccount);
item.setIcon(BrowserItem::BrowserIcon::BrowserIconMusic);
result->addItem(item);
item.setMediaIcon(MediaBrowserItem::MediaBrowserIcon::MediaBrowserIconAux);
} else if ((sourceItem.source == "SPOTIFY") && (sourceItem.status == SOURCE_STATUS_READY)) {
MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true);
item.setDescription(sourceItem.sourceAccount);
item.setIcon(BrowserItem::BrowserIcon::BrowserIconMusic);
item.setMediaIcon(MediaBrowserItem::MediaBrowserIcon::MediaBrowserIconSpotify);
result->addItem(item);
}
} }
result->finish(Device::DeviceErrorNoError); result->finish(Device::DeviceErrorNoError);
} else { } else {
@ -415,7 +450,6 @@ void DevicePluginBose::onGroupObjectReceived(QUuid requestId, GroupObject group)
void DevicePluginBose::onZoneObjectReceived(QUuid requestId, ZoneObject zone) void DevicePluginBose::onZoneObjectReceived(QUuid requestId, ZoneObject zone)
{ {
Q_UNUSED(requestId); Q_UNUSED(requestId);
qDebug(dcBose()) << "Zone master" << zone.deviceID;
foreach (MemberObject member, zone.members) { foreach (MemberObject member, zone.members) {
qDebug(dcBose()) << "-> member:" << member.deviceID; qDebug(dcBose()) << "-> member:" << member.deviceID;
} }

View File

@ -48,7 +48,6 @@ 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;
@ -66,6 +65,7 @@ private:
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_asyncExecuteBroweItems;
QHash<Device *, SourcesObject> m_sourcesObjects;
private slots: private slots:
void onPluginTimer(); void onPluginTimer();

View File

@ -229,8 +229,9 @@ QUuid SoundTouch::setKey(KEY_VALUE keyValue)
} }
xml.writeEndElement(); //key xml.writeEndElement(); //key
xml.writeEndDocument(); xml.writeEndDocument();
//qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -251,7 +252,9 @@ QUuid SoundTouch::setKey(KEY_VALUE keyValue)
xml.writeCharacters("POWER"); xml.writeCharacters("POWER");
xml.writeEndElement(); //key xml.writeEndElement(); //key
xml.writeEndDocument(); xml.writeEndDocument();
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [reply] {reply->deleteLater();}); connect(reply, &QNetworkReply::finished, this, [reply] {reply->deleteLater();});
} }
return requestId; return requestId;
@ -269,8 +272,9 @@ QUuid SoundTouch::setVolume(int volume)
content.append("<volume>"); content.append("<volume>");
content.append(QByteArray::number(volume)); content.append(QByteArray::number(volume));
content.append("</volume>"); content.append("</volume>");
//qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -294,9 +298,9 @@ QUuid SoundTouch::setSource(ContentItemObject contentItem)
xml.writeAttribute("sourceAccount", contentItem.sourceAccount); xml.writeAttribute("sourceAccount", contentItem.sourceAccount);
xml.writeEndElement(); //ContentItem xml.writeEndElement(); //ContentItem
xml.writeEndDocument(); xml.writeEndDocument();
qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -323,8 +327,9 @@ QUuid SoundTouch::setZone(ZoneObject zone)
} }
xml.writeEndElement(); //zone xml.writeEndElement(); //zone
xml.writeEndDocument(); xml.writeEndDocument();
qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -351,8 +356,9 @@ QUuid SoundTouch::addZoneSlave(ZoneObject zone)
} }
xml.writeEndElement(); //zone xml.writeEndElement(); //zone
xml.writeEndDocument(); xml.writeEndDocument();
qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -379,8 +385,9 @@ QUuid SoundTouch::removeZoneSlave(ZoneObject zone)
} }
xml.writeEndElement(); //zone xml.writeEndElement(); //zone
xml.writeEndDocument(); xml.writeEndDocument();
qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -400,8 +407,9 @@ QUuid SoundTouch::setBass(int volume)
content.append("<bass>"); content.append("<bass>");
content.append(QByteArray::number(volume)); content.append(QByteArray::number(volume));
content.append("</bass>"); content.append("</bass>");
qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -421,8 +429,9 @@ QUuid SoundTouch::setName(QString name)
content.append("<name>"); content.append("<name>");
content.append(name); content.append(name);
content.append("</name>"); content.append("</name>");
qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -450,8 +459,9 @@ QUuid SoundTouch::setSpeaker(PlayInfoObject playInfo)
xml.writeTextElement("volume", QString::number(playInfo.volume)); xml.writeTextElement("volume", QString::number(playInfo.volume));
xml.writeEndElement(); //play_info xml.writeEndElement(); //play_info
xml.writeEndDocument(); xml.writeEndDocument();
qDebug(dcBose) << "Sending request" << url << content; QNetworkRequest request(url);
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
QNetworkReply *reply = m_networkAccessManager->post(request, content);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
reply->deleteLater(); reply->deleteLater();
emitRequestStatus(requestId, reply); emitRequestStatus(requestId, reply);
@ -509,6 +519,7 @@ QUuid SoundTouch::sendGetRequest(QString path)
if (reply->error() != QNetworkReply::NoError) { if (reply->error() != QNetworkReply::NoError) {
emit requestExecuted(requestId, false); emit requestExecuted(requestId, false);
emit connectionChanged(false); emit connectionChanged(false);
qCWarning(dcBose()) << "Request error" << reply->errorString();
return; return;
} }
emit connectionChanged(true); emit connectionChanged(true);
@ -522,7 +533,6 @@ QUuid SoundTouch::sendGetRequest(QString path)
QByteArray data = reply->readAll(); QByteArray data = reply->readAll();
parseData(requestId, data); parseData(requestId, data);
}); });
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRestRequestError(QNetworkReply::NetworkError)));
return requestId; return requestId;
} }
@ -542,6 +552,7 @@ void SoundTouch::emitRequestStatus(QUuid requestId, QNetworkReply *reply)
return; return;
} }
QByteArray data = reply->readAll(); QByteArray data = reply->readAll();
qCDebug(dcBose()) << "Request status" << data;
QXmlStreamReader xml; QXmlStreamReader xml;
xml.addData(data); xml.addData(data);
@ -732,7 +743,6 @@ void SoundTouch::parseData(QUuid requestId, const QByteArray &data)
xml.skipCurrentElement(); xml.skipCurrentElement();
} }
} }
emit nowPlayingReceived(requestId, nowPlaying); emit nowPlayingReceived(requestId, nowPlaying);
} else if (xml.name() == "volume") { } else if (xml.name() == "volume") {
VolumeObject volumeObject; VolumeObject volumeObject;
@ -767,10 +777,12 @@ void SoundTouch::parseData(QUuid requestId, const QByteArray &data)
if(xml.attributes().hasAttribute("source")) { if(xml.attributes().hasAttribute("source")) {
//qDebug(dcBose) << "Source" << xml.attributes().value("source").toString(); //qDebug(dcBose) << "Source" << xml.attributes().value("source").toString();
sourceItem.source = xml.attributes().value("source").toString(); sourceItem.source = xml.attributes().value("source").toString();
} else if(xml.attributes().hasAttribute("sourceAccount")) { }
if(xml.attributes().hasAttribute("sourceAccount")) {
//qDebug(dcBose) << "Source Account" << xml.attributes().value("sourceAccount").toString(); //qDebug(dcBose) << "Source Account" << xml.attributes().value("sourceAccount").toString();
sourceItem.sourceAccount = xml.attributes().value("sourceAccount").toString(); sourceItem.sourceAccount = xml.attributes().value("sourceAccount").toString();
} else if(xml.attributes().hasAttribute("status")) { }
if(xml.attributes().hasAttribute("status")) {
QString status = xml.attributes().value("status").toString().toUpper(); //UNAVAILABLE, READY QString status = xml.attributes().value("status").toString().toUpper(); //UNAVAILABLE, READY
//qDebug(dcBose) << "status" << status; //qDebug(dcBose) << "status" << status;
if (status == "READY") { if (status == "READY") {
@ -778,11 +790,13 @@ void SoundTouch::parseData(QUuid requestId, const QByteArray &data)
} else { } else {
sourceItem.status = SOURCE_STATUS_UNAVAILABLE; sourceItem.status = SOURCE_STATUS_UNAVAILABLE;
} }
} else if(xml.attributes().hasAttribute("isLocal")) { }
if(xml.attributes().hasAttribute("isLocal")) {
//qDebug(dcBose) << "is Local" << xml.attributes().value("isLocal").toString(); //qDebug(dcBose) << "is Local" << xml.attributes().value("isLocal").toString();
sourceItem.isLocal = ( xml.attributes().value("isLocal").toString().toUpper() == "TRUE" ); sourceItem.isLocal = ( xml.attributes().value("isLocal").toString().toUpper() == "TRUE" );
} else if(xml.attributes().hasAttribute("multiroomallowed")) { }
//Debug(dcBose) << "multiroom allowed" << xml.attributes().value("multiroomallowed").toString(); if(xml.attributes().hasAttribute("multiroomallowed")) {
//qCDebug(dcBose) << "multiroom allowed" << xml.attributes().value("multiroomallowed").toString();
sourceItem.multiroomallowed = ( xml.attributes().value("multiroomallowed").toString().toUpper() == "TRUE" ); sourceItem.multiroomallowed = ( xml.attributes().value("multiroomallowed").toString().toUpper() == "TRUE" );
} }
sourceItem.displayName = xml.readElementText(); sourceItem.displayName = xml.readElementText();
@ -812,11 +826,9 @@ void SoundTouch::parseData(QUuid requestId, const QByteArray &data)
emit bassReceived(requestId, bassObject); emit bassReceived(requestId, bassObject);
} else if (xml.name() == "bassCapabilities") { } else if (xml.name() == "bassCapabilities") {
BassCapabilitiesObject bassCapabilities; BassCapabilitiesObject bassCapabilities;
if(xml.attributes().hasAttribute("deviceID")) { if(xml.attributes().hasAttribute("deviceID")) {
bassCapabilities.deviceID = xml.attributes().value("deviceID").toString(); bassCapabilities.deviceID = xml.attributes().value("deviceID").toString();
} }
while(xml.readNextStartElement()){ while(xml.readNextStartElement()){
if(xml.name() == "bassAvailable"){ if(xml.name() == "bassAvailable"){
//qDebug(dcBose) << "BassAvailable" << xml.readElementText(); //qDebug(dcBose) << "BassAvailable" << xml.readElementText();