refactored AVR connection

This commit is contained in:
nymea 2019-06-28 20:14:43 +02:00
parent 89462334a2
commit 8d60bbb719
7 changed files with 466 additions and 299 deletions

261
denon/avrconnection.cpp Normal file
View File

@ -0,0 +1,261 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@nymea.io> *
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io> *
* *
* This file is part of nymea. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "avrconnection.h"
#include "extern-plugininfo.h"
AvrConnection::AvrConnection(const QHostAddress &hostAddress, const int &port, QObject *parent) :
QObject(parent),
m_hostAddress(hostAddress),
m_port(port)
{
m_socket = new QTcpSocket(this);
connect(m_socket, &QTcpSocket::connected, this, &AvrConnection::onConnected);
connect(m_socket, &QTcpSocket::disconnected, this, &AvrConnection::onDisconnected);
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)));
}
AvrConnection::~AvrConnection()
{
m_socket->close();
}
void AvrConnection::connect()
{
if (m_socket->state() == QAbstractSocket::ConnectingState) {
return;
}
m_socket->connectToHost(m_hostAddress, m_port);
}
void AvrConnection::disconnect()
{
m_socket->close();
}
QHostAddress AvrConnection::hostAddress() const
{
return m_hostAddress;
}
int AvrConnection::port() const
{
return m_port;
}
bool AvrConnection::connected()
{
return m_socket->isOpen();
}
void AvrConnection::getAllStatus()
{
sendCommand("PW?\rSI?\rMV?\rMS?\rMU?\r");
}
void AvrConnection::getChannel()
{
sendCommand("SI?\r");
}
void AvrConnection::getVolume()
{
sendCommand("MV?\r");
}
void AvrConnection::getMute()
{
sendCommand("MU?\r");
}
void AvrConnection::getPower()
{
sendCommand("PW?\r");
}
void AvrConnection::getSurroundMode()
{
sendCommand("MS?\r");
}
void AvrConnection::sendCommand(const QByteArray &message)
{
m_socket->write(message);
}
void AvrConnection::setChannel(const QByteArray &channel)
{
QByteArray cmd = "SI" + channel + "\r";
qCDebug(dcDenon) << "Change to channel:" << cmd;
sendCommand(cmd);
}
void AvrConnection::setVolume(int volume)
{
qCDebug(dcDenon) << "Set volume" << volume;
QByteArray cmd = "MV" + QByteArray::number(volume) + "\r";
sendCommand(cmd);
}
void AvrConnection::setMute(bool mute)
{
qCDebug(dcDenon) << "Set mute" << mute;
QByteArray cmd;
if (mute) {
cmd = "MUON\r";
} else {
cmd = "MUOFF\r";
}
sendCommand(cmd);
}
void AvrConnection::setPower(bool power)
{
qCDebug(dcDenon) << "Set power" << power;
QByteArray cmd;
if (power) {
cmd = "PWON\r";
} else {
cmd = "PWSTANDBY\r";
}
sendCommand(cmd);
}
void AvrConnection::setSurroundMode(const QByteArray &surroundMode)
{
qCDebug(dcDenon) << "Set surround mode" << surroundMode;
QByteArray cmd = "MS" + surroundMode + "\r";
sendCommand(cmd);
}
void AvrConnection::increaseVolume()
{
qCDebug(dcDenon) << "Execute volume increase";
QByteArray cmd = "MVUP\r";
sendCommand(cmd);
}
void AvrConnection::decreaseVolume()
{
qCDebug(dcDenon) << "Execute volume decrease";
QByteArray cmd = "MVDOWN\r";
sendCommand(cmd);
}
void AvrConnection::onConnected()
{
qCDebug(dcDenon) << "connected successfully to" << hostAddress().toString() << port();
emit connectionStatusChanged(true);
}
void AvrConnection::onDisconnected()
{
qCDebug(dcDenon) << "disconnected from" << hostAddress().toString() << port();
emit connectionStatusChanged(false);
}
void AvrConnection::onError(QAbstractSocket::SocketError socketError)
{
qCWarning(dcDenon) << "socket error:" << socketError << m_socket->errorString();
emit socketErrorOccured(socketError);
}
void AvrConnection::readData()
{
QByteArray data = m_socket->readAll();
qCDebug(dcDenon) << "Data received" << data;
if (data.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")) {
QByteArray cmd;
if (data.contains("TUNER")) {
cmd = "TUNER";
} else if (data.contains("DVD")) {
cmd = "DVD";
} else if (data.contains("BD")) {
cmd = "BD";
} else if (data.contains("TV")) {
cmd = "TV";
} else if (data.contains("SAT/CBL")) {
cmd = "SAT/CBL";
} else if (data.contains("MPLAY")) {
cmd = "MPLAY";
} else if (data.contains("GAME")) {
cmd = "GAME";
} else if (data.contains("AUX1")) {
cmd = "AUX1";
} else if (data.contains("NET")) {
cmd = "NET";
} else if (data.contains("PANDORA")) {
cmd = "PANDORA";
} else if (data.contains("SIRIUSXM")) {
cmd = "SIRIUSXM";
} else if (data.contains("SPOTIFY")) {
cmd = "SPOTIFY";
} else if (data.contains("FLICKR")) {
cmd = "FLICKR";
} else if (data.contains("FAVORITES")) {
cmd = "FAVORITES";
} else if (data.contains("IRADIO")) {
cmd = "IRADIO";
} else if (data.contains("SERVER")) {
cmd = "SERVER";
} else if (data.contains("USB/IPOD")) {
cmd = "USB/IPOD";
} else if (data.contains("IPD")) {
cmd = "IPD";
} else if (data.contains("IRP")) {
cmd = "IRP";
} else if (data.contains("FVP")) {
cmd = "FVP";
}
emit channelChanged(cmd);
}
if (data.contains("PWON")) {
emit powerChanged(true);
}
if (data.contains("PWSTANDBY")) {
emit powerChanged(false);
}
if (data.contains("MUON")) {
emit muteChanged(false);
}
if (data.contains("MUOFF")) {
emit muteChanged(false);
}
if (data.left(2).contains("MS")) {
data.remove(0, 2);
QByteArray cmd = data;
emit surroundModeChanged(cmd);
}
}

