actions and states are now fixed
parent
f7284bd57e
commit
dbef0ff202
|
|
@ -1,3 +1,25 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "soundtouch.h"
|
||||
#include "hardwaremanager.h"
|
||||
#include "devices/device.h"
|
||||
|
|
@ -18,6 +40,7 @@ SoundTouch::SoundTouch(NetworkAccessManager *networkAccessManager, QString ipAdd
|
|||
url.setPort(8080);
|
||||
qDebug(dcBose) << "Connecting websocket to" << url;
|
||||
//TODO missing websocket subprotocol "gabbo"
|
||||
//Seems QWebsockets doesn't support subprotocols
|
||||
m_websocket->open(url);
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +51,7 @@ void SoundTouch::getInfo()
|
|||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/info");
|
||||
qDebug(dcBose) << "Sending request" << url;
|
||||
//qDebug(dcBose) << "Sending request" << url;
|
||||
QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
|
@ -40,7 +63,7 @@ void SoundTouch::getVolume()
|
|||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/volume");
|
||||
qDebug(dcBose) << "Sending request" << url;
|
||||
//qDebug(dcBose) << "Sending request" << url;
|
||||
QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
|
@ -52,7 +75,7 @@ void SoundTouch::getNowPlaying()
|
|||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/now_playing");
|
||||
qDebug(dcBose) << "Sending request" << url;
|
||||
//qDebug(dcBose) << "Sending request" << url;
|
||||
QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
|
@ -64,7 +87,7 @@ void SoundTouch::getBass()
|
|||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/bass");
|
||||
qDebug(dcBose) << "Sending request" << url;
|
||||
//qDebug(dcBose) << "Sending request" << url;
|
||||
QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
|
@ -83,12 +106,38 @@ void SoundTouch::getGroup()
|
|||
|
||||
void SoundTouch::getSources()
|
||||
{
|
||||
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/sources");
|
||||
//qDebug(dcBose) << "Sending request" << url;
|
||||
QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::getZone()
|
||||
{
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/getZone");
|
||||
qDebug(dcBose) << "Sending request" << url;
|
||||
QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::getPresets()
|
||||
{
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/presets");
|
||||
qDebug(dcBose) << "Sending request" << url;
|
||||
QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::setKey(KEY_VALUE keyValue)
|
||||
|
|
@ -107,6 +156,9 @@ void SoundTouch::setKey(KEY_VALUE keyValue)
|
|||
case KEY_VALUE_STOP:
|
||||
content.append("STOP");
|
||||
break;
|
||||
case KEY_VALUE_PAUSE:
|
||||
content.append("PAUSE");
|
||||
break;
|
||||
case KEY_VALUE_PLAY_PAUSE:
|
||||
content.append("PLAY_PAUSE");
|
||||
break;
|
||||
|
|
@ -165,7 +217,7 @@ void SoundTouch::setKey(KEY_VALUE keyValue)
|
|||
content.append("<key state=\"release\" sender=\"Gabbo\">");
|
||||
content.append("POWER");
|
||||
content.append("</key>");
|
||||
qDebug(dcBose) << "Sending request" << url << content;
|
||||
//qDebug(dcBose) << "Sending request" << url << content;
|
||||
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content);
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
|
@ -182,6 +234,106 @@ void SoundTouch::setVolume(int volume)
|
|||
content.append("<volume>");
|
||||
content.append(QByteArray::number(volume));
|
||||
content.append("</volume>");
|
||||
//qDebug(dcBose) << "Sending request" << url << content;
|
||||
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content);
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::setSource(ContentItemObject contentItem)
|
||||
{
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/select"); //Select source
|
||||
QByteArray content;
|
||||
QXmlStreamWriter xml(&content);
|
||||
xml.writeStartDocument();
|
||||
xml.writeStartElement("ContentItem");
|
||||
xml.writeAttribute("source", contentItem.source);
|
||||
xml.writeAttribute("sourceAccount", contentItem.sourceAccount);
|
||||
xml.writeEndElement(); //ContentItem
|
||||
xml.writeEndDocument();
|
||||
qDebug(dcBose) << "Sending request" << url << content;
|
||||
|
||||
//QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content);
|
||||
//connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::setZone(ZoneObject zone)
|
||||
{
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/setZone");
|
||||
QByteArray content;
|
||||
QXmlStreamWriter xml(&content);
|
||||
xml.writeStartDocument();
|
||||
xml.writeStartElement("zone");
|
||||
xml.writeAttribute("master", zone.deviceID);
|
||||
xml.writeTextElement("member", zone.member.deviceID);
|
||||
xml.writeAttribute("ipaddress", zone.member.ipAddress);
|
||||
xml.writeEndElement(); //zone
|
||||
xml.writeEndDocument();
|
||||
qDebug(dcBose) << "Sending request" << url << content;
|
||||
//QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content);
|
||||
//connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::addZoneSlave(ZoneObject zone)
|
||||
{
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/addZoneSlave");
|
||||
QByteArray content;
|
||||
QXmlStreamWriter xml(&content);
|
||||
xml.writeStartDocument();
|
||||
xml.writeStartElement("zone");
|
||||
xml.writeAttribute("master", zone.deviceID);
|
||||
xml.writeTextElement("member", zone.member.deviceID);
|
||||
xml.writeAttribute("ipaddress", zone.member.ipAddress);
|
||||
xml.writeEndElement(); //zone
|
||||
xml.writeEndDocument();
|
||||
qDebug(dcBose) << "Sending request" << url << content;
|
||||
//QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content);
|
||||
//connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::removeZoneSlave(ZoneObject zone)
|
||||
{
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/removeZoneSlave");
|
||||
QByteArray content;
|
||||
QXmlStreamWriter xml(&content);
|
||||
xml.writeStartDocument();
|
||||
xml.writeStartElement("zone");
|
||||
xml.writeAttribute("master", zone.deviceID);
|
||||
xml.writeTextElement("member", zone.member.deviceID);
|
||||
xml.writeAttribute("ipaddress", zone.member.ipAddress);
|
||||
xml.writeEndElement(); //zone
|
||||
xml.writeEndDocument();
|
||||
qDebug(dcBose) << "Sending request" << url << content;
|
||||
//QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content);
|
||||
//connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::setBass(int volume)
|
||||
{
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/bass");
|
||||
QByteArray content = ("<?xml version=\"1.0\" ?>");
|
||||
content.append("<bass>");
|
||||
content.append(QByteArray::number(volume));
|
||||
content.append("</bass>");
|
||||
qDebug(dcBose) << "Sending request" << url << content;
|
||||
QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content);
|
||||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
|
|
@ -203,6 +355,30 @@ void SoundTouch::setName(QString name)
|
|||
connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::setSpeaker(PlayInfoObject playInfo)
|
||||
{
|
||||
QUrl url;
|
||||
url.setHost(m_ipAddress);
|
||||
url.setScheme("http");
|
||||
url.setPort(m_port);
|
||||
url.setPath("/speaker");
|
||||
QByteArray content;
|
||||
QXmlStreamWriter xml(&content);
|
||||
xml.writeStartDocument();
|
||||
xml.writeStartElement("play_info");
|
||||
xml.writeTextElement("app_key", playInfo.appKey);
|
||||
xml.writeTextElement("url", playInfo.url);
|
||||
xml.writeTextElement("service", playInfo.services);
|
||||
xml.writeTextElement("reason", playInfo.reason);
|
||||
xml.writeTextElement("message", playInfo.message);
|
||||
xml.writeTextElement("volume", QString::number(playInfo.volume));
|
||||
xml.writeEndElement(); //play_info
|
||||
xml.writeEndDocument();
|
||||
qDebug(dcBose) << "Sending request" << url << content;
|
||||
//QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content);
|
||||
//connect(reply, &QNetworkReply::finished, this, &SoundTouch::onRestRequestFinished);
|
||||
}
|
||||
|
||||
void SoundTouch::onWebsocketConnected()
|
||||
{
|
||||
qDebug(dcBose) << "Bose websocket connected";
|
||||
|
|
@ -229,9 +405,9 @@ void SoundTouch::onRestRequestFinished() {
|
|||
reply->deleteLater();
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
qDebug(dcBose) << "REST message received:" << data;
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
|
||||
//qDebug(dcBose) << data;
|
||||
// Check HTTP status code
|
||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcBose()) << "Request error:" << status << reply->errorString();
|
||||
|
|
@ -250,24 +426,28 @@ void SoundTouch::onRestRequestFinished() {
|
|||
}
|
||||
while(xml.readNextStartElement()){
|
||||
if(xml.name() == "name"){
|
||||
qDebug(dcBose) << "name" << xml.readElementText();
|
||||
//qDebug(dcBose) << "name" << xml.readElementText();
|
||||
info.name = xml.readElementText();
|
||||
} else if(xml.name() == "type"){
|
||||
qDebug(dcBose) << "type" << xml.readElementText();
|
||||
//qDebug(dcBose) << "type" << xml.readElementText();
|
||||
info.type = xml.readElementText();
|
||||
} else if(xml.name() == "components"){
|
||||
qDebug(dcBose) << "components element";
|
||||
//qDebug(dcBose) << "components element";
|
||||
while(xml.readNextStartElement()){
|
||||
if(xml.name() == "component"){
|
||||
ComponentObject component;
|
||||
while(xml.readNextStartElement()){
|
||||
if(xml.name() == "softwareVersion"){
|
||||
qDebug(dcBose) << "Software version" << xml.readElementText();
|
||||
//qDebug(dcBose) << "Software version" << xml.readElementText();
|
||||
component.softwareVersion = xml.readElementText();
|
||||
} else if(xml.name() == "serialNumber") {
|
||||
qDebug(dcBose) << "Serialnumber" << xml.readElementText();
|
||||
//qDebug(dcBose) << "Serialnumber" << xml.readElementText();
|
||||
component.serialNumber = xml.readElementText();
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
info.components.append(component);
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
|
|
@ -288,27 +468,171 @@ void SoundTouch::onRestRequestFinished() {
|
|||
}
|
||||
}
|
||||
emit infoReceived(info);
|
||||
} else if (xml.name() == "now_playing") {
|
||||
} else if (xml.name() == "nowPlaying") {
|
||||
NowPlayingObject nowPlaying;
|
||||
if(xml.attributes().hasAttribute("deviceID")) {
|
||||
//qDebug(dcBose) << "Device ID" << xml.attributes().value("deviceID").toString();
|
||||
nowPlaying.deviceID = xml.attributes().value("deviceID").toString();
|
||||
}
|
||||
if(xml.attributes().hasAttribute("source")) {
|
||||
//qDebug(dcBose) << "Source" << xml.attributes().value("source").toString();
|
||||
nowPlaying.source = xml.attributes().value("source").toString();
|
||||
}
|
||||
if(xml.attributes().hasAttribute("sourceAccount")) {
|
||||
//qDebug(dcBose) << "Source Account" << xml.attributes().value("sourceAccount").toString();
|
||||
nowPlaying.sourceAccount = xml.attributes().value("sourceAccount").toString();
|
||||
}
|
||||
while(xml.readNextStartElement()){
|
||||
if (xml.name() == "track") {
|
||||
//qDebug(dcBose) << "track" << xml.readElementText();
|
||||
nowPlaying.track = xml.readElementText();
|
||||
} else if(xml.name() == "artist") {
|
||||
//qDebug(dcBose) << "artist" << xml.readElementText();
|
||||
nowPlaying.artist = xml.readElementText();
|
||||
} else if(xml.name() == "album") {
|
||||
//qDebug(dcBose) << "album" << xml.readElementText();
|
||||
nowPlaying.album = xml.readElementText();
|
||||
} else if(xml.name() == "genre") {
|
||||
//qDebug(dcBose) << "genre" << xml.readElementText();
|
||||
nowPlaying.genre = xml.readElementText();
|
||||
} else if(xml.name() == "rating") {
|
||||
//qDebug(dcBose) << "rating" << xml.readElementText();
|
||||
nowPlaying.rating = xml.readElementText();
|
||||
} else if(xml.name() == "stationName") {
|
||||
//qDebug(dcBose) << "Station name" << xml.readElementText();
|
||||
nowPlaying.stationName = xml.readElementText();
|
||||
} else if(xml.name() == "art") {
|
||||
ArtObject art;
|
||||
if(xml.attributes().hasAttribute("artImageStatus")) {
|
||||
QString artStatus = xml.attributes().value("artImageStatus").toString().toUpper();
|
||||
//ART_STATUS: INVALID, SHOW_DEFAULT_IMAGE, DOWNLOADING, IMAGE_PRESENT
|
||||
//qDebug(dcBose) << "Art Image status" << artStatus;
|
||||
if (artStatus == "INVALID") {
|
||||
art.artStatus = ART_STATUS_INVALID;
|
||||
} else if (artStatus == "SHOW_DEFAULT_IMAGE") {
|
||||
art.artStatus = ART_STATUS_SHOW_DEFAULT_IMAGE;
|
||||
} else if (artStatus == "DOWNLOADING") {
|
||||
art.artStatus = ART_STATUS_DOWNLOADING;
|
||||
} else if (artStatus == "IMAGE_PRESENT") {
|
||||
art.artStatus = ART_STATUS_IMAGE_PRESENT;
|
||||
}
|
||||
}
|
||||
nowPlaying.art.url = xml.readElementText();
|
||||
}else if(xml.name() == "playStatus") {
|
||||
QString playStatus = xml.readElementText();
|
||||
//qDebug(dcBose) << "Play Status" << playStatus;
|
||||
//Modes: PLAY_STATE, PAUSE_STATE, STOP_STATE, BUFFERING_STATE
|
||||
if (playStatus == "PLAY_STATE") {
|
||||
nowPlaying.playStatus = PLAY_STATUS_PLAY_STATE;
|
||||
} else if (playStatus == "PAUSE_STATE") {
|
||||
nowPlaying.playStatus = PLAY_STATUS_PAUSE_STATE;
|
||||
} else if (playStatus == "STOP_STATE") {
|
||||
nowPlaying.playStatus = PLAY_STATUS_STOP_STATE;
|
||||
} else if (playStatus == "BUFFERING_STATE") {
|
||||
nowPlaying.playStatus = PLAY_STATUS_BUFFERING_STATE;
|
||||
}
|
||||
} else if(xml.name() == "shuffleSetting") {
|
||||
QString shuffle = xml.readElementText().toUpper();
|
||||
//qDebug(dcBose) << "Shuffle Setting" << shuffle;
|
||||
if (shuffle == "SHUFFLE_ON") {
|
||||
nowPlaying.shuffleSetting = SHUFFLE_STATUS_SHUFFLE_ON;
|
||||
} else {
|
||||
nowPlaying.shuffleSetting = SHUFFLE_STATUS_SHUFFLE_OFF;
|
||||
}
|
||||
}else if(xml.name() == "repeatSetting") {
|
||||
QString repeat = xml.readElementText().toUpper();
|
||||
//qDebug(dcBose) << "Repeat Setting" << repeat;
|
||||
//Modes: REPEAT_OFF, REPEAT_ALL, REPEAT_ONE
|
||||
if (repeat == "REPEAT_OFF") {
|
||||
nowPlaying.repeatSettings = REPEAT_STATUS_REPEAT_OFF;
|
||||
} else if (repeat == "REPEAT_ONE") {
|
||||
nowPlaying.repeatSettings = REPEAT_STATUS_REPEAT_ONE;
|
||||
} else if (repeat == "REPEAT_ALL") {
|
||||
nowPlaying.repeatSettings = REPEAT_STATUS_REPEAT_ALL;
|
||||
}
|
||||
} else if(xml.name() == "streamType") {
|
||||
QString streamType = xml.readElementText().toUpper();
|
||||
//qDebug(dcBose) << "Stream Type" << streamType;
|
||||
//Types: TRACK_ONDEMAND, RADIO_STREAMING, RADIO_TRACKS, NO_TRANSPORT_CONTROLS
|
||||
if (streamType == "RADIO_TRACKS") {
|
||||
nowPlaying.streamType = STREAM_STATUS_RADIO_TRACKS;
|
||||
} else if (streamType == "TRACK_ONDEMAND") {
|
||||
nowPlaying.streamType = STREAM_STATUS_TRACK_ONDEMAND;
|
||||
} else if (streamType == "RADIO_STREAMING") {
|
||||
nowPlaying.streamType = STREAM_STATUS_RADIO_STREAMING;
|
||||
} else if (streamType == "NO_TRANSPORT_CONTROLS") {
|
||||
nowPlaying.streamType = STREAM_STATUS_NO_TRANSPORT_CONTROLS;
|
||||
};
|
||||
} else if(xml.name() == "stationLocation") {
|
||||
nowPlaying.stationLocation = xml.readElementText();
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
emit
|
||||
emit nowPlayingReceived(nowPlaying);
|
||||
} else if (xml.name() == "volume") {
|
||||
VolumeObject volumeObject;
|
||||
if(xml.attributes().hasAttribute("deviceID")) {
|
||||
//qDebug(dcBose) << "Device ID" << xml.attributes().value("deviceID").toString();
|
||||
volumeObject.deviceID = xml.attributes().value("deviceID").toString();
|
||||
}
|
||||
while(xml.readNextStartElement()){
|
||||
if(xml.name() == "targetvolume"){
|
||||
//qDebug(dcBose) << "Target volume" << xml.readElementText();
|
||||
volumeObject.targetVolume = xml.readElementText().toInt();
|
||||
}else if(xml.name() == "actualvolume"){
|
||||
//qDebug(dcBose) << "Actual volume" << xml.readElementText();
|
||||
volumeObject.actualVolume = xml.readElementText().toInt();
|
||||
}else if(xml.name() == "muteenabled"){
|
||||
//qDebug(dcBose) << "Mute enabled" << xml.readElementText();
|
||||
volumeObject.muteEnabled = ( xml.readElementText().toUpper() == "TRUE" ); //TODO convert from "false" to bool
|
||||
}else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
emit volumeReceived(volumeObject);
|
||||
} else if (xml.name() == "sources") {
|
||||
SourcesObject sourcesObject;
|
||||
if(xml.attributes().hasAttribute("deviceID")) {
|
||||
//qDebug(dcBose) << "Device ID" << xml.attributes().value("deviceID").toString();
|
||||
sourcesObject.deviceId = xml.attributes().value("deviceID").toString();
|
||||
}
|
||||
while(xml.readNextStartElement()){
|
||||
if(xml.name() == "sourceItem"){
|
||||
SourceItemObject sourceItem;
|
||||
if(xml.attributes().hasAttribute("source")) {
|
||||
//qDebug(dcBose) << "Source" << xml.attributes().value("source").toString();
|
||||
sourceItem.source = xml.attributes().value("source").toString();
|
||||
} else if(xml.attributes().hasAttribute("sourceAccount")) {
|
||||
//qDebug(dcBose) << "Source Account" << xml.attributes().value("sourceAccount").toString();
|
||||
sourceItem.sourceAccount = xml.attributes().value("sourceAccount").toString();
|
||||
} else if(xml.attributes().hasAttribute("status")) {
|
||||
QString status = xml.attributes().value("status").toString().toUpper(); //UNAVAILABLE, READY
|
||||
//qDebug(dcBose) << "status" << status;
|
||||
if (status == "READY") {
|
||||
sourceItem.status = SOURCE_STATUS_READY;
|
||||
} else {
|
||||
sourceItem.status = SOURCE_STATUS_UNAVAILABLE;
|
||||
}
|
||||
} else if(xml.attributes().hasAttribute("isLocal")) {
|
||||
//qDebug(dcBose) << "is Local" << xml.attributes().value("isLocal").toString();
|
||||
sourceItem.isLocal = ( xml.attributes().value("isLocal").toString().toUpper() == "TRUE" );
|
||||
} else if(xml.attributes().hasAttribute("multiroomallowed")) {
|
||||
//Debug(dcBose) << "multiroom allowed" << xml.attributes().value("multiroomallowed").toString();
|
||||
sourceItem.multiroomallowed = ( xml.attributes().value("multiroomallowed").toString().toUpper() == "TRUE" );
|
||||
}
|
||||
sourceItem.displayName = xml.readElementText();
|
||||
sourcesObject.sourceItems.append(sourceItem);
|
||||
}else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
emit sourcesReceived(sourcesObject);
|
||||
} else {
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
/*while (!xml.atEnd()) {
|
||||
if (xml.readNext()) {
|
||||
if (xml.tokenType() == TokenType::)
|
||||
qDebug(dcBose) << "element" << xml.tokenString() << xml.readElementText();
|
||||
}
|
||||
|
||||
if (xml.hasError()) {
|
||||
qCWarning(dcBose()) << "Error when parsing XML response";
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SOUNDTOUCH_H
|
||||
#define SOUNDTOUCH_H
|
||||
|
||||
|
|
@ -23,29 +45,31 @@ public:
|
|||
void getNowPlaying(); //Get information about what's playing on a product.
|
||||
void getBass(); //Get the bass level of a product, if supported.
|
||||
void getGroup(); //Get the current left/right stereo pair configuration of a product.
|
||||
void getSources(); //Get available sources for a product.
|
||||
void getSources(); //Get available sources for a product.
|
||||
void getZone(); //Get the current multiroom zone state of a product.
|
||||
//void getPresets(); //Get information related to the user's SoundTouch presets.
|
||||
//void getBassCapabilities(); //Get whether a product supports reducing bass.
|
||||
//void speaker(); //initiate playback of a specified network-accessible audio file on a Bose SoundTouch product.
|
||||
void setKey(KEY_VALUE keyValue); //Start and control playback on a product.
|
||||
void setVolume(int volume); //Set the volume of a product.
|
||||
void setSource(SOURCE_STATUS source); //Select a product's source.
|
||||
/*void setZone(QString zone); //Create a zone of synced products.
|
||||
void addZoneSlave(); //Add one or more slave product(s) to a multiroom zone.
|
||||
void removeZoneSlave(); //Remove one or more slave product(s) from a multiroom zone.
|
||||
void setBass(int volume); //Set the bass level of a product, if supported.*/
|
||||
void setName(QString name); //Set the products user-facing name.
|
||||
void getPresets(); //Get information related to the user's SoundTouch presets.
|
||||
void getBassCapabilities(); //Get whether a product supports reducing bass.
|
||||
|
||||
void setKey(KEY_VALUE keyValue); //Start and control playback on a product.
|
||||
void setVolume(int volume); //Set the volume of a product.
|
||||
void setSource(ContentItemObject contentItem); //Select a product's source.
|
||||
void setZone(ZoneObject zone); //Create a zone of synced products.
|
||||
void addZoneSlave(ZoneObject zone); //Add one or more slave product(s) to a multiroom zone.
|
||||
void removeZoneSlave(ZoneObject zone); //Remove one or more slave product(s) from a multiroom zone.
|
||||
void setBass(int volume); //Set the bass level of a product, if supported.*/
|
||||
void setName(QString name); //Set the products user-facing name.
|
||||
void setSpeaker(PlayInfoObject playInfo); //initiate playback of a specified network-accessible audio file on a Bose SoundTouch product.
|
||||
|
||||
|
||||
private:
|
||||
NetworkAccessManager *m_networkAccessManager = nullptr;
|
||||
QString m_ipAddress;
|
||||
int m_port = 8090;
|
||||
QWebSocket *m_websocket = nullptr;
|
||||
//QHash<QNetworkReply *, Device*> m_requests;
|
||||
|
||||
signals:
|
||||
void connectionChanged(bool connected);
|
||||
|
||||
void infoReceived(InfoObject info);
|
||||
void nowPlayingReceived(NowPlayingObject nowPlaying);
|
||||
void volumeReceived(VolumeObject volume);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SOUNDTOUCHTYPES_H
|
||||
#define SOUNDTOUCHTYPES_H
|
||||
|
||||
|
|
@ -157,7 +179,7 @@ struct SourceItemObject {
|
|||
|
||||
struct SourcesObject {
|
||||
QString deviceId;
|
||||
SourceItemObject sourceItem;
|
||||
QList<SourceItemObject> sourceItems;
|
||||
};
|
||||
|
||||
struct VolumeObject {
|
||||
|
|
@ -216,5 +238,13 @@ struct GroupObject {
|
|||
PLAY_STATUS status; //Element. The state of the stereo pair group.
|
||||
};
|
||||
|
||||
struct PlayInfoObject {
|
||||
QString appKey; //Element. An authorization key used to identify the client application. Apply for an app key by creating an app here.
|
||||
QString url; //Element. A fully qualified, web hosted stream URL. The URL should include the 'http://' prefix as well as a stream suffix ('mp3', ...) for proper playback.
|
||||
QString services; //Element. This indicates the service providing the notification. This text will appear on the device display (when available) and the SoundTouch application screen.
|
||||
QString reason; //Element. This indicates the reason for the notification. This text will appear on the device display (when available) and the SoundTouch application screen. If a reason string is not provided, the field with be blank.
|
||||
QString message; //Element. This indicates further details about the notification. This text will appear on the device display (when available) and the SoundTouch application screen. If a message string is not provided, the field with be blank.
|
||||
int volume; //Element. This indicates the desired volume level while playing the notification. The value represents a percentage (0 to 100) of the full audible range of the speaker device. A value less than 10 or greater than 70 will result in an error and not play the notification. Upon completion of the notification, the speaker volume will return to its original value. If not present, the notification will play at the existing volume level.
|
||||
};
|
||||
#endif // SOUNDTOUCHTYPES_H
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue