added join/unjoin group
This commit is contained in:
parent
9388a563ff
commit
daaf76ed58
165
denon/heos.cpp
165
denon/heos.cpp
@ -53,7 +53,7 @@ Heos::~Heos()
|
||||
m_socket->close();
|
||||
}
|
||||
|
||||
void Heos::connectHeos()
|
||||
void Heos::connectDevice()
|
||||
{
|
||||
if (m_socket->state() == QAbstractSocket::ConnectingState) {
|
||||
return;
|
||||
@ -61,6 +61,18 @@ void Heos::connectHeos()
|
||||
m_socket->connectToHost(m_hostAddress, 1255);
|
||||
}
|
||||
|
||||
bool Heos::connected()
|
||||
{
|
||||
return m_socket->isOpen();
|
||||
}
|
||||
|
||||
|
||||
void Heos::disconnectDevice()
|
||||
{
|
||||
m_socket->close();
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
* PLAYER COMMANDS
|
||||
********************************/
|
||||
@ -182,17 +194,19 @@ void Heos::getNowPlayingMedia(int playerId)
|
||||
m_socket->write(cmd);
|
||||
}
|
||||
|
||||
HeosPlayer *Heos::getPlayer(int playerId)
|
||||
{
|
||||
return m_heosPlayers.value(playerId);
|
||||
}
|
||||
|
||||
void Heos::getPlayers()
|
||||
{
|
||||
QByteArray cmd = "heos://player/get_players\r\n";
|
||||
m_socket->write(cmd);
|
||||
}
|
||||
|
||||
void Heos::getPlayerInfo(int playerId)
|
||||
{
|
||||
QByteArray cmd = "heos://player/get_player_info?pid=" + QVariant(playerId).toByteArray() + "\r\n";
|
||||
qCDebug(dcDenon) << "Get player info:" << cmd;
|
||||
m_socket->write(cmd);
|
||||
}
|
||||
|
||||
void Heos::getVolume(int playerId)
|
||||
{
|
||||
QByteArray cmd = "heos://player/get_volume?pid=" + QVariant(playerId).toByteArray() + "\r\n";
|
||||
@ -331,6 +345,19 @@ void Heos::setGroupMute(int groupId, bool mute)
|
||||
m_socket->write(cmd);
|
||||
}
|
||||
|
||||
void Heos::setGroup(QList<int> playerIds)
|
||||
{
|
||||
QByteArray cmd = "heos://group/set_group?pid=";
|
||||
foreach(int playerId, playerIds) {
|
||||
cmd.append(QVariant(playerId).toByteArray());
|
||||
cmd.append(',');
|
||||
}
|
||||
cmd.resize(cmd.size()-1); //remove last ','
|
||||
cmd.append("\r\n");
|
||||
qCDebug(dcDenon) << "Set group:" << cmd;
|
||||
m_socket->write(cmd);
|
||||
}
|
||||
|
||||
void Heos::toggleGroupMute(int groupId)
|
||||
{
|
||||
QByteArray cmd = "heos://group/toggle_mute?gid=" + QVariant(groupId).toByteArray() + "\r\n";
|
||||
@ -483,7 +510,7 @@ void Heos::onDisconnected()
|
||||
{
|
||||
qCDebug(dcDenon()) << "Disconnected from" << m_hostAddress.toString() << "try reconnecting in 5 seconds";
|
||||
QTimer::singleShot(5000, this, [this](){
|
||||
connectHeos();
|
||||
connectDevice();
|
||||
});
|
||||
emit connectionStatusChanged(false);
|
||||
}
|
||||
@ -495,7 +522,6 @@ void Heos::onError(QAbstractSocket::SocketError socketError)
|
||||
|
||||
void Heos::readData()
|
||||
{
|
||||
|
||||
QByteArray data;
|
||||
QJsonParseError error;
|
||||
|
||||
@ -534,9 +560,11 @@ void Heos::readData()
|
||||
if (enabled.contains("off")) {
|
||||
qDebug(dcDenon) << "Events are disabled";
|
||||
m_eventRegistered = false;
|
||||
emit systemEventsEnabled(false);
|
||||
} else {
|
||||
qDebug(dcDenon) << "Events are enabled";
|
||||
m_eventRegistered = true;
|
||||
emit systemEventsEnabled(true);
|
||||
}
|
||||
|
||||
} else if (command.contains("check_account")) {
|
||||
@ -551,8 +579,9 @@ void Heos::readData()
|
||||
|
||||
} else if (command.contains("prettify_json_response")) {
|
||||
|
||||
} else {
|
||||
qDebug(dcDenon) << "Unhandled Heos system command" << command;
|
||||
}
|
||||
}
|
||||
/* 4.2 Player Commands
|
||||
* 4.2.1 Get Players
|
||||
* 4.2.2 Get Player Info
|
||||
@ -578,7 +607,7 @@ void Heos::readData()
|
||||
* 4.2.25 Get QuickSelects [LS AVR Only]
|
||||
* 4.2.26 Check for Firmware Update
|
||||
*/
|
||||
if (command.startsWith("player")) {
|
||||
} else if (command.startsWith("player")) {
|
||||
int playerId = 0;
|
||||
if (message.hasQueryItem("pid")) {
|
||||
playerId = message.queryItemValue("pid").toInt();
|
||||
@ -586,28 +615,45 @@ void Heos::readData()
|
||||
|
||||
if (command.contains("get_players")) {
|
||||
QVariantList payloadVariantList = jsonDoc.toVariant().toMap().value("payload").toList();
|
||||
|
||||
QList<HeosPlayer *> players;
|
||||
foreach (const QVariant &payloadEntryVariant, payloadVariantList) {
|
||||
playerId = payloadEntryVariant.toMap().value("pid").toInt();
|
||||
if(!m_heosPlayers.contains(playerId)){
|
||||
QString serialNumber = payloadEntryVariant.toMap().value("serial").toString();
|
||||
QString name = payloadEntryVariant.toMap().value("name").toString();
|
||||
HeosPlayer *heosPlayer = new HeosPlayer(playerId, name, serialNumber, this);
|
||||
m_heosPlayers.insert(playerId, heosPlayer);
|
||||
emit playerDiscovered(heosPlayer);
|
||||
}
|
||||
HeosPlayer *player = new HeosPlayer(payloadEntryVariant.toMap().value("pid").toInt());
|
||||
player->setSerialNumber(payloadEntryVariant.toMap().value("serial").toString());
|
||||
player->setName(payloadEntryVariant.toMap().value("name").toString());
|
||||
getPlayerInfo(player->playerId());
|
||||
players.append(player);
|
||||
}
|
||||
}else if (command.contains("get_player_info")) {
|
||||
emit playersRecieved(players);
|
||||
|
||||
} else if (command.contains("get_player_info")) {
|
||||
//update heos player info
|
||||
int pid = dataMap.value("payload").toMap().value("pid").toInt();
|
||||
HeosPlayer *player = new HeosPlayer(pid);
|
||||
player->setName(dataMap.value("payload").toMap().value("name").toString());
|
||||
if (dataMap.value("payload").toMap().contains("gid")) {
|
||||
player->setGroupId(dataMap.value("payload").toMap().value("gid").toInt());
|
||||
} else {
|
||||
player->setGroupId(-1); //no group assigned
|
||||
}
|
||||
player->setPlayerModel(dataMap.value("payload").toMap().value("model").toString());
|
||||
player->setPlayerVersion(dataMap.value("payload").toMap().value("version").toString());
|
||||
player->setLineOut(dataMap.value("payload").toMap().value("lineout").toString());
|
||||
player->setControl(dataMap.value("payload").toMap().value("control").toString());
|
||||
player->setSerialNumber(dataMap.value("payload").toMap().value("serial").toString());
|
||||
player->setNetwork(dataMap.value("payload").toMap().value("network").toString());
|
||||
emit playerInfoRecieved(player);
|
||||
|
||||
} else if (command.contains("get_now_playing_media")) {
|
||||
|
||||
QString artist = dataMap.value("payload").toMap().value("artist").toString();
|
||||
QString song = dataMap.value("payload").toMap().value("song").toString();
|
||||
QString artwork = dataMap.value("payload").toMap().value("image_url").toString();
|
||||
QString album = dataMap.value("payload").toMap().value("album").toString();
|
||||
SOURCE_ID sourceId = SOURCE_ID(dataMap.value("payload").toMap().value("sid").toInt());
|
||||
QString sourceId = dataMap.value("payload").toMap().value("sid").toString();
|
||||
qDebug(dcDenon) << "Now playing" << playerId << sourceId << artist << album << song;
|
||||
emit nowPlayingMediaStatusReceived(playerId, sourceId, artist, album, song, artwork);
|
||||
}else if (command.contains("get_play_state") || command.contains("set_play_state")) {
|
||||
|
||||
} else if (command.contains("get_play_state") || command.contains("set_play_state")) {
|
||||
if (message.hasQueryItem("state")) {
|
||||
PLAYER_STATE playState = PLAYER_STATE_STOP;
|
||||
if (message.queryItemValue("state").contains("play")) {
|
||||
@ -657,22 +703,23 @@ void Heos::readData()
|
||||
QVariantMap payloadVariantMap = jsonDoc.toVariant().toMap().value("payload").toMap();
|
||||
bool updateExist = payloadVariantMap.value("update").toString().contains("exist");
|
||||
emit playerUpdateAvailable(playerId, updateExist);
|
||||
} else {
|
||||
qDebug(dcDenon) << "Unhandled Heos group command" << command;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 4.3 Group Commands
|
||||
* 4.3.1 Get Groups
|
||||
* 4.3.2 Get Group Info
|
||||
* 4.3.3 Set Group
|
||||
* 4.3.4 Get Group Volume
|
||||
* 4.3.5 Set Group Volume
|
||||
* 4.2.6 Group Volume Up
|
||||
* 4.2.7 Group Volume Down
|
||||
* 4.3.8 Get Group Mute
|
||||
* 4.3.9 Set Group Mute
|
||||
* 4.3.10 Toggle Group Mute
|
||||
*/
|
||||
if (command.startsWith("group")) {
|
||||
* 4.3 Group Commands
|
||||
* 4.3.1 Get Groups
|
||||
* 4.3.2 Get Group Info
|
||||
* 4.3.3 Set Group
|
||||
* 4.3.4 Get Group Volume
|
||||
* 4.3.5 Set Group Volume
|
||||
* 4.2.6 Group Volume Up
|
||||
* 4.2.7 Group Volume Down
|
||||
* 4.3.8 Get Group Mute
|
||||
* 4.3.9 Set Group Mute
|
||||
* 4.3.10 Toggle Group Mute
|
||||
*/
|
||||
} else if (command.startsWith("group")) {
|
||||
int groupId = 0;
|
||||
if (message.hasQueryItem("gid")) {
|
||||
qDebug(dcDenon) << "Group id" << message.queryItemValue("gid");
|
||||
@ -698,8 +745,32 @@ void Heos::readData()
|
||||
}
|
||||
emit groupsReceived(groups);
|
||||
} else if (command.contains("get_group_info")) {
|
||||
QVariantMap payloadVariantMap = jsonDoc.toVariant().toMap().value("payload").toMap();
|
||||
GroupObject group;
|
||||
group.groupId = payloadVariantMap.value("gid").toInt();
|
||||
group.name = payloadVariantMap.value("name").toString();
|
||||
if (!payloadVariantMap.value("players").toList().isEmpty()) {
|
||||
QVariantList playerlist = payloadVariantMap.value("players").toList();
|
||||
foreach (const QVariant &playerVariant, playerlist) {
|
||||
PlayerObject player;
|
||||
player.name = playerVariant.toMap().value("name").toString();
|
||||
player.playerId = playerVariant.toMap().value("pid").toInt();
|
||||
group.players.append(player);
|
||||
}
|
||||
}
|
||||
emit groupInfoReceived(group);
|
||||
|
||||
} else if (command.contains("set_group")) {
|
||||
if (message.hasQueryItem("gid")) {
|
||||
|
||||
int groupId = message.queryItemValue("gid").toInt();
|
||||
QString groupName = message.queryItemValue("name");
|
||||
emit setGroupReceived(groupId, groupName);
|
||||
} else {
|
||||
//No group Id so it must have been an ungoup request
|
||||
int playerId = message.queryItemValue("pid").toInt();
|
||||
emit deleteGroupReceived(playerId);
|
||||
}
|
||||
|
||||
} else if (command.contains("get_volume") || command.contains("set_volume")) {
|
||||
|
||||
@ -722,8 +793,10 @@ void Heos::readData()
|
||||
}
|
||||
} else if (command.contains("toggle_mute")) {
|
||||
|
||||
} else {
|
||||
qDebug(dcDenon) << "Unhandled Heos group command" << command;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 4.4 Browse Commands
|
||||
* 4.4.1 Get Music Sources - "command": "browse/get_music_sources"
|
||||
@ -742,7 +815,7 @@ void Heos::readData()
|
||||
* 4.4.15 Delete HEOS Playlist - "command": "browse/delete_playlist "
|
||||
* 4.4.17 Retrieve Album Metadata - "command": "browse/retrieve_metadata",
|
||||
*/
|
||||
if (command.startsWith("browse") || command.startsWith(" browse")) {
|
||||
} else if (command.startsWith("browse") || command.startsWith(" browse")) {
|
||||
|
||||
if (command.contains("get_music_sources") || command.contains("get_source_info")) {
|
||||
qDebug(dcDenon()) << "Get music source request response received" << command;
|
||||
@ -835,8 +908,10 @@ void Heos::readData()
|
||||
|
||||
} else if (command.contains("retrieve_metadata")) {
|
||||
|
||||
} else {
|
||||
qDebug(dcDenon) << "Unhandled Heos browse command" << command;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 5. Change Events (Unsolicited Responses) 5.1 Sources Changed
|
||||
@ -853,7 +928,7 @@ void Heos::readData()
|
||||
* 5.12 Group Volume Changed
|
||||
* 5.13 User Changed
|
||||
*/
|
||||
if (command.startsWith("event")) {
|
||||
} else if (command.startsWith("event")) {
|
||||
if (command.contains("sources_changed")) {
|
||||
emit sourcesChanged();
|
||||
|
||||
@ -864,7 +939,7 @@ void Heos::readData()
|
||||
emit groupsChanged();
|
||||
|
||||
} else if (command.contains("player_state_changed")) {
|
||||
qDebug() << "Player state changed";
|
||||
qDebug(dcDenon()) << "Player state changed";
|
||||
if (message.hasQueryItem("pid")) {
|
||||
int playerId = message.queryItemValue("pid").toInt();
|
||||
if (message.hasQueryItem("state")) {
|
||||
@ -880,13 +955,13 @@ void Heos::readData()
|
||||
}
|
||||
}
|
||||
} else if (command.contains("player_now_playing_changed")) {
|
||||
qDebug(dcDenon()) << "Player now playing changed";
|
||||
qDebug(dcDenon()) << "Player now playing changed, player id:" << message.queryItemValue("pid").toInt();
|
||||
if (message.hasQueryItem("pid")) {
|
||||
int playerId = message.queryItemValue("pid").toInt();
|
||||
emit playerNowPlayingChanged(playerId);
|
||||
}
|
||||
} else if (command.contains("player_now_playing_progress")) {
|
||||
qDebug(dcDenon()) << "Player now playing progress";
|
||||
//qDebug(dcDenon()) << "Player now playing progress";
|
||||
if (message.hasQueryItem("pid")) {
|
||||
int playerId = message.queryItemValue("pid").toInt();
|
||||
int currentPossition = message.queryItemValue("cur_pos").toInt();
|
||||
@ -994,7 +1069,11 @@ void Heos::readData()
|
||||
username = message.queryItemValue("un");
|
||||
}
|
||||
emit userChanged(signedIn, username);
|
||||
} else {
|
||||
qDebug(dcDenon) << "Unhandled Heos event";
|
||||
}
|
||||
} else {
|
||||
qDebug(dcDenon) << "Unhandled Heos category" << command;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
denon/heos.h
28
denon/heos.h
@ -38,6 +38,11 @@
|
||||
#include "heosplayer.h"
|
||||
#include "heostypes.h"
|
||||
|
||||
#include "devices/device.h"
|
||||
#include "types/mediabrowseritem.h"
|
||||
#include "devices/browseresult.h"
|
||||
#include "devices/browseritemresult.h"
|
||||
|
||||
class Heos : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -46,10 +51,12 @@ public:
|
||||
explicit Heos(const QHostAddress &hostAddress, QObject *parent = nullptr);
|
||||
~Heos();
|
||||
|
||||
void connectHeos();
|
||||
void connectDevice();
|
||||
void disconnectDevice();
|
||||
bool connected();
|
||||
|
||||
void setAddress(QHostAddress address);
|
||||
QHostAddress getAddress();
|
||||
HeosPlayer *getPlayer(int playerId);
|
||||
|
||||
// Heos system commands
|
||||
void registerForChangeEvents(bool state); //By default HEOS speaker does not send Change events. Controller needs to send this command with enable=on when it is ready to receive unsolicit responses from CLI. Please refer to "Driver Initialization" section regarding when to register for change events.
|
||||
@ -62,6 +69,7 @@ public:
|
||||
|
||||
//Player Get Calls
|
||||
void getPlayers(); //get a list of players associated with this heos master
|
||||
void getPlayerInfo(int playerId);
|
||||
void getPlayerState(int playerId);
|
||||
void getVolume(int playerId);
|
||||
void getNowPlayingMedia(int playerId);
|
||||
@ -87,9 +95,12 @@ public:
|
||||
void getGroupInfo(int groupId);
|
||||
void getGroupVolume(int groupId);
|
||||
void getGroupMute(int groupId);
|
||||
|
||||
//Group Set Calls
|
||||
void setGroupVolume(int groupId, bool volume);
|
||||
void setGroupMute(int groupId, bool mute);
|
||||
void setGroup(QList<int> playerIds);
|
||||
void deleteGroup(int leadPlayerId);
|
||||
void toggleGroupMute(int groupId);
|
||||
void groupVolumeUp(int groupId, int step = 5);
|
||||
void groupVolumeDown(int groupId, int step = 5);
|
||||
@ -101,8 +112,6 @@ public:
|
||||
void browseSource(const QString &sourceId);
|
||||
void browseSourceContainers(const QString &sourceId, const QString &containerId);
|
||||
|
||||
//void search();
|
||||
|
||||
//Play commands
|
||||
void playStation(int playerId, const QString &sourceId, const QString &containerId, const QString &mediaId, const QString &stationName);
|
||||
void playPresetStation(int playerId, int presetNumber);
|
||||
@ -114,14 +123,15 @@ private:
|
||||
bool m_eventRegistered = false;
|
||||
QHostAddress m_hostAddress;
|
||||
QTcpSocket *m_socket = nullptr;
|
||||
QHash<int, HeosPlayer*> m_heosPlayers;
|
||||
void setConnected(const bool &connected);
|
||||
|
||||
signals:
|
||||
void playerDiscovered(HeosPlayer *heosPlayer);
|
||||
void connectionStatusChanged(bool status);
|
||||
void systemEventsEnabled(bool status);
|
||||
|
||||
void playersChanged();
|
||||
void playersRecieved(QList<HeosPlayer *> heosPlayers);
|
||||
void playerInfoRecieved(HeosPlayer *heosPlayers);
|
||||
void playerQueueChanged(int playerId);
|
||||
void playerPlayStateReceived(int playerId, PLAYER_STATE state);
|
||||
void playerShuffleModeReceived(int playerId, bool shuffle);
|
||||
@ -134,12 +144,16 @@ signals:
|
||||
void playerNowPlayingChanged(int playerId);
|
||||
|
||||
void groupsReceived(QList<GroupObject> groups); // Callback of getGroups()
|
||||
void groupInfoReceived(GroupObject group);
|
||||
void groupVolumeReceived(int groupId, int volume);
|
||||
void groupMuteStatusReceived(int groupId, bool mute);
|
||||
void groupsChanged();
|
||||
|
||||
void setGroupReceived(int groupId, const QString &groupName); // Callback of setGroup()
|
||||
void deleteGroupReceived(int leadPlayerId); // Callback of deleteGroup();
|
||||
|
||||
void sourcesChanged();
|
||||
void nowPlayingMediaStatusReceived(int playerId, SOURCE_ID source, QString artist, QString album, QString Song, QString artwork);
|
||||
void nowPlayingMediaStatusReceived(int playerId, const QString &sourceId, const QString &artist, const QString &album, const QString &song, const QString &artwork);
|
||||
|
||||
void musicSourcesReceived(QList<MusicSourceObject> musicSources); //callback of getMusicSource, not associated to a playerId
|
||||
void browseRequestReceived(const QString &sourceId, const QString &containerId, QList<MusicSourceObject> musicSources, QList<MediaObject> mediaItems); //callback of browseSource
|
||||
|
||||
@ -30,15 +30,13 @@
|
||||
|
||||
#include "heosplayer.h"
|
||||
|
||||
HeosPlayer::HeosPlayer(int playerId, QObject *parent) :
|
||||
QObject(parent),
|
||||
HeosPlayer::HeosPlayer(int playerId) :
|
||||
m_playerId(playerId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HeosPlayer::HeosPlayer(int playerId, QString name, QString serialNumber, QObject *parent) :
|
||||
QObject(parent),
|
||||
HeosPlayer::HeosPlayer(int playerId, const QString &name, const QString &serialNumber) :
|
||||
m_playerId(playerId),
|
||||
m_serialNumber(serialNumber),
|
||||
m_name(name)
|
||||
@ -50,7 +48,7 @@ QString HeosPlayer::name()
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void HeosPlayer::setName(QString name)
|
||||
void HeosPlayer::setName(const QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
@ -75,29 +73,59 @@ QString HeosPlayer::playerModel()
|
||||
return m_playerModel;
|
||||
}
|
||||
|
||||
void HeosPlayer::setPlayerModel(const QString &playerModel)
|
||||
{
|
||||
m_playerModel = playerModel;
|
||||
}
|
||||
|
||||
QString HeosPlayer::playerVersion()
|
||||
{
|
||||
return m_playerVersion;
|
||||
}
|
||||
|
||||
void HeosPlayer::setPlayerVersion(const QString &playerVersion)
|
||||
{
|
||||
m_playerVersion = playerVersion;
|
||||
}
|
||||
|
||||
QString HeosPlayer::network()
|
||||
{
|
||||
return m_network;
|
||||
}
|
||||
|
||||
void HeosPlayer::setNetwork(const QString &network)
|
||||
{
|
||||
m_network = network;
|
||||
}
|
||||
|
||||
QString HeosPlayer::serialNumber()
|
||||
{
|
||||
return m_serialNumber;
|
||||
}
|
||||
|
||||
void HeosPlayer::setSerialNumber(const QString &serialNumber)
|
||||
{
|
||||
m_serialNumber = serialNumber;
|
||||
}
|
||||
|
||||
QString HeosPlayer::lineOut()
|
||||
{
|
||||
return m_lineOut;
|
||||
}
|
||||
|
||||
void HeosPlayer::setLineOut(const QString &lineout)
|
||||
{
|
||||
m_lineOut = lineout;
|
||||
}
|
||||
|
||||
QString HeosPlayer::control()
|
||||
{
|
||||
return m_control;
|
||||
}
|
||||
|
||||
void HeosPlayer::setControl(const QString &control)
|
||||
{
|
||||
m_control = control;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -31,26 +31,31 @@
|
||||
#ifndef HEOSPLAYER_H
|
||||
#define HEOSPLAYER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class HeosPlayer : public QObject
|
||||
class HeosPlayer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HeosPlayer(int playerId, QObject *parent = nullptr);
|
||||
explicit HeosPlayer(int playerId, QString name, QString serialNumber, QObject *parent = nullptr);
|
||||
explicit HeosPlayer(int playerId);
|
||||
explicit HeosPlayer(int playerId, const QString &name, const QString &serialNumber);
|
||||
|
||||
QString name();
|
||||
void setName(QString name);
|
||||
void setName(const QString &name);
|
||||
int playerId();
|
||||
int groupId();
|
||||
void setGroupId(int groupId);
|
||||
QString playerModel();
|
||||
void setPlayerModel(const QString &playerModel);
|
||||
QString playerVersion();
|
||||
void setPlayerVersion(const QString &playerVersion);
|
||||
QString network();
|
||||
void setNetwork(const QString &network);
|
||||
QString serialNumber();
|
||||
void setSerialNumber(const QString &serialNumber);
|
||||
QString lineOut();
|
||||
void setLineOut(const QString &lineout);
|
||||
QString control();
|
||||
void setControl(const QString &control);
|
||||
|
||||
private:
|
||||
int m_playerId;
|
||||
@ -62,7 +67,6 @@ private:
|
||||
QString m_playerModel;
|
||||
QString m_playerVersion;
|
||||
QString m_control;
|
||||
|
||||
};
|
||||
|
||||
#endif // HEOSPLAYER_H
|
||||
|
||||
@ -37,12 +37,14 @@
|
||||
#include "network/upnp/upnpdiscoveryreply.h"
|
||||
#include "platform/platformzeroconfcontroller.h"
|
||||
#include "network/zeroconf/zeroconfservicebrowser.h"
|
||||
#include "types/mediabrowseritem.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <QJsonDocument>
|
||||
#include <QTimer>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
|
||||
IntegrationPluginDenon::IntegrationPluginDenon()
|
||||
{
|
||||
@ -184,36 +186,43 @@ void IntegrationPluginDenon::setupThing(ThingSetupInfo *info)
|
||||
|
||||
denonConnection->connectDevice();
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == heosThingClassId) {
|
||||
qCDebug(dcDenon) << "Setup Denon device" << thing->paramValue(heosThingIpParamTypeId).toString();
|
||||
} else if (device->deviceClassId() == heosDeviceClassId) {
|
||||
qCDebug(dcDenon) << "Setup Denon device" << device->paramValue(heosDeviceIpParamTypeId).toString();
|
||||
|
||||
QHostAddress address(device->paramValue(heosDeviceIpParamTypeId).toString());
|
||||
if (address.isNull()) {
|
||||
qCWarning(dcDenon) << "Could not parse ip address" << device->paramValue(heosDeviceIpParamTypeId).toString();
|
||||
info->finish(Device::DeviceErrorInvalidParameter, QT_TR_NOOP("The given IP address is not valid."));
|
||||
return;
|
||||
}
|
||||
|
||||
QHostAddress address(thing->paramValue(heosThingIpParamTypeId).toString());
|
||||
Heos *heos = new Heos(address, this);
|
||||
|
||||
|
||||
connect(heos, &Heos::connectionStatusChanged, this, &IntegrationPluginDenon::onHeosConnectionChanged);
|
||||
connect(heos, &Heos::playerDiscovered, this, &IntegrationPluginDenon::onHeosPlayerDiscovered);
|
||||
connect(heos, &Heos::playStateReceived, this, &IntegrationPluginDenon::onHeosPlayStateReceived);
|
||||
connect(heos, &Heos::repeatModeReceived, this, &IntegrationPluginDenon::onHeosRepeatModeReceived);
|
||||
connect(heos, &Heos::shuffleModeReceived, this, &IntegrationPluginDenon::onHeosShuffleModeReceived);
|
||||
connect(heos, &Heos::muteStatusReceived, this, &IntegrationPluginDenon::onHeosMuteStatusReceived);
|
||||
connect(heos, &Heos::volumeStatusReceived, this, &IntegrationPluginDenon::onHeosVolumeStatusReceived);
|
||||
connect(heos, &Heos::playersChanged, this, &IntegrationPluginDenon::onHeosPlayersChanged);
|
||||
connect(heos, &Heos::playersRecieved, this, &IntegrationPluginDenon::onHeosPlayersReceived);
|
||||
connect(heos, &Heos::playerInfoRecieved, this, &IntegrationPluginDenon::onHeosPlayerInfoRecieved);
|
||||
connect(heos, &Heos::playerPlayStateReceived, this, &IntegrationPluginDenon::onHeosPlayStateReceived);
|
||||
connect(heos, &Heos::playerRepeatModeReceived, this, &IntegrationPluginDenon::onHeosRepeatModeReceived);
|
||||
connect(heos, &Heos::playerShuffleModeReceived, this, &IntegrationPluginDenon::onHeosShuffleModeReceived);
|
||||
connect(heos, &Heos::playerMuteStatusReceived, this, &IntegrationPluginDenon::onHeosMuteStatusReceived);
|
||||
connect(heos, &Heos::playerVolumeReceived, this, &IntegrationPluginDenon::onHeosVolumeStatusReceived);
|
||||
connect(heos, &Heos::nowPlayingMediaStatusReceived, this, &IntegrationPluginDenon::onHeosNowPlayingMediaStatusReceived);
|
||||
connect(heos, &Heos::playerNowPlayingChanged, this, &IntegrationPluginDenon::onHeosPlayerNowPlayingChanged);
|
||||
connect(heos, &Heos::musicSourcesReceived, this, &IntegrationPluginDenon::onHeosMusicSourcesReceived);
|
||||
connect(heos, &Heos::mediaItemsReceived, this, &IntegrationPluginDenon::onHeosMediaItemsReceived);
|
||||
connect(heos, &Heos::browseRequestReceived, this, &IntegrationPluginDenon::onHeosBrowseRequestReceived);
|
||||
connect(heos, &Heos::browseErrorReceived, this, &IntegrationPluginDenon::onHeosBrowseErrorReceived);
|
||||
connect(heos, &Heos::playerQueueChanged, this, &IntegrationPluginDenon::onHeosPlayerQueueChanged);
|
||||
connect(heos, &Heos::groupsReceived, this, &IntegrationPluginDenon::onHeosGroupsReceived);
|
||||
connect(heos, &Heos::groupsChanged, this, &IntegrationPluginDenon::onHeosGroupsChanged);
|
||||
|
||||
m_heos.insert(thing->id(), heos);
|
||||
m_heos.insert(device->id(), heos);
|
||||
|
||||
m_asyncHeosSetups.insert(heos, info);
|
||||
// In case the setup is cancelled before we finish it...
|
||||
connect(info, &QObject::destroyed, this, [this, info, heos]() { m_asyncHeosSetups.remove(heos); });
|
||||
|
||||
heos->connectHeos();
|
||||
heos->connectDevice();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -228,24 +237,24 @@ void IntegrationPluginDenon::thingRemoved(Thing *thing)
|
||||
{
|
||||
qCDebug(dcDenon) << "Delete " << thing->name();
|
||||
|
||||
AvrConnection *denonConnection = m_avrConnections.take(thing->id());
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
AvrConnection *denonConnection = m_avrConnections.value(thing->id());
|
||||
m_avrConnections.remove(thing->id());
|
||||
|
||||
denonConnection->disconnectDevice();
|
||||
denonConnection->deleteLater();
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == heosThingClassId) {
|
||||
if (m_avrConnections.contains(thing->id())) {
|
||||
AvrConnection *denonConnection = m_avrConnections.take(thing->id());
|
||||
denonConnection->disconnectDevice();
|
||||
denonConnection->deleteLater();
|
||||
}
|
||||
} else if (thing->thingClassId() == heosThingClassId) {
|
||||
if (m_heos.contains(thing->id())) {
|
||||
Heos *heos = m_heos.take(thing->id());
|
||||
heos->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
if (myThings().empty()) {
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
|
||||
m_pluginTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,7 +385,9 @@ void IntegrationPluginDenon::postSetupThing(Thing *thing)
|
||||
{
|
||||
if (thing->thingClassId() == heosThingClassId) {
|
||||
Heos *heos = m_heos.value(thing->id());
|
||||
device->setStateValue(heosConnectedStateTypeId, heos->connected());
|
||||
heos->getPlayers();
|
||||
heos->getGroups();
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == heosPlayerThingClassId) {
|
||||
@ -547,6 +558,7 @@ void IntegrationPluginDenon::onHeosConnectionChanged(bool status)
|
||||
{
|
||||
Heos *heos = static_cast<Heos *>(sender());
|
||||
heos->registerForChangeEvents(true);
|
||||
<<<<<<< HEAD:denon/integrationplugindenon.cpp
|
||||
|
||||
Thing *thing = myThings().findById(m_heos.key(heos));
|
||||
if (!thing)
|
||||
@ -563,6 +575,24 @@ void IntegrationPluginDenon::onHeosConnectionChanged(bool status)
|
||||
}
|
||||
}
|
||||
thing->setStateValue(heosConnectedStateTypeId, status);
|
||||
=======
|
||||
if (status) {
|
||||
// and from the first setup
|
||||
if (m_asyncHeosSetups.contains(heos)) {
|
||||
DeviceSetupInfo *info = m_asyncHeosSetups.take(heos);
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
}
|
||||
}
|
||||
|
||||
Device *device = myDevices().findById(m_heos.key(heos));
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
if (device->deviceClassId() == heosDeviceClassId) {
|
||||
// if the device is connected
|
||||
|
||||
device->setStateValue(heosConnectedStateTypeId, status);
|
||||
>>>>>>> added join/unjoin group:denon/IntegrationPlugindenon.cpp
|
||||
// update connection status for all child devices
|
||||
foreach (Thing *playerDevice, myThings()) {
|
||||
if (playerDevice->thingClassId() == heosPlayerThingClassId) {
|
||||
@ -574,23 +604,45 @@ void IntegrationPluginDenon::onHeosConnectionChanged(bool status)
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDenon::onHeosPlayersChanged()
|
||||
void IntegrationPluginDenon::onHeosPlayersChanged()
|
||||
{
|
||||
Heos *heos = static_cast<Heos *>(sender());
|
||||
heos->getPlayers();
|
||||
}
|
||||
|
||||
<<<<<<< HEAD:denon/integrationplugindenon.cpp
|
||||
void IntegrationPluginDenon::onHeosPlayerDiscovered(HeosPlayer *heosPlayer) {
|
||||
=======
|
||||
void IntegrationPluginDenon::onHeosPlayersReceived(QList<HeosPlayer *> heosPlayers) {
|
||||
|
||||
>>>>>>> added join/unjoin group:denon/IntegrationPlugindenon.cpp
|
||||
Heos *heos = static_cast<Heos *>(sender());
|
||||
|
||||
<<<<<<< HEAD:denon/integrationplugindenon.cpp
|
||||
Thing *thing = myThings().findById(m_heos.key(heos));
|
||||
|
||||
foreach (Thing *heosPlayerThing, myThings()) {
|
||||
if(heosPlayerThing->thingClassId() == heosPlayerThingClassId) {
|
||||
if (heosPlayerThing->paramValue(heosPlayerThingPlayerIdParamTypeId).toInt() == heosPlayer->playerId())
|
||||
return;
|
||||
=======
|
||||
QList<DeviceDescriptor> heosPlayerDescriptors;
|
||||
foreach (HeosPlayer *player, heosPlayers) {
|
||||
DeviceDescriptor descriptor(heosPlayerDeviceClassId, player->name(), player->playerModel(), device->id());
|
||||
ParamList params;
|
||||
if (!myDevices().filterByParam(heosPlayerDevicePlayerIdParamTypeId, player->playerId()).isEmpty()) {
|
||||
continue;
|
||||
>>>>>>> added join/unjoin group:denon/IntegrationPlugindenon.cpp
|
||||
}
|
||||
params.append(Param(heosPlayerDeviceModelParamTypeId, player->playerModel()));
|
||||
params.append(Param(heosPlayerDevicePlayerIdParamTypeId, player->playerId()));
|
||||
params.append(Param(heosPlayerDeviceSerialNumberParamTypeId, player->serialNumber()));
|
||||
params.append(Param(heosPlayerDeviceVersionParamTypeId, player->playerVersion()));
|
||||
descriptor.setParams(params);
|
||||
qCDebug(dcDenon) << "Found new heos player" << player->name();
|
||||
heosPlayerDescriptors.append(descriptor);
|
||||
}
|
||||
<<<<<<< HEAD:denon/integrationplugindenon.cpp
|
||||
QList<ThingDescriptor> heosPlayerDescriptors;
|
||||
ThingDescriptor descriptor(heosPlayerThingClassId, heosPlayer->name(), heosPlayer->playerModel(), thing->id());
|
||||
ParamList params;
|
||||
@ -605,6 +657,21 @@ void IntegrationPluginDenon::onHeosPlayerDiscovered(HeosPlayer *heosPlayer) {
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onHeosPlayStateReceived(int playerId, PLAYER_STATE state)
|
||||
=======
|
||||
|
||||
//TODO remove devices
|
||||
//TODO remove player from player Buffer
|
||||
autoDevicesAppeared(heosPlayerDescriptors);
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onHeosPlayerInfoRecieved(HeosPlayer *heosPlayer)
|
||||
{
|
||||
qDebug(dcDenon()) << "Heos player info received" << heosPlayer->name() << heosPlayer->playerId() << heosPlayer->groupId();
|
||||
m_playerBuffer.insert(heosPlayer->playerId(), heosPlayer);
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onHeosPlayStateReceived(int playerId, PLAYER_STATE state)
|
||||
>>>>>>> added join/unjoin group:denon/IntegrationPlugindenon.cpp
|
||||
{
|
||||
foreach(Thing *thing, myThings().filterByParam(heosPlayerThingPlayerIdParamTypeId, playerId)) {
|
||||
if (state == PLAYER_STATE_PAUSE) {
|
||||
@ -657,6 +724,7 @@ void IntegrationPluginDenon::onHeosVolumeStatusReceived(int playerId, int volume
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD:denon/integrationplugindenon.cpp
|
||||
void IntegrationPluginDenon::onHeosNowPlayingMediaStatusReceived(int playerId, SOURCE_ID sourceId, QString artist, QString album, QString song, QString artwork)
|
||||
{
|
||||
foreach(Thing *thing, myThings().filterByParam(heosPlayerThingPlayerIdParamTypeId, playerId)) {
|
||||
@ -739,6 +807,19 @@ void IntegrationPluginDenon::onHeosNowPlayingMediaStatusReceived(int playerId, S
|
||||
thing->setStateValue(heosPlayerSourceStateTypeId, source);
|
||||
break;
|
||||
}
|
||||
=======
|
||||
void IntegrationPluginDenon::onHeosNowPlayingMediaStatusReceived(int playerId, const QString &sourceId, const QString &artist, const QString &album, const QString &song, const QString &artwork)
|
||||
{
|
||||
Device *device = myDevices().filterByParam(heosPlayerDevicePlayerIdParamTypeId, playerId).first();
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
device->setStateValue(heosPlayerArtistStateTypeId, artist);
|
||||
device->setStateValue(heosPlayerTitleStateTypeId, song);
|
||||
device->setStateValue(heosPlayerArtworkStateTypeId, artwork);
|
||||
device->setStateValue(heosPlayerCollectionStateTypeId, album);
|
||||
device->setStateValue(heosPlayerSourceStateTypeId, sourceId);
|
||||
>>>>>>> added join/unjoin group:denon/IntegrationPlugindenon.cpp
|
||||
}
|
||||
|
||||
|
||||
@ -748,12 +829,37 @@ void IntegrationPluginDenon::onHeosMusicSourcesReceived(QList<MusicSourceObject>
|
||||
if (m_pendingGetSourcesRequest.contains(heos)) {
|
||||
BrowseResult *result = m_pendingGetSourcesRequest.take(heos);
|
||||
foreach(MusicSourceObject source, musicSources) {
|
||||
BrowserItem item;
|
||||
MediaBrowserItem item;
|
||||
item.setDisplayName(source.name);
|
||||
item.setId("source=" + QString::number(source.sourceId));
|
||||
item.setThumbnail(source.image_url);
|
||||
item.setExecutable(false);
|
||||
item.setBrowsable(true);
|
||||
item.setIcon(BrowserItem::BrowserIconMusic);
|
||||
if (source.name == "Amazon") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconAmazon);
|
||||
} else if (source.name == "Deezer") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconDeezer);
|
||||
} else if (source.name == "Napster") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconNapster);
|
||||
} else if (source.name == "SoundCloud") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconSoundCloud);
|
||||
} else if (source.name == "Tidal") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconTidal);
|
||||
} else if (source.name == "TuneIn") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconTuneIn);
|
||||
} else if (source.name == "Local Music") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconDisk);
|
||||
} else if (source.name == "Playlists") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconPlaylist);
|
||||
} else if (source.name == "History") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconRecentlyPlayed);
|
||||
} else if (source.name == "AUX Input") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconAux);
|
||||
} else if (source.name == "Favorites") {
|
||||
item.setIcon(BrowserItem::BrowserIconFavorites);
|
||||
} else {
|
||||
item.setThumbnail(source.image_url);
|
||||
}
|
||||
result->addItem(item);
|
||||
qDebug(dcDenon()) << "Music source received:" << source.name << source.type << source.sourceId << source.image_url;
|
||||
}
|
||||
@ -763,7 +869,7 @@ void IntegrationPluginDenon::onHeosMusicSourcesReceived(QList<MusicSourceObject>
|
||||
|
||||
void IntegrationPluginDenon::onHeosMediaItemsReceived(QList<MediaObject> mediaItems)
|
||||
|
||||
void DevicePluginDenon::onHeosBrowseRequestReceived(const QString &sourceId, const QString &containerId, QList<MusicSourceObject> musicSources, QList<MediaObject> mediaItems)
|
||||
void IntegrationPluginDenon::onHeosBrowseRequestReceived(const QString &sourceId, const QString &containerId, QList<MusicSourceObject> musicSources, QList<MediaObject> mediaItems)
|
||||
{
|
||||
QString identifier;
|
||||
if (containerId.isEmpty()) {
|
||||
@ -784,7 +890,7 @@ void IntegrationPluginDenon::onHeosBrowseRequestReceived(QList<MusicSourceObject
|
||||
if (m_pendingBrowseResult.contains(browseRequest)) {
|
||||
BrowseResult *result = m_pendingBrowseResult.take(browseRequest);
|
||||
foreach(MediaObject media, mediaItems) {
|
||||
BrowserItem item;
|
||||
MediaBrowserItem item;
|
||||
qDebug(dcDenon()) << "Adding Item" << media.name << media.mediaId << media.containerId << media.mediaType;
|
||||
item.setDisplayName(media.name);
|
||||
if (media.mediaType == MEDIA_TYPE_CONTAINER) {
|
||||
@ -800,12 +906,36 @@ void IntegrationPluginDenon::onHeosBrowseRequestReceived(QList<MusicSourceObject
|
||||
result->addItem(item);
|
||||
}
|
||||
foreach(MusicSourceObject source, musicSources) {
|
||||
BrowserItem item;
|
||||
MediaBrowserItem item;
|
||||
item.setDisplayName(source.name);
|
||||
qDebug(dcDenon()) << "Adding Item" << source.name << source.sourceId;
|
||||
//item.setDescription("test");
|
||||
item.setId("source=" + QString::number(source.sourceId));
|
||||
item.setThumbnail(source.image_url);
|
||||
item.setIcon(BrowserItem::BrowserIconMusic);
|
||||
if (source.name.contains("Amazon")) {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconAmazon);
|
||||
} else if (source.name == "Deezer") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconDeezer);
|
||||
} else if (source.name == "Napster") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconNapster);
|
||||
} else if (source.name == "SoundCloud") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconSoundCloud);
|
||||
} else if (source.name == "Tidal") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconTidal);
|
||||
} else if (source.name == "TuneIn") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconTuneIn);
|
||||
} else if (source.name == "Local Music") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconDisk);
|
||||
} else if (source.name == "Playlists") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconPlaylist);
|
||||
} else if (source.name == "History") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconRecentlyPlayed);
|
||||
} else if (source.name == "AUX Input") {
|
||||
item.setMediaIcon(MediaBrowserItem::MediaBrowserIconAux);
|
||||
} else if (source.name == "Favorites") {
|
||||
item.setIcon(BrowserItem::BrowserIconFavorites);
|
||||
} else {
|
||||
item.setThumbnail(source.image_url);
|
||||
}
|
||||
item.setExecutable(false);
|
||||
item.setBrowsable(true);
|
||||
result->addItem(item);
|
||||
@ -839,13 +969,31 @@ void IntegrationPluginDenon::onHeosPlayerNowPlayingChanged(int playerId)
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginDenon::onHeosPlayerQueueChanged(int playerId)
|
||||
void IntegrationPluginDenon::onHeosPlayerQueueChanged(int playerId)
|
||||
{
|
||||
Heos *heos = static_cast<Heos *>(sender());
|
||||
heos->getNowPlayingMedia(playerId);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD:denon/integrationplugindenon.cpp
|
||||
void IntegrationPluginDenon::onAvahiServiceEntryAdded(const ZeroConfServiceEntry &serviceEntry)
|
||||
=======
|
||||
void IntegrationPluginDenon::onHeosGroupsReceived(QList<GroupObject> groups)
|
||||
{
|
||||
m_groupBuffer.clear();
|
||||
foreach(GroupObject group, groups) {
|
||||
m_groupBuffer.insert(group.groupId, group);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onHeosGroupsChanged()
|
||||
{
|
||||
Heos *heos = static_cast<Heos *>(sender());
|
||||
heos->getGroups();
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvahiServiceEntryAdded(const ZeroConfServiceEntry &serviceEntry)
|
||||
>>>>>>> added join/unjoin group:denon/IntegrationPlugindenon.cpp
|
||||
{
|
||||
qCDebug(dcDenon()) << "Avahi service entry added:" << serviceEntry;
|
||||
}
|
||||
@ -877,9 +1025,55 @@ void IntegrationPluginDenon::browseDevice(BrowseResult *result)
|
||||
|
||||
if (result->itemId().isEmpty()) {
|
||||
qDebug(dcDenon()) << "Browse source";
|
||||
MediaBrowserItem item;
|
||||
item.setId("type=group");
|
||||
item.setIcon(BrowserItem::BrowserIcon::BrowserIconPackage);
|
||||
item.setBrowsable(true);
|
||||
item.setExecutable(false);
|
||||
item.setDisplayName("Groups");
|
||||
result->addItem(item);
|
||||
heos->getMusicSources();
|
||||
m_pendingGetSourcesRequest.insert(heos, result);
|
||||
connect(result, &QObject::destroyed, this, [this, heos](){m_pendingGetSourcesRequest.remove(heos);});
|
||||
} else if (result->itemId().startsWith("type=group")){
|
||||
qDebug(dcDenon()) << "Browse source" << result->itemId();
|
||||
int pid = result->device()->paramValue(heosPlayerDevicePlayerIdParamTypeId).toInt();
|
||||
HeosPlayer *browsingPlayer = m_playerBuffer.value(pid);
|
||||
foreach (GroupObject group, m_groupBuffer) {
|
||||
MediaBrowserItem item;
|
||||
item.setBrowsable(true);
|
||||
item.setExecutable(true);
|
||||
item.setIcon(BrowserItem::BrowserIconFolder);
|
||||
item.setDisplayName(group.name);
|
||||
item.setId(result->itemId() + "&" + "group=" + QString::number(group.groupId));
|
||||
// if player is already part of the group set action type id to unjoin
|
||||
if (browsingPlayer->groupId() == group.groupId) {
|
||||
item.setActionTypeIds(QList<ActionTypeId>() << heosPlayerUnjoinBrowserItemActionTypeId);
|
||||
} else {
|
||||
item.setActionTypeIds(QList<ActionTypeId>() << heosPlayerJoinBrowserItemActionTypeId);
|
||||
}
|
||||
result->addItem(item);
|
||||
}
|
||||
|
||||
foreach (HeosPlayer *player, m_playerBuffer.values()) {
|
||||
qDebug(dcDenon) << "Adding group item" << player->name();
|
||||
if (browsingPlayer->playerId() == player->playerId()) { //player is the current browsing device
|
||||
continue;
|
||||
}
|
||||
if (player->groupId() != -1) {// Dont display players that are already assigned to a group
|
||||
continue;
|
||||
}
|
||||
MediaBrowserItem item;
|
||||
item.setBrowsable(true);
|
||||
item.setExecutable(true);
|
||||
item.setIcon(BrowserItem::BrowserIconFile);
|
||||
item.setDisplayName(player->name());
|
||||
item.setId(result->itemId() + "&player=" + QString::number(player->playerId()));
|
||||
item.setActionTypeIds(QList<ActionTypeId>() << heosPlayerJoinBrowserItemActionTypeId);
|
||||
result->addItem(item);
|
||||
|
||||
}
|
||||
result->finish(Device::DeviceErrorNoError);
|
||||
|
||||
} else if (result->itemId().startsWith("source=")){
|
||||
qDebug(dcDenon()) << "Browse source" << result->itemId();
|
||||
@ -943,11 +1137,41 @@ void IntegrationPluginDenon::executeBrowserItem(BrowserActionInfo *info)
|
||||
|
||||
void IntegrationPluginDenon::executeBrowserItemAction(BrowserItemActionInfo *info)
|
||||
{
|
||||
Heos *kodi = m_heos.value(info->device()->parentId());
|
||||
if (!kodi) {
|
||||
Heos *heos = m_heos.value(info->device()->parentId());
|
||||
if (!heos) {
|
||||
info->finish(Device::DeviceErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
qDebug(dcDenon()) << "Execute browse item action called";
|
||||
|
||||
QUrlQuery query(info->browserItemAction().itemId());
|
||||
if (info->browserItemAction().actionTypeId() == heosPlayerJoinBrowserItemActionTypeId) {
|
||||
if (query.hasQueryItem("player")) {
|
||||
QList<int> playerIds;
|
||||
playerIds.append(query.queryItemValue("player").toInt());
|
||||
playerIds.append(info->device()->paramValue(heosPlayerDevicePlayerIdParamTypeId).toInt());
|
||||
heos->setGroup(playerIds);
|
||||
} else if(query.hasQueryItem("group")) {
|
||||
|
||||
GroupObject group = m_groupBuffer.value(query.queryItemValue("group").toInt());
|
||||
qDebug(dcDenon()) << "Execute browse item action called, Group:" << query.queryItemValue("group").toInt() << group.name;
|
||||
QList<int> playerIds;
|
||||
foreach(PlayerObject player, group.players) {
|
||||
playerIds.append(player.playerId);
|
||||
}
|
||||
playerIds.append(info->device()->paramValue(heosPlayerDevicePlayerIdParamTypeId).toInt());
|
||||
heos->setGroup(playerIds);
|
||||
}
|
||||
} else if (info->browserItemAction().actionTypeId() == heosPlayerUnjoinBrowserItemActionTypeId) {
|
||||
if(query.hasQueryItem("group")) {
|
||||
GroupObject group = m_groupBuffer.value(query.queryItemValue("group").toInt());
|
||||
QList<int> playerIds;
|
||||
foreach(PlayerObject player, group.players) {
|
||||
if (player.playerId != info->device()->paramValue(heosPlayerDevicePlayerIdParamTypeId).toInt())
|
||||
playerIds.append(player.playerId);
|
||||
}
|
||||
heos->setGroup(playerIds);
|
||||
}
|
||||
}
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -91,24 +91,31 @@ private:
|
||||
QHash<int, BrowserItemActionInfo*> m_pendingBrowserItemActions;
|
||||
QHash<QString, MediaObject> m_mediaObjects;
|
||||
|
||||
QHash<int, GroupObject> m_groupBuffer;
|
||||
QHash<int, HeosPlayer *> m_playerBuffer;
|
||||
|
||||
private slots:
|
||||
void onPluginTimer();
|
||||
|
||||
void onHeosConnectionChanged(bool status);
|
||||
void onHeosPlayersChanged();
|
||||
void onHeosPlayerDiscovered(HeosPlayer *heosPlayer);
|
||||
void onHeosPlayersReceived(QList<HeosPlayer *> players);
|
||||
void onHeosPlayerInfoRecieved(HeosPlayer *player);
|
||||
void onHeosPlayStateReceived(int playerId, PLAYER_STATE state);
|
||||
void onHeosShuffleModeReceived(int playerId, bool shuffle);
|
||||
void onHeosRepeatModeReceived(int playerId, REPEAT_MODE repeatMode);
|
||||
void onHeosMuteStatusReceived(int playerId, bool mute);
|
||||
void onHeosVolumeStatusReceived(int playerId, int volume);
|
||||
void onHeosNowPlayingMediaStatusReceived(int playerId, SOURCE_ID source, QString artist, QString album, QString Song, QString artwork);
|
||||
void onHeosNowPlayingMediaStatusReceived(int playerId, const QString &sourceId, const QString &artist, const QString &album, const QString &song, const QString &artwork);
|
||||
void onHeosMusicSourcesReceived(QList<MusicSourceObject> musicSources);
|
||||
//void onHeosMediaItemsReceived(QList<MediaObject> mediaItems);
|
||||
|
||||
void onHeosBrowseRequestReceived(const QString &sourceId, const QString &containerId, QList<MusicSourceObject> musicSources, QList<MediaObject> mediaItems);
|
||||
void onHeosBrowseErrorReceived(const QString &sourceId, const QString &containerId, int errorId, const QString &errorMessage);
|
||||
void onHeosPlayerNowPlayingChanged(int playerId);
|
||||
void onHeosPlayerQueueChanged(int playerId);
|
||||
void onHeosGroupsReceived(QList<GroupObject> groups);
|
||||
void onHeosGroupsChanged();
|
||||
|
||||
|
||||
void onAvahiServiceEntryAdded(const ZeroConfServiceEntry &serviceEntry);
|
||||
void onAvahiServiceEntryRemoved(const ZeroConfServiceEntry &serviceEntry);
|
||||
|
||||
@ -392,14 +392,14 @@
|
||||
],
|
||||
"browserItemActionTypes": [
|
||||
{
|
||||
"id": "34167b7d-c9d0-486c-b82b-0778d69599ea",
|
||||
"name": "updateLibrary",
|
||||
"displayName": "Update library"
|
||||
"id": "73112a01-84c7-4b1d-8b86-71672c110d06",
|
||||
"name": "join",
|
||||
"displayName": "Join group"
|
||||
},
|
||||
{
|
||||
"id": "02bcfbbe-d929-439e-a04f-68ace25e93a7",
|
||||
"name": "cleanLibrary",
|
||||
"displayName": "Clean library"
|
||||
"id": "1b866b95-1fc7-4b45-ad71-c85e43fcc367",
|
||||
"name": "unjoin",
|
||||
"displayName": "Unjoin group"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user