diff --git a/guh.pri b/guh.pri index 681a35e8..00172347 100644 --- a/guh.pri +++ b/guh.pri @@ -2,7 +2,7 @@ GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"') # define protocol versions -JSON_PROTOCOL_VERSION=34 +JSON_PROTOCOL_VERSION=35 REST_API_VERSION=1 DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" \ diff --git a/libguh/plugin/deviceclass.cpp b/libguh/plugin/deviceclass.cpp index a24428f4..224a1a51 100644 --- a/libguh/plugin/deviceclass.cpp +++ b/libguh/plugin/deviceclass.cpp @@ -111,6 +111,18 @@ void DeviceClass::setName(const QString &name) m_name = name; } +/*! Returns the list of basicTags of this DeviceClass. */ +QList DeviceClass::basicTags() const +{ + return m_basicTags; +} + +/*! Set the list of \a basicTags of this DeviceClass. */ +void DeviceClass::setBasicTags(const QList &basicTags) +{ + m_basicTags = basicTags; +} + /*! Returns the statesTypes of this DeviceClass. \{Device}{Devices} created from this \l{DeviceClass} must have their states matching to this template. */ QList DeviceClass::stateTypes() const diff --git a/libguh/plugin/deviceclass.h b/libguh/plugin/deviceclass.h index 88f66ef2..294669be 100644 --- a/libguh/plugin/deviceclass.h +++ b/libguh/plugin/deviceclass.h @@ -62,6 +62,9 @@ public: QString name() const; void setName(const QString &name); + QList basicTags() const; + void setBasicTags(const QList &basicTags); + QList stateTypes() const; void setStateTypes(const QList &stateTypes); bool hasStateType(const StateTypeId &stateTypeId); @@ -82,6 +85,7 @@ public: CreateMethods createMethods() const; void setCreateMethods(CreateMethods createMethods); + SetupMethod setupMethod() const; void setSetupMethod(SetupMethod setupMethod); @@ -95,6 +99,7 @@ private: VendorId m_vendorId; PluginId m_pluginId; QString m_name; + QList m_basicTags; QList m_stateTypes; QList m_eventTypes; QList m_allEventTypes; diff --git a/libguh/plugin/deviceplugin.cpp b/libguh/plugin/deviceplugin.cpp index f1a12fa7..2feb9c67 100644 --- a/libguh/plugin/deviceplugin.cpp +++ b/libguh/plugin/deviceplugin.cpp @@ -234,6 +234,12 @@ QList DevicePlugin::supportedDevices() const deviceClass.setPairingInfo(jo.value("pairingInfo").toString()); deviceClass.setParamTypes(parseParamTypes(jo.value("paramTypes").toArray())); + QList basicTags; + foreach (const QJsonValue &basicTagJson, jo.value("basicTags").toArray()) { + basicTags.append(basicTagStringToBasicTag(basicTagJson.toString())); + } + deviceClass.setBasicTags(basicTags); + QList actionTypes; QList stateTypes; foreach (const QJsonValue &stateTypesJson, jo.value("stateTypes").toArray()) { @@ -426,10 +432,13 @@ QList DevicePlugin::parseParamTypes(const QJsonArray &array) const .arg(pt.value("type").toString()) .arg(pt.value("name").toString()).toLatin1().data()); ParamType paramType(pt.value("name").toString(), t, pt.value("defaultValue").toVariant()); + + // set allowed values QVariantList allowedValues; foreach (const QJsonValue &allowedTypesJson, pt.value("allowedValues").toArray()) { allowedValues.append(allowedTypesJson.toVariant()); } + // set the input type if there is any if (pt.contains("inputType")) { paramType.setInputType(inputTypeStringToInputType(pt.value("inputType").toString())); @@ -501,18 +510,18 @@ DeviceManager::DeviceError DevicePlugin::setConfigValue(const QString ¶mName if (paramType.name() == paramName) { if (!value.canConvert(paramType.type())) { qCWarning(dcDeviceManager) << QString("Wrong parameter type for param %1. Got %2. Expected %3.") - .arg(paramName).arg(value.toString()).arg(QVariant::typeToName(paramType.type())); + .arg(paramName).arg(value.toString()).arg(QVariant::typeToName(paramType.type())); return DeviceManager::DeviceErrorInvalidParameter; } if (paramType.maxValue().isValid() && value > paramType.maxValue()) { qCWarning(dcDeviceManager) << QString("Value out of range for param %1. Got %2. Max: %3.") - .arg(paramName).arg(value.toString()).arg(paramType.maxValue().toString()); + .arg(paramName).arg(value.toString()).arg(paramType.maxValue().toString()); return DeviceManager::DeviceErrorInvalidParameter; } if (paramType.minValue().isValid() && value < paramType.minValue()) { qCWarning(dcDeviceManager) << QString("Value out of range for param %1. Got: %2. Min: %3.") - .arg(paramName).arg(value.toString()).arg(paramType.minValue().toString()); + .arg(paramName).arg(value.toString()).arg(paramType.minValue().toString()); return DeviceManager::DeviceErrorInvalidParameter; } found = true; @@ -763,6 +772,8 @@ Types::Unit DevicePlugin::unitStringToUnit(const QString &unitString) const return Types::UnitKiloWattHour; } else if (unitString == "EuroPerMegaWattHour") { return Types::UnitEuroPerMegaWattHour; + } else if (unitString == "EuroCentPerKiloWattHour") { + return Types::UnitEuroCentPerKiloWattHour; } else if (unitString == "Percentage") { return Types::UnitPercentage; } else if (unitString == "PartsPerMillion") { @@ -800,3 +811,48 @@ Types::InputType DevicePlugin::inputTypeStringToInputType(const QString &inputTy } return Types::InputTypeNone; } + +Types::BasicTag DevicePlugin::basicTagStringToBasicTag(const QString &basicTag) const +{ + if (basicTag == "Device") { + return Types::BasicTagDevice; + } else if (basicTag == "Service") { + return Types::BasicTagService; + } else if (basicTag == "Actuator") { + return Types::BasicTagActuator; + } else if (basicTag == "Sensor") { + return Types::BasicTagSensor; + } else if (basicTag == "Lighting") { + return Types::BasicTagLighting; + } else if (basicTag == "Energy") { + return Types::BasicTagEnergy; + } else if (basicTag == "Multimedia") { + return Types::BasicTagMultimedia; + } else if (basicTag == "Weather") { + return Types::BasicTagWeather; + } else if (basicTag == "Gateway") { + return Types::BasicTagGateway; + } else if (basicTag == "Heating") { + return Types::BasicTagHeating; + } else if (basicTag == "Cooling") { + return Types::BasicTagCooling; + } else if (basicTag == "Notification") { + return Types::BasicTagNotification; + } else if (basicTag == "Security") { + return Types::BasicTagSecurity; + } else if (basicTag == "Time") { + return Types::BasicTagTime; + } else if (basicTag == "Shading") { + return Types::BasicTagShading; + } else if (basicTag == "Appliance") { + return Types::BasicTagAppliance; + } else if (basicTag == "Camera") { + return Types::BasicTagCamera; + } else if (basicTag == "Lock") { + return Types::BasicTagLock; + } else { + qCWarning(dcDeviceManager) << "Could not parse basicTag:" << basicTag << "in plugin" << this->pluginName(); + } + + return Types::BasicTagDevice; +} diff --git a/libguh/plugin/deviceplugin.h b/libguh/plugin/deviceplugin.h index bbc3062e..6bf8d112 100644 --- a/libguh/plugin/deviceplugin.h +++ b/libguh/plugin/deviceplugin.h @@ -128,6 +128,7 @@ private: Types::Unit unitStringToUnit(const QString &unitString) const; Types::InputType inputTypeStringToInputType(const QString &inputType) const; + Types::BasicTag basicTagStringToBasicTag(const QString &basicTag) const; DeviceManager *m_deviceManager; diff --git a/libguh/typeutils.h b/libguh/typeutils.h index 175f5fc5..97e893c5 100644 --- a/libguh/typeutils.h +++ b/libguh/typeutils.h @@ -58,10 +58,11 @@ DECLARE_TYPE_ID(PairingTransaction) class Types { Q_GADGET + Q_ENUMS(InputType) + Q_ENUMS(BasicTag) + Q_ENUMS(Unit) Q_ENUMS(StateOperator) Q_ENUMS(ValueOperator) - Q_ENUMS(InputType) - Q_ENUMS(Unit) public: enum InputType { @@ -77,6 +78,27 @@ public: InputTypeMacAddress }; + enum BasicTag { + BasicTagService, + BasicTagDevice, + BasicTagSensor, + BasicTagActuator, + BasicTagLighting, + BasicTagEnergy, + BasicTagMultimedia, + BasicTagWeather, + BasicTagGateway, + BasicTagHeating, + BasicTagCooling, + BasicTagNotification, + BasicTagSecurity, + BasicTagTime, + BasicTagShading, + BasicTagAppliance, + BasicTagCamera, + BasicTagLock + }; + enum Unit { UnitNone, UnitSeconds, @@ -114,6 +136,7 @@ public: UnitKiloWatt, UnitKiloWattHour, UnitEuroPerMegaWattHour, + UnitEuroCentPerKiloWattHour, UnitPercentage, UnitPartsPerMillion, UnitEuro, @@ -136,9 +159,10 @@ public: Types(QObject *parent = 0); }; -Q_DECLARE_METATYPE(Types::ValueOperator) -Q_DECLARE_METATYPE(Types::StateOperator) Q_DECLARE_METATYPE(Types::InputType) Q_DECLARE_METATYPE(Types::Unit) +Q_DECLARE_METATYPE(Types::BasicTag) +Q_DECLARE_METATYPE(Types::ValueOperator) +Q_DECLARE_METATYPE(Types::StateOperator) #endif // TYPEUTILS_H diff --git a/plugins/deviceplugins/mock/devicepluginmock.json b/plugins/deviceplugins/mock/devicepluginmock.json index 4c16e6ad..5224fc24 100644 --- a/plugins/deviceplugins/mock/devicepluginmock.json +++ b/plugins/deviceplugins/mock/devicepluginmock.json @@ -12,6 +12,11 @@ "deviceClassId": "753f0d32-0468-4d08-82ed-1964aab03298", "idName": "mock", "name": "Mock Device", + "basicTags": [ + "Device", + "Actuator", + "Gateway" + ], "createMethods": ["user", "discovery"], "discoveryParamTypes": [ { diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index 7bcbf218..a8067e2c 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -38,6 +38,7 @@ bool JsonTypes::s_initialized = false; QString JsonTypes::s_lastError; QVariantList JsonTypes::s_basicType; +QVariantList JsonTypes::s_basicTag; QVariantList JsonTypes::s_stateOperator; QVariantList JsonTypes::s_valueOperator; QVariantList JsonTypes::s_inputType; @@ -79,6 +80,7 @@ void JsonTypes::init() { // BasicTypes s_basicType = enumToStrings(JsonTypes::staticMetaObject, "BasicType"); + s_basicTag = enumToStrings(Types::staticMetaObject, "BasicTag"); s_stateOperator = enumToStrings(Types::staticMetaObject, "StateOperator"); s_valueOperator = enumToStrings(Types::staticMetaObject, "ValueOperator"); s_inputType = enumToStrings(Types::staticMetaObject, "InputType"); @@ -188,6 +190,7 @@ void JsonTypes::init() s_deviceClass.insert("id", basicTypeToString(Uuid)); s_deviceClass.insert("vendorId", basicTypeToString(Uuid)); s_deviceClass.insert("name", basicTypeToString(String)); + s_deviceClass.insert("basicTags", QVariantList() << basicTagRef()); s_deviceClass.insert("stateTypes", QVariantList() << stateTypeRef()); s_deviceClass.insert("eventTypes", QVariantList() << eventTypeRef()); s_deviceClass.insert("actionTypes", QVariantList() << actionTypeRef()); @@ -263,6 +266,7 @@ QVariantMap JsonTypes::allTypes() { QVariantMap allTypes; allTypes.insert("BasicType", basicType()); + allTypes.insert("BasicTag", basicTag()); allTypes.insert("ParamType", paramTypeDescription()); allTypes.insert("InputType", inputType()); allTypes.insert("Unit", unit()); @@ -516,6 +520,11 @@ QVariantMap JsonTypes::packDeviceClass(const DeviceClass &deviceClass) variant.insert("name", deviceClass.name()); variant.insert("id", deviceClass.id()); variant.insert("vendorId", deviceClass.vendorId()); + + QVariantList basicTags; + foreach (const Types::BasicTag &basicTag, deviceClass.basicTags()) { + basicTags.append(s_basicTag.at(basicTag)); + } QVariantList stateTypes; foreach (const StateType &stateType, deviceClass.stateTypes()) { stateTypes.append(packStateType(stateType)); @@ -537,6 +546,7 @@ QVariantMap JsonTypes::packDeviceClass(const DeviceClass &deviceClass) discoveryParamTypes.append(packParamType(paramType)); } + variant.insert("basicTags", basicTags); variant.insert("paramTypes", paramTypes); variant.insert("discoveryParamTypes", discoveryParamTypes); variant.insert("stateTypes", stateTypes); @@ -1278,6 +1288,12 @@ QPair JsonTypes::validateVariant(const QVariant &templateVariant, qCWarning(dcJsonRpc) << QString("value %1 not allowed in %2").arg(variant.toString()).arg(unitRef()); return result; } + } else if (refName == basicTagRef()) { + QPair result = validateEnum(s_basicTag, variant); + if (!result.first) { + qCWarning(dcJsonRpc) << QString("value %1 not allowed in %2").arg(variant.toString()).arg(basicTagRef()); + return result; + } } else { Q_ASSERT_X(false, "JsonTypes", QString("Unhandled ref: %1").arg(refName).toLatin1().data()); return report(false, QString("Unhandled ref %1. Server implementation incomplete.").arg(refName)); diff --git a/server/jsonrpc/jsontypes.h b/server/jsonrpc/jsontypes.h index 6f5fe763..d0ac1123 100644 --- a/server/jsonrpc/jsontypes.h +++ b/server/jsonrpc/jsontypes.h @@ -83,6 +83,7 @@ class JsonTypes Q_GADGET Q_ENUMS(BasicType) Q_ENUMS(JsonError) + public: enum BasicType { Uuid, @@ -99,6 +100,7 @@ public: static QVariantMap allTypes(); DECLARE_TYPE(basicType, "BasicType", JsonTypes, BasicType) + DECLARE_TYPE(basicTag, "BasicTag", Types, BasicTag) DECLARE_TYPE(stateOperator, "StateOperator", Types, StateOperator) DECLARE_TYPE(valueOperator, "ValueOperator", Types, ValueOperator) DECLARE_TYPE(inputType, "InputType", Types, InputType) @@ -112,6 +114,7 @@ public: DECLARE_TYPE(loggingSource, "LoggingSource", Logging, LoggingSource) DECLARE_TYPE(loggingLevel, "LoggingLevel", Logging, LoggingLevel) DECLARE_TYPE(loggingEventType, "LoggingEventType", Logging, LoggingEventType) + DECLARE_OBJECT(paramType, "ParamType") DECLARE_OBJECT(param, "Param") DECLARE_OBJECT(paramDescriptor, "ParamDescriptor") diff --git a/tests/auto/api.json b/tests/auto/api.json index 3b2d42fd..fde4d1bf 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -1,4 +1,4 @@ -34 +35 { "methods": { "Actions.ExecuteAction": { @@ -533,6 +533,26 @@ "$ref:ParamType" ] }, + "BasicTag": [ + "BasicTagService", + "BasicTagDevice", + "BasicTagSensor", + "BasicTagActuator", + "BasicTagLighting", + "BasicTagEnergy", + "BasicTagMultimedia", + "BasicTagWeather", + "BasicTagGateway", + "BasicTagHeating", + "BasicTagCooling", + "BasicTagNotification", + "BasicTagSecurity", + "BasicTagTime", + "BasicTagShading", + "BasicTagAppliance", + "BasicTagCamera", + "BasicTagLock" + ], "BasicType": [ "Uuid", "String", @@ -563,6 +583,9 @@ "actionTypes": [ "$ref:ActionType" ], + "basicTags": [ + "$ref:BasicTag" + ], "createMethods": [ "$ref:CreateMethod" ], @@ -845,6 +868,7 @@ "UnitKiloWatt", "UnitKiloWattHour", "UnitEuroPerMegaWattHour", + "UnitEuroCentPerKiloWattHour", "UnitPercentage", "UnitPartsPerMillion", "UnitEuro",