From d956df8483daed4600f4721bd2094d7ebba10840 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 3 Jan 2019 01:18:23 +0100 Subject: [PATCH] Allow overriding device parameters from discovered devices --- libnymea-core/jsonrpc/devicehandler.cpp | 15 ++++++++------- libnymea-core/jsonrpc/jsontypes.cpp | 8 +++++++- libnymea-core/servers/rest/devicesresource.cpp | 4 ++-- libnymea/devicemanager.cpp | 18 +++++++++++++++--- libnymea/devicemanager.h | 2 +- nymea.pri | 2 +- tests/auto/api.json | 7 +++++-- 7 files changed, 39 insertions(+), 17 deletions(-) diff --git a/libnymea-core/jsonrpc/devicehandler.cpp b/libnymea-core/jsonrpc/devicehandler.cpp index 1af8161d..3608cb6d 100644 --- a/libnymea-core/jsonrpc/devicehandler.cpp +++ b/libnymea-core/jsonrpc/devicehandler.cpp @@ -118,9 +118,10 @@ DeviceHandler::DeviceHandler(QObject *parent) : params.clear(); returns.clear(); setDescription("AddConfiguredDevice", "Add a configured device with a setupMethod of SetupMethodJustAdd. " "For devices with a setupMethod different than SetupMethodJustAdd, use PairDevice. " - "Use deviceDescriptorId or deviceParams, depending on the createMethod of the device class. " - "CreateMethodJustAdd takes the parameters you want to have with that device. " - "CreateMethodDiscovery requires the use of a deviceDescriptorId." + "Devices with CreateMethodJustAdd require all parameters to be supplied here. " + "Devices with CreateMethodDiscovery require the use of a deviceDescriptorId. For discovered " + "devices params are not required and will be taken from the DeviceDescriptor, however, they " + "may be overridden by supplying parameters here." ); params.insert("deviceClassId", JsonTypes::basicTypeToString(JsonTypes::Uuid)); params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String)); @@ -138,7 +139,7 @@ DeviceHandler::DeviceHandler(QObject *parent) : "Use this for DeviceClasses with a setupMethod different than SetupMethodJustAdd. " "Use deviceDescriptorId or deviceParams, depending on the createMethod of the device class. " "CreateMethodJustAdd takes the parameters you want to have with that device. " - "CreateMethodDiscovery requires the use of a deviceDescriptorId. " + "CreateMethodDiscovery requires the use of a deviceDescriptorId, optionally, parameters can be overridden here. " "If success is true, the return values will contain a pairingTransactionId, a displayMessage and " "the setupMethod. Depending on the setupMethod you should either proceed with AddConfiguredDevice " "or PairDevice." @@ -336,7 +337,7 @@ JsonReply *DeviceHandler::GetDiscoveredDevices(const QVariantMap ¶ms) const DeviceManager::DeviceError status = NymeaCore::instance()->deviceManager()->discoverDevices(deviceClassId, discoveryParams); if (status == DeviceManager::DeviceErrorAsync ) { JsonReply *reply = createAsyncReply("GetDiscoveredDevices"); - connect(reply, &JsonReply::finished, [this, deviceClassId](){ m_discoverRequests.remove(deviceClassId); }); + connect(reply, &JsonReply::finished, this, [this, deviceClassId](){ m_discoverRequests.remove(deviceClassId); }); m_discoverRequests.insert(deviceClassId, reply); return reply; } @@ -393,7 +394,7 @@ JsonReply* DeviceHandler::AddConfiguredDevice(const QVariantMap ¶ms) if (deviceDescriptorId.isNull()) { status = NymeaCore::instance()->deviceManager()->addConfiguredDevice(deviceClass, deviceName, deviceParams, newDeviceId); } else { - status = NymeaCore::instance()->deviceManager()->addConfiguredDevice(deviceClass, deviceName, deviceDescriptorId, newDeviceId); + status = NymeaCore::instance()->deviceManager()->addConfiguredDevice(deviceClass, deviceName, deviceDescriptorId, deviceParams, newDeviceId); } QVariantMap returns; switch (status) { @@ -679,7 +680,7 @@ void DeviceHandler::devicesDiscovered(const DeviceClassId &deviceClassId, const return; // We didn't start this discovery... Ignore it. } - JsonReply *reply = 0; + JsonReply *reply = nullptr; reply = m_discoverRequests.take(deviceClassId); if (!reply) return; diff --git a/libnymea-core/jsonrpc/jsontypes.cpp b/libnymea-core/jsonrpc/jsontypes.cpp index cb2a5c95..9d80a86b 100644 --- a/libnymea-core/jsonrpc/jsontypes.cpp +++ b/libnymea-core/jsonrpc/jsontypes.cpp @@ -301,10 +301,11 @@ void JsonTypes::init() s_device.insert("setupComplete", basicTypeToString(Bool)); s_device.insert("o:parentId", basicTypeToString(Uuid)); - // DeviceDescription + // DeviceDescriptor s_deviceDescriptor.insert("id", basicTypeToString(Uuid)); s_deviceDescriptor.insert("title", basicTypeToString(String)); s_deviceDescriptor.insert("description", basicTypeToString(String)); + s_deviceDescriptor.insert("deviceParams", QVariantList() << paramRef()); // Rule s_rule.insert("id", basicTypeToString(Uuid)); @@ -862,6 +863,11 @@ QVariantMap JsonTypes::packDeviceDescriptor(const DeviceDescriptor &descriptor) variant.insert("id", descriptor.id()); variant.insert("title", descriptor.title()); variant.insert("description", descriptor.description()); + QVariantList params; + foreach (const Param ¶m, descriptor.params()) { + params.append(packParam(param)); + } + variant.insert("deviceParams", params); return variant; } diff --git a/libnymea-core/servers/rest/devicesresource.cpp b/libnymea-core/servers/rest/devicesresource.cpp index b98d2cc8..68693cde 100644 --- a/libnymea-core/servers/rest/devicesresource.cpp +++ b/libnymea-core/servers/rest/devicesresource.cpp @@ -72,7 +72,7 @@ QString DevicesResource::name() const */ HttpReply *DevicesResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens) { - m_device = 0; + m_device = nullptr; // get the main resource if (urlTokens.count() >= 4 && urlTokens.at(3) != "pair" && urlTokens.at(3) != "confirmpairing") { @@ -373,7 +373,7 @@ HttpReply *DevicesResource::addConfiguredDevice(const QByteArray &payload) const status = NymeaCore::instance()->deviceManager()->addConfiguredDevice(deviceClassId, deviceName, deviceParams, newDeviceId); } else { qCDebug(dcRest) << "Adding discovered device" << deviceName << "with DeviceDescriptorId" << deviceDescriptorId.toString(); - status = NymeaCore::instance()->deviceManager()->addConfiguredDevice(deviceClassId, deviceName, deviceDescriptorId, newDeviceId); + status = NymeaCore::instance()->deviceManager()->addConfiguredDevice(deviceClassId, deviceName, deviceDescriptorId, deviceParams, newDeviceId); } if (status == DeviceManager::DeviceErrorAsync) { HttpReply *reply = createAsyncReply(); diff --git a/libnymea/devicemanager.cpp b/libnymea/devicemanager.cpp index b1c9fa8f..65576005 100644 --- a/libnymea/devicemanager.cpp +++ b/libnymea/devicemanager.cpp @@ -459,9 +459,11 @@ DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const DeviceClassI /*! Add a new configured device for the given \l{DeviceClass} the given DeviceDescriptorId and \a deviceId. Only devices with \l{DeviceClass}{CreateMethodDiscovery} * can be created using this method. The \a deviceClassId must refer to an existing \l{DeviceClass} and the \a deviceDescriptorId must refer to an existing DeviceDescriptorId - * from the discovery. The \a name parameter should contain the device name. + * from the discovery. The \a name parameter should contain the device name. Optionally device params can be passed. By default the descriptor's params as found by the discovery + * are used but can be overridden here. + * * Returns \l{DeviceError} to inform about the result. */ -DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const DeviceClassId &deviceClassId, const QString &name, const DeviceDescriptorId &deviceDescriptorId, const DeviceId &deviceId) +DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const DeviceClassId &deviceClassId, const QString &name, const DeviceDescriptorId &deviceDescriptorId, const ParamList ¶ms, const DeviceId &deviceId) { DeviceClass deviceClass = findDeviceClass(deviceClassId); if (!deviceClass.isValid()) { @@ -476,7 +478,17 @@ DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const DeviceClassI return DeviceErrorDeviceDescriptorNotFound; } - return addConfiguredDeviceInternal(deviceClassId, name, descriptor.params(), deviceId); + // Merge params. Use the ones from the descriptor unless overrides are provided in the function call + ParamList finalParams; + foreach (const Param ¶m, descriptor.params()) { + if (params.hasParam(param.paramTypeId())) { + finalParams.append(Param(param.paramTypeId(), params.paramValue(param.paramTypeId()))); + } else { + finalParams.append(param); + } + } + + return addConfiguredDeviceInternal(deviceClassId, name, finalParams, deviceId); } diff --git a/libnymea/devicemanager.h b/libnymea/devicemanager.h index eb9de9bd..9d542887 100644 --- a/libnymea/devicemanager.h +++ b/libnymea/devicemanager.h @@ -113,7 +113,7 @@ public: QList configuredDevices() const; DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const QString &name, const ParamList ¶ms, const DeviceId id = DeviceId::createDeviceId()); - DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const QString &name, const DeviceDescriptorId &deviceDescriptorId, const DeviceId &id = DeviceId::createDeviceId()); + DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const QString &name, const DeviceDescriptorId &deviceDescriptorId, const ParamList ¶ms = ParamList(), const DeviceId &deviceId = DeviceId::createDeviceId()); DeviceError reconfigureDevice(const DeviceId &deviceId, const ParamList ¶ms, bool fromDiscovery = false); DeviceError reconfigureDevice(const DeviceId &deviceId, const DeviceDescriptorId &deviceDescriptorId); diff --git a/nymea.pri b/nymea.pri index 25c3cfd1..1d8c9692 100644 --- a/nymea.pri +++ b/nymea.pri @@ -6,7 +6,7 @@ NYMEA_PLUGINS_PATH=/usr/lib/$$system('dpkg-architecture -q DEB_HOST_MULTIARCH')/ # define protocol versions JSON_PROTOCOL_VERSION_MAJOR=1 -JSON_PROTOCOL_VERSION_MINOR=11 +JSON_PROTOCOL_VERSION_MINOR=12 REST_API_VERSION=1 DEFINES += NYMEA_VERSION_STRING=\\\"$${NYMEA_VERSION_STRING}\\\" \ diff --git a/tests/auto/api.json b/tests/auto/api.json index be41a5bd..92fe46e1 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -1,4 +1,4 @@ -1.11 +1.12 { "methods": { "Actions.ExecuteAction": { @@ -235,7 +235,7 @@ } }, "Devices.AddConfiguredDevice": { - "description": "Add a configured device with a setupMethod of SetupMethodJustAdd. For devices with a setupMethod different than SetupMethodJustAdd, use PairDevice. Use deviceDescriptorId or deviceParams, depending on the createMethod of the device class. CreateMethodJustAdd takes the parameters you want to have with that device. CreateMethodDiscovery requires the use of a deviceDescriptorId.", + "description": "Add a configured device with a setupMethod of SetupMethodJustAdd. For devices with a setupMethod different than SetupMethodJustAdd, use PairDevice. Devices with CreateMethodJustAdd require all parameters to be supplied here. Devices with CreateMethodDiscovery require the use of a deviceDescriptorId. For discovered devices params not not required and will be taken from the DeviceDescriptor, however they can be overridden by supplying parameters here.", "params": { "deviceClassId": "Uuid", "name": "String", @@ -1266,6 +1266,9 @@ }, "DeviceDescriptor": { "description": "String", + "deviceParams": [ + "$ref:Param" + ], "id": "Uuid", "title": "String" },