View File

@ -1,7 +1,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
* Copyright (C) 2016 Bernhard Trinnes <bernhard.trinnes@guh.guru> *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@nymea.io> *
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io> *
* *
* This file is part of nymea. *
* *
@ -21,36 +21,48 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef DENONCONNECTION_H
#define DENONCONNECTION_H
#ifndef AVRCONNECTION_H
#define AVRCONNECTION_H
#include <QObject>
#include <QTcpSocket>
#include <QHostAddress>
class DenonConnection : public QObject
class AvrConnection : public QObject
{
Q_OBJECT
public:
explicit DenonConnection(const QHostAddress &hostAddress, const int &port = 23, QObject *parent = 0);
~DenonConnection();
explicit AvrConnection(const QHostAddress &hostAddress, const int &port = 23, QObject *parent = nullptr);
~AvrConnection();
void connectDenon();
void disconnectDenon();
void connect();
void disconnect();
QHostAddress hostAddress() const;
int port() const;
bool connected();
void sendData(const QByteArray &message);
void getAllStatus();
void getChannel();
void getVolume();
void getMute();
void getPower();
void getSurroundMode();
void setChannel(const QByteArray &channel);
void setVolume(int volume);
void setMute(bool mute);
void setPower(bool power);
void setSurroundMode(const QByteArray &surroundMode);
void increaseVolume();
void decreaseVolume();
private:
QTcpSocket *m_socket;
QTcpSocket *m_socket = nullptr;
QHostAddress m_hostAddress;
int m_port;
bool m_connected;
void sendCommand(const QByteArray &message);
private slots:
void onConnected();
@ -58,13 +70,14 @@ private slots:
void onError(QAbstractSocket::SocketError socketError);
void readData();
void setConnected(const bool &connected);
signals:
void socketErrorOccured(QAbstractSocket::SocketError socketError);
void connectionStatusChanged();
void dataReady(const QByteArray &data);
void connectionStatusChanged(bool status);
void volumeChanged(int volume);
void muteChanged(bool mute);
void channelChanged(const QByteArray &channel);
void powerChanged(bool power);
void surroundModeChanged(const QByteArray &surroundMode);
};
#endif // DENONCONNECTION_H
#endif // AVRCONNECTION_H

View File

@ -6,12 +6,12 @@ TARGET = $$qtLibraryTarget(nymea_deviceplugindenon)
SOURCES += \
deviceplugindenon.cpp \
denonconnection.cpp \
heos.cpp \
heosplayer.cpp \
avrconnection.cpp
HEADERS += \
deviceplugindenon.h \
denonconnection.h \
heos.h \
heosplayer.h \
avrconnection.h

