diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index b9554c79..bcce7c9e 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -325,6 +325,77 @@ DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const DeviceClassI return addConfiguredDeviceInternal(deviceClassId, descriptor.params(), deviceId); } +DeviceManager::DeviceError DeviceManager::editDevice(const DeviceId &deviceId, const ParamList ¶ms) +{ + qDebug() << "EDIT DEVICE!!!!"; + + Device *device = findConfiguredDevice(deviceId); + if (!device) { + return DeviceErrorDeviceNotFound; + } + + ParamList effectiveParams = params; + DeviceClass deviceClass = findDeviceClass(device->deviceClassId()); + if (deviceClass.id().isNull()) { + return DeviceErrorDeviceClassNotFound; + } + + DevicePlugin *plugin = m_devicePlugins.value(deviceClass.pluginId()); + if (!plugin) { + return DeviceErrorPluginNotFound; + } + + // check if one of the given params is not editable + foreach (const ParamType ¶mType, deviceClass.paramTypes()) { + foreach (const Param ¶m, params) { + if (paramType.name() == param.name()) { + if (!paramType.editable()) + return DeviceErrorParameterNotEditable; + } + } + } + + DeviceError result = verifyParams(deviceClass.paramTypes(), effectiveParams, false); + if (result != DeviceErrorNoError) { + return result; + } + + device->setSetupComplete(false); + + // set new params + foreach (const Param ¶m, effectiveParams) { + device->setParamValue(param.name(), param.value()); + } + + DeviceSetupStatus status = plugin->editDevice(device); + switch (status) { + case DeviceSetupStatusFailure: + qWarning() << "Device edit failed. Not saving changes of device paramters."; + return DeviceErrorSetupFailed; + case DeviceSetupStatusAsync: + qDebug() << "Device edit async. Waiting for complete..."; + m_asyncDeviceEdit.append(device); + return DeviceErrorAsync; + case DeviceSetupStatusSuccess: + qDebug() << "Device params edit complete."; + break; + } + + storeConfiguredDevices(); + postSetupDevice(device); + emit deviceParamsChanged(device); + + return DeviceErrorNoError; +} + +DeviceManager::DeviceError DeviceManager::editDevice(const DeviceId &deviceId, const DeviceDescriptorId &deviceDescriptorId) +{ + Q_UNUSED(deviceId) + Q_UNUSED(deviceDescriptorId) + + return DeviceErrorNoError; +} + /*! Initiates a pairing with a \l{DeviceClass}{Device} with the given \a pairingTransactionId, \a deviceClassId and \a params. * Returns \l{DeviceManager::DeviceError}{DeviceError} to inform about the result. */ DeviceManager::DeviceError DeviceManager::pairDevice(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms) @@ -792,6 +863,16 @@ void DeviceManager::slotDeviceSetupFinished(Device *device, DeviceManager::Devic m_pluginTimerUsers.append(device); } + // if this is a async device edit + if (m_asyncDeviceEdit.contains(device)) { + m_asyncDeviceEdit.removeAll(device); + storeConfiguredDevices(); + device->setupCompleted(); + qDebug() << "emit Device edit finished!!!"; + emit deviceEditFinished(device, DeviceManager::DeviceErrorNoError); + return; + } + connect(device, SIGNAL(stateValueChanged(QUuid,QVariant)), this, SLOT(slotDeviceStateValueChanged(QUuid,QVariant))); device->setupCompleted(); @@ -879,6 +960,7 @@ void DeviceManager::autoDevicesAppeared(const DeviceClassId &deviceClassId, cons if (!deviceClass.isValid()) { return; } + DevicePlugin *plugin = m_devicePlugins.value(deviceClass.pluginId()); if (!plugin) { return; diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index f69102b0..1c9bb3ae 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -71,11 +71,11 @@ public: DeviceErrorSetupMethodNotSupported, DeviceErrorHardwareNotAvailable, DeviceErrorHardwareFailure, - // TODO: Bump API version - //DeviceErrorAuthentificationFailure, + DeviceErrorAuthentificationFailure, DeviceErrorAsync, DeviceErrorDeviceInUse, DeviceErrorPairingTransactionIdNotFound, + DeviceErrorParameterNotEditable }; enum DeviceSetupStatus { @@ -98,6 +98,10 @@ public: QList configuredDevices() const; DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const ParamList ¶ms, const DeviceId id = DeviceId::createDeviceId()); DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId, const DeviceId &id = DeviceId::createDeviceId()); + + DeviceError editDevice(const DeviceId &deviceId, const ParamList ¶ms); + DeviceError editDevice(const DeviceId &deviceId, const DeviceDescriptorId &deviceDescriptorId); + DeviceError pairDevice(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms); DeviceError pairDevice(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId); DeviceError confirmPairing(const PairingTransactionId &pairingTransactionId, const QString &secret = QString()); @@ -113,8 +117,10 @@ signals: void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value); void deviceRemoved(const DeviceId &deviceId); void deviceAdded(Device *device); + void deviceParamsChanged(Device *device); void devicesDiscovered(const DeviceClassId &deviceClassId, const QList &devices); void deviceSetupFinished(Device *device, DeviceError status); + void deviceEditFinished(Device *device, DeviceError status); void pairingFinished(const PairingTransactionId &pairingTransactionId, DeviceError status, const DeviceId &deviceId = DeviceId()); void actionExecutionFinished(const ActionId &actionId, DeviceError status); @@ -168,6 +174,8 @@ private: QHash > m_pairingsJustAdd; QHash > m_pairingsDiscovery; + QList m_asyncDeviceEdit; + QList m_discoveringPlugins; friend class DevicePlugin; diff --git a/libguh/plugin/device.cpp b/libguh/plugin/device.cpp index 8590c11f..ad873c74 100644 --- a/libguh/plugin/device.cpp +++ b/libguh/plugin/device.cpp @@ -215,3 +215,8 @@ bool Device::setupComplete() const { return m_setupComplete; } + +void Device::setSetupComplete(const bool &complete) +{ + m_setupComplete = complete; +} diff --git a/libguh/plugin/device.h b/libguh/plugin/device.h index 11328791..5f706d3a 100644 --- a/libguh/plugin/device.h +++ b/libguh/plugin/device.h @@ -73,6 +73,7 @@ private: Device(const PluginId &pluginId, const DeviceClassId &deviceClassId, QObject *parent = 0); void setupCompleted(); + void setSetupComplete(const bool &complete); private: DeviceId m_id; diff --git a/libguh/plugin/deviceplugin.cpp b/libguh/plugin/deviceplugin.cpp index 827e2eac..c21d5777 100644 --- a/libguh/plugin/deviceplugin.cpp +++ b/libguh/plugin/deviceplugin.cpp @@ -333,6 +333,12 @@ DeviceManager::DeviceSetupStatus DevicePlugin::setupDevice(Device *device) return DeviceManager::DeviceSetupStatusSuccess; } +DeviceManager::DeviceSetupStatus DevicePlugin::editDevice(Device *device) +{ + Q_UNUSED(device) + return DeviceManager::DeviceSetupStatusSuccess; +} + /*! This will be called when a new \a device was added successfully and the device setup is finished.*/ void DevicePlugin::postSetupDevice(Device *device) { @@ -413,6 +419,11 @@ QList DevicePlugin::parseParamTypes(const QJsonArray &array) const paramType.setInputType(Types::InputTypeMacAddress); } } + + // set editable if given (default true) + if (pt.contains("editable")) { + paramType.setEditable(pt.value("editable").toBool()); + } paramType.setAllowedValues(allowedValues); paramType.setLimits(pt.value("minValue").toVariant(), pt.value("maxValue").toVariant()); paramTypes.append(paramType); diff --git a/libguh/plugin/deviceplugin.h b/libguh/plugin/deviceplugin.h index f7eed06f..f814f40c 100644 --- a/libguh/plugin/deviceplugin.h +++ b/libguh/plugin/deviceplugin.h @@ -57,6 +57,7 @@ public: virtual DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms); virtual DeviceManager::DeviceSetupStatus setupDevice(Device *device); + virtual DeviceManager::DeviceSetupStatus editDevice(Device *device); virtual void postSetupDevice(Device *device); virtual void deviceRemoved(Device *device); diff --git a/libguh/types/paramtype.cpp b/libguh/types/paramtype.cpp index 694712e6..045a5b52 100644 --- a/libguh/types/paramtype.cpp +++ b/libguh/types/paramtype.cpp @@ -37,7 +37,8 @@ ParamType::ParamType(const QString &name, const QVariant::Type type, const QVari m_name(name), m_type(type), m_defaultValue(defaultValue), - m_inputType(Types::InputTypeNone) + m_inputType(Types::InputTypeNone), + m_editable(true) { } @@ -138,7 +139,19 @@ void ParamType::setAllowedValues(const QList allowedValues) m_allowedValues = allowedValues; } -/*! Writes the name, type defaultValue, min and max value of the given \a paramType to \a dbg. */ +/*! Returns true if this ParamType is editable by the user. By default each ParamType is editable. */ +bool ParamType::editable() const +{ + return m_editable; +} + +/*! Sets this ParamType \a editable. By default each ParamType is editable. */ +void ParamType::setEditable(const bool &editable) +{ + m_editable = editable; +} + +/*! Writes the name, type defaultValue, min value, max value and editable of the given \a paramType to \a dbg. */ QDebug operator<<(QDebug dbg, const ParamType ¶mType) { dbg.nospace() << "ParamType(Name: " << paramType.name() @@ -146,6 +159,8 @@ QDebug operator<<(QDebug dbg, const ParamType ¶mType) << ", Default:" << paramType.defaultValue() << ", Min:" << paramType.minValue() << ", Max:" << paramType.maxValue() + << ", Allowed values:" << paramType.allowedValues() + << ", Editable:" << paramType.editable() << ")"; return dbg.space(); diff --git a/libguh/types/paramtype.h b/libguh/types/paramtype.h index 50bea945..2cbb7d97 100644 --- a/libguh/types/paramtype.h +++ b/libguh/types/paramtype.h @@ -55,6 +55,9 @@ public: QList allowedValues() const; void setAllowedValues(const QList allowedValues); + bool editable() const; + void setEditable(const bool &editable); + private: QString m_name; QVariant::Type m_type; @@ -63,6 +66,7 @@ private: QVariant m_maxValue; Types::InputType m_inputType; QVariantList m_allowedValues; + bool m_editable; }; QDebug operator<<(QDebug dbg, const ParamType ¶mType); diff --git a/plugins/deviceplugins/mock/devicepluginmock.cpp b/plugins/deviceplugins/mock/devicepluginmock.cpp index 4589e356..c1f3e560 100644 --- a/plugins/deviceplugins/mock/devicepluginmock.cpp +++ b/plugins/deviceplugins/mock/devicepluginmock.cpp @@ -80,6 +80,26 @@ DeviceManager::DeviceSetupStatus DevicePluginMock::setupDevice(Device *device) return DeviceManager::DeviceSetupStatusSuccess; } +DeviceManager::DeviceSetupStatus DevicePluginMock::editDevice(Device *device) +{ + qDebug() << "Mockdevice edit params to" << device->paramValue("httpport").toInt() << device->paramValue("async").toBool() << device->paramValue("broken").toBool(); + + if (device->paramValue("broken").toBool()) { + qWarning() << "This device is intentionally broken."; + return DeviceManager::DeviceSetupStatusFailure; + } + + HttpDaemon *daemon = m_daemons.take(device); + daemon->updateDevice(device); + + if (device->paramValue("async").toBool()) { + m_asyncSetupDevices.append(device); + QTimer::singleShot(1000, this, SLOT(emitDeviceSetupFinished())); + return DeviceManager::DeviceSetupStatusAsync; + } + return DeviceManager::DeviceSetupStatusSuccess; +} + void DevicePluginMock::deviceRemoved(Device *device) { delete m_daemons.take(device); diff --git a/plugins/deviceplugins/mock/devicepluginmock.h b/plugins/deviceplugins/mock/devicepluginmock.h index 1ec4dfd4..09085a2a 100644 --- a/plugins/deviceplugins/mock/devicepluginmock.h +++ b/plugins/deviceplugins/mock/devicepluginmock.h @@ -43,6 +43,7 @@ public: DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override; DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; + DeviceManager::DeviceSetupStatus editDevice(Device *device) override; void deviceRemoved(Device *device) override; void startMonitoringAutoDevices() override; diff --git a/plugins/deviceplugins/mock/devicepluginmock.json b/plugins/deviceplugins/mock/devicepluginmock.json index 2495256c..99ec0875 100644 --- a/plugins/deviceplugins/mock/devicepluginmock.json +++ b/plugins/deviceplugins/mock/devicepluginmock.json @@ -32,7 +32,8 @@ { "name": "broken", "type": "bool", - "defaultValue": false + "defaultValue": false, + "editable": false } ], "stateTypes": [ diff --git a/plugins/deviceplugins/mock/httpdaemon.cpp b/plugins/deviceplugins/mock/httpdaemon.cpp index 9aa5396d..992e9668 100644 --- a/plugins/deviceplugins/mock/httpdaemon.cpp +++ b/plugins/deviceplugins/mock/httpdaemon.cpp @@ -60,6 +60,14 @@ void HttpDaemon::actionExecuted(const ActionTypeId &actionTypeId) m_actionList.append(qMakePair(actionTypeId, QDateTime::currentDateTime())); } +void HttpDaemon::updateDevice(Device *device) +{ + m_device = device; + close(); + listen(QHostAddress::Any, device->paramValue("httpport").toInt()); + qDebug() << "Mockdevice updated and listening now on" << device->paramValue("httpport").toInt(); +} + void HttpDaemon::readClient() { if (disabled) diff --git a/plugins/deviceplugins/mock/httpdaemon.h b/plugins/deviceplugins/mock/httpdaemon.h index 28afe226..078f3302 100644 --- a/plugins/deviceplugins/mock/httpdaemon.h +++ b/plugins/deviceplugins/mock/httpdaemon.h @@ -41,6 +41,8 @@ public: void actionExecuted(const ActionTypeId &actionTypeId); + void updateDevice(Device *device); + signals: void setState(const StateTypeId &stateTypeId, const QVariant &value); void triggerEvent(const EventTypeId &eventTypeId); diff --git a/server/guhcore.cpp b/server/guhcore.cpp index ceed7d53..6c6db200 100644 --- a/server/guhcore.cpp +++ b/server/guhcore.cpp @@ -266,6 +266,11 @@ QList GuhCore::findConfiguredDevices(const DeviceClassId &deviceClassI return m_deviceManager->findConfiguredDevices(deviceClassId); } +DeviceManager::DeviceError GuhCore::editDevice(const DeviceId &deviceId, const ParamList ¶ms) +{ + return m_deviceManager->editDevice(deviceId, params); +} + /*! Calls the metheod RuleEngine::rule(). * \sa RuleEngine, */ QList GuhCore::rules() const @@ -363,6 +368,7 @@ GuhCore::GuhCore(QObject *parent) : connect(m_deviceManager, &DeviceManager::actionExecutionFinished, this, &GuhCore::actionExecutionFinished); connect(m_deviceManager, &DeviceManager::devicesDiscovered, this, &GuhCore::devicesDiscovered); connect(m_deviceManager, &DeviceManager::deviceSetupFinished, this, &GuhCore::deviceSetupFinished); + connect(m_deviceManager, &DeviceManager::deviceEditFinished, this, &GuhCore::deviceEditFinished); connect(m_deviceManager, &DeviceManager::pairingFinished, this, &GuhCore::pairingFinished); connect(m_ruleEngine, &RuleEngine::ruleAdded, this, &GuhCore::ruleAdded); diff --git a/server/guhcore.h b/server/guhcore.h index a0400cbc..493eaaef 100644 --- a/server/guhcore.h +++ b/server/guhcore.h @@ -67,6 +67,7 @@ public: QList configuredDevices() const; Device *findConfiguredDevice(const DeviceId &deviceId) const; QList findConfiguredDevices(const DeviceClassId &deviceClassId) const; + DeviceManager::DeviceError editDevice(const DeviceId &deviceId, const ParamList ¶ms); DeviceManager::DeviceError removeConfiguredDevice(const DeviceId &deviceId, const QHash &removePolicyList); DeviceManager::DeviceError pairDevice(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId); @@ -95,6 +96,7 @@ signals: void devicesDiscovered(const DeviceClassId &deviceClassId, const QList deviceDescriptors); void deviceSetupFinished(Device *device, DeviceManager::DeviceError status); + void deviceEditFinished(Device *device, DeviceManager::DeviceError status); void pairingFinished(const PairingTransactionId &pairingTransactionId, DeviceManager::DeviceError status, const DeviceId &deviceId); void ruleRemoved(const RuleId &ruleId); @@ -115,6 +117,7 @@ private: LogEngine *m_logger; QHash m_pendingActions; + private slots: void gotEvent(const Event &event); void actionExecutionFinished(const ActionId &id, DeviceManager::DeviceError status); diff --git a/server/jsonrpc/devicehandler.cpp b/server/jsonrpc/devicehandler.cpp index 6c82a5b6..8b0d18a8 100644 --- a/server/jsonrpc/devicehandler.cpp +++ b/server/jsonrpc/devicehandler.cpp @@ -141,6 +141,21 @@ DeviceHandler::DeviceHandler(QObject *parent) : returns.insert("o:deviceDescriptors", deviceDescriptors); setReturns("GetDiscoveredDevices", returns); + params.clear(); returns.clear(); + setDescription("EditDevice", "Edit the parameters of a device. The device params will be set to the " + "passed parameters and the setup device will be called. If the device is discoverable, " + "you can perform a GetDiscoveredDevices before calling this method and pass " + "the new DeviceDescriptor (rediscover). If a parameter is not editable, you will find a " + "'editable': false in the ParamType. By default, every Param is editable."); + params.insert("deviceId", JsonTypes::basicTypeToString(JsonTypes::Uuid)); + params.insert("o:deviceDescriptorId", JsonTypes::basicTypeToString(JsonTypes::Uuid)); + QVariantList newDeviceParams; + newDeviceParams.append(JsonTypes::paramRef()); + params.insert("o:deviceParams", newDeviceParams); + setParams("EditDevice", params); + returns.insert("deviceError", JsonTypes::deviceErrorRef()); + setReturns("EditDevice", returns); + params.clear(); returns.clear(); setDescription("RemoveConfiguredDevice", "Remove a device from the system."); params.insert("deviceId", JsonTypes::basicTypeToString(JsonTypes::Uuid)); @@ -226,6 +241,7 @@ DeviceHandler::DeviceHandler(QObject *parent) : connect(GuhCore::instance(), &GuhCore::deviceAdded, this, &DeviceHandler::deviceAddedNotification); connect(GuhCore::instance(), &GuhCore::devicesDiscovered, this, &DeviceHandler::devicesDiscovered, Qt::QueuedConnection); connect(GuhCore::instance(), &GuhCore::deviceSetupFinished, this, &DeviceHandler::deviceSetupFinished); + connect(GuhCore::instance(), &GuhCore::deviceEditFinished, this, &DeviceHandler::deviceEditFinished); connect(GuhCore::instance(), &GuhCore::pairingFinished, this, &DeviceHandler::pairingFinished); } @@ -417,6 +433,31 @@ JsonReply* DeviceHandler::GetConfiguredDevices(const QVariantMap ¶ms) const return createReply(returns); } +JsonReply *DeviceHandler::EditDevice(const QVariantMap ¶ms) +{ + Q_UNUSED(params); + DeviceId deviceId = DeviceId(params.value("deviceId").toString()); + ParamList deviceParams = JsonTypes::unpackParams(params.value("deviceParams").toList()); + + DeviceManager::DeviceError status = GuhCore::instance()->editDevice(deviceId, deviceParams); + + // if (deviceDescriptorId.isNull()) { + // status = GuhCore::instance()->addConfiguredDevice(deviceClass, deviceParams, newDeviceId); + // } else { + // status = GuhCore::instance()->addConfiguredDevice(deviceClass, deviceDescriptorId, newDeviceId); + // } + + if (status == DeviceManager::DeviceErrorAsync) { + JsonReply *asyncReply = createAsyncReply("EditDevice"); + m_asynDeviceEditAdditions.insert(deviceId, asyncReply); + return asyncReply; + } + + QVariantMap returns; + returns.insert("deviceError", JsonTypes::deviceErrorToString(status)); + return createReply(returns); +} + JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap ¶ms) { DeviceId deviceId = DeviceId(params.value("deviceId").toString()); @@ -581,6 +622,21 @@ void DeviceHandler::deviceSetupFinished(Device *device, DeviceManager::DeviceErr } reply->setData(returns); reply->finished(); + +} + +void DeviceHandler::deviceEditFinished(Device *device, DeviceManager::DeviceError status) +{ + qDebug() << "got async edit finished"; + if (!m_asynDeviceEditAdditions.contains(device->id())) { + return; + } + JsonReply *reply = m_asynDeviceEditAdditions.take(device->id()); + + QVariantMap returns; + returns.insert("deviceError", JsonTypes::deviceErrorToString(status)); + reply->setData(returns); + reply->finished(); } void DeviceHandler::pairingFinished(const PairingTransactionId &pairingTransactionId, DeviceManager::DeviceError status, const DeviceId &deviceId) diff --git a/server/jsonrpc/devicehandler.h b/server/jsonrpc/devicehandler.h index 11253325..2592a23b 100644 --- a/server/jsonrpc/devicehandler.h +++ b/server/jsonrpc/devicehandler.h @@ -53,6 +53,8 @@ public: Q_INVOKABLE JsonReply* GetConfiguredDevices(const QVariantMap ¶ms) const; + Q_INVOKABLE JsonReply* EditDevice(const QVariantMap ¶ms); + Q_INVOKABLE JsonReply* RemoveConfiguredDevice(const QVariantMap ¶ms); Q_INVOKABLE JsonReply* GetEventTypes(const QVariantMap ¶ms) const; @@ -81,12 +83,15 @@ private slots: void deviceSetupFinished(Device *device, DeviceManager::DeviceError status); + void deviceEditFinished(Device *device, DeviceManager::DeviceError status); + void pairingFinished(const PairingTransactionId &pairingTransactionId, DeviceManager::DeviceError status, const DeviceId &deviceId); private: // A cache for async replies mutable QHash m_discoverRequests; mutable QHash m_asynDeviceAdditions; + mutable QHash m_asynDeviceEditAdditions; mutable QHash m_asyncPairingRequests; }; diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index 7d918585..fe1c945f 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -94,6 +94,7 @@ void JsonTypes::init() s_paramType.insert("o:maxValue", basicTypeToString(Variant)); s_paramType.insert("o:allowedValues", QVariantList() << basicTypeToString(Variant)); s_paramType.insert("o:inputType", inputTypeRef()); + s_paramType.insert("o:editable", basicTypeToString(Bool)); // Param s_param.insert("name", basicTypeToString(String)); @@ -430,6 +431,7 @@ QVariantMap JsonTypes::packParamType(const ParamType ¶mType) QVariantMap variantMap; variantMap.insert("name", paramType.name()); variantMap.insert("type", QVariant::typeToName(paramType.type())); + // optional if (paramType.defaultValue().isValid()) { variantMap.insert("defaultValue", paramType.defaultValue()); } @@ -445,6 +447,10 @@ QVariantMap JsonTypes::packParamType(const ParamType ¶mType) if (paramType.inputType() != Types::InputTypeNone) { variantMap.insert("inputType", s_inputType.at(paramType.inputType())); } + // only add if this param is NOT ediable + if (!paramType.editable()) { + variantMap.insert("editable", paramType.editable()); + } return variantMap; } diff --git a/tests/auto/devices/testdevices.cpp b/tests/auto/devices/testdevices.cpp index 491b9c19..d9144073 100644 --- a/tests/auto/devices/testdevices.cpp +++ b/tests/auto/devices/testdevices.cpp @@ -70,6 +70,9 @@ private slots: void getStateValues_data(); void getStateValues(); + void editDevices_data(); + void editDevices(); + // Keep this the last one! It'll remove the configured mock device void removeDevice_data(); void removeDevice(); @@ -513,6 +516,122 @@ void TestDevices::getStateValues() } } +void TestDevices::editDevices_data() +{ + QVariantList asyncChangeDeviceParams; + QVariantMap asyncParamDifferent; + asyncParamDifferent.insert("name", "async"); + asyncParamDifferent.insert("value", true); + asyncChangeDeviceParams.append(asyncParamDifferent); + + QVariantList httpportChangeDeviceParams; + QVariantMap httpportParamDifferent; + httpportParamDifferent.insert("name", "httpport"); + httpportParamDifferent.insert("value", 666); + httpportChangeDeviceParams.append(httpportParamDifferent); + + QVariantList brokenChangedDeviceParams; + QVariantMap brokenParamDifferent; + brokenParamDifferent.insert("name", "broken"); + brokenParamDifferent.insert("value", true); + brokenChangedDeviceParams.append(brokenParamDifferent); + + QVariantList asyncAndPortChangeDeviceParams; + asyncAndPortChangeDeviceParams.append(asyncParamDifferent); + asyncAndPortChangeDeviceParams.append(httpportParamDifferent); + + QVariantList changeAllDeviceParams; + changeAllDeviceParams.append(asyncParamDifferent); + changeAllDeviceParams.append(httpportParamDifferent); + changeAllDeviceParams.append(brokenParamDifferent); + + + QTest::addColumn("newDeviceParams"); + QTest::addColumn("deviceError"); + + QTest::newRow("valid - change async param") << asyncChangeDeviceParams << DeviceManager::DeviceErrorNoError; + QTest::newRow("valid - change httpport param") << httpportChangeDeviceParams << DeviceManager::DeviceErrorNoError; + QTest::newRow("valid - change httpport and async param") << asyncAndPortChangeDeviceParams << DeviceManager::DeviceErrorNoError; + QTest::newRow("invalid - change broken param (not editable)") << brokenChangedDeviceParams << DeviceManager::DeviceErrorParameterNotEditable; + QTest::newRow("invalid - change all params (also the not editable one)") << changeAllDeviceParams << DeviceManager::DeviceErrorParameterNotEditable; +} + +void TestDevices::editDevices() +{ + QFETCH(QVariantList, newDeviceParams); + QFETCH(DeviceManager::DeviceError, deviceError); + + // add device + QVariantMap params; + params.insert("deviceClassId", mockDeviceClassId); + QVariantList deviceParams; + QVariantMap asyncParam; + asyncParam.insert("name", "async"); + asyncParam.insert("value", false); + deviceParams.append(asyncParam); + QVariantMap brokenParam; + brokenParam.insert("name", "broken"); + brokenParam.insert("value", false); + deviceParams.append(brokenParam); + QVariantMap httpportParam; + httpportParam.insert("name", "httpport"); + httpportParam.insert("value", 8890); + deviceParams.append(httpportParam); + params.insert("deviceParams", deviceParams); + QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); + verifyDeviceError(response); + + // now edit the added device + DeviceId deviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); + QVERIFY(!deviceId.isNull()); + + QVariantMap editParams; + editParams.insert("deviceId", deviceId); + editParams.insert("deviceParams", newDeviceParams); + + response.clear(); + response = injectAndWait("Devices.EditDevice", editParams); + verifyDeviceError(response, deviceError); + + if (deviceError != DeviceManager::DeviceErrorNoError) { + params.clear(); + params.insert("deviceId", deviceId); + response.clear(); + response = injectAndWait("Devices.RemoveConfiguredDevice", params); + verifyDeviceError(response); + return; + } + + // Restart the core instance to check if settings are loaded at startup + restartServer(); + + response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); + + bool found = false; + foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { + if (DeviceId(device.toMap().value("id").toString()) == deviceId) { + qDebug() << "found added device" << device.toMap().value("params"); + + foreach (QVariant newParam, newDeviceParams) { + foreach (QVariant deviceParam, device.toMap().value("params").toList()) { + if (newParam.toMap().value("name").toString() == deviceParam.toMap().value("name").toString()) { + QCOMPARE(newParam.toMap().value("value"), deviceParam.toMap().value("value")); + } + } + } + found = true; + break; + } + } + QVERIFY2(found, "Device missing in config!"); + + params.clear(); + params.insert("deviceId", deviceId); + response = injectAndWait("Devices.RemoveConfiguredDevice", params); + verifyDeviceError(response); +} + + void TestDevices::removeDevice_data() { QTest::addColumn("deviceId");