From e6929df34fbcb2b7df9070b26683eac4817e8acc Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 6 Jan 2019 21:49:54 +0100 Subject: [PATCH] add support for overriding discovery params --- libnymea-app-core/devicediscovery.cpp | 92 ++++++++++++++++++++------- libnymea-app-core/devicediscovery.h | 45 ++++++++----- libnymea-app-core/devicemanager.cpp | 4 +- libnymea-app-core/devicemanager.h | 2 +- libnymea-app-core/libnymea-app-core.h | 1 + nymea-app/ui/NewDeviceWizard.qml | 39 +++++++----- 6 files changed, 127 insertions(+), 56 deletions(-) diff --git a/libnymea-app-core/devicediscovery.cpp b/libnymea-app-core/devicediscovery.cpp index fb80e008..ec3a2e6e 100644 --- a/libnymea-app-core/devicediscovery.cpp +++ b/libnymea-app-core/devicediscovery.cpp @@ -17,11 +17,11 @@ QVariant DeviceDiscovery::data(const QModelIndex &index, int role) const { switch (role) { case RoleId: - return m_foundDevices.at(index.row()).m_id; + return m_foundDevices.at(index.row())->id(); case RoleName: - return m_foundDevices.at(index.row()).m_name; + return m_foundDevices.at(index.row())->name(); case RoleDescription: - return m_foundDevices.at(index.row()).m_description; + return m_foundDevices.at(index.row())->description(); } return QVariant(); @@ -38,17 +38,21 @@ QHash DeviceDiscovery::roleNames() const void DeviceDiscovery::discoverDevices(const QUuid &deviceClassId, const QVariantList &discoveryParams) { + if (m_busy) { + qWarning() << "Busy... not restarting discovery"; + return; + } beginResetModel(); m_foundDevices.clear(); endResetModel(); emit countChanged(); - if (!m_jsonRpcClient) { - qWarning() << "Cannot discover devices. No JsonRpcClient set"; + if (!m_engine) { + qWarning() << "Cannot discover devices. No Engine set"; return; } - if (!m_jsonRpcClient->connected()) { - qWarning() << "Cannot discover devices. JsonRpcClient not connected."; + if (!m_engine->jsonRpcClient()->connected()) { + qWarning() << "Cannot discover devices. Not connected."; return; } @@ -57,21 +61,29 @@ void DeviceDiscovery::discoverDevices(const QUuid &deviceClassId, const QVariant if (!discoveryParams.isEmpty()) { params.insert("discoveryParams", discoveryParams); } - m_jsonRpcClient->sendCommand("Devices.GetDiscoveredDevices", params, this, "discoverDevicesResponse"); + m_engine->jsonRpcClient()->sendCommand("Devices.GetDiscoveredDevices", params, this, "discoverDevicesResponse"); m_busy = true; emit busyChanged(); } -JsonRpcClient *DeviceDiscovery::jsonRpcClient() const +DeviceDescriptor *DeviceDiscovery::get(int index) const { - return m_jsonRpcClient; + if (index < 0 || index >= m_foundDevices.count()) { + return nullptr; + } + return m_foundDevices.at(index); } -void DeviceDiscovery::setJsonRpcClient(JsonRpcClient *jsonRpcClient) +Engine *DeviceDiscovery::engine() const { - if (m_jsonRpcClient != jsonRpcClient) { - m_jsonRpcClient = jsonRpcClient; - emit jsonRpcClientChanged(); + return m_engine; +} + +void DeviceDiscovery::setEngine(Engine *engine) +{ + if (m_engine != engine) { + m_engine = engine; + emit engineChanged(); } } @@ -87,13 +99,19 @@ void DeviceDiscovery::discoverDevicesResponse(const QVariantMap ¶ms) // qDebug() << "response received" << params; QVariantList descriptors = params.value("params").toMap().value("deviceDescriptors").toList(); - foreach (const QVariant &descriptor, descriptors) { - qDebug() << "descriptor" << descriptor; - if (!contains(descriptor.toMap().value("id").toUuid())) { + foreach (const QVariant &descriptorVariant, descriptors) { + qDebug() << "Found device. Descriptor:" << descriptorVariant; + if (!contains(descriptorVariant.toMap().value("id").toUuid())) { beginInsertRows(QModelIndex(), m_foundDevices.count(), m_foundDevices.count()); - m_foundDevices.append(DeviceDescriptor(descriptor.toMap().value("id").toUuid(), - descriptor.toMap().value("title").toString(), - descriptor.toMap().value("description").toString())); + DeviceDescriptor *descriptor = new DeviceDescriptor(descriptorVariant.toMap().value("id").toUuid(), + descriptorVariant.toMap().value("title").toString(), + descriptorVariant.toMap().value("description").toString()); + foreach (const QVariant ¶mVariant, descriptorVariant.toMap().value("deviceParams").toList()) { + qDebug() << "Adding param:" << paramVariant.toMap().value("paramTypeId").toString() << paramVariant.toMap().value("value"); + Param* p = new Param(paramVariant.toMap().value("paramTypeId").toString(), paramVariant.toMap().value("value")); + descriptor->params()->addParam(p); + } + m_foundDevices.append(descriptor); endInsertRows(); emit countChanged(); } @@ -102,10 +120,40 @@ void DeviceDiscovery::discoverDevicesResponse(const QVariantMap ¶ms) bool DeviceDiscovery::contains(const QUuid &deviceDescriptorId) const { - foreach (const DeviceDescriptor &descriptor, m_foundDevices) { - if (descriptor.m_id == deviceDescriptorId) { + foreach (DeviceDescriptor *descriptor, m_foundDevices) { + if (descriptor->id() == deviceDescriptorId) { return true; } } return false; } + +DeviceDescriptor::DeviceDescriptor(const QUuid &id, const QString &name, const QString &description, QObject *parent): + QObject(parent), + m_id(id), + m_name(name), + m_description(description), + m_params(new Params(this)) +{ + +} + +QUuid DeviceDescriptor::id() const +{ + return m_id; +} + +QString DeviceDescriptor::name() const +{ + return m_name; +} + +QString DeviceDescriptor::description() const +{ + return m_description; +} + +Params* DeviceDescriptor::params() const +{ + return m_params; +} diff --git a/libnymea-app-core/devicediscovery.h b/libnymea-app-core/devicediscovery.h index 45661b5a..1e486b65 100644 --- a/libnymea-app-core/devicediscovery.h +++ b/libnymea-app-core/devicediscovery.h @@ -4,12 +4,33 @@ #include #include -#include "jsonrpc/jsonrpcclient.h" +#include "engine.h" + +class DeviceDescriptor: public QObject { + Q_OBJECT + Q_PROPERTY(QUuid id READ id CONSTANT) + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString description READ description CONSTANT) + Q_PROPERTY(Params* params READ params CONSTANT) +public: + DeviceDescriptor(const QUuid &id, const QString &name, const QString &description, QObject *parent = nullptr); + + QUuid id() const; + QString name() const; + QString description() const; + Params* params() const; + +private: + QUuid m_id; + QString m_name; + QString m_description; + Params *m_params = nullptr; +}; class DeviceDiscovery : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(JsonRpcClient* jsonRpcClient READ jsonRpcClient WRITE setJsonRpcClient) + Q_PROPERTY(Engine* engine READ engine WRITE setEngine) Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) Q_PROPERTY(int count READ rowCount NOTIFY countChanged) public: @@ -28,8 +49,10 @@ public: Q_INVOKABLE void discoverDevices(const QUuid &deviceClassId, const QVariantList &discoveryParams = {}); - JsonRpcClient* jsonRpcClient() const; - void setJsonRpcClient(JsonRpcClient *jsonRpcClient); + Q_INVOKABLE DeviceDescriptor* get(int index) const; + + Engine* engine() const; + void setEngine(Engine *jsonRpcClient); bool busy() const; @@ -39,22 +62,14 @@ private slots: signals: void busyChanged(); void countChanged(); - void jsonRpcClientChanged(); + void engineChanged(); private: - class DeviceDescriptor { - public: - DeviceDescriptor(const QUuid &id, const QString &name, const QString &description): m_id(id), m_name(name), m_description(description) {} - QUuid m_id; - QString m_name; - QString m_description; - }; - - JsonRpcClient *m_jsonRpcClient = nullptr; + Engine *m_engine = nullptr; bool m_busy = false; bool contains(const QUuid &deviceDescriptorId) const; - QList m_foundDevices; + QList m_foundDevices; }; #endif // DEVICEDISCOVERY_H diff --git a/libnymea-app-core/devicemanager.cpp b/libnymea-app-core/devicemanager.cpp index 35f3eb3c..7cd02d87 100644 --- a/libnymea-app-core/devicemanager.cpp +++ b/libnymea-app-core/devicemanager.cpp @@ -241,6 +241,7 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap ¶ms) device->setStateValue(stateTypeId, value); // qDebug() << "Set device state value:" << device->stateValue(stateTypeId) << value; } + qDebug() << "Confgured Device JSON:" << qUtf8Printable(QJsonDocument::fromVariant(deviceVariant).toJson(QJsonDocument::Indented)); devices()->addDevice(device); qDebug() << "*** Added device:" << endl << device; } @@ -318,13 +319,14 @@ void DeviceManager::savePluginConfig(const QUuid &pluginId) m_jsonClient->sendCommand("Devices.SetPluginConfiguration", params, this, "setPluginConfigResponse"); } -void DeviceManager::addDiscoveredDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name) +void DeviceManager::addDiscoveredDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name, const QVariantList &deviceParams) { qDebug() << "JsonRpc: add discovered device " << deviceClassId.toString(); QVariantMap params; params.insert("deviceClassId", deviceClassId.toString()); params.insert("name", name); params.insert("deviceDescriptorId", deviceDescriptorId.toString()); + params.insert("deviceParams", deviceParams); m_jsonClient->sendCommand("Devices.AddConfiguredDevice", params, this, "addDeviceResponse"); } diff --git a/libnymea-app-core/devicemanager.h b/libnymea-app-core/devicemanager.h index a7ecafa8..d6b2a343 100644 --- a/libnymea-app-core/devicemanager.h +++ b/libnymea-app-core/devicemanager.h @@ -64,7 +64,7 @@ public: bool fetchingData() const; Q_INVOKABLE void addDevice(const QUuid &deviceClassId, const QString &name, const QVariantList &deviceParams); - Q_INVOKABLE void addDiscoveredDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name); + Q_INVOKABLE void addDiscoveredDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name, const QVariantList &deviceParams); Q_INVOKABLE void pairDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name); Q_INVOKABLE void confirmPairing(const QUuid &pairingTransactionId, const QString &secret = QString()); Q_INVOKABLE void removeDevice(const QUuid &deviceId, RemovePolicy policy = RemovePolicyNone); diff --git a/libnymea-app-core/libnymea-app-core.h b/libnymea-app-core/libnymea-app-core.h index 9e0d6744..c710add8 100644 --- a/libnymea-app-core/libnymea-app-core.h +++ b/libnymea-app-core/libnymea-app-core.h @@ -114,6 +114,7 @@ void registerQmlTypes() { qmlRegisterUncreatableType(uri, 1, 0, "DeviceClasses", "Can't create this in QML. Get it from the DeviceManager."); qmlRegisterType(uri, 1, 0, "DeviceClassesProxy"); qmlRegisterType(uri, 1, 0, "DeviceDiscovery"); + qmlRegisterUncreatableType(uri, 1, 0, "DeviceDescriptor", "Get it from DeviceDiscovery"); qmlRegisterType(uri, 1, 0, "DeviceModel"); diff --git a/nymea-app/ui/NewDeviceWizard.qml b/nymea-app/ui/NewDeviceWizard.qml index 67c2c8bb..099d855d 100644 --- a/nymea-app/ui/NewDeviceWizard.qml +++ b/nymea-app/ui/NewDeviceWizard.qml @@ -24,10 +24,10 @@ Page { QtObject { id: d property var vendorId: null - property var deviceClass: null - property var deviceDescriptorId: null + property DeviceClass deviceClass: null + property DeviceDescriptor deviceDescriptor: null property var discoveryParams: [] - property var deviceName: null + property string deviceName: null property int pairRequestId: 0 property var pairingTransactionId: null property int addRequestId: 0 @@ -64,7 +64,7 @@ Page { DeviceDiscovery { id: discovery - jsonRpcClient: engine.jsonRpcClient + engine: _engine } StackView { @@ -229,7 +229,7 @@ Page { subText: model.description iconName: app.interfacesToIcon(discoveryView.deviceClass.interfaces) onClicked: { - d.deviceDescriptorId = model.id; + d.deviceDescriptor = discovery.get(index); d.deviceName = model.name; internalPageStack.push(paramsPage) } @@ -320,11 +320,14 @@ Page { Repeater { id: paramRepeater - model: d.deviceDescriptorId == null ? d.deviceClass.paramTypes : null + model: engine.jsonRpcClient.ensureServerVersion("1.12") || d.deviceDescriptor == null ? d.deviceClass.paramTypes : null delegate: ParamDelegate { // Layout.preferredHeight: 60 Layout.fillWidth: true paramType: d.deviceClass.paramTypes.get(index) + value: d.deviceDescriptor && d.deviceDescriptor.params.getParam(paramType.id) ? + d.deviceDescriptor.params.getParam(paramType.id).value : + d.deviceClass.paramTypes.get(index).defaultValue } } @@ -336,19 +339,21 @@ Page { text: "OK" onClicked: { print("setupMethod", d.deviceClass.setupMethod) + + var params = [] + for (var i = 0; i < paramRepeater.count; i++) { + var param = {} + param.paramTypeId = paramRepeater.itemAt(i).paramType.id + param.value = paramRepeater.itemAt(i).value + print("adding param", param.paramTypeId, param.value) + params.push(param) + } + switch (d.deviceClass.setupMethod) { case 0: - if (d.deviceDescriptorId) { - engine.deviceManager.addDiscoveredDevice(d.deviceClass.id, d.deviceDescriptorId, nameTextField.text); + if (d.deviceDescriptor) { + engine.deviceManager.addDiscoveredDevice(d.deviceClass.id, d.deviceDescriptor.id, nameTextField.text, params); } else { - var params = [] - for (var i = 0; i < paramRepeater.count; i++) { - var param = {} - param.paramTypeId = paramRepeater.itemAt(i).paramType.id - param.value = paramRepeater.itemAt(i).value - print("adding param", param.paramTypeId, param.value) - params.push(param) - } engine.deviceManager.addDevice(d.deviceClass.id, nameTextField.text, params); } @@ -357,7 +362,7 @@ Page { case 1: case 2: case 3: - engine.deviceManager.pairDevice(d.deviceClass.id, d.deviceDescriptorId, nameTextField.text); + engine.deviceManager.pairDevice(d.deviceClass.id, d.deviceDescriptor.id, nameTextField.text); break; }