View File

@ -1,108 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
* Copyright (C) 2016 Bernhard Trinnes <bernhard.trinnes@guh.io> *
* *
* This file is part of nymea. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "denonconnection.h"
#include "extern-plugininfo.h"
DenonConnection::DenonConnection(const QHostAddress &hostAddress, const int &port, QObject *parent) :
QObject(parent),
m_hostAddress(hostAddress),
m_port(port),
m_connected(false)
{
m_socket = new QTcpSocket(this);
connect(m_socket, &QTcpSocket::connected, this, &DenonConnection::onConnected);
connect(m_socket, &QTcpSocket::disconnected, this, &DenonConnection::onDisconnected);
connect(m_socket, &QTcpSocket::readyRead, this, &DenonConnection::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)));
}
DenonConnection::~DenonConnection()
{
m_socket->close();
}
void DenonConnection::connectDenon()
{
if (m_socket->state() == QAbstractSocket::ConnectingState) {
return;
}
m_socket->connectToHost(m_hostAddress, m_port);
}
void DenonConnection::disconnectDenon()
{
m_socket->close();
}
QHostAddress DenonConnection::hostAddress() const
{
return m_hostAddress;
}
int DenonConnection::port() const
{
return m_port;
}
bool DenonConnection::connected()
{
return m_connected;
}
void DenonConnection::sendData(const QByteArray &message)
{
m_socket->write(message);
}
void DenonConnection::onConnected()
{
qCDebug(dcDenon) << "connected successfully to" << hostAddress().toString() << port();
setConnected(true);
}
void DenonConnection::onDisconnected()
{
qCDebug(dcDenon) << "disconnected from" << hostAddress().toString() << port();
setConnected(false);
}
void DenonConnection::onError(QAbstractSocket::SocketError socketError)
{
qCWarning(dcDenon) << "socket error:" << socketError << m_socket->errorString();
emit socketErrorOccured(socketError);
}
void DenonConnection::readData()
{
QByteArray data = m_socket->readAll();
emit dataReady(QString(data).toUtf8());
}
void DenonConnection::setConnected(const bool &connected)
{
m_connected = connected;
emit connectionStatusChanged();
}

View File

