added sonos plug-in
This commit is contained in:
parent
97f507033e
commit
9b81617c09
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "sonos/sonos/noson"]
|
||||
path = sonos/sonos/noson
|
||||
url = https://github.com/janbar/noson.git
|
||||
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
</TS>
|
||||
@ -40,6 +40,7 @@ PLUGIN_DIRS = \
|
||||
serialportcommander \
|
||||
simulation \
|
||||
snapd \
|
||||
sonos \
|
||||
tasmota \
|
||||
tcpcommander \
|
||||
texasinstruments \
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
</TS>
|
||||
279
sonos/devicepluginsonos.cpp
Normal file
279
sonos/devicepluginsonos.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* 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 "devicepluginsonos.h"
|
||||
#include "devices/device.h"
|
||||
#include "plugininfo.h"
|
||||
|
||||
|
||||
#include <noson/sonostypes.h>
|
||||
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
|
||||
DevicePluginSonos::DevicePluginSonos()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DevicePluginSonos::~DevicePluginSonos()
|
||||
{
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
|
||||
}
|
||||
|
||||
void DevicePluginSonos::init()
|
||||
{
|
||||
qDebug(dcSonos) << "Nymea sonos plug-in using libnoson Copyright (C) 2018 Jean-Luc Barriere";
|
||||
m_sonosSystem = new SONOS::System(nullptr, nullptr);
|
||||
}
|
||||
|
||||
Device::DeviceSetupStatus DevicePluginSonos::setupDevice(Device *device)
|
||||
{
|
||||
if (device->deviceClassId() == sonosDeviceClassId) {
|
||||
if (!m_sonosSystem->Discover()) {
|
||||
return Device::DeviceSetupStatusFailure;
|
||||
}
|
||||
QString zoneName = device->paramValue(sonosDeviceZoneNameParamTypeId).toString();
|
||||
|
||||
SONOS::ZoneList zones = m_sonosSystem->GetZoneList();
|
||||
|
||||
for(SONOS::ZoneList::const_iterator iz = zones.begin(); iz != zones.end(); ++iz) {
|
||||
|
||||
if (iz->second->GetZoneName().c_str() == zoneName) {
|
||||
if (!m_sonosSystem->ConnectZone(iz->second, nullptr, nullptr)) {
|
||||
qCDebug(dcSonos()) << "Failed connecting to zone" << zoneName;
|
||||
return Device::DeviceSetupStatusFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
device->setStateValue(sonosConnectedStateTypeId, true);
|
||||
}
|
||||
return Device::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
void DevicePluginSonos::postSetupDevice(Device *device)
|
||||
{
|
||||
if (device->deviceClassId() == sonosDeviceClassId) {
|
||||
SONOS::ZonePtr pl = m_sonosSystem->GetConnectedZone();
|
||||
uint8_t volume;
|
||||
uint8_t mute;
|
||||
for (SONOS::Zone::iterator ip = pl->begin(); ip != pl->end(); ++ip) {
|
||||
if (!m_sonosSystem->GetPlayer()->GetVolume((*ip)->GetUUID(), &volume)) {
|
||||
qWarning(dcSonos()) << "Could not get volume for" << (*ip)->GetHost().c_str();
|
||||
} else {
|
||||
device->setStateValue(sonosVolumeStateTypeId, volume);
|
||||
}
|
||||
|
||||
if (!m_sonosSystem->GetPlayer()->GetMute((*ip)->GetUUID(), &mute)) {
|
||||
qWarning(dcSonos()) << "Could not get mute state for" << (*ip)->GetHost().c_str();
|
||||
} else {
|
||||
device->setStateValue(sonosMuteStateTypeId, mute);
|
||||
}
|
||||
}
|
||||
|
||||
while(m_sonosSystem->GetPlayer()->TransportPropertyEmpty());
|
||||
|
||||
SONOS::AVTProperty properties = m_sonosSystem->GetPlayer()->GetTransportProperty();
|
||||
|
||||
qDebug(dcSonos()) << "Transport Status" << properties.TransportStatus.c_str();
|
||||
qDebug(dcSonos()) << "Transport State" << properties.TransportState.c_str();
|
||||
if (properties.TransportState.c_str() == "PLAYING") {
|
||||
device->setStateValue(sonosPlaybackStatusStateTypeId, "Playing");
|
||||
} else if (properties.TransportState.c_str() == "PAUSED") {
|
||||
device->setStateValue(sonosPlaybackStatusStateTypeId, "Paused");
|
||||
} else if (properties.TransportState.c_str() == "STOPPED") {
|
||||
device->setStateValue(sonosPlaybackStatusStateTypeId, "Stopped");
|
||||
}
|
||||
|
||||
qDebug(dcSonos()) << "AVTransport URI" << properties.AVTransportURI.c_str();
|
||||
qDebug(dcSonos()) << "AVTransportTitle" << properties.AVTransportURIMetaData->GetValue("dc:title").c_str();
|
||||
qDebug(dcSonos()) << "Current Track" << properties.CurrentTrack;
|
||||
qDebug(dcSonos()) << "Current Track Duration" << properties.CurrentTrackDuration.c_str();
|
||||
qDebug(dcSonos()) << "Current Track URI" << properties.CurrentTrackURI.c_str();
|
||||
//device->setStateValue(sonosArtworkStateTypeId, properties.CurrentTrackURI.c_str());
|
||||
qDebug(dcSonos()) << "Current Track Title" << properties.CurrentTrackMetaData->GetValue("dc:title").c_str();
|
||||
device->setStateValue(sonosTitleStateTypeId, properties.CurrentTrackMetaData->GetValue("dc:title").c_str());
|
||||
qDebug(dcSonos()) << "Current Track Album" << properties.CurrentTrackMetaData->GetValue("upnp:album").c_str();
|
||||
qDebug(dcSonos()) << "Current Track Artist" << properties.CurrentTrackMetaData->GetValue("dc:creator").c_str();
|
||||
device->setStateValue(sonosArtistStateTypeId, properties.CurrentTrackMetaData->GetValue("dc:creator").c_str());
|
||||
qDebug(dcSonos()) << "Current Crossfade Mode" << properties.CurrentCrossfadeMode.c_str();
|
||||
qDebug(dcSonos()) << "Current Play Mode" << properties.CurrentPlayMode.c_str();
|
||||
qDebug(dcSonos()) << "Current TransportActions" << properties.CurrentTransportActions.c_str();
|
||||
qDebug(dcSonos()) << "Number Of Tracks" << properties.NumberOfTracks;
|
||||
qDebug(dcSonos()) << "Alarm Running" << properties.r_AlarmRunning.c_str();
|
||||
qDebug(dcSonos()) << "Alarm ID Running" << properties.r_AlarmIDRunning.c_str();
|
||||
qDebug(dcSonos()) << "Alarm Logged Start Time" << properties.r_AlarmLoggedStartTime.c_str();
|
||||
qDebug(dcSonos()) << "AlarmState" << properties.r_AlarmState.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginSonos::deviceRemoved(Device *device)
|
||||
{
|
||||
qCDebug(dcSonos) << "Delete " << device->name();
|
||||
if (myDevices().empty()) {
|
||||
delete m_sonosSystem;
|
||||
}
|
||||
}
|
||||
|
||||
Device::DeviceError DevicePluginSonos::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
Q_UNUSED(deviceClassId)
|
||||
|
||||
|
||||
if (!m_sonosSystem->Discover()) {
|
||||
return Device::DeviceErrorDeviceNotFound;
|
||||
}
|
||||
|
||||
QList<DeviceDescriptor> descriptors;
|
||||
SONOS::ZoneList zones = m_sonosSystem->GetZoneList();
|
||||
|
||||
for (SONOS::ZoneList::const_iterator it = zones.begin(); it != zones.end(); ++it) {
|
||||
qDebug(dcSonos()) << "Found zone" << it->second->GetZoneName().c_str();
|
||||
DeviceDescriptor descriptor(sonosDeviceClassId, it->second->GetZoneName().c_str());
|
||||
ParamList params;
|
||||
params << Param(sonosDeviceZoneNameParamTypeId, it->second->GetZoneName().c_str());
|
||||
descriptor.setParams(params);
|
||||
descriptors << descriptor;
|
||||
}
|
||||
emit devicesDiscovered(sonosDeviceClassId, descriptors);
|
||||
return Device::DeviceErrorAsync;
|
||||
}
|
||||
|
||||
Device::DeviceError DevicePluginSonos::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
Q_UNUSED(action)
|
||||
if (device->deviceClassId() == sonosDeviceClassId) {
|
||||
|
||||
if (action.actionTypeId() == sonosPlayActionTypeId) {
|
||||
if (!m_sonosSystem->GetPlayer()->Play()) {
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == sonosShuffleActionTypeId) {
|
||||
SONOS::PlayMode_t mode = SONOS::PlayMode_t::PlayMode_NORMAL;;
|
||||
if (action.param(sonosShuffleActionShuffleParamTypeId).value().toBool()) {
|
||||
mode = SONOS::PlayMode_t::PlayMode_NORMAL;
|
||||
}
|
||||
if (!m_sonosSystem->GetPlayer()->SetPlayMode(mode)) {
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == sonosRepeatActionTypeId) {
|
||||
SONOS::PlayMode_t mode;
|
||||
if (action.param(sonosRepeatActionRepeatParamTypeId).value().toString() == "None") {
|
||||
mode = SONOS::PlayMode_t::PlayMode_NORMAL;
|
||||
} else if (action.param(sonosShuffleActionShuffleParamTypeId).value().toString() == "One") {
|
||||
mode = SONOS::PlayMode_t::PlayMode_REPEAT_ONE;
|
||||
} else if (action.param(sonosShuffleActionShuffleParamTypeId).value().toString() == "All") {
|
||||
mode = SONOS::PlayMode_t::PlayMode_REPEAT_ALL;
|
||||
} else {
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
|
||||
if (!m_sonosSystem->GetPlayer()->SetPlayMode(mode)) {
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == sonosPauseActionTypeId) {
|
||||
if (!m_sonosSystem->GetPlayer()->Pause()) {
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == sonosStopActionTypeId) {
|
||||
if (!m_sonosSystem->GetPlayer()->Stop()) {
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == sonosMuteActionTypeId) {
|
||||
bool mute = action.param(sonosMuteActionMuteParamTypeId).value().toBool();
|
||||
|
||||
SONOS::ZonePtr pl = m_sonosSystem->GetConnectedZone();
|
||||
for (SONOS::Zone::iterator ip = pl->begin(); ip != pl->end(); ++ip) {
|
||||
if (!m_sonosSystem->GetPlayer()->SetMute((*ip)->GetUUID(), mute)) {
|
||||
qWarning(dcSonos()) << "Could not set mute state for" << (*ip)->GetHost().c_str();
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == sonosSkipNextActionTypeId) {
|
||||
if (!m_sonosSystem->GetPlayer()->Next()) {
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == sonosSkipBackActionTypeId) {
|
||||
if(!m_sonosSystem->GetPlayer()->Previous()) {
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == sonosSkipBackActionTypeId) {
|
||||
int volume = action.param(sonosVolumeActionVolumeParamTypeId).value().toInt();
|
||||
|
||||
SONOS::ZonePtr pl = m_sonosSystem->GetConnectedZone();
|
||||
for (SONOS::Zone::iterator ip = pl->begin(); ip != pl->end(); ++ip) {
|
||||
if (!m_sonosSystem->GetPlayer()->SetVolume((*ip)->GetUUID(), volume)) {
|
||||
qWarning(dcSonos()) << "Could not set volume for" << (*ip)->GetHost().c_str();
|
||||
return Device::DeviceErrorHardwareFailure;
|
||||
}
|
||||
}
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
return Device::DeviceErrorActionTypeNotFound;
|
||||
}
|
||||
return Device::DeviceErrorDeviceClassNotFound;
|
||||
}
|
||||
|
||||
void DevicePluginSonos::onPluginTimer()
|
||||
{
|
||||
}
|
||||
|
||||
void DevicePluginSonos::handleEventCB(void* handle)
|
||||
{
|
||||
Q_UNUSED(handle);
|
||||
/*unsigned char mask = m_sonosSystem->LastEvents();
|
||||
if ((mask & SONOS::SVCEvent_TransportChanged))
|
||||
qDebug(dcSonos()) << "Event Transport changed";
|
||||
if ((mask & SONOS::SVCEvent_AlarmClockChanged))
|
||||
qDebug(dcSonos()) << "Alarm clock changed";
|
||||
if ((mask & SONOS::SVCEvent_ZGTopologyChanged))
|
||||
qDebug(dcSonos()) << "ZG Topology changed";
|
||||
if ((mask & SONOS::SVCEvent_ContentDirectoryChanged))
|
||||
qDebug(dcSonos()) << "Content directory changed";
|
||||
if ((mask & SONOS::SVCEvent_RenderingControlChanged))
|
||||
qDebug(dcSonos()) << "Rendering control changed";*/
|
||||
}
|
||||
69
sonos/devicepluginsonos.h
Normal file
69
sonos/devicepluginsonos.h
Normal file
@ -0,0 +1,69 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2019 Bernhard Trinnes <bernhard.trinnes@nymea.io *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef DEVICEPLUGINSONOS_H
|
||||
#define DEVICEPLUGINSONOS_H
|
||||
|
||||
#include "devices/deviceplugin.h"
|
||||
#include "plugintimer.h"
|
||||
|
||||
#include <noson/sonossystem.h>
|
||||
|
||||
#include <QHash>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
class DevicePluginSonos : public DevicePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginsonos.json")
|
||||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
public:
|
||||
explicit DevicePluginSonos();
|
||||
~DevicePluginSonos() override;
|
||||
|
||||
void init() override;
|
||||
Device::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
void postSetupDevice(Device *device) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
Device::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||
Device::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
|
||||
private:
|
||||
SONOS::System *m_sonosSystem = nullptr;
|
||||
PluginTimer *m_pluginTimer;
|
||||
|
||||
static void handleEventCB(void *handle);
|
||||
|
||||
private slots:
|
||||
void onPluginTimer();
|
||||
/*void onConnectionChanged();
|
||||
void onStateChanged();
|
||||
void onActionExecuted(int actionId, bool success);
|
||||
void versionDataReceived(const QVariantMap &data);
|
||||
void onSetupFinished(const QVariantMap &data);
|
||||
|
||||
void onPlaybackStatusChanged(const QString &playbackStatus);*/
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINSONOS_H
|
||||
176
sonos/devicepluginsonos.json
Normal file
176
sonos/devicepluginsonos.json
Normal file
@ -0,0 +1,176 @@
|
||||
{
|
||||
"id": "cdb07719-c445-4fa5-9c7a-564ee02a4412",
|
||||
"name": "Sonos",
|
||||
"displayName": "Sonos",
|
||||
"vendors": [
|
||||
{
|
||||
"id": "30a60752-d06f-4ec9-a4e1-9810a5d22fa3",
|
||||
"name": "sonos",
|
||||
"displayName": "Sonos",
|
||||
"deviceClasses": [
|
||||
{
|
||||
"id": "22df416d-7732-44f1-b6b9-e41296211178",
|
||||
"name": "sonos",
|
||||
"displayName": "Sonos",
|
||||
"interfaces": ["extendedvolumecontroller", "mediametadataprovider", "shufflerepeat", "connectable"],
|
||||
"createMethods": ["discovery"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "defc44cd-2ffb-4af1-b348-d6a3474c7515",
|
||||
"name": "zoneName",
|
||||
"displayName": "Zone name",
|
||||
"type" : "QString"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "09dfbd40-c97c-4a20-9ecd-f80e389a4864",
|
||||
"name": "connected",
|
||||
"displayName": "connected",
|
||||
"displayNameEvent": "connected changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"id": "bc98cdb0-4d0e-48ca-afc7-922e49bb7813",
|
||||
"name": "mute",
|
||||
"displayName": "mute",
|
||||
"displayNameEvent": "mute changed",
|
||||
"displayNameAction": "Set mute",
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "9dfe5d78-4c3f-497c-bab1-bb9fdf7e93a9",
|
||||
"name": "volume",
|
||||
"displayName": "volume",
|
||||
"displayNameEvent": "volume changed",
|
||||
"displayNameAction": "Set volume",
|
||||
"unit": "Percentage",
|
||||
"type": "int",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"defaultValue": 50,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "2dd512b7-40c2-488e-8d4f-6519edaa6f74",
|
||||
"name": "playbackStatus",
|
||||
"displayName": "playback status",
|
||||
"type": "QString",
|
||||
"possibleValues": ["Playing", "Paused", "Stopped"],
|
||||
"defaultValue": "Stopped",
|
||||
"displayNameEvent": "playback status changed",
|
||||
"displayNameAction": "set playback status",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "f2209fec-cceb-46ad-8189-4caf42166e6b",
|
||||
"type": "QString",
|
||||
"name": "title",
|
||||
"displayName": "Title",
|
||||
"displayNameEvent": "Title changed",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "8cb920a3-3bf1-4231-92d4-8ac27e7b3d65",
|
||||
"type": "QString",
|
||||
"name": "artist",
|
||||
"displayName": "Artist",
|
||||
"displayNameEvent": "Artist changed",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "ce399eec-9f6a-4903-9916-0e90e38b255e",
|
||||
"type": "QString",
|
||||
"name": "collection",
|
||||
"displayName": "Collection",
|
||||
"displayNameEvent": "Collection changed",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "44304c82-c2f6-433b-b62b-815382617d0b",
|
||||
"type": "QString",
|
||||
"name": "artwork",
|
||||
"displayName": "Artwork",
|
||||
"displayNameEvent": "Artwork changed",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "5913aa2a-629d-4de5-bf44-a4a1f130c118",
|
||||
"type": "bool",
|
||||
"name": "shuffle",
|
||||
"displayName": "Shuffle",
|
||||
"displayNameEvent": "Shuffle changed",
|
||||
"displayNameAction": "Set shuffle",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "bc02c28e-3f5d-4de4-b9b5-c0b1576c6e7e",
|
||||
"type": "QString",
|
||||
"name": "repeat",
|
||||
"displayName": "Repeat",
|
||||
"displayNameEvent": "Repeat changed",
|
||||
"displayNameAction": "Set repeat",
|
||||
"possibleValues": ["None", "One", "All"],
|
||||
"defaultValue": "None",
|
||||
"writable": true
|
||||
}
|
||||
],
|
||||
"eventTypes": [
|
||||
{
|
||||
"id": "2535a1eb-7643-4874-98f6-b027fdff6311",
|
||||
"name": "onPlayerPlay",
|
||||
"displayName": "player play"
|
||||
},
|
||||
{
|
||||
"id": "99498b1c-e9c0-480a-9e91-662ee79ba976",
|
||||
"name": "onPlayerPause",
|
||||
"displayName": "player pause"
|
||||
},
|
||||
{
|
||||
"id": "a02ce255-3abb-435d-a92e-7f99c952ecb2",
|
||||
"name": "onPlayerStop",
|
||||
"displayName": "player stop"
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "a180807d-1265-4831-9d86-a421767418dd",
|
||||
"name": "skipBack",
|
||||
"displayName": "skip back"
|
||||
},
|
||||
{
|
||||
"id": "7e70b47b-7e79-4521-be34-04a3c427e5b1",
|
||||
"name": "fastRewind",
|
||||
"displayName": "rewind"
|
||||
},
|
||||
{
|
||||
"id": "ae3cbe03-ee3e-410e-abbd-efabc2402198",
|
||||
"name": "stop",
|
||||
"displayName": "stop"
|
||||
},
|
||||
{
|
||||
"id": "4d2ee668-a2e3-4795-8b96-0c800b703b46",
|
||||
"name": "play",
|
||||
"displayName": "play"
|
||||
},
|
||||
{
|
||||
"id": "3cf341cb-fe63-40bc-a450-9678d18e91e3",
|
||||
"name": "pause",
|
||||
"displayName": "pause"
|
||||
},
|
||||
{
|
||||
"id": "85d7126a-b123-4a28-aeb4-d84bcfb4d14f",
|
||||
"name": "skipNext",
|
||||
"displayName": "skipNext"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
1
sonos/noson
Submodule
1
sonos/noson
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 569f2b3087d2ba39bfe796bd6dd20b767fb68eb7
|
||||
2
unipi/.crossbuilder/cache.conf
Normal file
2
unipi/.crossbuilder/cache.conf
Normal file
@ -0,0 +1,2 @@
|
||||
TARGET_ARCH=armhf
|
||||
TARGET_UBUNTU=stretch
|
||||
Loading…
x
Reference in New Issue
Block a user