denon avr fixed discovery and added async actions
This commit is contained in:
parent
99b00d5ac8
commit
c03d67b9ff
@ -1,4 +1,4 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
@ -43,6 +43,23 @@ AvrConnection::AvrConnection(const QHostAddress &hostAddress, const int &port, Q
|
||||
connect(m_socket, &QTcpSocket::readyRead, this, &AvrConnection::readData);
|
||||
// Note: error signal will be interpreted as function, not as signal in C++11
|
||||
connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
|
||||
|
||||
m_commandTimer = new QTimer(this);
|
||||
m_commandTimer->start(50); // 50ms is the minimum request interval specified
|
||||
|
||||
connect(m_commandTimer, &QTimer::timeout, this, [this] {
|
||||
if (!m_commandBuffer.isEmpty()) {
|
||||
QPair<QUuid, QByteArray> command = m_commandBuffer.takeFirst();
|
||||
if (m_socket->write(command.second) == -1) {
|
||||
emit commandExecuted(command.first, false);
|
||||
qCWarning(dcDenon()) << "Could not execute command" << command.second;
|
||||
} else {
|
||||
emit commandExecuted(command.first, true);
|
||||
}
|
||||
} else {
|
||||
m_commandTimer->stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AvrConnection::~AvrConnection()
|
||||
@ -78,56 +95,62 @@ bool AvrConnection::connected()
|
||||
return m_socket->isOpen();
|
||||
}
|
||||
|
||||
void AvrConnection::getAllStatus()
|
||||
QUuid AvrConnection::getChannel()
|
||||
{
|
||||
sendCommand("PW?\rSI?\rMV?\rMS?\rMU?\r");
|
||||
return sendCommand("SI?\r");
|
||||
}
|
||||
|
||||
void AvrConnection::getChannel()
|
||||
QUuid AvrConnection::getVolume()
|
||||
{
|
||||
sendCommand("SI?\r");
|
||||
return sendCommand("MV?\r");
|
||||
}
|
||||
|
||||
void AvrConnection::getVolume()
|
||||
QUuid AvrConnection::getMute()
|
||||
{
|
||||
sendCommand("MV?\r");
|
||||
return sendCommand("MU?\r");
|
||||
}
|
||||
|
||||
void AvrConnection::getMute()
|
||||
QUuid AvrConnection::getPower()
|
||||
{
|
||||
sendCommand("MU?\r");
|
||||
return sendCommand("PW?\r");
|
||||
}
|
||||
|
||||
void AvrConnection::getPower()
|
||||
QUuid AvrConnection::getSurroundMode()
|
||||
{
|
||||
sendCommand("PW?\r");
|
||||
return sendCommand("MS?\r");
|
||||
}
|
||||
|
||||
void AvrConnection::getSurroundMode()
|
||||
QUuid AvrConnection::getPlayBackInfo()
|
||||
{
|
||||
sendCommand("MS?\r");
|
||||
return sendCommand("NSE\r");
|
||||
}
|
||||
|
||||
void AvrConnection::sendCommand(const QByteArray &message)
|
||||
QUuid AvrConnection::sendCommand(const QByteArray &message)
|
||||
{
|
||||
m_socket->write(message);
|
||||
QUuid commandId = QUuid::createUuid();
|
||||
|
||||
if (!m_commandTimer->isActive())
|
||||
m_commandTimer->start(50);
|
||||
|
||||
m_commandBuffer.append(QPair<QUuid, QByteArray>(commandId, message));
|
||||
return commandId;
|
||||
}
|
||||
|
||||
void AvrConnection::setChannel(const QByteArray &channel)
|
||||
QUuid AvrConnection::setChannel(const QByteArray &channel)
|
||||
{
|
||||
QByteArray cmd = "SI" + channel + "\r";
|
||||
qCDebug(dcDenon) << "Change to channel:" << cmd;
|
||||
sendCommand(cmd);
|
||||
qCDebug(dcDenon) << "Change to channel:" << channel;
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
void AvrConnection::setVolume(int volume)
|
||||
QUuid AvrConnection::setVolume(int volume)
|
||||
{
|
||||
qCDebug(dcDenon) << "Set volume" << volume;
|
||||
QByteArray cmd = "MV" + QByteArray::number(volume) + "\r";
|
||||
sendCommand(cmd);
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
void AvrConnection::setMute(bool mute)
|
||||
QUuid AvrConnection::setMute(bool mute)
|
||||
{
|
||||
qCDebug(dcDenon) << "Set mute" << mute;
|
||||
QByteArray cmd;
|
||||
@ -136,10 +159,10 @@ void AvrConnection::setMute(bool mute)
|
||||
} else {
|
||||
cmd = "MUOFF\r";
|
||||
}
|
||||
sendCommand(cmd);
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
void AvrConnection::setPower(bool power)
|
||||
QUuid AvrConnection::setPower(bool power)
|
||||
{
|
||||
qCDebug(dcDenon) << "Set power" << power;
|
||||
QByteArray cmd;
|
||||
@ -148,28 +171,125 @@ void AvrConnection::setPower(bool power)
|
||||
} else {
|
||||
cmd = "PWSTANDBY\r";
|
||||
}
|
||||
sendCommand(cmd);
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
void AvrConnection::setSurroundMode(const QByteArray &surroundMode)
|
||||
QUuid AvrConnection::setSurroundMode(const QByteArray &surroundMode)
|
||||
{
|
||||
qCDebug(dcDenon) << "Set surround mode" << surroundMode;
|
||||
QByteArray cmd = "MS" + surroundMode + "\r";
|
||||
sendCommand(cmd);
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
void AvrConnection::increaseVolume()
|
||||
QUuid AvrConnection::enableToneControl(bool enabled)
|
||||
{
|
||||
QByteArray cmd;
|
||||
if (enabled) {
|
||||
cmd = "PSTONE CTRL ON\r";
|
||||
} else {
|
||||
cmd = "PSTONE CTRL OFF\r";
|
||||
}
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
QUuid AvrConnection::setBassLevel(int level)
|
||||
{
|
||||
QByteArray cmd;
|
||||
cmd = "PSBAS ";
|
||||
cmd.append(50 + level);
|
||||
cmd.append("\r");
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
QUuid AvrConnection::setTrebleLevel(int level)
|
||||
{
|
||||
QByteArray cmd;
|
||||
cmd = "PSTRE ";
|
||||
cmd.append(50 + level);
|
||||
cmd.append("\r");
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
QUuid AvrConnection::getBassLevel()
|
||||
{
|
||||
return sendCommand("PSBAS ?\r");
|
||||
}
|
||||
|
||||
QUuid AvrConnection::getTrebleLevel()
|
||||
{
|
||||
return sendCommand("PSTRE ?\r");
|
||||
}
|
||||
|
||||
QUuid AvrConnection::getToneControl()
|
||||
{
|
||||
return sendCommand("PSTONE CTRL ?\r");
|
||||
}
|
||||
|
||||
QUuid AvrConnection::play()
|
||||
{
|
||||
return sendCommand("NS9A\r");
|
||||
}
|
||||
|
||||
QUuid AvrConnection::pause()
|
||||
{
|
||||
return sendCommand("NS9B\r");
|
||||
}
|
||||
|
||||
QUuid AvrConnection::stop()
|
||||
{
|
||||
return sendCommand("NS9C\r");
|
||||
}
|
||||
|
||||
QUuid AvrConnection::skipNext()
|
||||
{
|
||||
return sendCommand("NS9D\r");
|
||||
}
|
||||
|
||||
QUuid AvrConnection::skipBack()
|
||||
{
|
||||
return sendCommand("NS9E\r");
|
||||
}
|
||||
|
||||
QUuid AvrConnection::setRandom(bool on)
|
||||
{
|
||||
QByteArray cmd;
|
||||
if (on) {
|
||||
cmd = "NS9K\r";
|
||||
} else {
|
||||
cmd = "NS9M\r";
|
||||
}
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
QUuid AvrConnection::setRepeat(AvrConnection::RepeatMode mode)
|
||||
{
|
||||
QByteArray cmd;
|
||||
switch (mode) {
|
||||
case RepeatModeRepeatAll:
|
||||
cmd = "NS9I\r";
|
||||
break;
|
||||
case RepeatModeRepeatOne:
|
||||
cmd = "NS9H\r";
|
||||
break;
|
||||
case RepeatModeRepeatNone:
|
||||
cmd = "NS9J\r";
|
||||
break;
|
||||
}
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
QUuid AvrConnection::increaseVolume()
|
||||
{
|
||||
qCDebug(dcDenon) << "Execute volume increase";
|
||||
QByteArray cmd = "MVUP\r";
|
||||
sendCommand(cmd);
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
void AvrConnection::decreaseVolume()
|
||||
QUuid AvrConnection::decreaseVolume()
|
||||
{
|
||||
qCDebug(dcDenon) << "Execute volume decrease";
|
||||
QByteArray cmd = "MVDOWN\r";
|
||||
sendCommand(cmd);
|
||||
return sendCommand(cmd);
|
||||
}
|
||||
|
||||
void AvrConnection::onConnected()
|
||||
@ -192,16 +312,20 @@ void AvrConnection::onError(QAbstractSocket::SocketError socketError)
|
||||
|
||||
void AvrConnection::readData()
|
||||
{
|
||||
QByteArray data = m_socket->readAll();
|
||||
qCDebug(dcDenon) << "Data received" << data;
|
||||
QString data = QString(m_socket->readAll());
|
||||
|
||||
if (data.contains("MV") && !data.contains("MAX")){
|
||||
QStringList lines = data.split('\r');
|
||||
foreach (QString line, lines) {
|
||||
if(line.isEmpty())
|
||||
continue;
|
||||
|
||||
qCDebug(dcDenon) << "Data received" << line;
|
||||
if (line.contains("MV") && !data.contains("MAX")){
|
||||
int index = data.indexOf("MV");
|
||||
int volume = data.mid(index+2, 2).toInt();
|
||||
emit volumeChanged(volume);
|
||||
}
|
||||
|
||||
if (data.left(2).contains("SI")) {
|
||||
} else if (line.left(2).contains("SI")) {
|
||||
QByteArray cmd;
|
||||
if (data.contains("TUNER")) {
|
||||
cmd = "TUNER";
|
||||
@ -245,24 +369,55 @@ void AvrConnection::readData()
|
||||
cmd = "FVP";
|
||||
}
|
||||
emit channelChanged(cmd);
|
||||
}
|
||||
|
||||
if (data.contains("PWON")) {
|
||||
} else if (data.contains("PWON")) {
|
||||
emit powerChanged(true);
|
||||
}
|
||||
if (data.contains("PWSTANDBY")) {
|
||||
} else if (data.contains("PWSTANDBY")) {
|
||||
emit powerChanged(false);
|
||||
}
|
||||
if (data.contains("MUON")) {
|
||||
} else if (data.contains("MUON")) {
|
||||
emit muteChanged(true);
|
||||
} else if (data.contains("MUOFF")) {
|
||||
emit muteChanged(false);
|
||||
}
|
||||
if (data.contains("MUOFF")) {
|
||||
emit muteChanged(false);
|
||||
}
|
||||
} else if (data.left(2).contains("MS")) {
|
||||
QString surroundMode = data.remove(0, 2).trimmed();
|
||||
qCDebug(dcDenon()) << "Surround mode changed" << surroundMode;
|
||||
emit surroundModeChanged(surroundMode);
|
||||
|
||||
if (data.left(2).contains("MS")) {
|
||||
data.remove(0, 2);
|
||||
QByteArray cmd = data;
|
||||
emit surroundModeChanged(cmd);
|
||||
} else if (data.left(4).contains("NSE0")) {
|
||||
QString nowPlaying = QString(data).remove(0, 4).trimmed();
|
||||
qCDebug(dcDenon()) << "Playbackstatus" << nowPlaying;
|
||||
if (nowPlaying.contains("Now Playing")) {
|
||||
emit playBackModeChanged(PlayBackMode::PlayBackModePlaying);
|
||||
} else {
|
||||
emit playBackModeChanged(PlayBackMode::PlayBackModeStopped);
|
||||
}
|
||||
} else if (data.left(4).contains("NSE1")) {
|
||||
QString song = QString(data).remove(0, 4).trimmed();
|
||||
qCDebug(dcDenon()) << "Song" << song;
|
||||
emit songChanged(song);
|
||||
} else if (data.left(4).contains("NSE2")) {
|
||||
QString artist = QString(data).remove(0, 4).trimmed();
|
||||
qCDebug(dcDenon()) << "Artist" << artist;
|
||||
emit artistChanged(artist);
|
||||
} else if (data.left(4).contains("NSE4")) {
|
||||
QString album = QString(data).remove(0, 4).trimmed();
|
||||
qCDebug(dcDenon()) << "Album" << album;
|
||||
emit albumChanged(album);
|
||||
} else if (data.contains("PSTONE CTRL ON")) {
|
||||
qCDebug(dcDenon()) << "Tone control is on";
|
||||
emit toneControlEnabledChanged(true);
|
||||
} else if (data.contains("PSTONE CTRL OFF")) {
|
||||
qCDebug(dcDenon()) << "Tone control is off";
|
||||
emit toneControlEnabledChanged(false);
|
||||
} else if (data.contains("PSBAS")) {
|
||||
int index = data.indexOf("PSBAS");
|
||||
int bass = data.mid(index+6, 2).toInt() - 50;
|
||||
qCDebug(dcDenon()) << "Bass level" << bass;
|
||||
emit bassLevelChanged(bass);
|
||||
} else if (data.contains("PSTRE")) {
|
||||
int index = data.indexOf("PSTRE");
|
||||
int treble = data.mid(index+6, 2).toInt() - 50;
|
||||
qCDebug(dcDenon()) << "Treble level" << treble;
|
||||
emit trebleLevelChanged(treble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,11 +34,25 @@
|
||||
#include <QObject>
|
||||
#include <QTcpSocket>
|
||||
#include <QHostAddress>
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
|
||||
class AvrConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum RepeatMode {
|
||||
RepeatModeRepeatAll,
|
||||
RepeatModeRepeatOne,
|
||||
RepeatModeRepeatNone
|
||||
};
|
||||
|
||||
enum PlayBackMode {
|
||||
PlayBackModePlaying,
|
||||
PlayBackModeStopped,
|
||||
PlayBackModePaused
|
||||
};
|
||||
|
||||
explicit AvrConnection(const QHostAddress &hostAddress, const int &port = 23, QObject *parent = nullptr);
|
||||
~AvrConnection();
|
||||
|
||||
@ -49,27 +63,44 @@ public:
|
||||
int port() const;
|
||||
bool connected();
|
||||
|
||||
void getAllStatus();
|
||||
void getChannel();
|
||||
void getVolume();
|
||||
void getMute();
|
||||
void getPower();
|
||||
void getSurroundMode();
|
||||
QUuid getChannel();
|
||||
QUuid getVolume();
|
||||
QUuid getMute();
|
||||
QUuid getPower();
|
||||
QUuid getSurroundMode();
|
||||
QUuid getPlayBackInfo();
|
||||
|
||||
void setChannel(const QByteArray &channel);
|
||||
void setVolume(int volume);
|
||||
void setMute(bool mute);
|
||||
void setPower(bool power);
|
||||
void setSurroundMode(const QByteArray &surroundMode);
|
||||
QUuid setChannel(const QByteArray &channel);
|
||||
QUuid setVolume(int volume);
|
||||
QUuid setMute(bool mute);
|
||||
QUuid setPower(bool power);
|
||||
QUuid setSurroundMode(const QByteArray &surroundMode);
|
||||
QUuid enableToneControl(bool enabled);
|
||||
QUuid setBassLevel(int level); //-6 to +6
|
||||
QUuid setTrebleLevel(int level); //-6 to +6
|
||||
|
||||
void increaseVolume();
|
||||
void decreaseVolume();
|
||||
QUuid getBassLevel();
|
||||
QUuid getTrebleLevel();
|
||||
QUuid getToneControl();
|
||||
|
||||
QUuid play();
|
||||
QUuid pause();
|
||||
QUuid stop();
|
||||
QUuid skipNext();
|
||||
QUuid skipBack();
|
||||
QUuid setRandom(bool on);
|
||||
QUuid setRepeat(RepeatMode mode);
|
||||
|
||||
QUuid increaseVolume();
|
||||
QUuid decreaseVolume();
|
||||
private:
|
||||
QTimer *m_commandTimer = nullptr;
|
||||
QTcpSocket *m_socket = nullptr;
|
||||
QHostAddress m_hostAddress;
|
||||
int m_port;
|
||||
QList<QPair<QUuid, QByteArray>> m_commandBuffer;
|
||||
|
||||
void sendCommand(const QByteArray &message);
|
||||
QUuid sendCommand(const QByteArray &message);
|
||||
|
||||
private slots:
|
||||
void onConnected();
|
||||
@ -80,11 +111,19 @@ private slots:
|
||||
signals:
|
||||
void socketErrorOccured(QAbstractSocket::SocketError socketError);
|
||||
void connectionStatusChanged(bool status);
|
||||
void commandExecuted(const QUuid &commandId, bool success);
|
||||
void volumeChanged(int volume);
|
||||
void muteChanged(bool mute);
|
||||
void channelChanged(const QByteArray &channel);
|
||||
void channelChanged(const QString &channel);
|
||||
void powerChanged(bool power);
|
||||
void surroundModeChanged(const QByteArray &surroundMode);
|
||||
void surroundModeChanged(const QString &surroundMode);
|
||||
void songChanged(const QString &song);
|
||||
void artistChanged(const QString &artist);
|
||||
void albumChanged(const QString &album);
|
||||
void playBackModeChanged(AvrConnection::PlayBackMode);
|
||||
void bassLevelChanged(int level);
|
||||
void trebleLevelChanged(int level);
|
||||
void toneControlEnabledChanged(bool enabled);
|
||||
};
|
||||
|
||||
#endif // AVRCONNECTION_H
|
||||
|
||||
@ -58,14 +58,15 @@ void IntegrationPluginDenon::init()
|
||||
void IntegrationPluginDenon::discoverThings(ThingDiscoveryInfo *info)
|
||||
{
|
||||
if (info->thingClassId() == AVRX1000ThingClassId) {
|
||||
if (!hardwareManager()->zeroConfController()->available() || !hardwareManager()->zeroConfController()->enabled()) {
|
||||
//: Error discovering Denon things
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Thing discovery is not available."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_serviceBrowser) {
|
||||
m_serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser();;
|
||||
m_serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser();
|
||||
}
|
||||
|
||||
if (!hardwareManager()->zeroConfController()->available()) {
|
||||
qCDebug(dcDenon()) << "Error discovering Denon things. Available:" << hardwareManager()->zeroConfController()->available();
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable, "Thing discovery not possible");
|
||||
return;
|
||||
}
|
||||
|
||||
QTimer::singleShot(2000, info, [this, info](){
|
||||
@ -196,16 +197,30 @@ void IntegrationPluginDenon::setupThing(ThingSetupInfo *info)
|
||||
AvrConnection *denonConnection = new AvrConnection(address, 23, this);
|
||||
connect(denonConnection, &AvrConnection::connectionStatusChanged, this, &IntegrationPluginDenon::onAvrConnectionChanged);
|
||||
connect(denonConnection, &AvrConnection::socketErrorOccured, this, &IntegrationPluginDenon::onAvrSocketError);
|
||||
connect(denonConnection, &AvrConnection::commandExecuted, this, &IntegrationPluginDenon::onAvrCommandExecuted);
|
||||
connect(denonConnection, &AvrConnection::channelChanged, this, &IntegrationPluginDenon::onAvrChannelChanged);
|
||||
connect(denonConnection, &AvrConnection::powerChanged, this, &IntegrationPluginDenon::onAvrPowerChanged);
|
||||
connect(denonConnection, &AvrConnection::volumeChanged, this, &IntegrationPluginDenon::onAvrVolumeChanged);
|
||||
connect(denonConnection, &AvrConnection::surroundModeChanged, this, &IntegrationPluginDenon::onAvrSurroundModeChanged);
|
||||
connect(denonConnection, &AvrConnection::muteChanged, this, &IntegrationPluginDenon::onAvrMuteChanged);
|
||||
connect(denonConnection, &AvrConnection::artistChanged, this, &IntegrationPluginDenon::onAvrArtistChanged);
|
||||
connect(denonConnection, &AvrConnection::albumChanged, this, &IntegrationPluginDenon::onAvrAlbumChanged);
|
||||
connect(denonConnection, &AvrConnection::songChanged, this, &IntegrationPluginDenon::onAvrSongChanged);
|
||||
connect(denonConnection, &AvrConnection::playBackModeChanged, this, &IntegrationPluginDenon::onAvrPlayBackModeChanged);
|
||||
connect(denonConnection, &AvrConnection::bassLevelChanged, this, &IntegrationPluginDenon::onAvrBassLevelChanged);
|
||||
connect(denonConnection, &AvrConnection::trebleLevelChanged, this, &IntegrationPluginDenon::onAvrTrebleLevelChanged);
|
||||
connect(denonConnection, &AvrConnection::toneControlEnabledChanged, this, &IntegrationPluginDenon::onAvrToneControlEnabledChanged);
|
||||
|
||||
m_avrConnections.insert(thing->id(), denonConnection);
|
||||
m_asyncAvrSetups.insert(denonConnection, info);
|
||||
// In case the setup is cancelled before we finish it...
|
||||
connect(info, &QObject::destroyed, this, [this, denonConnection]() { m_asyncAvrSetups.remove(denonConnection); });
|
||||
connect(info, &ThingSetupInfo::aborted, this, [this, thing] () {
|
||||
if (m_avrConnections.contains(thing->id())) {
|
||||
AvrConnection *connection = m_avrConnections.take(thing->id());
|
||||
connection->deleteLater();
|
||||
}
|
||||
});
|
||||
denonConnection->connectDevice();
|
||||
return;
|
||||
} else if (thing->thingClassId() == heosThingClassId) {
|
||||
@ -273,48 +288,120 @@ void IntegrationPluginDenon::executeAction(ThingActionInfo *info)
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
AvrConnection *avrConnection = m_avrConnections.value(thing->id());
|
||||
|
||||
if (action.actionTypeId() == AVRX1000PowerActionTypeId) {
|
||||
|
||||
if (action.actionTypeId() == AVRX1000PlayActionTypeId) {
|
||||
QUuid commandId = avrConnection->play();
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000PauseActionTypeId) {
|
||||
QUuid commandId = avrConnection->pause();
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000StopActionTypeId) {
|
||||
QUuid commandId = avrConnection->stop();
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000SkipNextActionTypeId) {
|
||||
QUuid commandId = avrConnection->skipNext();
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000SkipBackActionTypeId) {
|
||||
QUuid commandId = avrConnection->skipBack();
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000PowerActionTypeId) {
|
||||
bool power = action.param(AVRX1000PowerActionPowerParamTypeId).value().toBool();
|
||||
avrConnection->setPower(power);
|
||||
return info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
QUuid commandId = avrConnection->setPower(power);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000VolumeActionTypeId) {
|
||||
|
||||
int vol = action.param(AVRX1000VolumeActionVolumeParamTypeId).value().toInt();
|
||||
avrConnection->setVolume(vol);
|
||||
return info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
QUuid commandId = avrConnection->setVolume(vol);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000ChannelActionTypeId) {
|
||||
|
||||
qCDebug(dcDenon) << "Execute update action";
|
||||
QByteArray channel = action.param(AVRX1000ChannelActionChannelParamTypeId).value().toByteArray();
|
||||
avrConnection->setChannel(channel);
|
||||
return info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
QUuid commandId = avrConnection->setChannel(channel);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000IncreaseVolumeActionTypeId) {
|
||||
|
||||
avrConnection->increaseVolume();
|
||||
return info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
QUuid commandId = avrConnection->increaseVolume();
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000DecreaseVolumeActionTypeId) {
|
||||
|
||||
avrConnection->decreaseVolume();
|
||||
return info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
QUuid commandId = avrConnection->decreaseVolume();
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000SurroundModeActionTypeId) {
|
||||
|
||||
QByteArray surroundMode = action.param(AVRX1000SurroundModeActionSurroundModeParamTypeId).value().toByteArray();
|
||||
avrConnection->setSurroundMode(surroundMode);
|
||||
return info->finish(Thing::ThingErrorNoError);
|
||||
QUuid commandId = avrConnection->setSurroundMode(surroundMode);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000MuteActionTypeId) {
|
||||
bool mute = action.param(AVRX1000MuteActionMuteParamTypeId).value().toBool();
|
||||
QUuid commandId = avrConnection->setMute(mute);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000RepeatActionTypeId) {
|
||||
QString repeatMode = action.param(AVRX1000RepeatActionRepeatParamTypeId).value().toString();
|
||||
QUuid commandId;
|
||||
if (repeatMode == "One") {
|
||||
commandId = avrConnection->setRepeat(AvrConnection::RepeatModeRepeatOne);
|
||||
} else if (repeatMode == "All") {
|
||||
commandId = avrConnection->setRepeat(AvrConnection::RepeatModeRepeatAll);
|
||||
} else {
|
||||
commandId = avrConnection->setRepeat(AvrConnection::RepeatModeRepeatNone);
|
||||
}
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000ShuffleActionTypeId) {
|
||||
bool shuffle = action.param(AVRX1000ShuffleActionShuffleParamTypeId).value().toBool();
|
||||
QUuid commandId = avrConnection->setRandom(shuffle);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000PlaybackStatusActionTypeId) {
|
||||
QString playbackStatus = action.param(AVRX1000PlaybackStatusActionPlaybackStatusParamTypeId).value().toString();
|
||||
QUuid commandId;
|
||||
if (playbackStatus == "Playing") {
|
||||
commandId = avrConnection->play();
|
||||
} else if (playbackStatus == "Stopped") {
|
||||
commandId = avrConnection->stop();
|
||||
} else if (playbackStatus == "Paused") {
|
||||
commandId = avrConnection->pause();
|
||||
} else {
|
||||
qCWarning(dcDenon()) << "Unrecognized playback status" << playbackStatus;
|
||||
return info->finish(Thing::ThingErrorHardwareFailure, "Unrecognized command");
|
||||
}
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000ToneControlActionTypeId) {
|
||||
bool enable = action.param(AVRX1000ToneControlActionToneControlParamTypeId).value().toBool();
|
||||
QUuid commandId = avrConnection->enableToneControl(enable);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000BassActionTypeId) {
|
||||
int bass = action.param(AVRX1000BassActionBassParamTypeId).value().toInt();
|
||||
QUuid commandId = avrConnection->setBassLevel(bass);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else if (action.actionTypeId() == AVRX1000TrebleActionTypeId) {
|
||||
int treble = action.param(AVRX1000TrebleActionTrebleParamTypeId).value().toInt();
|
||||
QUuid commandId = avrConnection->setTrebleLevel(treble);
|
||||
connect(info, &ThingActionInfo::aborted, [this, commandId] {m_avrPendingActions.remove(commandId);});
|
||||
m_avrPendingActions.insert(commandId, info);
|
||||
} else {
|
||||
qCWarning(dcDenon()) << "ActionType not found" << thing->thingClass().name() << action.actionTypeId() ;
|
||||
return info->finish(Thing::ThingErrorActionTypeNotFound);
|
||||
}
|
||||
|
||||
} else if (thing->thingClassId() == heosThingClassId) {
|
||||
|
||||
Heos *heos = m_heosConnections.value(thing->id());
|
||||
if (action.actionTypeId() == heosRebootActionTypeId) {
|
||||
heos->rebootSpeaker();
|
||||
return info->finish(Thing::ThingErrorNoError);
|
||||
} else {
|
||||
qCWarning(dcDenon()) << "ActionType not found" << thing->thingClass().name() << action.actionTypeId() ;
|
||||
return info->finish(Thing::ThingErrorActionTypeNotFound);
|
||||
}
|
||||
} else if (thing->thingClassId() == heosPlayerThingClassId) {
|
||||
|
||||
@ -369,16 +456,31 @@ void IntegrationPluginDenon::executeAction(ThingActionInfo *info)
|
||||
heos->playNext(playerId);
|
||||
return info->finish(Thing::ThingErrorNoError);
|
||||
} else {
|
||||
qCWarning(dcDenon()) << "ActionType not found" << thing->thingClass().name() << action.actionTypeId() ;
|
||||
return info->finish(Thing::ThingErrorActionTypeNotFound);
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcDenon()) << "ThingClass not found" << thing->thingClass().name() << thing->thingClassId() ;
|
||||
return info->finish(Thing::ThingErrorThingClassNotFound);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::postSetupThing(Thing *thing)
|
||||
{
|
||||
if (thing->thingClassId() == heosThingClassId) {
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
AvrConnection *avrConnection = m_avrConnections.value(thing->id());
|
||||
thing->setStateValue(AVRX1000ConnectedStateTypeId, avrConnection->connected());
|
||||
avrConnection->getPower();
|
||||
avrConnection->getMute();
|
||||
avrConnection->getVolume();
|
||||
avrConnection->getChannel();
|
||||
avrConnection->getSurroundMode();
|
||||
avrConnection->getPlayBackInfo();
|
||||
avrConnection->getBassLevel();
|
||||
avrConnection->getTrebleLevel();
|
||||
avrConnection->getToneControl();
|
||||
|
||||
} else if (thing->thingClassId() == heosThingClassId) {
|
||||
Heos *heos = m_heosConnections.value(thing->id());
|
||||
thing->setStateValue(heosConnectedStateTypeId, heos->connected());
|
||||
if (pluginStorage()->childGroups().contains(thing->id().toString())) {
|
||||
@ -414,13 +516,21 @@ void IntegrationPluginDenon::postSetupThing(Thing *thing)
|
||||
|
||||
void IntegrationPluginDenon::onPluginTimer()
|
||||
{
|
||||
foreach(AvrConnection *denonConnection, m_avrConnections.values()) {
|
||||
if (!denonConnection->connected()) {
|
||||
denonConnection->connectDevice();
|
||||
foreach(AvrConnection *avrConnection, m_avrConnections.values()) {
|
||||
if (!avrConnection->connected()) {
|
||||
avrConnection->connectDevice();
|
||||
}
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(avrConnection));
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
denonConnection->getAllStatus();
|
||||
avrConnection->getPower();
|
||||
avrConnection->getMute();
|
||||
avrConnection->getVolume();
|
||||
avrConnection->getChannel();
|
||||
avrConnection->getSurroundMode();
|
||||
avrConnection->getPlayBackInfo();
|
||||
avrConnection->getBassLevel();
|
||||
avrConnection->getTrebleLevel();
|
||||
avrConnection->getToneControl();
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,19 +547,25 @@ void IntegrationPluginDenon::onPluginTimer()
|
||||
void IntegrationPluginDenon::onAvrConnectionChanged(bool status)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
// if the thing is connected
|
||||
if (status) {
|
||||
// and from the first setup
|
||||
// if the thing and from the first setup
|
||||
if (m_asyncAvrSetups.contains(denonConnection)) {
|
||||
// and ist connected
|
||||
if (status) {
|
||||
ThingSetupInfo *info = m_asyncAvrSetups.take(denonConnection);
|
||||
info->thing()->setStateValue(AVRX1000ConnectedStateTypeId, true);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing) {
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000ConnectedStateTypeId, denonConnection->connected());
|
||||
}
|
||||
}
|
||||
@ -458,15 +574,17 @@ void IntegrationPluginDenon::onAvrVolumeChanged(int volume)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing)
|
||||
if (!thing) {
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000VolumeStateTypeId, volume);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrChannelChanged(const QByteArray &channel)
|
||||
void IntegrationPluginDenon::onAvrChannelChanged(const QString &channel)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
@ -482,8 +600,10 @@ void IntegrationPluginDenon::onAvrMuteChanged(bool mute)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing)
|
||||
if (!thing) {
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000MuteStateTypeId, mute);
|
||||
@ -502,27 +622,127 @@ void IntegrationPluginDenon::onAvrPowerChanged(bool power)
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrSurroundModeChanged(const QByteArray &surroundMode)
|
||||
void IntegrationPluginDenon::onAvrSurroundModeChanged(const QString &surroundMode)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing)
|
||||
if (!thing){
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
|
||||
}
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000SurroundModeStateTypeId, surroundMode);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrSongChanged(const QString &song)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing){
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000TitleStateTypeId, song);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrArtistChanged(const QString &artist)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing){
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000ArtistStateTypeId, artist);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrAlbumChanged(const QString &album)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing){
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000CollectionStateTypeId, album);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrBassLevelChanged(int level)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing){
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000BassStateTypeId, level);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrTrebleLevelChanged(int level)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing){
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000TrebleStateTypeId, level);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrToneControlEnabledChanged(bool enabled)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing){
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
thing->setStateValue(AVRX1000ToneControlStateTypeId, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrPlayBackModeChanged(AvrConnection::PlayBackMode mode)
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing){
|
||||
qCWarning(dcDenon()) << "Could not find a thing associated to this AVR connection";
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
switch (mode) {
|
||||
case AvrConnection::PlayBackModePlaying:
|
||||
thing->setStateValue(AVRX1000PlaybackStatusStateTypeId, "Playing");
|
||||
break;
|
||||
case AvrConnection::PlayBackModePaused:
|
||||
thing->setStateValue(AVRX1000PlaybackStatusStateTypeId, "Paused");
|
||||
break;
|
||||
case AvrConnection::PlayBackModeStopped:
|
||||
thing->setStateValue(AVRX1000PlaybackStatusStateTypeId, "Stopped");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IntegrationPluginDenon::onAvrSocketError()
|
||||
{
|
||||
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
|
||||
Thing *thing = myThings().findById(m_avrConnections.key(denonConnection));
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
if (thing->thingClassId() == AVRX1000ThingClassId) {
|
||||
|
||||
// Check if setup running for this thing
|
||||
if (m_asyncAvrSetups.contains(denonConnection)) {
|
||||
@ -532,7 +752,27 @@ void IntegrationPluginDenon::onAvrSocketError()
|
||||
// Delete the connection, the thing will not be added and
|
||||
// the connection will be created in the next setup
|
||||
denonConnection->deleteLater();
|
||||
m_avrConnections.remove(thing->id());
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginDenon::onAvrCommandExecuted(const QUuid &commandId, bool success)
|
||||
{
|
||||
if (m_avrPendingActions.contains(commandId)) {
|
||||
ThingActionInfo *info = m_avrPendingActions.take(commandId);
|
||||
if (success){
|
||||
if(info->action().actionTypeId() == AVRX1000PlayActionTypeId) {
|
||||
info->thing()->setStateValue(AVRX1000PlaybackStatusStateTypeId, "Playing");
|
||||
} else if(info->action().actionTypeId() == AVRX1000PauseActionTypeId) {
|
||||
info->thing()->setStateValue(AVRX1000PlaybackStatusStateTypeId, "Paused");
|
||||
} else if(info->action().actionTypeId() == AVRX1000StopActionTypeId) {
|
||||
info->thing()->setStateValue(AVRX1000PlaybackStatusStateTypeId, "Stopped");
|
||||
} else if(info->action().actionTypeId() == AVRX1000PlaybackStatusActionTypeId) {
|
||||
info->thing()->setStateValue(AVRX1000PlaybackStatusStateTypeId, info->action().param(AVRX1000PlaybackStatusActionPlaybackStatusParamTypeId).value());
|
||||
}
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
} else {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -663,7 +903,7 @@ void IntegrationPluginDenon::onHeosRepeatModeReceived(int playerId, REPEAT_MODE
|
||||
void IntegrationPluginDenon::onHeosShuffleModeReceived(int playerId, bool shuffle)
|
||||
{
|
||||
foreach(Thing *thing, myThings().filterByParam(heosPlayerThingPlayerIdParamTypeId, playerId)) {
|
||||
thing->setStateValue(heosPlayerMuteStateTypeId, shuffle);
|
||||
thing->setStateValue(heosPlayerShuffleStateTypeId, shuffle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,8 @@ private:
|
||||
QHash<const Action *, int> m_asyncActions;
|
||||
QUrl m_notificationUrl;
|
||||
|
||||
QHash<int, ThingActionInfo*> m_pendingActions;
|
||||
QHash<int, ThingActionInfo*> m_heosPendingActions;
|
||||
QHash<QUuid, ThingActionInfo*> m_avrPendingActions;
|
||||
|
||||
QHash<Heos*, BrowseResult*> m_pendingGetSourcesRequest;
|
||||
QHash<QString, BrowseResult*> m_pendingBrowseResult; // QString = containerId or sourceId
|
||||
@ -128,11 +129,20 @@ private slots:
|
||||
|
||||
void onAvrConnectionChanged(bool status);
|
||||
void onAvrSocketError();
|
||||
void onAvrCommandExecuted(const QUuid &commandId, bool success);
|
||||
|
||||
void onAvrVolumeChanged(int volume);
|
||||
void onAvrChannelChanged(const QByteArray &channel);
|
||||
void onAvrChannelChanged(const QString &channel);
|
||||
void onAvrMuteChanged(bool mute);
|
||||
void onAvrPowerChanged(bool power);
|
||||
void onAvrSurroundModeChanged(const QByteArray &surroundMode);
|
||||
void onAvrSurroundModeChanged(const QString &surroundMode);
|
||||
void onAvrSongChanged(const QString &song);
|
||||
void onAvrArtistChanged(const QString &artist);
|
||||
void onAvrAlbumChanged(const QString &album);
|
||||
void onAvrPlayBackModeChanged(AvrConnection::PlayBackMode mode);
|
||||
void onAvrBassLevelChanged(int level);
|
||||
void onAvrTrebleLevelChanged(int level);
|
||||
void onAvrToneControlEnabledChanged(bool enabled);
|
||||
|
||||
void onPluginConfigurationChanged(const ParamTypeId ¶mTypeId, const QVariant &value);
|
||||
};
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
"name": "AVRX1000",
|
||||
"displayName": "AVR X1000",
|
||||
"createMethods": ["discovery"],
|
||||
"interfaces": ["extendedvolumecontroller", "connectable", "power"],
|
||||
"interfaces": ["mediaplayer", "mediacontroller", "extendedvolumecontroller", "mediametadataprovider", "shufflerepeat", "connectable", "power"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "cb6eeeb0-3d75-43b6-8177-b5ac19648557",
|
||||
@ -49,7 +49,7 @@
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"displayName": "power",
|
||||
"displayName": "Power",
|
||||
"id": "1cdb6b54-6831-4900-95b2-c78f64497701",
|
||||
"name": "power",
|
||||
"displayNameEvent": "Power changed",
|
||||
@ -80,6 +80,40 @@
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"displayName": "Tone control",
|
||||
"id": "d57c1e5e-2cc9-4638-999c-1523f16dbb83",
|
||||
"name": "toneControl",
|
||||
"displayNameEvent": "Tone control changed",
|
||||
"displayNameAction": "Set tone control",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"displayName": "Bass",
|
||||
"id": "2c92b22e-d5b2-4991-a523-64222bffc9e7",
|
||||
"name": "bass",
|
||||
"displayNameEvent": "Bass changed",
|
||||
"displayNameAction": "Set bass",
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"minValue": -50,
|
||||
"maxValue": 49,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"displayName": "Treble",
|
||||
"id": "38a3be02-6ed4-4a84-903e-eb923b933989",
|
||||
"name": "treble",
|
||||
"displayNameEvent": "Treble changed",
|
||||
"displayNameAction": "Set treble",
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"minValue": -50,
|
||||
"maxValue": 49,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"displayName": "Channel",
|
||||
"id": "f29ffa2c-31d6-4d88-b160-a38288c82ce1",
|
||||
@ -136,6 +170,85 @@
|
||||
"MATRIX"
|
||||
],
|
||||
"defaultValue": "MOVIE"
|
||||
},
|
||||
{
|
||||
"id": "50b34df4-90f7-41aa-9a57-6f2d31a18430",
|
||||
"name": "artist",
|
||||
"displayName": "Artist",
|
||||
"displayNameEvent": "Artist changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "d4f14d93-8cae-4e1b-9ee7-a5c21c0211df",
|
||||
"name": "collection",
|
||||
"displayName": "Album",
|
||||
"displayNameEvent": "Album changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "d32493d8-5faf-4c7a-ba94-847dc9b81615",
|
||||
"name": "title",
|
||||
"displayName": "Title",
|
||||
"displayNameEvent": "Title changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "6c4a208b-5b04-40cc-b14b-8f79aff30307",
|
||||
"name": "artwork",
|
||||
"displayName": "Artwork",
|
||||
"displayNameEvent": "Artwork changed",
|
||||
"type": "QString",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "2f372374-16f3-4900-afdc-834f51075d07",
|
||||
"name": "playerType",
|
||||
"displayName": "Player type",
|
||||
"displayNameEvent": "Player type changed",
|
||||
"possibleValues": [
|
||||
"audio",
|
||||
"video"
|
||||
],
|
||||
"type": "QString",
|
||||
"defaultValue": "audio"
|
||||
},
|
||||
{
|
||||
"id": "8ef6708c-812a-4e6a-a608-9e480aa3b7bf",
|
||||
"name": "playbackStatus",
|
||||
"displayName": "Playback status",
|
||||
"displayNameEvent": "Playback status changed",
|
||||
"displayNameAction": "Set playback status",
|
||||
"type": "QString",
|
||||
"defaultValue": "Stopped",
|
||||
"possibleValues": ["Playing", "Paused", "Stopped"],
|
||||
"cached": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "8ad33cb9-e758-433d-a013-2e4d43157c92",
|
||||
"name": "shuffle",
|
||||
"displayName": "Shuffle",
|
||||
"displayNameEvent": "Shuffle changed",
|
||||
"displayNameAction": "Set shuffle",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "9478987b-14e4-4572-a059-a18a5a9db229",
|
||||
"name": "repeat",
|
||||
"displayName": "Repeat mode",
|
||||
"displayNameEvent": "Repeat mode changed",
|
||||
"displayNameAction": "Set repeat mode",
|
||||
"type": "QString",
|
||||
"defaultValue": "None",
|
||||
"possibleValues": ["None", "One", "All"],
|
||||
"cached": false,
|
||||
"writable": true
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
@ -164,6 +277,31 @@
|
||||
"type": "int"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "3f2eb789-918c-475a-a295-14c0c24338b8",
|
||||
"name": "skipBack",
|
||||
"displayName": "Skip back"
|
||||
},
|
||||
{
|
||||
"id": "ddab0869-5b90-4fd4-9c40-9ad57101b87c",
|
||||
"name": "stop",
|
||||
"displayName": "Stop"
|
||||
},
|
||||
{
|
||||
"id": "d04eb30b-838d-4fbd-b781-c01005b59756",
|
||||
"name": "play",
|
||||
"displayName": "Play"
|
||||
},
|
||||
{
|
||||
"id": "3de38047-006f-4d97-9326-08bb5ad79b05",
|
||||
"name": "pause",
|
||||
"displayName": "Pause"
|
||||
},
|
||||
{
|
||||
"id": "bf9664e4-a53e-474c-afcc-88f25e6fe365",
|
||||
"name": "skipNext",
|
||||
"displayName": "Skip next"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user