Update Denon plugin
parent
79479ff162
commit
2b099ecdd7
|
|
@ -59,49 +59,56 @@ DevicePluginDenon::DevicePluginDenon()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::DeviceError DevicePluginDenon::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
void DevicePluginDenon::discoverDevices(DeviceDiscoveryInfo *info)
|
||||||
{
|
{
|
||||||
Q_UNUSED(params)
|
if (info->deviceClassId() == AVRX1000DeviceClassId) {
|
||||||
|
if (!hardwareManager()->zeroConfController()->available() || !hardwareManager()->zeroConfController()->enabled()) {
|
||||||
|
//: Error discovering Denon devices
|
||||||
|
info->finish(Device::DeviceErrorHardwareNotAvailable, QT_TR_NOOP("Device discovery is not available."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (deviceClassId == AVRX1000DeviceClassId) {
|
|
||||||
if (!m_serviceBrowser) {
|
if (!m_serviceBrowser) {
|
||||||
m_serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser();
|
m_serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser();
|
||||||
connect(m_serviceBrowser, &ZeroConfServiceBrowser::serviceEntryAdded, this, &DevicePluginDenon::onAvahiServiceEntryAdded);
|
connect(m_serviceBrowser, &ZeroConfServiceBrowser::serviceEntryAdded, this, &DevicePluginDenon::onAvahiServiceEntryAdded);
|
||||||
connect(m_serviceBrowser, &ZeroConfServiceBrowser::serviceEntryRemoved, this, &DevicePluginDenon::onAvahiServiceEntryRemoved);
|
connect(m_serviceBrowser, &ZeroConfServiceBrowser::serviceEntryRemoved, this, &DevicePluginDenon::onAvahiServiceEntryRemoved);
|
||||||
}
|
}
|
||||||
QStringList discoveredIds;
|
|
||||||
|
|
||||||
QList<DeviceDescriptor> deviceDescriptors;
|
QTimer::singleShot(2000, info, [this, info](){
|
||||||
foreach (const ZeroConfServiceEntry &service, m_serviceBrowser->serviceEntries()) {
|
QStringList discoveredIds;
|
||||||
if (service.txt().contains("am=AVRX1000")) {
|
|
||||||
|
|
||||||
QString id = service.name().split("@").first();
|
foreach (const ZeroConfServiceEntry &service, m_serviceBrowser->serviceEntries()) {
|
||||||
QString name = service.name().split("@").last();
|
if (service.txt().contains("am=AVRX1000")) {
|
||||||
QString address = service.hostAddress().toString();
|
|
||||||
qCDebug(dcDenon) << "service discovered" << name << "ID:" << id;
|
QString id = service.name().split("@").first();
|
||||||
if (discoveredIds.contains(id))
|
QString name = service.name().split("@").last();
|
||||||
break;
|
QString address = service.hostAddress().toString();
|
||||||
discoveredIds.append(id);
|
qCDebug(dcDenon) << "service discovered" << name << "ID:" << id;
|
||||||
DeviceDescriptor deviceDescriptor(AVRX1000DeviceClassId, name, address);
|
if (discoveredIds.contains(id))
|
||||||
ParamList params;
|
|
||||||
params.append(Param(AVRX1000DeviceIpParamTypeId, address));
|
|
||||||
params.append(Param(AVRX1000DeviceIdParamTypeId, id));
|
|
||||||
deviceDescriptor.setParams(params);
|
|
||||||
foreach (Device *existingDevice, myDevices()) {
|
|
||||||
if (existingDevice->paramValue(AVRX1000DeviceIdParamTypeId).toString() == id) {
|
|
||||||
deviceDescriptor.setDeviceId(existingDevice->id());
|
|
||||||
break;
|
break;
|
||||||
|
discoveredIds.append(id);
|
||||||
|
DeviceDescriptor deviceDescriptor(AVRX1000DeviceClassId, name, address);
|
||||||
|
ParamList params;
|
||||||
|
params.append(Param(AVRX1000DeviceIpParamTypeId, address));
|
||||||
|
params.append(Param(AVRX1000DeviceIdParamTypeId, id));
|
||||||
|
deviceDescriptor.setParams(params);
|
||||||
|
foreach (Device *existingDevice, myDevices()) {
|
||||||
|
if (existingDevice->paramValue(AVRX1000DeviceIdParamTypeId).toString() == id) {
|
||||||
|
deviceDescriptor.setDeviceId(existingDevice->id());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
info->addDeviceDescriptor(deviceDescriptor);
|
||||||
}
|
}
|
||||||
deviceDescriptors.append(deviceDescriptor);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
emit devicesDiscovered(AVRX1000DeviceClassId, deviceDescriptors);
|
info->finish(Device::DeviceErrorNoError);
|
||||||
return Device::DeviceErrorAsync;
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceClassId == heosDeviceClassId) {
|
if (info->deviceClassId() == heosDeviceClassId) {
|
||||||
/*
|
/*
|
||||||
* The HEOS products can be discovered using the UPnP SSDP protocol. Through discovery,
|
* The HEOS products can be discovered using the UPnP SSDP protocol. Through discovery,
|
||||||
* the IP address of the HEOS products can be retrieved. Once the IP address is retrieved,
|
* the IP address of the HEOS products can be retrieved. Once the IP address is retrieved,
|
||||||
|
|
@ -110,18 +117,49 @@ Device::DeviceError DevicePluginDenon::discoverDevices(const DeviceClassId &devi
|
||||||
* Search target name (ST) in M-SEARCH discovery request is 'urn:schemas-denon-com:device:ACT-Denon:1'.
|
* Search target name (ST) in M-SEARCH discovery request is 'urn:schemas-denon-com:device:ACT-Denon:1'.
|
||||||
*/
|
*/
|
||||||
UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices();
|
UpnpDiscoveryReply *reply = hardwareManager()->upnpDiscovery()->discoverDevices();
|
||||||
connect(reply, &UpnpDiscoveryReply::finished, this, &DevicePluginDenon::onUpnpDiscoveryFinished);
|
connect(reply, &UpnpDiscoveryReply::finished, info, [this, reply, info](){
|
||||||
return Device::DeviceErrorAsync;
|
reply->deleteLater();
|
||||||
|
|
||||||
|
if (reply->error() != UpnpDiscoveryReply::UpnpDiscoveryReplyErrorNoError) {
|
||||||
|
qCWarning(dcDenon()) << "Upnp discovery error" << reply->error();
|
||||||
|
info->finish(Device::DeviceErrorHardwareFailure, QT_TR_NOOP("UPnP discovery failed."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const UpnpDeviceDescriptor &upnpDevice, reply->deviceDescriptors()) {
|
||||||
|
qCDebug(dcDenon) << "UPnP device found:" << upnpDevice.modelDescription() << upnpDevice.friendlyName() << upnpDevice.hostAddress().toString() << upnpDevice.modelName() << upnpDevice.manufacturer() << upnpDevice.serialNumber();
|
||||||
|
|
||||||
|
if (upnpDevice.modelName().contains("HEOS")) {
|
||||||
|
QString serialNumber = upnpDevice.serialNumber();
|
||||||
|
if (serialNumber != "0000001") {
|
||||||
|
// child devices have serial number 0000001
|
||||||
|
qCDebug(dcDenon) << "UPnP device found:" << upnpDevice.modelDescription() << upnpDevice.friendlyName() << upnpDevice.hostAddress().toString() << upnpDevice.modelName() << upnpDevice.manufacturer() << upnpDevice.serialNumber();
|
||||||
|
DeviceDescriptor descriptor(heosDeviceClassId, upnpDevice.modelName(), serialNumber);
|
||||||
|
ParamList params;
|
||||||
|
foreach (Device *existingDevice, myDevices()) {
|
||||||
|
if (existingDevice->paramValue(heosDeviceSerialNumberParamTypeId).toString().contains(serialNumber, Qt::CaseSensitivity::CaseInsensitive)) {
|
||||||
|
descriptor.setDeviceId(existingDevice->id());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params.append(Param(heosDeviceModelNameParamTypeId, upnpDevice.modelName()));
|
||||||
|
params.append(Param(heosDeviceIpParamTypeId, upnpDevice.hostAddress().toString()));
|
||||||
|
params.append(Param(heosDeviceSerialNumberParamTypeId, serialNumber));
|
||||||
|
descriptor.setParams(params);
|
||||||
|
info->addDeviceDescriptor(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return Device::DeviceErrorDeviceClassNotFound;
|
info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::DeviceSetupStatus DevicePluginDenon::setupDevice(Device *device)
|
void DevicePluginDenon::setupDevice(DeviceSetupInfo *info)
|
||||||
{
|
{
|
||||||
if(!m_pluginTimer) {
|
Device *device = info->device();
|
||||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(60);
|
|
||||||
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginDenon::onPluginTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->deviceClassId() == AVRX1000DeviceClassId) {
|
if (device->deviceClassId() == AVRX1000DeviceClassId) {
|
||||||
qCDebug(dcDenon) << "Setup Denon device" << device->paramValue(AVRX1000DeviceIpParamTypeId).toString();
|
qCDebug(dcDenon) << "Setup Denon device" << device->paramValue(AVRX1000DeviceIpParamTypeId).toString();
|
||||||
|
|
@ -129,7 +167,8 @@ Device::DeviceSetupStatus DevicePluginDenon::setupDevice(Device *device)
|
||||||
QHostAddress address(device->paramValue(AVRX1000DeviceIpParamTypeId).toString());
|
QHostAddress address(device->paramValue(AVRX1000DeviceIpParamTypeId).toString());
|
||||||
if (address.isNull()) {
|
if (address.isNull()) {
|
||||||
qCWarning(dcDenon) << "Could not parse ip address" << device->paramValue(AVRX1000DeviceIpParamTypeId).toString();
|
qCWarning(dcDenon) << "Could not parse ip address" << device->paramValue(AVRX1000DeviceIpParamTypeId).toString();
|
||||||
return Device::DeviceSetupStatusFailure;
|
info->finish(Device::DeviceErrorInvalidParameter, QT_TR_NOOP("The given IP address is not valid."));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AvrConnection *denonConnection = new AvrConnection(address, 23, this);
|
AvrConnection *denonConnection = new AvrConnection(address, 23, this);
|
||||||
|
|
@ -141,10 +180,13 @@ Device::DeviceSetupStatus DevicePluginDenon::setupDevice(Device *device)
|
||||||
connect(denonConnection, &AvrConnection::surroundModeChanged, this, &DevicePluginDenon::onAvrSurroundModeChanged);
|
connect(denonConnection, &AvrConnection::surroundModeChanged, this, &DevicePluginDenon::onAvrSurroundModeChanged);
|
||||||
connect(denonConnection, &AvrConnection::muteChanged, this, &DevicePluginDenon::onAvrMuteChanged);
|
connect(denonConnection, &AvrConnection::muteChanged, this, &DevicePluginDenon::onAvrMuteChanged);
|
||||||
|
|
||||||
m_asyncAvrSetups.append(denonConnection);
|
|
||||||
denonConnection->connectDevice();
|
|
||||||
m_avrConnections.insert(device, denonConnection);
|
m_avrConnections.insert(device, denonConnection);
|
||||||
return Device::DeviceSetupStatusAsync;
|
m_asyncAvrSetups.insert(denonConnection, info);
|
||||||
|
// In case the setup is cancelled before we finish it...
|
||||||
|
connect(info, &QObject::destroyed, this, [this, info, denonConnection]() { m_asyncAvrSetups.remove(denonConnection); });
|
||||||
|
|
||||||
|
denonConnection->connectDevice();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->deviceClassId() == heosDeviceClassId) {
|
if (device->deviceClassId() == heosDeviceClassId) {
|
||||||
|
|
@ -161,16 +203,20 @@ Device::DeviceSetupStatus DevicePluginDenon::setupDevice(Device *device)
|
||||||
connect(heos, &Heos::volumeStatusReceived, this, &DevicePluginDenon::onHeosVolumeStatusReceived);
|
connect(heos, &Heos::volumeStatusReceived, this, &DevicePluginDenon::onHeosVolumeStatusReceived);
|
||||||
connect(heos, &Heos::nowPlayingMediaStatusReceived, this, &DevicePluginDenon::onHeosNowPlayingMediaStatusReceived);
|
connect(heos, &Heos::nowPlayingMediaStatusReceived, this, &DevicePluginDenon::onHeosNowPlayingMediaStatusReceived);
|
||||||
|
|
||||||
m_asyncHeosSetups.append(heos);
|
|
||||||
heos->connectHeos();
|
|
||||||
m_heos.insert(device, heos);
|
m_heos.insert(device, heos);
|
||||||
return Device::DeviceSetupStatusAsync;
|
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();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->deviceClassId() == heosPlayerDeviceClassId) {
|
if (device->deviceClassId() == heosPlayerDeviceClassId) {
|
||||||
return Device::DeviceSetupStatusSuccess;
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return Device::DeviceSetupStatusFailure;
|
info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginDenon::deviceRemoved(Device *device)
|
void DevicePluginDenon::deviceRemoved(Device *device)
|
||||||
|
|
@ -198,8 +244,11 @@ void DevicePluginDenon::deviceRemoved(Device *device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::DeviceError DevicePluginDenon::executeAction(Device *device, const Action &action)
|
void DevicePluginDenon::executeAction(DeviceActionInfo *info)
|
||||||
{
|
{
|
||||||
|
Device *device = info->device();
|
||||||
|
Action action = info->action();
|
||||||
|
|
||||||
qCDebug(dcDenon) << "Execute action" << device->id() << action.id() << action.params();
|
qCDebug(dcDenon) << "Execute action" << device->id() << action.id() << action.params();
|
||||||
if (device->deviceClassId() == AVRX1000DeviceClassId) {
|
if (device->deviceClassId() == AVRX1000DeviceClassId) {
|
||||||
AvrConnection *avrConnection = m_avrConnections.value(device);
|
AvrConnection *avrConnection = m_avrConnections.value(device);
|
||||||
|
|
@ -208,38 +257,38 @@ Device::DeviceError DevicePluginDenon::executeAction(Device *device, const Actio
|
||||||
|
|
||||||
bool power = action.param(AVRX1000PowerActionPowerParamTypeId).value().toBool();
|
bool power = action.param(AVRX1000PowerActionPowerParamTypeId).value().toBool();
|
||||||
avrConnection->setPower(power);
|
avrConnection->setPower(power);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
|
|
||||||
} else if (action.actionTypeId() == AVRX1000VolumeActionTypeId) {
|
} else if (action.actionTypeId() == AVRX1000VolumeActionTypeId) {
|
||||||
|
|
||||||
int vol = action.param(AVRX1000VolumeActionVolumeParamTypeId).value().toInt();
|
int vol = action.param(AVRX1000VolumeActionVolumeParamTypeId).value().toInt();
|
||||||
avrConnection->setVolume(vol);
|
avrConnection->setVolume(vol);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
|
|
||||||
} else if (action.actionTypeId() == AVRX1000ChannelActionTypeId) {
|
} else if (action.actionTypeId() == AVRX1000ChannelActionTypeId) {
|
||||||
|
|
||||||
qCDebug(dcDenon) << "Execute update action" << action.id();
|
qCDebug(dcDenon) << "Execute update action" << action.id();
|
||||||
QByteArray channel = action.param(AVRX1000ChannelActionChannelParamTypeId).value().toByteArray();
|
QByteArray channel = action.param(AVRX1000ChannelActionChannelParamTypeId).value().toByteArray();
|
||||||
avrConnection->setChannel(channel);
|
avrConnection->setChannel(channel);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
|
|
||||||
} else if (action.actionTypeId() == AVRX1000IncreaseVolumeActionTypeId) {
|
} else if (action.actionTypeId() == AVRX1000IncreaseVolumeActionTypeId) {
|
||||||
|
|
||||||
avrConnection->increaseVolume();
|
avrConnection->increaseVolume();
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
|
|
||||||
} else if (action.actionTypeId() == AVRX1000DecreaseVolumeActionTypeId) {
|
} else if (action.actionTypeId() == AVRX1000DecreaseVolumeActionTypeId) {
|
||||||
|
|
||||||
avrConnection->decreaseVolume();
|
avrConnection->decreaseVolume();
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
|
|
||||||
} else if (action.actionTypeId() == AVRX1000SurroundModeActionTypeId) {
|
} else if (action.actionTypeId() == AVRX1000SurroundModeActionTypeId) {
|
||||||
|
|
||||||
QByteArray surroundMode = action.param(AVRX1000SurroundModeActionSurroundModeParamTypeId).value().toByteArray();
|
QByteArray surroundMode = action.param(AVRX1000SurroundModeActionSurroundModeParamTypeId).value().toByteArray();
|
||||||
avrConnection->setSurroundMode(surroundMode);
|
avrConnection->setSurroundMode(surroundMode);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
return Device::DeviceErrorActionTypeNotFound;
|
return info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->deviceClassId() == heosPlayerDeviceClassId) {
|
if (device->deviceClassId() == heosPlayerDeviceClassId) {
|
||||||
|
|
@ -251,13 +300,13 @@ Device::DeviceError DevicePluginDenon::executeAction(Device *device, const Actio
|
||||||
if (action.actionTypeId() == heosPlayerVolumeActionTypeId) {
|
if (action.actionTypeId() == heosPlayerVolumeActionTypeId) {
|
||||||
int volume = action.param(heosPlayerVolumeActionVolumeParamTypeId).value().toInt();
|
int volume = action.param(heosPlayerVolumeActionVolumeParamTypeId).value().toInt();
|
||||||
heos->setVolume(playerId, volume);
|
heos->setVolume(playerId, volume);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == heosPlayerMuteActionTypeId) {
|
if (action.actionTypeId() == heosPlayerMuteActionTypeId) {
|
||||||
bool mute = action.param(heosPlayerMuteActionMuteParamTypeId).value().toBool();
|
bool mute = action.param(heosPlayerMuteActionMuteParamTypeId).value().toBool();
|
||||||
heos->setMute(playerId, mute);
|
heos->setMute(playerId, mute);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == heosPlayerPlaybackStatusActionTypeId) {
|
if (action.actionTypeId() == heosPlayerPlaybackStatusActionTypeId) {
|
||||||
|
|
@ -269,54 +318,53 @@ Device::DeviceError DevicePluginDenon::executeAction(Device *device, const Actio
|
||||||
} else if (playbackStatus == "pausing") {
|
} else if (playbackStatus == "pausing") {
|
||||||
heos->setPlayerState(playerId, PLAYER_STATE_PAUSE);
|
heos->setPlayerState(playerId, PLAYER_STATE_PAUSE);
|
||||||
}
|
}
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == heosPlayerShuffleActionTypeId) {
|
if (action.actionTypeId() == heosPlayerShuffleActionTypeId) {
|
||||||
bool shuffle = action.param(heosPlayerShuffleActionShuffleParamTypeId).value().toBool();
|
bool shuffle = action.param(heosPlayerShuffleActionShuffleParamTypeId).value().toBool();
|
||||||
REPEAT_MODE repeatMode = REPEAT_MODE_OFF;
|
REPEAT_MODE repeatMode = REPEAT_MODE_OFF;
|
||||||
if ( device->stateValue(heosPlayerRepeatStateTypeId) == "One") {
|
if (device->stateValue(heosPlayerRepeatStateTypeId) == "One") {
|
||||||
repeatMode = REPEAT_MODE_ONE;
|
repeatMode = REPEAT_MODE_ONE;
|
||||||
} else if ( device->stateValue(heosPlayerRepeatStateTypeId) == "All") {
|
} else if (device->stateValue(heosPlayerRepeatStateTypeId) == "All") {
|
||||||
repeatMode = REPEAT_MODE_ALL;
|
repeatMode = REPEAT_MODE_ALL;
|
||||||
}
|
}
|
||||||
heos->setPlayMode(playerId, repeatMode, shuffle);
|
heos->setPlayMode(playerId, repeatMode, shuffle);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == heosPlayerSkipBackActionTypeId) {
|
if (action.actionTypeId() == heosPlayerSkipBackActionTypeId) {
|
||||||
heos->playPrevious(playerId);
|
heos->playPrevious(playerId);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == heosPlayerStopActionTypeId) {
|
if (action.actionTypeId() == heosPlayerStopActionTypeId) {
|
||||||
heos->setPlayerState(playerId, PLAYER_STATE_STOP);
|
heos->setPlayerState(playerId, PLAYER_STATE_STOP);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == heosPlayerPlayActionTypeId) {
|
if (action.actionTypeId() == heosPlayerPlayActionTypeId) {
|
||||||
heos->setPlayerState(playerId, PLAYER_STATE_PLAY);
|
heos->setPlayerState(playerId, PLAYER_STATE_PLAY);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == heosPlayerPauseActionTypeId) {
|
if (action.actionTypeId() == heosPlayerPauseActionTypeId) {
|
||||||
heos->setPlayerState(playerId, PLAYER_STATE_PAUSE);
|
heos->setPlayerState(playerId, PLAYER_STATE_PAUSE);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.actionTypeId() == heosPlayerSkipNextActionTypeId) {
|
if (action.actionTypeId() == heosPlayerSkipNextActionTypeId) {
|
||||||
heos->playNext(playerId);
|
heos->playNext(playerId);
|
||||||
return Device::DeviceErrorNoError;
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
return Device::DeviceErrorActionTypeNotFound;
|
return info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||||
}
|
}
|
||||||
return Device::DeviceErrorDeviceClassNotFound;
|
return info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginDenon::postSetupDevice(Device *device)
|
void DevicePluginDenon::postSetupDevice(Device *device)
|
||||||
{
|
{
|
||||||
if (device->deviceClassId() == heosDeviceClassId) {
|
if (device->deviceClassId() == heosDeviceClassId) {
|
||||||
|
|
||||||
Heos *heos = m_heos.value(device);
|
Heos *heos = m_heos.value(device);
|
||||||
heos->getPlayers();
|
heos->getPlayers();
|
||||||
}
|
}
|
||||||
|
|
@ -332,6 +380,11 @@ void DevicePluginDenon::postSetupDevice(Device *device)
|
||||||
heos->getMute(playerId);
|
heos->getMute(playerId);
|
||||||
heos->getNowPlayingMedia(playerId);
|
heos->getNowPlayingMedia(playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_pluginTimer) {
|
||||||
|
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(60);
|
||||||
|
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginDenon::onPluginTimer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -381,9 +434,8 @@ void DevicePluginDenon::onAvrConnectionChanged(bool status)
|
||||||
if (status) {
|
if (status) {
|
||||||
// and from the first setup
|
// and from the first setup
|
||||||
if (m_asyncAvrSetups.contains(denonConnection)) {
|
if (m_asyncAvrSetups.contains(denonConnection)) {
|
||||||
m_asyncAvrSetups.removeAll(denonConnection);
|
DeviceSetupInfo *info = m_asyncAvrSetups.take(denonConnection);
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
emit deviceSetupFinished(device, Device::DeviceSetupStatusSuccess);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
device->setStateValue(AVRX1000ConnectedStateTypeId, denonConnection->connected());
|
device->setStateValue(AVRX1000ConnectedStateTypeId, denonConnection->connected());
|
||||||
|
|
@ -462,9 +514,9 @@ void DevicePluginDenon::onAvrSocketError()
|
||||||
|
|
||||||
// Check if setup running for this device
|
// Check if setup running for this device
|
||||||
if (m_asyncAvrSetups.contains(denonConnection)) {
|
if (m_asyncAvrSetups.contains(denonConnection)) {
|
||||||
m_asyncAvrSetups.removeAll(denonConnection);
|
DeviceSetupInfo *info = m_asyncAvrSetups.take(denonConnection);
|
||||||
qCWarning(dcDenon()) << "Could not add device. The setup failed.";
|
qCWarning(dcDenon()) << "Could not add device. The setup failed.";
|
||||||
emit deviceSetupFinished(device, Device::DeviceSetupStatusFailure);
|
info->finish(Device::DeviceErrorHardwareFailure);
|
||||||
// Delete the connection, the device will not be added and
|
// Delete the connection, the device will not be added and
|
||||||
// the connection will be created in the next setup
|
// the connection will be created in the next setup
|
||||||
denonConnection->deleteLater();
|
denonConnection->deleteLater();
|
||||||
|
|
@ -473,50 +525,6 @@ void DevicePluginDenon::onAvrSocketError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginDenon::onUpnpDiscoveryFinished()
|
|
||||||
{
|
|
||||||
qCDebug(dcDenon()) << "Upnp discovery finished";
|
|
||||||
UpnpDiscoveryReply *reply = static_cast<UpnpDiscoveryReply *>(sender());
|
|
||||||
if (reply->error() != UpnpDiscoveryReply::UpnpDiscoveryReplyErrorNoError) {
|
|
||||||
qCWarning(dcDenon()) << "Upnp discovery error" << reply->error();
|
|
||||||
}
|
|
||||||
reply->deleteLater();
|
|
||||||
|
|
||||||
if (reply->deviceDescriptors().isEmpty()) {
|
|
||||||
qCDebug(dcDenon) << "No UPnP device found.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<DeviceDescriptor> heosDescriptors;
|
|
||||||
foreach (const UpnpDeviceDescriptor &upnpDevice, reply->deviceDescriptors()) {
|
|
||||||
|
|
||||||
if (upnpDevice.modelName().contains("HEOS")) {
|
|
||||||
QString serialNumber = upnpDevice.serialNumber();
|
|
||||||
if (serialNumber != "0000001") {
|
|
||||||
// child devices have serial number 0000001
|
|
||||||
qCDebug(dcDenon) << "UPnP device found:" << upnpDevice.modelDescription() << upnpDevice.friendlyName() << upnpDevice.hostAddress().toString() << upnpDevice.modelName() << upnpDevice.manufacturer() << upnpDevice.serialNumber();
|
|
||||||
DeviceDescriptor descriptor(heosDeviceClassId, upnpDevice.modelName(), serialNumber);
|
|
||||||
ParamList params;
|
|
||||||
foreach (Device *existingDevice, myDevices()) {
|
|
||||||
if (existingDevice->paramValue(heosDeviceSerialNumberParamTypeId).toString().contains(serialNumber, Qt::CaseSensitivity::CaseInsensitive)) {
|
|
||||||
descriptor.setDeviceId(existingDevice->id());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params.append(Param(heosDeviceModelNameParamTypeId, upnpDevice.modelName()));
|
|
||||||
params.append(Param(heosDeviceIpParamTypeId, upnpDevice.hostAddress().toString()));
|
|
||||||
params.append(Param(heosDeviceSerialNumberParamTypeId, serialNumber));
|
|
||||||
descriptor.setParams(params);
|
|
||||||
heosDescriptors.append(descriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qCDebug(dcDenon) << "UPnP device found:" << upnpDevice.modelDescription() << upnpDevice.friendlyName() << upnpDevice.hostAddress().toString() << upnpDevice.modelName() << upnpDevice.manufacturer() << upnpDevice.serialNumber();
|
|
||||||
}
|
|
||||||
if (!heosDescriptors.isEmpty()) {
|
|
||||||
emit devicesDiscovered(heosDeviceClassId, heosDescriptors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginDenon::onHeosConnectionChanged(bool status)
|
void DevicePluginDenon::onHeosConnectionChanged(bool status)
|
||||||
{
|
{
|
||||||
Heos *heos = static_cast<Heos *>(sender());
|
Heos *heos = static_cast<Heos *>(sender());
|
||||||
|
|
@ -530,9 +538,9 @@ void DevicePluginDenon::onHeosConnectionChanged(bool status)
|
||||||
if (status) {
|
if (status) {
|
||||||
// and from the first setup
|
// and from the first setup
|
||||||
if (m_asyncHeosSetups.contains(heos)) {
|
if (m_asyncHeosSetups.contains(heos)) {
|
||||||
m_asyncHeosSetups.removeAll(heos);
|
DeviceSetupInfo *info = m_asyncHeosSetups.take(heos);
|
||||||
heos->getPlayers();
|
heos->getPlayers();
|
||||||
emit deviceSetupFinished(device, Device::DeviceSetupStatusSuccess);
|
info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
device->setStateValue(heosConnectedStateTypeId, status);
|
device->setStateValue(heosConnectedStateTypeId, status);
|
||||||
|
|
@ -568,7 +576,7 @@ void DevicePluginDenon::onHeosPlayerDiscovered(HeosPlayer *heosPlayer) {
|
||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
qCDebug(dcDenon) << "Found new heos player" << heosPlayer->name();
|
qCDebug(dcDenon) << "Found new heos player" << heosPlayer->name();
|
||||||
heosPlayerDescriptors.append(descriptor);
|
heosPlayerDescriptors.append(descriptor);
|
||||||
autoDevicesAppeared(heosPlayerDeviceClassId, heosPlayerDescriptors);
|
autoDevicesAppeared(heosPlayerDescriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginDenon::onHeosPlayStateReceived(int playerId, PLAYER_STATE state)
|
void DevicePluginDenon::onHeosPlayStateReceived(int playerId, PLAYER_STATE state)
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,10 @@ class DevicePluginDenon : public DevicePlugin
|
||||||
public:
|
public:
|
||||||
explicit DevicePluginDenon();
|
explicit DevicePluginDenon();
|
||||||
|
|
||||||
Device::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
void discoverDevices(DeviceDiscoveryInfo *info) override;
|
||||||
Device::DeviceSetupStatus setupDevice(Device *device) override;
|
void setupDevice(DeviceSetupInfo *info) override;
|
||||||
void postSetupDevice(Device * device) override;
|
void postSetupDevice(Device *device) override;
|
||||||
Device::DeviceError executeAction(Device *device, const Action &action) override;
|
void executeAction(DeviceActionInfo *info) override;
|
||||||
void deviceRemoved(Device *device) override;
|
void deviceRemoved(Device *device) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -62,8 +62,8 @@ private:
|
||||||
QHash<Device *, AvrConnection*> m_avrConnections;
|
QHash<Device *, AvrConnection*> m_avrConnections;
|
||||||
QHash<Device *, Heos*> m_heos;
|
QHash<Device *, Heos*> m_heos;
|
||||||
|
|
||||||
QList<AvrConnection *> m_asyncAvrSetups;
|
QHash<AvrConnection*, DeviceSetupInfo*> m_asyncAvrSetups;
|
||||||
QList<Heos *> m_asyncHeosSetups;
|
QHash<Heos*, DeviceSetupInfo*> m_asyncHeosSetups;
|
||||||
|
|
||||||
QHash<int, Device *> m_playerIds;
|
QHash<int, Device *> m_playerIds;
|
||||||
QHash<int, Device *> m_discoveredPlayerIds;
|
QHash<int, Device *> m_discoveredPlayerIds;
|
||||||
|
|
@ -72,7 +72,6 @@ private:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onPluginTimer();
|
void onPluginTimer();
|
||||||
void onUpnpDiscoveryFinished();
|
|
||||||
|
|
||||||
void onHeosConnectionChanged(bool status);
|
void onHeosConnectionChanged(bool status);
|
||||||
void onHeosPlayerDiscovered(HeosPlayer *heosPlayer);
|
void onHeosPlayerDiscovered(HeosPlayer *heosPlayer);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue