diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index dfe24574..829c702e 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -167,7 +167,7 @@ DeviceManager::DeviceError DeviceManager::discoverDevices(const DeviceClassId &d Optionally you can supply an id yourself if you must keep track of the added device. If you don't supply it, a new one will be generated. */ -DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const DeviceClassId &deviceClassId, const QVariantMap ¶ms, const DeviceId id) +DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const DeviceClassId &deviceClassId, const QList ¶ms, const DeviceId id) { DeviceClass deviceClass = findDeviceClass(deviceClassId); if (!deviceClass.isValid()) { @@ -198,7 +198,7 @@ DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const DeviceClassI return addConfiguredDeviceInternal(deviceClassId, descriptor.params(), deviceId); } -DeviceManager::DeviceError DeviceManager::addConfiguredDeviceInternal(const DeviceClassId &deviceClassId, const QVariantMap ¶ms, const DeviceId id) +DeviceManager::DeviceError DeviceManager::addConfiguredDeviceInternal(const DeviceClassId &deviceClassId, const QList ¶ms, const DeviceId id) { DeviceClass deviceClass = findDeviceClass(deviceClassId); if (deviceClass.id().isNull()) { @@ -207,18 +207,24 @@ DeviceManager::DeviceError DeviceManager::addConfiguredDeviceInternal(const Devi } // Make sure we have all required params - foreach (const QVariant ¶m, deviceClass.params()) { - if (!params.contains(param.toMap().value("name").toString())) { - qWarning() << "Missing parameter when creating device:" << param.toMap().value("name").toString(); + foreach (const ParamType ¶mType, deviceClass.params()) { + bool found = false; + foreach (const Param ¶m, params) { + if (param.name() == paramType.name()) { + found = true; + } + } + + if (!found) { + qWarning() << "Missing parameter when creating device:" << paramType.name(); return DeviceErrorMissingParameter; } } // Make sure we don't have unused params - foreach (const QString ¶mId, params.keys()) { - qDebug() << "searching" << paramId << "in" << deviceClass.params(); + foreach (const Param ¶m, params) { bool found = false; - foreach (const QVariant ¶m, deviceClass.params()) { - if (param.toMap().value("name").toString() == paramId) { + foreach (const ParamType ¶mType, deviceClass.params()) { + if (paramType.name() == param.name()) { found = true; continue; } @@ -399,7 +405,17 @@ void DeviceManager::loadConfiguredDevices() settings.beginGroup(idString); Device *device = new Device(PluginId(settings.value("pluginid").toString()), DeviceId(idString), DeviceClassId(settings.value("deviceClassId").toString()), this); device->setName(settings.value("devicename").toString()); - device->setParams(settings.value("params").toMap()); + + QList params; + foreach (QString paramNameString, settings.childGroups()) { + settings.beginGroup(paramNameString); + Param param(paramNameString.remove(QRegExp("^Param-"))); + param.setValue(settings.value("value")); + param.setOperand((Param::OperandType)settings.value("operand").toInt()); + settings.endGroup(); + } + device->setParams(params); + settings.endGroup(); setupDevice(device); @@ -417,7 +433,12 @@ void DeviceManager::storeConfiguredDevices() settings.setValue("devicename", device->name()); settings.setValue("deviceClassId", device->deviceClassId().toString()); settings.setValue("pluginid", device->pluginId()); - settings.setValue("params", device->params()); + foreach (const Param ¶m, device->params()) { + settings.beginGroup("Param-" + param.name()); + settings.setValue("value", param.value()); + settings.setValue("operand", param.operand()); + settings.endGroup(); + } settings.endGroup(); } } diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index f0aea7f4..68cfd97e 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -72,7 +72,7 @@ public: DeviceError discoverDevices(const DeviceClassId &deviceClassId, const QVariantMap ¶ms) const; QList configuredDevices() const; - DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const QVariantMap ¶ms, const DeviceId id = DeviceId::createDeviceId()); + DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const QList ¶ms, const DeviceId id = DeviceId::createDeviceId()); DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId, const DeviceId &id = DeviceId::createDeviceId()); DeviceError removeConfiguredDevice(const DeviceId &deviceId); @@ -103,7 +103,7 @@ private slots: void timerEvent(); private: - DeviceError addConfiguredDeviceInternal(const DeviceClassId &deviceClassId, const QVariantMap ¶ms, const DeviceId id = DeviceId::createDeviceId()); + DeviceError addConfiguredDeviceInternal(const DeviceClassId &deviceClassId, const QList ¶ms, const DeviceId id = DeviceId::createDeviceId()); bool setupDevice(Device *device); QHash m_supportedVendors; diff --git a/libguh/libguh.pro b/libguh/libguh.pro index 241fb8ab..bd873d29 100644 --- a/libguh/libguh.pro +++ b/libguh/libguh.pro @@ -20,6 +20,8 @@ SOURCES += plugin/device.cpp \ types/eventtype.cpp \ types/event.cpp \ types/vendor.cpp \ + types/paramtype.cpp \ + types/param.cpp HEADERS += plugin/device.h \ plugin/deviceclass.h \ @@ -36,4 +38,6 @@ HEADERS += plugin/device.h \ types/event.h \ types/vendor.h \ types/typeutils.h \ + types/paramtype.h \ + types/param.h diff --git a/libguh/plugin/device.cpp b/libguh/plugin/device.cpp index 03695ce2..6b9d7319 100644 --- a/libguh/plugin/device.cpp +++ b/libguh/plugin/device.cpp @@ -82,23 +82,43 @@ void Device::setName(const QString &name) } /*! Returns the parameter of this Device. It must match the parameter description in the associated \l{DeviceClass}. */ -QVariantMap Device::params() const +QList Device::params() const { return m_params; } /*! Sets the \a params of this Device. It must match the parameter description in the associated \l{DeviceClass}. */ -void Device::setParams(const QVariantMap ¶ms) +void Device::setParams(const QList ¶ms) { m_params = params; } +QVariant Device::paramValue(const QString ¶mName) const +{ + foreach (const Param ¶m, m_params) { + if (param.name() == paramName) { + return param.value(); + } + } + return QVariant(); +} + /*! Returns the states of this Device. It must match the \l{StateType} description in the associated \l{DeviceClass}. */ QList Device::states() const { return m_states; } +bool Device::hasParam(const QString ¶mName) const +{ + foreach (const Param ¶m, m_params) { + if (param.name() == paramName) { + return true; + } + } + return false; +} + /*! Sets the \a states of this Device. It must match the \l{StateType} description in the associated \l{DeviceClass}. */ void Device::setStates(const QList &states) { diff --git a/libguh/plugin/device.h b/libguh/plugin/device.h index 68779fa6..02aa6d29 100644 --- a/libguh/plugin/device.h +++ b/libguh/plugin/device.h @@ -23,6 +23,7 @@ #include "plugin/deviceclass.h" #include "types/state.h" +#include "types/param.h" #include #include @@ -43,10 +44,13 @@ public: QString name() const; void setName(const QString &name); - QVariantMap params() const; - void setParams(const QVariantMap ¶ms); + QList params() const; + void setParams(const QList ¶ms); + + QVariant paramValue(const QString ¶mName) const; QList states() const; + bool hasParam(const QString ¶mName) const; void setStates(const QList &states); bool hasState(const StateTypeId &stateTypeId) const; @@ -65,7 +69,7 @@ private: DeviceClassId m_deviceClassId; PluginId m_pluginId; QString m_name; - QVariantMap m_params; + QList m_params; QList m_states; }; diff --git a/libguh/plugin/deviceclass.cpp b/libguh/plugin/deviceclass.cpp index 0f591d04..a558cf4a 100644 --- a/libguh/plugin/deviceclass.cpp +++ b/libguh/plugin/deviceclass.cpp @@ -129,14 +129,14 @@ void DeviceClass::setActions(const QList &actionTypes) /*! Returns the params description of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their params matching to this template. */ -QVariantList DeviceClass::params() const +QList DeviceClass::params() const { return m_params; } /*! Set the \a params of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their actions matching to this template. */ -void DeviceClass::setParams(const QVariantList ¶ms) +void DeviceClass::setParams(const QList ¶ms) { m_params = params; } diff --git a/libguh/plugin/deviceclass.h b/libguh/plugin/deviceclass.h index 11fccfc5..b74b81c1 100644 --- a/libguh/plugin/deviceclass.h +++ b/libguh/plugin/deviceclass.h @@ -24,6 +24,7 @@ #include "types/eventtype.h" #include "types/actiontype.h" #include "types/statetype.h" +#include "types/paramtype.h" #include #include @@ -62,8 +63,8 @@ public: QList actions() const; void setActions(const QList &actionTypes); - QVariantList params() const; - void setParams(const QVariantList ¶ms); + QList params() const; + void setParams(const QList ¶ms); CreateMethod createMethod() const; void setCreateMethod(CreateMethod createMethod); @@ -80,7 +81,7 @@ private: QList m_states; QList m_events; QList m_actions; - QVariantList m_params; + QList m_params; CreateMethod m_createMethod; SetupMethod m_setupMethod; }; diff --git a/libguh/plugin/devicedescriptor.cpp b/libguh/plugin/devicedescriptor.cpp index 34bd3a86..b65de7a0 100644 --- a/libguh/plugin/devicedescriptor.cpp +++ b/libguh/plugin/devicedescriptor.cpp @@ -58,12 +58,12 @@ void DeviceDescriptor::setDescription(const QString &description) m_description = description; } -QVariantMap DeviceDescriptor::params() const +QList DeviceDescriptor::params() const { return m_params; } -void DeviceDescriptor::setParams(const QVariantMap ¶ms) +void DeviceDescriptor::setParams(const QList ¶ms) { m_params = params; } diff --git a/libguh/plugin/devicedescriptor.h b/libguh/plugin/devicedescriptor.h index ab239d7b..3aa8ef7b 100644 --- a/libguh/plugin/devicedescriptor.h +++ b/libguh/plugin/devicedescriptor.h @@ -2,6 +2,7 @@ #define DEVICEDESCRIPTION_H #include +#include #include @@ -23,15 +24,15 @@ public: QString description() const; void setDescription(const QString &description); - QVariantMap params() const; - void setParams(const QVariantMap ¶ms); + QList params() const; + void setParams(const QList ¶ms); private: DeviceDescriptorId m_id; DeviceClassId m_deviceClassId; QString m_title; QString m_description; - QVariantMap m_params; + QList m_params; }; #endif // DEVICEDESCRIPTION_H diff --git a/libguh/plugin/deviceplugin.cpp b/libguh/plugin/deviceplugin.cpp index 92fea89f..4c4829f1 100644 --- a/libguh/plugin/deviceplugin.cpp +++ b/libguh/plugin/deviceplugin.cpp @@ -216,12 +216,12 @@ QList DevicePlugin::myDevices() const Find a certain device from myDevices() by its params. All parameters must match or the device will not be found. Be prepared for nullptrs. */ -Device *DevicePlugin::findDeviceByParams(const QVariantMap ¶ms) const +Device *DevicePlugin::findDeviceByParams(const QList ¶ms) const { foreach (Device *device, myDevices()) { bool matching = true; - foreach (const QString ¶mName, device->params().keys()) { - if (device->params().value(paramName) == params.value(paramName)) { + foreach (const Param ¶m, params) { + if (device->paramValue(param.name()) == param.value()) { return device; } } diff --git a/libguh/plugin/deviceplugin.h b/libguh/plugin/deviceplugin.h index 1890e125..a001aaba 100644 --- a/libguh/plugin/deviceplugin.h +++ b/libguh/plugin/deviceplugin.h @@ -74,7 +74,7 @@ signals: protected: DeviceManager *deviceManager() const; QList myDevices() const; - Device* findDeviceByParams(const QVariantMap ¶ms) const; + Device* findDeviceByParams(const QList ¶ms) const; void transmitData(QList rawData); diff --git a/libguh/types/action.cpp b/libguh/types/action.cpp index 89816918..68744958 100644 --- a/libguh/types/action.cpp +++ b/libguh/types/action.cpp @@ -58,13 +58,23 @@ DeviceId Action::deviceId() const } /*! Returns the parameters for this Action.*/ -QVariantMap Action::params() const +QList Action::params() const { return m_params; } /*! Set the the parameters for this Action. \a params must match the template in the \l{ActionType} referred by \l{Action::actionTypeId()}*/ -void Action::setParams(const QVariantMap ¶ms) +void Action::setParams(const QList ¶ms) { m_params = params; } + +Param Action::param(const QString ¶mName) const +{ + foreach (const Param ¶m, m_params) { + if (param.name() == paramName) { + return param; + } + } + return Param(QString()); +} diff --git a/libguh/types/action.h b/libguh/types/action.h index 28a0cd4c..cfed1194 100644 --- a/libguh/types/action.h +++ b/libguh/types/action.h @@ -20,6 +20,7 @@ #define ACTION_H #include "typeutils.h" +#include "param.h" #include @@ -33,13 +34,14 @@ public: ActionTypeId actionTypeId() const; DeviceId deviceId() const; - QVariantMap params() const; - void setParams(const QVariantMap ¶ms); + QList params() const; + void setParams(const QList ¶ms); + Param param(const QString ¶mName) const; private: ActionTypeId m_actionTypeId; DeviceId m_deviceId; - QVariantMap m_params; + QList m_params; }; #endif // ACTION_H diff --git a/libguh/types/event.cpp b/libguh/types/event.cpp index 76a68914..f7031bb0 100644 --- a/libguh/types/event.cpp +++ b/libguh/types/event.cpp @@ -36,7 +36,7 @@ /*! Constructs a Event reflecting the \l{Event} given by \a EventTypeId, associated with the \l{Device} given by \a deviceId and the parameters given by \a params. The parameters must match the description in the reflecting \l{Event}.*/ -Event::Event(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QVariantMap ¶ms): +Event::Event(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList ¶ms): m_eventTypeId(eventTypeId), m_deviceId(deviceId), m_params(params) @@ -56,31 +56,43 @@ DeviceId Event::deviceId() const } /*! Returns the parameters of this Event.*/ -QVariantMap Event::params() const +QList Event::params() const { return m_params; } /*! Set the parameters of this Event to \a params.*/ -void Event::setParams(const QVariantMap ¶ms) +void Event::setParams(const QList ¶ms) { m_params = params; } +Param Event::param(const QString ¶mName) const +{ + foreach (const Param ¶m, m_params) { + if (param.name() == paramName) { + return param; + } + } + return Param(QString()); +} + /*! Compare this Event to the Event given by \a other. Events are equal (returns true) if eventTypeId, deviceId and params match. */ bool Event::operator ==(const Event &other) const { - - bool result =m_eventTypeId == other.eventTypeId() - && m_deviceId == other.deviceId() - && m_params == other.params(); - - qDebug() << "comparing event" << *this << "with" << other << "result is" << result << "params" << m_params << "other" << other.params(); + bool paramsMatch = true; + foreach (const Param &otherParam, other.params()) { + Param param = this->param(otherParam.name()); + if (!param.isValid() || param.value() != otherParam.value()) { + paramsMatch = false; + break; + } + } return m_eventTypeId == other.eventTypeId() && m_deviceId == other.deviceId() - && m_params == other.params(); + && paramsMatch; } QDebug operator<<(QDebug dbg, const Event &event) diff --git a/libguh/types/event.h b/libguh/types/event.h index ac79a953..c85fc775 100644 --- a/libguh/types/event.h +++ b/libguh/types/event.h @@ -20,6 +20,7 @@ #define EVENT_H #include "typeutils.h" +#include "types/param.h" #include #include @@ -28,20 +29,21 @@ class Event { public: - Event(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QVariantMap ¶ms); + Event(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList ¶ms = QList()); EventTypeId eventTypeId() const; DeviceId deviceId() const; - QVariantMap params() const; - void setParams(const QVariantMap ¶ms); + QList params() const; + void setParams(const QList ¶ms); + Param param(const QString ¶mName) const; bool operator ==(const Event &other) const; private: EventTypeId m_eventTypeId; DeviceId m_deviceId; - QVariantMap m_params; + QList m_params; }; QDebug operator<<(QDebug dbg, const Event &event); QDebug operator<<(QDebug dbg, const QList &events); diff --git a/libguh/types/param.cpp b/libguh/types/param.cpp new file mode 100644 index 00000000..41318cde --- /dev/null +++ b/libguh/types/param.cpp @@ -0,0 +1,62 @@ +#include "param.h" + +#include + +Param::Param(const QString &name, const QVariant &value): + m_name (name), + m_value(value), + m_operand(OperandTypeEquals) +{ +} + +QString Param::name() const +{ + return m_name; +} + +void Param::setName(const QString &name) +{ + m_name = name; +} + +QVariant Param::value() const +{ + return m_value; +} + +void Param::setValue(const QVariant &value) +{ + m_value = value; +} + +Param::OperandType Param::operand() const +{ + return m_operand; +} + +void Param::setOperand(Param::OperandType operand) +{ + m_operand = operand; +} + +bool Param::isValid() const +{ + return !m_name.isEmpty() && m_value.isValid(); +} + +QDebug operator<<(QDebug dbg, const Param ¶m) +{ + dbg.nospace() << "Param(Name: " << param.name() << ", Value:" << param.value() << ")"; + + return dbg.space(); +} + +QDebug operator<<(QDebug dbg, const QList ¶ms) +{ + dbg.nospace() << "ParamList (count:" << params.count() << ")"; + for (int i = 0; i < params.count(); i++ ) { + dbg.nospace() << " " << i << ": " << params.at(i); + } + + return dbg.space(); +} diff --git a/libguh/types/param.h b/libguh/types/param.h new file mode 100644 index 00000000..743c7a20 --- /dev/null +++ b/libguh/types/param.h @@ -0,0 +1,41 @@ +#ifndef PARAM_H +#define PARAM_H + +#include +#include + +class Param +{ +public: + enum OperandType { + OperandTypeEquals, + OperandTypeNotEquals, + OperandTypeLess, + OperandTypeGreater, + OperandTypeLessThan, + OperandTypeGreaterThan + }; + + Param(const QString &name, const QVariant &value = QVariant()); + + QString name() const; + void setName(const QString &name); + + QVariant value() const; + void setValue(const QVariant &value); + + OperandType operand() const; + void setOperand(OperandType operand); + + bool isValid() const; + +private: + QString m_name; + QVariant m_value; + OperandType m_operand; +}; + +QDebug operator<<(QDebug dbg, const Param ¶m); +QDebug operator<<(QDebug dbg, const QList ¶ms); + +#endif // PARAM_H diff --git a/libguh/types/paramtype.cpp b/libguh/types/paramtype.cpp new file mode 100644 index 00000000..bee8493a --- /dev/null +++ b/libguh/types/paramtype.cpp @@ -0,0 +1,58 @@ +#include "paramtype.h" + +ParamType::ParamType(const QString &name, const QVariant::Type type, const QVariant &defaultValue): + m_name(name), + m_type(type), + m_defaultValue(defaultValue) +{ +} + +QString ParamType::name() const +{ + return m_name; +} + +void ParamType::setName(const QString &name) +{ + m_name = name; +} + +QVariant::Type ParamType::type() const +{ + return m_type; +} + +void ParamType::setType(QVariant::Type type) +{ + m_type = type; +} + +QVariant ParamType::defaultValue() const +{ + return m_defaultValue; +} + +void ParamType::setDefaultValue(const QVariant &defaultValue) +{ + m_defaultValue = defaultValue; +} + +QVariant ParamType::minValue() const +{ + return m_minValue; +} + +void ParamType::setMinValue(const QVariant &minValue) +{ + m_minValue = minValue; +} + +QVariant ParamType::maxValue() const +{ + return m_maxValue; +} + +void ParamType::setMaxValue(const QVariant &maxValue) +{ + m_maxValue = maxValue; +} diff --git a/libguh/types/paramtype.h b/libguh/types/paramtype.h new file mode 100644 index 00000000..a15b1482 --- /dev/null +++ b/libguh/types/paramtype.h @@ -0,0 +1,34 @@ +#ifndef PARAMTYPE_H +#define PARAMTYPE_H + +#include + +class ParamType +{ +public: + ParamType(const QString &name, const QVariant::Type type, const QVariant &defaultValue = QVariant()); + + QString name() const; + void setName(const QString &name); + + QVariant::Type type() const; + void setType(QVariant::Type type); + + QVariant defaultValue() const; + void setDefaultValue(const QVariant &defaultValue); + + QVariant minValue() const; + void setMinValue(const QVariant &minValue); + + QVariant maxValue() const; + void setMaxValue(const QVariant &maxValue); + +private: + QString m_name; + QVariant::Type m_type; + QVariant m_defaultValue; + QVariant m_minValue; + QVariant m_maxValue; +}; + +#endif // PARAMTYPE_H diff --git a/libguh/typeutils.h b/libguh/typeutils.h index fd24dace..1e559128 100644 --- a/libguh/typeutils.h +++ b/libguh/typeutils.h @@ -28,14 +28,4 @@ DECLARE_TYPE_ID(StateType) DECLARE_TYPE_ID(ActionType) DECLARE_TYPE_ID(Plugin) - -enum ParamOperand { - ParamOperandEquals, - ParamOperandNotEquals, - ParamOperandLess, - ParamOperandGreater, - ParamOperandLessThan, - ParamOperandGreaterThan -}; - #endif // TYPEUTILS_H diff --git a/plugins/deviceplugins/boblight/devicepluginboblight.cpp b/plugins/deviceplugins/boblight/devicepluginboblight.cpp index 9a897918..efb38730 100644 --- a/plugins/deviceplugins/boblight/devicepluginboblight.cpp +++ b/plugins/deviceplugins/boblight/devicepluginboblight.cpp @@ -85,8 +85,10 @@ bool DevicePluginBoblight::configureAutoDevice(QList loadedDevices, De if (loadedDevices.count() < m_bobClient->lightsCount()) { int index = loadedDevices.count(); device->setName("Boblight Channel " + QString::number(index)); - QVariantMap params; - params.insert("channel", index); + QList params; + Param param("channel"); + param.setValue(index); + params.append(param); device->setParams(params); device->setStateValue(colorStateTypeId, m_bobClient->currentColor(index)); return true; @@ -120,12 +122,12 @@ DeviceManager::DeviceError DevicePluginBoblight::executeAction(Device *device, c if (!m_bobClient->connected()) { return DeviceManager::DeviceErrorSetupFailed; } - QColor newColor = action.params().first().value(); + QColor newColor = action.param("color").value().value(); if (!newColor.isValid()) { return DeviceManager::DeviceErrorActionParameterError; } qDebug() << "executing boblight action" << newColor; - m_bobClient->setColor(device->params().value("channel").toInt(), newColor); + m_bobClient->setColor(device->paramValue("channel").toInt(), newColor); m_bobClient->sync(); device->setStateValue(colorStateTypeId, newColor); diff --git a/plugins/deviceplugins/elro/devicepluginelro.cpp b/plugins/deviceplugins/elro/devicepluginelro.cpp index 27af620d..eab97e14 100644 --- a/plugins/deviceplugins/elro/devicepluginelro.cpp +++ b/plugins/deviceplugins/elro/devicepluginelro.cpp @@ -91,22 +91,16 @@ QList DevicePluginElro::supportedDevices() const DeviceClass deviceClassElroRemote(pluginId(), elroVendorId, elroRemoteId); deviceClassElroRemote.setName("Elro Remote"); - QVariantList deviceParamsRemote; - QVariantMap channelParam; - channelParam.insert("name", "channel1"); - channelParam.insert("type", "bool"); + QList deviceParamsRemote; + ParamType channelParam = ParamType("channel1", QVariant::Bool); deviceParamsRemote.append(channelParam); - channelParam.insert("name", "channel2"); - channelParam.insert("type", "bool"); + channelParam = ParamType("channel2", QVariant::Bool); deviceParamsRemote.append(channelParam); - channelParam.insert("name", "channel3"); - channelParam.insert("type", "bool"); + channelParam = ParamType("channel3", QVariant::Bool); deviceParamsRemote.append(channelParam); - channelParam.insert("name", "channel4"); - channelParam.insert("type", "bool"); + channelParam = ParamType("channel4", QVariant::Bool); deviceParamsRemote.append(channelParam); - channelParam.insert("name", "channel5"); - channelParam.insert("type", "bool"); + channelParam = ParamType("channel5", QVariant::Bool); deviceParamsRemote.append(channelParam); deviceClassElroRemote.setParams(deviceParamsRemote); @@ -152,37 +146,26 @@ QList DevicePluginElro::supportedDevices() const DeviceClass deviceClassElroSwitch(pluginId(), elroVendorId, elroSwitchId); deviceClassElroSwitch.setName("Elro Power Switch"); - QVariantList deviceParamsSwitch; - QVariantMap paramSwitch; - paramSwitch.insert("name", "channel1"); - paramSwitch.insert("type", "bool"); + QList deviceParamsSwitch; + ParamType paramSwitch = ParamType("channel1", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "channel2"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel2", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "channel3"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel3", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "channel4"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel4", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "channel5"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel5", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "A"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel6", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "B"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel7", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "C"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel8", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "D"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel9", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - paramSwitch.insert("name", "E"); - paramSwitch.insert("type", "bool"); + paramSwitch = ParamType("channel10", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); deviceClassElroSwitch.setParams(deviceParamsSwitch); @@ -230,27 +213,27 @@ DeviceManager::DeviceError DevicePluginElro::executeAction(Device *device, const // ======================================= // create the bincode // channels - if(device->params().value("channel1").toBool()){ + if(device->paramValue("channel1").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } - if(device->params().value("channel2").toBool()){ + if(device->paramValue("channel2").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } - if(device->params().value("channel3").toBool()){ + if(device->paramValue("channel3").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } - if(device->params().value("channel4").toBool()){ + if(device->paramValue("channel4").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } - if(device->params().value("channel5").toBool()){ + if(device->paramValue("channel5").toBool()){ binCode.append("00"); }else{ binCode.append("01"); @@ -258,33 +241,33 @@ DeviceManager::DeviceError DevicePluginElro::executeAction(Device *device, const // ======================================= // Buttons - if(device->params().value("A").toBool()){ + if(device->paramValue("A").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } - if(device->params().value("B").toBool()){ + if(device->paramValue("B").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } - if(device->params().value("C").toBool()){ + if(device->paramValue("C").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } - if(device->params().value("D").toBool()){ + if(device->paramValue("D").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } - if(device->params().value("E").toBool()){ + if(device->paramValue("E").toBool()){ binCode.append("00"); }else{ binCode.append("01"); } // Power - if(action.params().value("power").toBool()){ + if(action.param("power").value().toBool()){ binCode.append("0001"); }else{ binCode.append("0100"); @@ -312,7 +295,7 @@ DeviceManager::DeviceError DevicePluginElro::executeAction(Device *device, const // ======================================= // send data to driver //qDebug() << "rawData" << rawData; - qDebug() << "transmit" << pluginName() << action.params().value("power").toBool(); + qDebug() << "transmit" << pluginName() << action.param("power").value().toBool(); transmitData(rawData); return DeviceManager::DeviceErrorNoError; } @@ -409,11 +392,11 @@ void DevicePluginElro::radioData(QList rawData) Device *device = 0; QList deviceList = deviceManager()->findConfiguredDevices(elroRemoteId); foreach (Device *dev, deviceList) { - if (dev->params().contains("channel1") && dev->params().value("channel1").toBool() == group.at(0) && - dev->params().contains("channel2") && dev->params().value("channel2").toBool() == group.at(1) && - dev->params().contains("channel3") && dev->params().value("channel3").toBool() == group.at(2) && - dev->params().contains("channel4") && dev->params().value("channel4").toBool() == group.at(3) && - dev->params().contains("channel5") && dev->params().value("channel5").toBool() == group.at(4) + if (dev->hasParam("channel1") && dev->paramValue("channel1").toBool() == group.at(0) && + dev->hasParam("channel2") && dev->paramValue("channel2").toBool() == group.at(1) && + dev->hasParam("channel3") && dev->paramValue("channel3").toBool() == group.at(2) && + dev->hasParam("channel4") && dev->paramValue("channel4").toBool() == group.at(3) && + dev->hasParam("channel5") && dev->paramValue("channel5").toBool() == group.at(4) ) { // Yippie! We found the device. device = dev; @@ -425,8 +408,9 @@ void DevicePluginElro::radioData(QList rawData) return; } - QVariantMap params; - params.insert("power", power); + QList params; + Param powerParam("power", power); + params.append(powerParam); // FIXME: find a better way to get to the remote DeviceClass DeviceClass deviceClass = supportedDevices().first(); diff --git a/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp b/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp index 8d7dff2b..bff211a0 100644 --- a/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp +++ b/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp @@ -189,11 +189,9 @@ QList DevicePluginIntertechno::supportedDevices() const DeviceClass deviceClassIntertechnoRemote(pluginId(), intertechnoVendorId, intertechnoRemote); deviceClassIntertechnoRemote.setName("Intertechno Remote"); - QVariantList remoteParams; - QVariantMap familyParam; + QList remoteParams; // family code = A-P - familyParam.insert("name", "familyCode"); - familyParam.insert("type", "string"); + ParamType familyParam("familyCode", QVariant::String); remoteParams.append(familyParam); deviceClassIntertechnoRemote.setParams(remoteParams); @@ -309,11 +307,9 @@ QList DevicePluginIntertechno::supportedDevices() const DeviceClass deviceClassIntertechnoSwitch(pluginId(), intertechnoVendorId, intertechnoSwitch); deviceClassIntertechnoSwitch.setName("Intertechno Switch"); - QVariantList switchDeviceParams; - QVariantMap buttonParam; + QList switchDeviceParams; // button code = 1-16 - buttonParam.insert("name", "buttonCode"); - buttonParam.insert("type", "int"); + ParamType buttonParam("buttonCode", QVariant::Int); switchDeviceParams.append(familyParam); switchDeviceParams.append(buttonParam); @@ -363,7 +359,7 @@ DeviceManager::DeviceError DevicePluginIntertechno::executeAction(Device *device QList rawData; QByteArray binCode; - QString familyCode = device->params().value("familyCode").toString(); + QString familyCode = device->paramValue("familyCode").toString(); // ======================================= // generate bin from family code @@ -403,7 +399,7 @@ DeviceManager::DeviceError DevicePluginIntertechno::executeAction(Device *device return DeviceManager::DeviceErrorDeviceParameterError; } - QString buttonCode = device->params().value("buttonCode").toString(); + QString buttonCode = device->paramValue("buttonCode").toString(); // ======================================= // generate bin from button code @@ -449,7 +445,7 @@ DeviceManager::DeviceError DevicePluginIntertechno::executeAction(Device *device // ======================================= // add power nibble - if(action.params().value("power").toBool()){ + if(action.param("power").value().toBool()){ binCode.append("0101"); }else{ binCode.append("0100"); @@ -476,7 +472,7 @@ DeviceManager::DeviceError DevicePluginIntertechno::executeAction(Device *device // ======================================= // send data to driver - qDebug() << "transmit" << pluginName() << familyCode << buttonCode << action.params().value("power").toBool(); + qDebug() << "transmit" << pluginName() << familyCode << buttonCode << action.param("power").value().toBool(); transmitData(rawData); return DeviceManager::DeviceErrorNoError; @@ -687,7 +683,7 @@ void DevicePluginIntertechno::radioData(QList rawData) // =================================================== Device *device = 0; foreach (Device *dev, deviceList) { - if (dev->params().contains("familyCode") && dev->params().value("familyCode").toString() == familyCode) { + if (dev->paramValue("familyCode").toString() == familyCode) { // Yippie! We found the device. device = dev; break; @@ -698,8 +694,9 @@ void DevicePluginIntertechno::radioData(QList rawData) return; } - QVariantMap params; - params.insert("power", power); + QList params; + Param powerParam("power", power); + params.append(powerParam); // FIXME: find a better way to get to the remote DeviceClass DeviceClass deviceClass = supportedDevices().first(); diff --git a/plugins/deviceplugins/lircd/devicepluginlircd.cpp b/plugins/deviceplugins/lircd/devicepluginlircd.cpp index 20cf462c..a9f6d5ad 100644 --- a/plugins/deviceplugins/lircd/devicepluginlircd.cpp +++ b/plugins/deviceplugins/lircd/devicepluginlircd.cpp @@ -37,10 +37,8 @@ QList DevicePluginLircd::supportedDevices() const DeviceClass deviceClassLircd(pluginId(), lircdVendorId, lircdDeviceClassId); deviceClassLircd.setName("IR Receiver"); - QVariantList params; - QVariantMap remoteNameParam; - remoteNameParam.insert("name", "remoteName"); - remoteNameParam.insert("type", "string"); + QList params; + ParamType remoteNameParam("remoteName", QVariant::String); params.append(remoteNameParam); deviceClassLircd.setParams(params); @@ -102,7 +100,7 @@ void DevicePluginLircd::buttonPressed(const QString &remoteName, const QString & Device *remote = nullptr; QList configuredRemotes = deviceManager()->findConfiguredDevices(lircdDeviceClassId); foreach (Device *device, configuredRemotes) { - if (device->params().value("remoteName").toString() == remoteName) { + if (device->paramValue("remoteName").toString() == remoteName) { remote = device; break; } @@ -115,9 +113,10 @@ void DevicePluginLircd::buttonPressed(const QString &remoteName, const QString & qDebug() << "found remote" << remoteName << supportedDevices().first().events().count(); foreach (const EventType &eventType, supportedDevices().first().events()) { if (eventType.name() == buttonName) { - QVariantMap param; - param.insert("repeat", repeat); - Event event(eventType.id(), remote->id(), param); + QList params; + Param param("repeat", repeat); + params.append(param); + Event event(eventType.id(), remote->id(), params); emitEvent(event); } } diff --git a/plugins/deviceplugins/mock/devicepluginmock.cpp b/plugins/deviceplugins/mock/devicepluginmock.cpp index 0401833e..33501d99 100644 --- a/plugins/deviceplugins/mock/devicepluginmock.cpp +++ b/plugins/deviceplugins/mock/devicepluginmock.cpp @@ -54,10 +54,8 @@ QList DevicePluginMock::supportedDevices() const DeviceClass deviceClassMock(pluginId(), guhVendorId, mockDeviceClassId); deviceClassMock.setName("Mock Device"); - QVariantList mockParams; - QVariantMap portParam; - portParam.insert("name", "httpport"); - portParam.insert("type", "int"); + QList mockParams; + ParamType portParam("httpport", QVariant::Int); mockParams.append(portParam); deviceClassMock.setParams(mockParams); @@ -137,7 +135,7 @@ PluginId DevicePluginMock::pluginId() const bool DevicePluginMock::deviceCreated(Device *device) { - qDebug() << "Mockdevice created returning true" << device->params().value("httpport").toInt(); + qDebug() << "Mockdevice created returning true" << device->paramValue("httpport").toInt(); HttpDaemon *daemon = new HttpDaemon(device, this); m_daemons.insert(device, daemon); @@ -169,8 +167,9 @@ bool DevicePluginMock::configureAutoDevice(QList loadedDevices, Device } device->setName("Mock Device (Auto created)"); - QVariantMap params; - params.insert("httpport", 4242); + QList params; + Param param("httpport", 4242); + params.append(param); device->setParams(params); return true; } @@ -202,7 +201,7 @@ void DevicePluginMock::triggerEvent(const EventTypeId &id) Device *device = m_daemons.key(daemon); - Event event(id, device->id(), QVariantMap()); + Event event(id, device->id()); qDebug() << "Emitting event " << event.eventTypeId(); emit emitEvent(event); diff --git a/plugins/deviceplugins/mock/httpdaemon.cpp b/plugins/deviceplugins/mock/httpdaemon.cpp index eef0c26d..388fd674 100644 --- a/plugins/deviceplugins/mock/httpdaemon.cpp +++ b/plugins/deviceplugins/mock/httpdaemon.cpp @@ -15,7 +15,7 @@ HttpDaemon::HttpDaemon(Device *device, DevicePlugin *parent): QTcpServer(parent), disabled(false), m_plugin(parent), m_device(device) { - listen(QHostAddress::Any, device->params().value("httpport").toInt()); + listen(QHostAddress::Any, device->paramValue("httpport").toInt()); } void HttpDaemon::incomingConnection(qintptr socket) diff --git a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp index 9f3c91b5..c63437a5 100644 --- a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp +++ b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp @@ -192,20 +192,14 @@ QList DevicePluginOpenweathermap::supportedDevices() const deviceClassOpenweathermap.setCreateMethod(DeviceClass::CreateMethodDiscovery); // Params - QVariantList params; - QVariantMap locationParam; - locationParam.insert("name", "location"); - locationParam.insert("type", "string"); + QList params; + ParamType locationParam("location", QVariant::String); params.append(locationParam); - QVariantMap countryParam; - countryParam.insert("name", "country"); - countryParam.insert("type", "string"); + ParamType countryParam("country", QVariant::String); params.append(countryParam); - QVariantMap idParam; - idParam.insert("name", "id"); - idParam.insert("type", "string"); + ParamType idParam("id", QVariant::String); params.append(idParam); deviceClassOpenweathermap.setParams(params); @@ -310,7 +304,7 @@ DeviceManager::DeviceError DevicePluginOpenweathermap::discoverDevices(const Dev bool DevicePluginOpenweathermap::deviceCreated(Device *device) { - m_openweaher->update(device->params().value("id").toString()); + m_openweaher->update(device->paramValue("id").toString()); return true; } @@ -323,7 +317,7 @@ DeviceManager::DeviceError DevicePluginOpenweathermap::executeAction(Device *dev { qDebug() << "execute action " << updateWeatherActionTypeId.toString(); if(action.actionTypeId() == updateWeatherActionTypeId){ - m_openweaher->update(device->params().value("id").toString()); + m_openweaher->update(device->paramValue("id").toString()); } return DeviceManager::DeviceErrorNoError; } @@ -341,7 +335,7 @@ PluginId DevicePluginOpenweathermap::pluginId() const void DevicePluginOpenweathermap::guhTimer() { foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) { - m_openweaher->update(device->params().value("id").toString()); + m_openweaher->update(device->paramValue("id").toString()); } } @@ -350,10 +344,13 @@ void DevicePluginOpenweathermap::searchResultsReady(const QList &ci QList retList; foreach (QVariantMap elemant, cityList) { DeviceDescriptor descriptor(openweathermapDeviceClassId, elemant.value("name").toString(),elemant.value("country").toString()); - QVariantMap params; - params.insert("location", elemant.value("name")); - params.insert("country", elemant.value("country")); - params.insert("id", elemant.value("id")); + QList params; + Param locationParam("location", elemant.value("name")); + params.append(locationParam); + Param countryParam("country", elemant.value("country")); + params.append(countryParam); + Param idParam("id", elemant.value("id")); + params.append(idParam); descriptor.setParams(params); retList.append(descriptor); } @@ -373,7 +370,7 @@ void DevicePluginOpenweathermap::weatherDataReady(const QByteArray &data) QVariantMap dataMap = jsonDoc.toVariant().toMap(); foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) { - if(device->params().value("id").toString() == dataMap.value("id").toString()){ + if(device->paramValue("id").toString() == dataMap.value("id").toString()){ if(dataMap.contains("clouds")){ int cloudiness = dataMap.value("clouds").toMap().value("all").toInt(); diff --git a/plugins/deviceplugins/wifidetector/devicepluginwifidetector.cpp b/plugins/deviceplugins/wifidetector/devicepluginwifidetector.cpp index c71f4da2..192a8649 100644 --- a/plugins/deviceplugins/wifidetector/devicepluginwifidetector.cpp +++ b/plugins/deviceplugins/wifidetector/devicepluginwifidetector.cpp @@ -48,10 +48,8 @@ QList DevicePluginWifiDetector::supportedDevices() const DeviceClass deviceClassWifiDetector(pluginId(), guhVendorId, detectorId); deviceClassWifiDetector.setName("WiFi Device"); - QVariantList detectorParams; - QVariantMap macParam; - macParam.insert("name", "mac"); - macParam.insert("type", "string"); + QList detectorParams; + ParamType macParam("mac", QVariant::String); detectorParams.append(macParam); deviceClassWifiDetector.setParams(detectorParams); @@ -123,7 +121,7 @@ void DevicePluginWifiDetector::processFinished(int exitCode, QProcess::ExitStatu foreach (Device *device, watchedDevices) { bool wasInRange = device->stateValue(inRangeStateTypeId).toBool(); - bool wasFound = foundDevices.contains(device->params().value("mac").toString().toLower()); + bool wasFound = foundDevices.contains(device->paramValue("mac").toString().toLower()); if (wasInRange != wasFound) { device->setStateValue(inRangeStateTypeId, wasFound); } diff --git a/server/jsonrpc/actionhandler.cpp b/server/jsonrpc/actionhandler.cpp index 7db2f734..e3dfab3a 100644 --- a/server/jsonrpc/actionhandler.cpp +++ b/server/jsonrpc/actionhandler.cpp @@ -48,7 +48,7 @@ JsonReply* ActionHandler::ExecuteAction(const QVariantMap ¶ms) DeviceId deviceId(params.value("deviceId").toString()); ActionTypeId actionTypeId(params.value("actionTypeId").toString()); - QVariantMap actionParams = params.value("params").toMap(); + QList actionParams = JsonTypes::unpackParams(params.value("params").toList()); Action action(deviceId, actionTypeId); action.setParams(actionParams); diff --git a/server/jsonrpc/devicehandler.cpp b/server/jsonrpc/devicehandler.cpp index 3fbcaf10..1a4def26 100644 --- a/server/jsonrpc/devicehandler.cpp +++ b/server/jsonrpc/devicehandler.cpp @@ -250,7 +250,12 @@ JsonReply* DeviceHandler::SetPluginConfiguration(const QVariantMap ¶ms) JsonReply* DeviceHandler::AddConfiguredDevice(const QVariantMap ¶ms) { DeviceClassId deviceClass(params.value("deviceClassId").toString()); - QVariantMap deviceParams = params.value("deviceParams").toMap(); + QList deviceParams; + foreach (const QString ¶mName, params.value("deviceParams").toMap().keys()) { + Param param(paramName); + param.setValue(params.value("deviceParams").toMap().value(paramName)); + deviceParams.append(param); + } DeviceDescriptorId deviceDescriptorId(params.value("deviceDescriptorId").toString()); DeviceId newDeviceId = DeviceId::createDeviceId(); DeviceManager::DeviceError status; diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index b9373f85..2b81f1da 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -31,6 +31,7 @@ QVariantList JsonTypes::s_basicTypes; QVariantList JsonTypes::s_ruleTypes; QVariantList JsonTypes::s_createMethodTypes; QVariantList JsonTypes::s_setupMethodTypes; +QVariantList JsonTypes::s_operandTypes; QVariantMap JsonTypes::s_paramType; QVariantMap JsonTypes::s_param; @@ -54,16 +55,19 @@ void JsonTypes::init() s_ruleTypes << "RuleTypeMatchAll" << "RuleTypeMatchAny"; s_createMethodTypes << "CreateMethodUser" << "CreateMethodAuto" << "CreateMethodDiscovery"; s_setupMethodTypes << "SetupMethodJustAdd" << "SetupMethodDisplayPin" << "SetupMethodEnterPin" << "SetupMethodPushButton"; + s_operandTypes << "OperandTypeEquals" << "OperandTypeNotEquals" << "OperandTypeLess" << "OperandTypeGreater" << "OperandTypeLessThan" << "OperandTypeGreaterThan"; // ParamType s_paramType.insert("name", "string"); s_paramType.insert("type", basicTypesRef()); -// s_paramType.insert("default", "value"); -// s_paramType.insert("value", "value"); + s_paramType.insert("o:defaultValue", "value"); + s_paramType.insert("o:minValue", "value"); + s_paramType.insert("o:maxValue", "value"); // Param s_param.insert("name", "string"); s_param.insert("value", basicTypesRef()); + s_param.insert("operand", operandTypesRef()); // StateType s_stateType.insert("id", "uuid"); @@ -147,6 +151,7 @@ QVariantMap JsonTypes::allTypes() allTypes.insert("ParamType", paramTypeDescription()); allTypes.insert("CreateMethodType", createMethodTypes()); allTypes.insert("SetupMethodType", setupMethodTypes()); + allTypes.insert("OperandType", operandTypes()); allTypes.insert("StateType", stateTypeDescription()); allTypes.insert("EventType", eventTypeDescription()); allTypes.insert("ActionType", actionTypeDescription()); @@ -178,7 +183,11 @@ QVariantMap JsonTypes::packEvent(const Event &event) QVariantMap variant; variant.insert("eventTypeId", event.eventTypeId()); variant.insert("deviceId", event.deviceId()); - variant.insert("params", event.params()); + QVariantList params; + foreach (const Param ¶m, event.params()) { + params.append(packParam(param)); + } + variant.insert("params", params); return variant; } @@ -196,7 +205,11 @@ QVariantMap JsonTypes::packAction(const Action &action) QVariantMap variant; variant.insert("actionTypeId", action.actionTypeId()); variant.insert("deviceId", action.deviceId()); - variant.insert("params", action.params()); + QVariantList params; + foreach (const Param ¶m, action.params()) { + params.append(packParam(param)); + } + variant.insert("params", params); return variant; } @@ -210,6 +223,32 @@ QVariantMap JsonTypes::packStateType(const StateType &stateType) return variantMap; } +QVariantMap JsonTypes::packParam(const Param ¶m) +{ + QVariantMap variantMap; + variantMap.insert("name", param.name()); + variantMap.insert("value", param.value()); + variantMap.insert("operand", s_operandTypes.at(param.operand())); + return variantMap; +} + +QVariantMap JsonTypes::packParamType(const ParamType ¶mType) +{ + QVariantMap variantMap; + variantMap.insert("name", paramType.name()); + variantMap.insert("type", QVariant::typeToName(paramType.type())); + if (paramType.defaultValue().isValid()) { + variantMap.insert("defaultValue", paramType.defaultValue()); + } + if (paramType.minValue().isValid()) { + variantMap.insert("minValue", paramType.minValue()); + } + if (paramType.maxValue().isValid()) { + variantMap.insert("maxValue", paramType.maxValue()); + } + return variantMap; +} + QVariantMap JsonTypes::packVendor(const Vendor &vendor) { QVariantMap variantMap; @@ -235,7 +274,12 @@ QVariantMap JsonTypes::packDeviceClass(const DeviceClass &deviceClass) foreach (const ActionType &actionType, deviceClass.actions()) { actionTypes.append(packActionType(actionType)); } - variant.insert("params", deviceClass.params()); + QVariantList paramTypes; + foreach (const ParamType ¶mType, deviceClass.params()) { + paramTypes.append(packParamType(paramType)); + } + + variant.insert("params", paramTypes); variant.insert("states", stateTypes); variant.insert("events", eventTypes); variant.insert("actions", actionTypes); @@ -257,7 +301,11 @@ QVariantMap JsonTypes::packDevice(Device *device) variant.insert("id", device->id()); variant.insert("deviceClassId", device->deviceClassId()); variant.insert("name", device->name()); - variant.insert("params", device->params()); + QVariantList params; + foreach (const Param ¶m, device->params()) { + params.append(packParam(param)); + } + variant.insert("params", params); return variant; } @@ -293,6 +341,35 @@ QVariantMap JsonTypes::packRule(const Rule &rule) return ruleMap; } +Param JsonTypes::unpackParam(const QVariantMap ¶mMap) +{ + Param param(paramMap.value("name").toString(), paramMap.value("value")); + QString operandString = paramMap.value("operand").toString(); + if (operandString == "OperandTypeEquals") { + param.setOperand(Param::OperandTypeEquals); + } else if (operandString == "OperandTypeNotEquals") { + param.setOperand(Param::OperandTypeNotEquals); + } else if (operandString == "OperandTypeLess") { + param.setOperand(Param::OperandTypeLess); + } else if (operandString == "OperandTypeGreater") { + param.setOperand(Param::OperandTypeGreater); + } else if (operandString == "OperandTypeLessThan") { + param.setOperand(Param::OperandTypeLessThan); + } else if (operandString == "OperandTypeGreaterThan") { + param.setOperand(Param::OperandTypeGreaterThan); + } + return param; +} + +QList JsonTypes::unpackParams(const QVariantList ¶mList) +{ + QList params; + foreach (const QVariant ¶mVariant, paramList) { + params.append(unpackParam(paramVariant.toMap())); + } + return params; +} + QPair JsonTypes::validateMap(const QVariantMap &templateMap, const QVariantMap &map) { s_lastError.clear(); @@ -333,6 +410,7 @@ QPair JsonTypes::validateMap(const QVariantMap &templateMap, cons QPair JsonTypes::validateProperty(const QVariant &templateValue, const QVariant &value) { + qDebug() << "validating property. template:" << templateValue << "got:" << value; QString strippedTemplateValue = templateValue.toString(); if (strippedTemplateValue == "variant") { @@ -378,20 +456,26 @@ QPair JsonTypes::validateVariant(const QVariant &templateVariant, case QVariant::String: if (templateVariant.toString().startsWith("$ref:")) { QString refName = templateVariant.toString(); - if (refName == JsonTypes::actionRef()) { + if (refName == actionRef()) { qDebug() << "validating action"; QPair result = validateMap(actionDescription(), variant.toMap()); if (!result.first) { qDebug() << "Error validating action"; return result; } - } else if (refName == JsonTypes::eventRef()) { + } else if (refName == eventRef()) { qDebug() << "validating event"; QPair result = validateMap(eventDescription(), variant.toMap()); if (!result.first) { qDebug() << "event not valid"; return result; } + } else if (refName == paramRef()) { + QPair result = validateMap(paramDescription(), variant.toMap()); + if (!result.first) { + qDebug() << "Param not valid"; + return result; + } } else if (refName == deviceRef()) { QPair result = validateMap(deviceDescription(), variant.toMap()); if (!result.first) { @@ -475,6 +559,12 @@ QPair JsonTypes::validateVariant(const QVariant &templateVariant, qDebug() << "value not allowed in" << createMethodTypesRef(); return result; } + } else if (refName == operandTypesRef()) { + QPair result = validateOperandType(variant); + if (!result.first) { + qDebug() << QString("value %1 not allowed in %2").arg(variant.toString()).arg(operandTypesRef()); + return result; + } } else { qDebug() << "unhandled ref:" << refName; return report(false, QString("Unhandled ref %1. Server implementation incomplete.").arg(refName)); @@ -543,3 +633,8 @@ QPair JsonTypes::validateSetupMethodType(const QVariant &variant) { return report(s_setupMethodTypes.contains(variant.toString()), QString("Unknwon setupMethod type %1").arg(variant.toString())); } + +QPair JsonTypes::validateOperandType(const QVariant &variant) +{ + return report(s_operandTypes.contains(variant.toString()), QString("Unknown operand type %1").arg(variant.toString())); +} diff --git a/server/jsonrpc/jsontypes.h b/server/jsonrpc/jsontypes.h index 5a701147..30e1eb72 100644 --- a/server/jsonrpc/jsontypes.h +++ b/server/jsonrpc/jsontypes.h @@ -26,6 +26,7 @@ #include "types/event.h" #include "types/action.h" #include "types/actiontype.h" +#include "types/paramtype.h" #include @@ -66,6 +67,7 @@ public: DECLARE_TYPE(ruleTypes, "RuleType") DECLARE_TYPE(createMethodTypes, "CreateMethodType") DECLARE_TYPE(setupMethodTypes, "SetupMethodType") + DECLARE_TYPE(operandTypes, "OperandType") DECLARE_OBJECT(paramType, "ParamType") DECLARE_OBJECT(param, "Param") DECLARE_OBJECT(stateType, "StateType") @@ -86,6 +88,8 @@ public: static QVariantMap packActionType(const ActionType &actionType); static QVariantMap packAction(const Action &action); static QVariantMap packStateType(const StateType &stateType); + static QVariantMap packParam(const Param ¶m); + static QVariantMap packParamType(const ParamType ¶mType); static QVariantMap packVendor(const Vendor &vendor); static QVariantMap packDeviceClass(const DeviceClass &deviceClass); static QVariantMap packPlugin(DevicePlugin *plugin); @@ -93,6 +97,9 @@ public: static QVariantMap packDeviceDescriptor(const DeviceDescriptor &descriptor); static QVariantMap packRule(const Rule &rule); + static Param unpackParam(const QVariantMap ¶mMap); + static QList unpackParams(const QVariantList ¶mList); + static QPair validateMap(const QVariantMap &templateMap, const QVariantMap &map); static QPair validateProperty(const QVariant &templateValue, const QVariant &value); static QPair validateList(const QVariantList &templateList, const QVariantList &list); @@ -101,6 +108,7 @@ public: static QPair validateRuleType(const QVariant &variant); static QPair validateCreateMethodType(const QVariant &variant); static QPair validateSetupMethodType(const QVariant &variant); + static QPair validateOperandType(const QVariant &variant); private: static bool s_initialized; diff --git a/server/jsonrpc/ruleshandler.cpp b/server/jsonrpc/ruleshandler.cpp index 5a9964c6..f651a5f4 100644 --- a/server/jsonrpc/ruleshandler.cpp +++ b/server/jsonrpc/ruleshandler.cpp @@ -82,7 +82,7 @@ JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms) EventTypeId eventTypeId(eventMap.value("eventTypeId").toString()); DeviceId eventDeviceId(eventMap.value("deviceId").toString()); - QVariantMap eventParams = eventMap.value("params").toMap(); + QList eventParams = JsonTypes::unpackParams(eventMap.value("params").toList()); Event event(eventTypeId, eventDeviceId, eventParams); QList actions; @@ -91,7 +91,7 @@ JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms) foreach (const QVariant &actionVariant, actionList) { QVariantMap actionMap = actionVariant.toMap(); Action action(DeviceId(actionMap.value("deviceId").toString()), ActionTypeId(actionMap.value("actionTypeId").toString())); - action.setParams(actionMap.value("params").toMap()); + action.setParams(JsonTypes::unpackParams(actionMap.value("params").toList())); actions.append(action); } diff --git a/server/ruleengine.cpp b/server/ruleengine.cpp index 60684302..57f220b1 100644 --- a/server/ruleengine.cpp +++ b/server/ruleengine.cpp @@ -80,7 +80,17 @@ RuleEngine::RuleEngine(QObject *parent) : settings.beginGroup("event"); EventTypeId eventTypeId(settings.value("eventTypeId").toString()); DeviceId deviceId(settings.value("deviceId").toString()); - Event event(eventTypeId, deviceId, settings.value("params").toMap()); + QList params; + foreach (QString groupName, settings.childGroups()) { + if (groupName.startsWith("Param-")) { + settings.beginGroup(groupName); + Param param(groupName.remove(QRegExp("^Param-")), settings.value("value")); + param.setOperand((Param::OperandType)settings.value("operand").toInt()); + params.append(param); + settings.endGroup(); + } + } + Event event(eventTypeId, deviceId, params); settings.endGroup(); settings.beginGroup("states"); @@ -99,7 +109,18 @@ RuleEngine::RuleEngine(QObject *parent) : foreach (const QString &actionIdString, settings.childGroups()) { settings.beginGroup(actionIdString); Action action = Action(DeviceId(settings.value("deviceId").toString()), ActionTypeId(settings.value("actionTypeId").toString())); - action.setParams(settings.value("params").toMap()); + QList params; + foreach (QString paramNameString, settings.childGroups()) { + if (paramNameString.startsWith("Param-")) { + settings.beginGroup(paramNameString); + Param param(paramNameString.remove(QRegExp("^Param-")), settings.value("value")); + param.setOperand((Param::OperandType)settings.value("operand").toInt()); + params.append(param); + settings.endGroup(); + } + } + action.setParams(params); + settings.endGroup(); actions.append(action); } @@ -187,7 +208,13 @@ RuleEngine::RuleError RuleEngine::addRule(const Event &event, const QList settings.beginGroup("event"); settings.setValue("eventTypeId", event.eventTypeId()); settings.setValue("deviceId", event.deviceId()); - settings.setValue("params", event.params()); + foreach (const Param ¶m, event.params()) { + settings.beginGroup("Param-" + param.name()); + settings.setValue("value", param.value()); + settings.setValue("operand", param.operand()); + settings.endGroup(); + } + settings.endGroup(); settings.beginGroup("states"); @@ -205,7 +232,12 @@ RuleEngine::RuleError RuleEngine::addRule(const Event &event, const QList settings.beginGroup(action.actionTypeId().toString()); settings.setValue("deviceId", action.deviceId()); settings.setValue("actionTypeId", action.actionTypeId()); - settings.setValue("params", action.params()); + foreach (const Param ¶m, action.params()) { + settings.beginGroup("Param-" + param.name()); + settings.setValue("value", param.value()); + settings.endGroup(); + } + settings.endGroup(); } diff --git a/tests/auto/testjsonrpc.cpp b/tests/auto/testjsonrpc.cpp index 78282ae9..f4b31f51 100644 --- a/tests/auto/testjsonrpc.cpp +++ b/tests/auto/testjsonrpc.cpp @@ -315,6 +315,7 @@ void TestJSONRPC::getConfiguredDevices() QVariant response = injectAndWait("Devices.GetConfiguredDevices"); QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); + qDebug() << "got devices" << devices; QCOMPARE(devices.count(), 2); // There should be one auto created mock device and the one created in initTestcase() }