diff --git a/bose/integrationpluginbose.cpp b/bose/integrationpluginbose.cpp index 0662cf97..818075a0 100644 --- a/bose/integrationpluginbose.cpp +++ b/bose/integrationpluginbose.cpp @@ -49,6 +49,12 @@ IntegrationPluginBose::~IntegrationPluginBose() void IntegrationPluginBose::init() { m_serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_soundtouch._tcp"); + + updateConsumerKey(); + + connect(this, &IntegrationPlugin::configValueChanged, this, &IntegrationPluginBose::updateConsumerKey); + connect(apiKeyStorage(), &ApiKeyStorage::keyAdded, this, &IntegrationPluginBose::updateConsumerKey); + connect(apiKeyStorage(), &ApiKeyStorage::keyUpdated, this, &IntegrationPluginBose::updateConsumerKey); } void IntegrationPluginBose::setupThing(ThingSetupInfo *info) @@ -275,6 +281,28 @@ void IntegrationPluginBose::executeAction(ThingActionInfo *info) } m_pendingActions.insert(requestId, info); connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_pendingActions.remove(requestId);}); + } else if (action.actionTypeId() == soundtouchAlertActionTypeId) { + if (m_consumerKey.isEmpty()) { + return info->finish(Thing::ThingErrorHardwareFailure, tr("No consumer key available.")); + } + QUrl alertUrl; + QString alertSound = action.param(soundtouchAlertActionSoundParamTypeId).value().toString(); + if (alertSound == "Doorbell") { + alertUrl = configValue(bosePluginDoorbellSoundUrlParamTypeId).toString(); + } else if (alertSound == "Notification") { + alertUrl = configValue(bosePluginNotificationSoundUrlParamTypeId).toString(); + } + if (!alertUrl.isValid()) { + return info->finish(Thing::ThingErrorHardwareFailure, tr("Sound URL is not valid.")); + } + PlayInfoObject playInfo; + playInfo.url = alertUrl.toString(); + playInfo.appKey = m_consumerKey; + playInfo.volume = action.param(soundtouchAlertActionVolumeParamTypeId).value().toInt(); + playInfo.reason = action.param(soundtouchAlertActionMessageParamTypeId).value().toString(); + QUuid requestId = soundTouch->setSpeaker(playInfo); + m_pendingActions.insert(requestId, info); + connect(info, &ThingActionInfo::aborted, this, [requestId, this] {m_pendingActions.remove(requestId);}); } else { qCWarning(dcBose()) << "ActionTypeId not found" << action.actionTypeId(); return info->finish(Thing::ThingErrorActionTypeNotFound); @@ -369,6 +397,22 @@ void IntegrationPluginBose::executeBrowserItem(BrowserActionInfo *info) } } +void IntegrationPluginBose::updateConsumerKey() +{ + QString key = configValue(bosePluginCustomConsumerKeyParamTypeId).toString(); + if (!key.isEmpty()) { + m_consumerKey = key; + return; + } + key = apiKeyStorage()->requestKey("bose").data("consumerKey"); + if (!key.isEmpty()) { + m_consumerKey = key; + return; + } + qCWarning(dcBose()) << "No API key set."; + qCWarning(dcBose()) << "Either install an API key pacakge (nymea-apikeysprovider-plugin-*) or provide a key in the plugin settings."; +} + void IntegrationPluginBose::onPluginTimer() { foreach(SoundTouch *soundTouch, m_soundTouch.values()) { diff --git a/bose/integrationpluginbose.h b/bose/integrationpluginbose.h index 4ce61d7a..16223879 100644 --- a/bose/integrationpluginbose.h +++ b/bose/integrationpluginbose.h @@ -63,6 +63,7 @@ public: void executeBrowserItem(BrowserActionInfo *info) override; private: + QString m_consumerKey; ZeroConfServiceBrowser *m_serviceBrowser = nullptr; PluginTimer *m_pluginTimer = nullptr; @@ -79,15 +80,17 @@ private slots: void onDeviceNameChanged(); void onRequestExecuted(QUuid requestId, bool success); - void onInfoObjectReceived(QUuid requestId, InfoObject infoObject); - void onNowPlayingObjectReceived(QUuid requestId, NowPlayingObject nowPlaying); - void onVolumeObjectReceived(QUuid requestId, VolumeObject volume); - void onSourcesObjectReceived(QUuid requestId, SourcesObject sources); - void onBassObjectReceived(QUuid requestId, BassObject bass); - void onBassCapabilitiesObjectReceived(QUuid requestId, BassCapabilitiesObject bassCapabilities); - void onGroupObjectReceived(QUuid requestId, GroupObject group); - void onZoneObjectReceived(QUuid requestId, ZoneObject zone); - void onPresetsReceived(QUuid requestId, QList presets); + void onInfoObjectReceived(QUuid requestId, InfoObject infoObject); + void onNowPlayingObjectReceived(QUuid requestId, NowPlayingObject nowPlaying); + void onVolumeObjectReceived(QUuid requestId, VolumeObject volume); + void onSourcesObjectReceived(QUuid requestId, SourcesObject sources); + void onBassObjectReceived(QUuid requestId, BassObject bass); + void onBassCapabilitiesObjectReceived(QUuid requestId, BassCapabilitiesObject bassCapabilities); + void onGroupObjectReceived(QUuid requestId, GroupObject group); + void onZoneObjectReceived(QUuid requestId, ZoneObject zone); + void onPresetsReceived(QUuid requestId, QList presets); + + void updateConsumerKey(); }; #endif // INTEGRATIONPLUGINBOSE_H diff --git a/bose/integrationpluginbose.json b/bose/integrationpluginbose.json index f3e07d94..5021a90c 100644 --- a/bose/integrationpluginbose.json +++ b/bose/integrationpluginbose.json @@ -2,6 +2,37 @@ "id": "472a3f24-b05c-49b3-ad9a-dfda608b6760", "name": "Bose", "displayName": "Bose", + "apiKeys": ["bose"], + "paramTypes": [ + { + "id": "a5fcebca-b37d-4c14-ba22-1e5f1dd377e7", + "name": "customConsumerKey", + "displayName": "Custom consumer key", + "type" : "QString", + "defaultValue": "" + }, + { + "id": "2c41fcc1-b28f-4f7e-9a8c-74972c60d22f", + "name": "customConsumerSecret", + "displayName": "Custom consumer secret", + "type" : "QString", + "defaultValue": "" + }, + { + "id": "82883f9b-4397-404a-9126-4e9d5a22e6c6", + "name": "doorbellSoundUrl", + "displayName": "Doorbell sound url", + "type" : "QString", + "defaultValue": "https://downloads.nymea.io/notification-sounds/doorbell.mp3" + }, + { + "id": "8717d14e-c3d5-44a7-b658-4826dd4013c2", + "name": "notificationSoundUrl", + "displayName": "Notification sound url", + "type" : "QString", + "defaultValue": "https://downloads.nymea.io/notification-sounds/notification.mp3" + } + ], "vendors": [ { "id": "433c45cd-5bc1-4239-a8a1-487c70ffdfc7", @@ -12,7 +43,7 @@ "id": "f9b7a3f5-6353-48b1-afc1-66f914412f82", "name": "soundtouch", "displayName": "SoundTouch", - "interfaces": ["extendedvolumecontroller", "mediametadataprovider", "shufflerepeat", "connectable"], + "interfaces": ["extendedvolumecontroller", "mediametadataprovider", "shufflerepeat", "alert", "connectable"], "createMethods": ["discovery"], "browsable": true, "paramTypes": [ @@ -221,6 +252,42 @@ ] } ] + }, + { + "id": "de24c5ec-1e36-4149-bfaa-71fb05264aa3", + "name": "alert", + "displayName": "Alert", + "paramTypes": [ + { + "id": "4c13007a-82e6-484f-959a-bf3731c18768", + "name": "sound", + "displayName": "Sound", + "type": "QString", + "defaultValue": "Notification", + "allowedValues": [ + "Doorbell", + "Warning", + "Noification", + "Error" + ] + }, + { + "id": "346e1544-16fa-49a1-85ac-6be657c737d8", + "name": "message", + "displayName": "Display message", + "type": "QString", + "defaultValue": "None" + }, + { + "id": "8527bff6-811f-41f5-a098-e4b356e2463c", + "name": "volume", + "displayName": "Volume", + "type": "int", + "minValue": 10, + "maxValue": 70, + "defaultValue": "30" + } + ] } ] }