@ -43,7 +43,7 @@
#include "deviceplugindenon.h"
#include "plugininfo.h"
#include "plugin/device.h"
#include "devices/device.h"
#include "network/networkaccessmanager.h"
#include "network/upnp/upnpdiscovery.h"
#include "network/upnp/upnpdiscoveryreply.h"
@ -59,7 +59,7 @@ DevicePluginDenon::DevicePluginDenon()
{
}
DeviceManager::DeviceError DevicePluginDenon::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
Device::DeviceError DevicePluginDenon::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params)
@ -67,7 +67,7 @@ DeviceManager::DeviceError DevicePluginDenon::discoverDevices(const DeviceClassI
UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices("urn:schemas-upnp-org:device:MediaRenderer:1", "nymea", 7000);
connect(reply, &UpnpDiscoveryReply::finished, this, &DevicePluginDenon::onUpnpDiscoveryFinished);
return DeviceManager::DeviceErrorAsync;
return Device::DeviceErrorAsync;
}
if (deviceClassId == heosDeviceClassId) {
@ -80,9 +80,9 @@ DeviceManager::DeviceError DevicePluginDenon::discoverDevices(const DeviceClassI
*/
UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices();
connect(reply, &UpnpDiscoveryReply::finished, this, &DevicePluginDenon::onUpnpDiscoveryFinished);
return DeviceManager::DeviceErrorAsync;
return Device::DeviceErrorAsync;
}
return DeviceManager::DeviceErrorDeviceClassNotFound;
return Device::DeviceErrorDeviceClassNotFound;
}
Device::DeviceSetupStatus DevicePluginDenon::setupDevice(Device *device)
@ -98,18 +98,22 @@ Device::DeviceSetupStatus DevicePluginDenon::setupDevice(Device *device)
QHostAddress address(device->paramValue(AVRX1000DeviceIpParamTypeId).toString());
if (address.isNull()) {
qCWarning(dcDenon) << "Could not parse ip address" << device->paramValue(AVRX1000DeviceIpParamTypeId).toString();
return DeviceManager::DeviceSetupStatusFailure;
return Device::DeviceSetupStatusFailure;
}
DenonConnection *denonConnection = new DenonConnection(address, 23, this);
connect(denonConnection, &DenonConnection::connectionStatusChanged, this, &DevicePluginDenon::onAVRConnectionChanged);
connect(denonConnection, &DenonConnection::socketErrorOccured, this, &DevicePluginDenon::onAVRSocketError);
connect(denonConnection, &DenonConnection::dataReady, this, &DevicePluginDenon::onAVRDataReceived);
AvrConnection *denonConnection = new AvrConnection(address, 23, this);
connect(denonConnection, &AvrConnection::connectionStatusChanged, this, &DevicePluginDenon::onAvrConnectionChanged);
connect(denonConnection, &AvrConnection::socketErrorOccured, this, &DevicePluginDenon::onAvrSocketError);
connect(denonConnection, &AvrConnection::channelChanged, this, &DevicePluginDenon::onAvrChannelChanged);
connect(denonConnection, &AvrConnection::powerChanged, this, &DevicePluginDenon::onAvrPowerChanged);
connect(denonConnection, &AvrConnection::volumeChanged, this, &DevicePluginDenon::onAvrVolumeChanged);
connect(denonConnection, &AvrConnection::surroundModeChanged, this, &DevicePluginDenon::onAvrSurroundModeChanged);
connect(denonConnection, &AvrConnection::muteChanged, this, &DevicePluginDenon::onAvrMuteChanged);
m_asyncSetups.append(denonConnection);
denonConnection->connectDenon();
m_denonConnections.insert(device, denonConnection);
return DeviceManager::DeviceSetupStatusAsync;
denonConnection->connect();
m_avrConnections.insert(device, denonConnection);
return Device::DeviceSetupStatusAsync;
}
if (device->deviceClassId() == heosDeviceClassId) {
@ -128,13 +132,13 @@ Device::DeviceSetupStatus DevicePluginDenon::setupDevice(Device *device)
heos->connectHeos();
m_heos.insert(device, heos);
return DeviceManager::DeviceSetupStatusAsync;
return Device::DeviceSetupStatusAsync;
}
if (device->deviceClassId() == heosPlayerDeviceClassId) {
return DeviceManager::DeviceSetupStatusSuccess;
return Device::DeviceSetupStatusSuccess;
}
return DeviceManager::DeviceSetupStatusFailure;
return Device::DeviceSetupStatusFailure;
}
void DevicePluginDenon::deviceRemoved(Device *device)
@ -142,17 +146,17 @@ void DevicePluginDenon::deviceRemoved(Device *device)
qCDebug(dcDenon) << "Delete " << device->name();
if (device->deviceClassId() == AVRX1000DeviceClassId) {
DenonConnection *denonConnection = m_denonConnections.value(device);
m_denonConnections.remove(device);
denonConnection->disconnectDenon();
AvrConnection *denonConnection = m_avrConnections.value(device);
m_avrConnections.remove(device);
denonConnection->disconnect();
denonConnection->deleteLater();
}
if (device->deviceClassId() == heosDeviceClassId) {
if (m_denonConnections.contains(device)) {
DenonConnection *denonConnection = m_denonConnections.value(device);
m_denonConnections.remove(device);
denonConnection->disconnectDenon();
if (m_avrConnections.contains(device)) {
AvrConnection *denonConnection = m_avrConnections.value(device);
m_avrConnections.remove(device);
denonConnection->disconnect();
denonConnection->deleteLater();
}
}
@ -166,57 +170,44 @@ Device::DeviceError DevicePluginDenon::executeAction(Device *device, const Actio
{
qCDebug(dcDenon) << "Execute action" << device->id() << action.id() << action.params();
if (device->deviceClassId() == AVRX1000DeviceClassId) {
DenonConnection *denonConnection = m_denonConnections.value(device);
AvrConnection *avrConnection = m_avrConnections.value(device);
if (action.actionTypeId() == AVRX1000PowerActionTypeId) {
qCDebug(dcDenon) << "set power action" << action.id();
qCDebug(dcDenon) << "power: " << action.param(AVRX1000PowerActionPowerParamTypeId).value().Bool;
if (action.param(AVRX1000PowerActionPowerParamTypeId).value().toBool() == true) {
QByteArray cmd = "PWON\r";
qCDebug(dcDenon) << "Execute power: " << action.id() << cmd;
denonConnection->sendData(cmd);
} else {
QByteArray cmd = "PWSTANDBY\r";
qCDebug(dcDenon) << "Execute power: " << action.id() << cmd;
denonConnection->sendData(cmd);
}
bool power = action.param(AVRX1000PowerActionPowerParamTypeId).value().toBool();
avrConnection->setPower(power);
return Device::DeviceErrorNoError;
} else if (action.actionTypeId() == AVRX1000VolumeActionTypeId) {
QByteArray vol = action.param(AVRX1000VolumeActionVolumeParamTypeId).value().toByteArray();
QByteArray cmd = "MV" + vol + "\r";
qCDebug(dcDenon) << "Execute volume" << action.id() << cmd;
denonConnection->sendData(cmd);
return DeviceManager::DeviceErrorNoError;
int vol = action.param(AVRX1000VolumeActionVolumeParamTypeId).value().toInt();
avrConnection->setVolume(vol);
return Device::DeviceErrorNoError;
} else if (action.actionTypeId() == AVRX1000ChannelActionTypeId) {
qCDebug(dcDenon) << "Execute update action" << action.id();
QByteArray channel = action.param(AVRX1000ChannelActionChannelParamTypeId).value().toByteArray();
QByteArray cmd = "SI" + channel + "\r";
qCDebug(dcDenon) << "Change to channel:" << cmd;
denonConnection->sendData(cmd);
return DeviceManager::DeviceErrorNoError;
avrConnection->setChannel(channel);
return Device::DeviceErrorNoError;
} else if (action.actionTypeId() == AVRX1000IncreaseVolumeActionTypeId) {
QByteArray cmd = "MVUP\r";
qCDebug(dcDenon) << "Execute volume increase" << action.id() << cmd;
denonConnection->sendData(cmd);
return DeviceManager::DeviceErrorNoError;
avrConnection->increaseVolume();
return Device::DeviceErrorNoError;
} else if (action.actionTypeId() == AVRX1000DecreaseVolumeActionTypeId) {
QByteArray cmd = "MVDOWN\r";
qCDebug(dcDenon) << "Execute volume decrease" << action.id() << cmd;
denonConnection->sendData(cmd);
return DeviceManager::DeviceErrorNoError;
avrConnection->decreaseVolume();
return Device::DeviceErrorNoError;
} else if (action.actionTypeId() == AVRX1000SurroundModeActionTypeId) {
QByteArray surroundMode = action.param(AVRX1000SurroundModeActionSurroundModeParamTypeId).value().toByteArray();
avrConnection->setSurroundMode(surroundMode);
return Device::DeviceErrorNoError;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
return Device::DeviceErrorActionTypeNotFound;
}
if (device->deviceClassId() == heosPlayerDeviceClassId) {
@ -228,13 +219,13 @@ Device::DeviceError DevicePluginDenon::executeAction(Device *device, const Actio
if (action.actionTypeId() == heosPlayerVolumeActionTypeId) {
int volume = action.param(heosPlayerVolumeActionVolumeParamTypeId).value().toInt();
heos->setVolume(playerId, volume);
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
if (action.actionTypeId() == heosPlayerMuteActionTypeId) {
bool mute = action.param(heosPlayerMuteActionMuteParamTypeId).value().toBool();
heos->setMute(playerId, mute);
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
if (action.actionTypeId() == heosPlayerPlaybackStatusActionTypeId) {
@ -246,7 +237,7 @@ Device::DeviceError DevicePluginDenon::executeAction(Device *device, const Actio
} else if (playbackStatus == "pausing") {
heos->setPlayerState(playerId, Heos::HeosPlayerState::Pause);
}
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
if (action.actionTypeId() == heosPlayerShuffleActionTypeId) {
@ -255,45 +246,45 @@ Device::DeviceError DevicePluginDenon::executeAction(Device *device, const Actio
repeatMode = Heos::HeosRepeatMode::Off;
heos->setPlayMode(playerId, repeatMode, shuffle);
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
if (action.actionTypeId() == heosPlayerSkipBackActionTypeId) {
heos->playPrevious(playerId);
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
if (action.actionTypeId() == heosPlayerFastRewindActionTypeId) {
return DeviceManager::DeviceErrorActionTypeNotFound;
return Device::DeviceErrorActionTypeNotFound;
}
if (action.actionTypeId() == heosPlayerStopActionTypeId) {
heos->setPlayerState(playerId, Heos::HeosPlayerState::Stop);
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
if (action.actionTypeId() == heosPlayerPlayActionTypeId) {
heos->setPlayerState(playerId, Heos::HeosPlayerState::Play);
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
if (action.actionTypeId() == heosPlayerPauseActionTypeId) {
heos->setPlayerState(playerId, Heos::HeosPlayerState::Pause);
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
if (action.actionTypeId() == heosPlayerFastForwardActionTypeId) {
return DeviceManager::DeviceErrorActionTypeNotFound;
return Device::DeviceErrorActionTypeNotFound;
}
if (action.actionTypeId() == heosPlayerSkipNextActionTypeId) {
heos->playNext(playerId);
return DeviceManager::DeviceErrorNoError;
return Device::DeviceErrorNoError;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
return Device::DeviceErrorActionTypeNotFound;
}
return Device::DeviceErrorDeviceClassNotFound;
}
@ -324,13 +315,13 @@ void DevicePluginDenon::postSetupDevice(Device *device)
void DevicePluginDenon::onPluginTimer()
{
foreach(DenonConnection *denonConnection, m_denonConnections.values()) {
foreach(AvrConnection *denonConnection, m_avrConnections.values()) {
if (!denonConnection->connected()) {
denonConnection->connectDenon();
denonConnection->connect();
}
Device *device = m_denonConnections.key(denonConnection);
Device *device = m_avrConnections.key(denonConnection);
if (device->deviceClassId() == AVRX1000DeviceClassId) {
denonConnection->sendData("PW?\rSI?\rMV?\r");
denonConnection->getAllStatus();
}
}
@ -360,113 +351,94 @@ void DevicePluginDenon::onPluginTimer()
}
}
void DevicePluginDenon::onAVRConnectionChanged()
void DevicePluginDenon::onAvrConnectionChanged(bool status)
{
DenonConnection *denonConnection = static_cast<DenonConnection *>(sender());
Device *device = m_denonConnections.key(denonConnection);
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
Device *device = m_avrConnections.key(denonConnection);
if (!device)
return;
if (device->deviceClassId() == AVRX1000DeviceClassId) {
// if the device is connected
if (denonConnection->connected()) {
if (status) {
// and from the first setup
if (m_asyncSetups.contains(denonConnection)) {
m_asyncSetups.removeAll(denonConnection);
denonConnection->sendData("PW?\rSI?\rMV?\r");
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
emit deviceSetupFinished(device, Device::DeviceSetupStatusSuccess);
}
}
device->setStateValue(AVRX1000ConnectedStateTypeId, denonConnection->connected());
}
}
void DevicePluginDenon::onAVRDataReceived(const QByteArray &data)
void DevicePluginDenon::onAvrVolumeChanged(int volume)
{
DenonConnection *denonConnection = static_cast<DenonConnection *>(sender());
Device *device = m_denonConnections.key(denonConnection);
qCDebug(dcDenon) << "Data received" << data;
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
Device *device = m_avrConnections.key(denonConnection);
if (!device)
return;
if (device->deviceClassId() == AVRX1000DeviceClassId) {
if (data.contains("MV") && !data.contains("MAX")){
int index = data.indexOf("MV");
int vol = data.mid(index+2, 2).toInt();
device->setStateValue(AVRX1000VolumeStateTypeId, volume);
}
}
qCDebug(dcDenon) << "Update volume:" << vol;
device->setStateValue(AVRX1000VolumeStateTypeId, vol);
}
void DevicePluginDenon::onAvrMuteChanged(bool mute)
{
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
Device *device = m_avrConnections.key(denonConnection);
if (!device)
return;
if (data.contains("SI")) {
QString cmd;
if (data.contains("TUNER")) {
cmd = "TUNER";
} else if (data.contains("DVD")) {
cmd = "DVD";
} else if (data.contains("BD")) {
cmd = "BD";
} else if (data.contains("TV")) {
cmd = "TV";
} else if (data.contains("SAT/CBL")) {
cmd = "SAT/CBL";
} else if (data.contains("MPLAY")) {
cmd = "MPLAY";
} else if (data.contains("GAME")) {
cmd = "GAME";
} else if (data.contains("AUX1")) {
cmd = "AUX1";
} else if (data.contains("NET")) {
cmd = "NET";
} else if (data.contains("PANDORA")) {
cmd = "PANDORA";
} else if (data.contains("SIRIUSXM")) {
cmd = "SIRIUSXM";
} else if (data.contains("SPOTIFY")) {
cmd = "SPOTIFY";
} else if (data.contains("FLICKR")) {
cmd = "FLICKR";
} else if (data.contains("FAVORITES")) {
cmd = "FAVORITES";
} else if (data.contains("IRADIO")) {
cmd = "IRADIO";
} else if (data.contains("SERVER")) {
cmd = "SERVER";
} else if (data.contains("USB/IPOD")) {
cmd = "USB/IPOD";
} else if (data.contains("IPD")) {
cmd = "IPD";
} else if (data.contains("IRP")) {
cmd = "IRP";
} else if (data.contains("FVP")) {
cmd = "FVP";
}
qCDebug(dcDenon) << "Update channel:" << cmd;
device->setStateValue(AVRX1000ChannelStateTypeId, cmd);
}
if (device->deviceClassId() == AVRX1000DeviceClassId) {
device->setStateValue(AVRX1000MuteStateTypeId, mute);
}
}
if (data.contains("PWON")) {
qCDebug(dcDenon) << "Update power on";
device->setStateValue(AVRX1000PowerStateTypeId, true);
} else if (data.contains("PWSTANDBY")) {
qCDebug(dcDenon) << "Update power off";
device->setStateValue(AVRX1000PowerStateTypeId, false);
}
void DevicePluginDenon::onAvrPowerChanged(bool power)
{
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
Device *device = m_avrConnections.key(denonConnection);
if (!device)
return;
if (device->deviceClassId() == AVRX1000DeviceClassId) {
device->setStateValue(AVRX1000PowerStateTypeId, power);
}
}
void DevicePluginDenon::onAvrSurroundModeChanged(const QByteArray &surroundMode)
{
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
Device *device = m_avrConnections.key(denonConnection);
if (!device)
return;
if (device->deviceClassId() == AVRX1000DeviceClassId) {
device->setStateValue(AVRX1000SurroundModeStateTypeId, surroundMode);
}
}
void DevicePluginDenon::onAVRSocketError()
void DevicePluginDenon::onAvrSocketError()
{
DenonConnection *denonConnection = static_cast<DenonConnection *>(sender());
Device *device = m_denonConnections.key(denonConnection);
AvrConnection *denonConnection = static_cast<AvrConnection *>(sender());
Device *device = m_avrConnections.key(denonConnection);
if (!device)
return;
if (device->deviceClassId() == AVRX1000DeviceClassId) {
// Check if setup running for this device
if (m_asyncSetups.contains(denonConnection)) {
m_asyncSetups.removeAll(denonConnection);
qCWarning(dcDenon()) << "Could not add device. The setup failed.";
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
emit deviceSetupFinished(device, Device::DeviceSetupStatusFailure);
// Delete the connection, the device will not be added and
// the connection will be created in the next setup
denonConnection->deleteLater();
m_denonConnections.remove(device);
m_avrConnections.remove(device);
}
}
}
@ -510,7 +482,7 @@ void DevicePluginDenon::onUpnpDiscoveryFinished()
}
}
//if (upnpDevice.modelName().contains("")) {
qCDebug(dcDenon) << "UPnP device found:" << upnpDevice.modelDescription() << upnpDevice.friendlyName() << upnpDevice.hostAddress().toString() << upnpDevice.modelName() << upnpDevice.manufacturer() << upnpDevice.serialNumber();
qCDebug(dcDenon) << "UPnP device found:" << upnpDevice.modelDescription() << upnpDevice.friendlyName() << upnpDevice.hostAddress().toString() << upnpDevice.modelName() << upnpDevice.manufacturer() << upnpDevice.serialNumber();
//}
}
if (!heosDescriptors.isEmpty()) {
@ -527,7 +499,7 @@ void DevicePluginDenon::onHeosConnectionChanged()
heos->registerForChangeEvents(true);
Device *device = m_heos.key(heos);
if (!device->setupComplete() && heos->connected()) {
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
emit deviceSetupFinished(device, Device::DeviceSetupStatusSuccess);
}
}
@ -623,3 +595,4 @@ void DevicePluginDenon::onHeosNowPlayingMediaStatusReceived(int playerId, QStrin
break;
}
}

View File

@ -24,10 +24,9 @@
#ifndef DEVICEPLUGINDENON_H
#define DEVICEPLUGINDENON_H
#include "devicemanager.h"
#include "plugin/deviceplugin.h"
#include "devices/deviceplugin.h"
#include "plugintimer.h"
#include "denonconnection.h"
#include "avrconnection.h"
#include "heos.h"
#include <QPair>
@ -47,18 +46,18 @@ class DevicePluginDenon : public DevicePlugin
public:
explicit DevicePluginDenon();
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
Device::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
Device::DeviceSetupStatus setupDevice(Device *device) override;
void postSetupDevice(Device * device) override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
Device::DeviceError executeAction(Device *device, const Action &action) override;
void deviceRemoved(Device *device) override;
private:
PluginTimer *m_pluginTimer = nullptr;
QHash<Device *, DenonConnection*> m_denonConnections;
QHash<Device *, AvrConnection*> m_avrConnections;
QHash<Device *, Heos*> m_heos;
QList<DenonConnection *> m_asyncSetups;
QList<AvrConnection *> m_asyncSetups;
QHash<int, Device *> m_playerIds;
QHash<int, Device *> m_discoveredPlayerIds;
@ -67,11 +66,6 @@ private:
private slots:
void onPluginTimer();
void onAVRConnectionChanged();
void onAVRDataReceived(const QByteArray &data);
void onAVRSocketError();
void onUpnpDiscoveryFinished();
void onHeosConnectionChanged();
@ -82,6 +76,14 @@ private slots:
void onHeosMuteStatusReceived(int playerId, bool mute);
void onHeosVolumeStatusReceived(int playerId, int volume);
void onHeosNowPlayingMediaStatusReceived(int playerId, QString source, QString artist, QString album, QString Song, QString artwork);
void onAvrConnectionChanged(bool status);
void onAvrSocketError();
void onAvrVolumeChanged(int volume);
void onAvrChannelChanged(const QByteArray &channel);
void onAvrMuteChanged(bool mute);
void onAvrPowerChanged(bool power);
void onAvrSurroundModeChanged(const QByteArray &surroundMode);
};
#endif // DEVICEPLUGINDENON_H

View File

@ -94,6 +94,32 @@
"FVP"
],
"defaultValue": "TUNER"
},
{
"displayName": "Surround mode",
"id": "4f203bdd-691c-4384-a934-2d49a5448f0a",
"name": "surroundMode",
"displayNameEvent": "Surround mode changed",
"displayNameAction": "Set surround mode",
"type": "QString",
"writable": true,
"possibleValues": [
"MOVIE",
"MUSIC",
"GAME",
"PURE DIRECT",
"DIRECT",
"STEREO",
"STANDARD",
"DOLBY DIGITAL",
"DTS SUROUND",
"MCH STEREO",
"ROCK ARENA",
"JAZZ CLUB",
"MONO MOVIE",
"MATRIX"
],
"defaultValue": "MOVIE"
}
],
"actionTypes": [
@ -156,8 +182,8 @@
{
"id": "4d1790bf-28c6-4c1f-8892-ba1a0ef140f5",
"name": "connected",
"displayName": "connected",
"displayNameEvent": "connected changed",
"displayName": "Connected",
"displayNameEvent": "Connected changed",
"defaultValue": false,
"type": "bool"
}
@ -200,7 +226,7 @@
"id": "9a4e527e-057c-4b19-8a02-605cc8349f5e",
"name": "connected",
"displayName": "connected",
"displayNameEvent": "connected changed",
"displayNameEvent": "Connected changed",
"type": "bool",
"defaultValue": false,
"cached": false
@ -208,9 +234,9 @@
{
"id": "fcc89c7c-b793-4b6f-a3dc-0e0e3a86748f",
"name": "mute",
"displayName": "mute",
"displayNameEvent": "mute changed",
"displayNameAction": "set mute",
"displayName": "Mute",
"displayNameEvent": "Mute changed",
"displayNameAction": "Set mute",
"type": "bool",
"defaultValue": false,
"cached": false,
@ -219,7 +245,7 @@
{
"id": "6d4886a1-fa5d-4889-96c5-7a1c206f59be",
"name": "volume",
"displayName": "volume",
"displayName": "Volume",
"displayNameEvent": "volume changed",
"displayNameAction": "set volume",
"type": "int",