From a0b974ce295ae81a4afc8ac60781678801a6db41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 16 May 2016 12:29:42 +0200 Subject: [PATCH] improve plugin parsing mechanism --- libguh/plugin/deviceclass.cpp | 9 +++++ libguh/plugin/deviceclass.h | 1 + libguh/plugin/deviceplugin.cpp | 36 ++++++++++++------- .../denon/deviceplugindenon.json | 1 + .../deviceplugins/kodi/devicepluginkodi.json | 3 ++ 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/libguh/plugin/deviceclass.cpp b/libguh/plugin/deviceclass.cpp index 8d3c7d1e..aea17923 100644 --- a/libguh/plugin/deviceclass.cpp +++ b/libguh/plugin/deviceclass.cpp @@ -289,6 +289,15 @@ QList DeviceClass::stateTypes() const return m_stateTypes; } +StateType DeviceClass::getStateType(const StateTypeId &stateTypeId) +{ + foreach (const StateType &stateType, m_stateTypes) { + if (stateType.id() == stateTypeId) + return stateType; + } + return StateType(StateTypeId()); +} + /*! Set the \a stateTypes of this DeviceClass. \{Device}{Devices} created from this \l{DeviceClass} must have their states matching to this template. */ void DeviceClass::setStateTypes(const QList &stateTypes) diff --git a/libguh/plugin/deviceclass.h b/libguh/plugin/deviceclass.h index 76f84b73..81c1094f 100644 --- a/libguh/plugin/deviceclass.h +++ b/libguh/plugin/deviceclass.h @@ -141,6 +141,7 @@ public: void setBasicTags(const QList &basicTags); QList stateTypes() const; + StateType getStateType(const StateTypeId &stateTypeId); void setStateTypes(const QList &stateTypes); bool hasStateType(const StateTypeId &stateTypeId); diff --git a/libguh/plugin/deviceplugin.cpp b/libguh/plugin/deviceplugin.cpp index 7617d080..8b3fd48a 100644 --- a/libguh/plugin/deviceplugin.cpp +++ b/libguh/plugin/deviceplugin.cpp @@ -257,13 +257,14 @@ QList DevicePlugin::supportedDevices() const } deviceClass.setBasicTags(basicTags); + // State Types QList actionTypes; QList stateTypes; foreach (const QJsonValue &stateTypesJson, jo.value("stateTypes").toArray()) { QJsonObject st = stateTypesJson.toObject(); - QStringList missingFields = verifyFields(QStringList() << "type" << "id" << "name" << "index", st); + QStringList missingFields = verifyFields(QStringList() << "type" << "id" << "name" << "index" << "defaultValue", st); if (!missingFields.isEmpty()) { - qCWarning(dcDeviceManager) << "Skipping device class" << deviceClass.name() << "because of missing" << missingFields.join(", ") << "in stateTypes"; + qCWarning(dcDeviceManager) << "Skipping device class" << deviceClass.name() << "because of missing" << missingFields.join(", ") << "in stateType" << st; broken = true; break; } @@ -276,6 +277,7 @@ QList DevicePlugin::supportedDevices() const QPair unitVerification = loadAndVerifyUnit(st.value("unit").toString()); if (!unitVerification.first) { broken = true; + break; } else { stateType.setUnit(unitVerification.second); } @@ -293,16 +295,16 @@ QList DevicePlugin::supportedDevices() const } stateType.setPossibleValues(possibleValues); - // inform the plugin developer about the error in the plugin json file - Q_ASSERT_X(stateType.possibleValues().contains(stateType.defaultValue()), - QString("\"%1\" plugin").arg(pluginName()).toLatin1().data(), - QString("The given default value \"%1\" is not in the possible values of the stateType \"%2\".") - .arg(stateType.defaultValue().toString()).arg(stateType.name()).toLatin1().data()); - + if (!stateType.possibleValues().contains(stateType.defaultValue())) { + qCWarning(dcDeviceManager()) << QString("\"%1\" plugin:").arg(pluginName()).toLatin1().data() << QString("The given default value \"%1\" is not in the possible values of the stateType \"%2\".") + .arg(stateType.defaultValue().toString()).arg(stateType.name()).toLatin1().data(); + broken = true; + break; + } } stateTypes.append(stateType); - // create ActionType if this StateType is writable + // ActionTypes for writeable StateTypes if (st.contains("writable") && st.value("writable").toBool()) { // Note: fields already checked in StateType ActionType actionType(ActionTypeId(stateType.id().toString())); @@ -318,6 +320,7 @@ QList DevicePlugin::supportedDevices() const } deviceClass.setStateTypes(stateTypes); + // ActionTypes foreach (const QJsonValue &actionTypesJson, jo.value("actionTypes").toArray()) { QJsonObject at = actionTypesJson.toObject(); QStringList missingFields = verifyFields(QStringList() << "id" << "name" << "index", at); @@ -333,6 +336,7 @@ QList DevicePlugin::supportedDevices() const QPair > paramVerification = parseParamTypes(at.value("paramTypes").toArray()); if (!paramVerification.first) { broken = true; + break; } else { actionType.setParamTypes(paramVerification.second); } @@ -341,6 +345,7 @@ QList DevicePlugin::supportedDevices() const } deviceClass.setActionTypes(actionTypes); + // EventTypes QList eventTypes; foreach (const QJsonValue &eventTypesJson, jo.value("eventTypes").toArray()) { QJsonObject et = eventTypesJson.toObject(); @@ -358,6 +363,7 @@ QList DevicePlugin::supportedDevices() const QPair > paramVerification = parseParamTypes(et.value("paramTypes").toArray()); if (!paramVerification.first) { broken = true; + break; } else { eventType.setParamTypes(paramVerification.second); } @@ -366,12 +372,16 @@ QList DevicePlugin::supportedDevices() const } deviceClass.setEventTypes(eventTypes); - // Note: do this after the actionType / stateType / eventType parsing + // Note: keep this after the actionType / stateType / eventType parsing if (jo.contains("criticalStateTypeId")) { StateTypeId criticalStateTypeId = StateTypeId(jo.value("criticalStateTypeId").toString()); if (!deviceClass.hasStateType(criticalStateTypeId)) { qCWarning(dcDeviceManager) << "Skipping device class" << deviceClass.name() << ": the definend critical stateTypeId" << criticalStateTypeId.toString() << "does not match any StateType of this DeviceClass."; broken = true; + } else if (deviceClass.getStateType(criticalStateTypeId).type() != QVariant::Bool) { + // Make sure the critical stateType is a bool state + qCWarning(dcDeviceManager) << "Skipping device class" << deviceClass.name() << ": the definend critical stateTypeId" << criticalStateTypeId.toString() << "is not a bool StateType."; + broken = true; } else { deviceClass.setCriticalStateTypeId(criticalStateTypeId); } @@ -397,9 +407,11 @@ QList DevicePlugin::supportedDevices() const } } - if (!broken) + if (!broken) { deviceClasses.append(deviceClass); - + } else { + qCWarning(dcDeviceManager()) << "Skipping device class" << deviceClass.name(); + } } } return deviceClasses; diff --git a/plugins/deviceplugins/denon/deviceplugindenon.json b/plugins/deviceplugins/denon/deviceplugindenon.json index 46e68c79..04caaabb 100644 --- a/plugins/deviceplugins/denon/deviceplugindenon.json +++ b/plugins/deviceplugins/denon/deviceplugindenon.json @@ -34,6 +34,7 @@ "idName": "connected", "name": "connected", "index": 0, + "defaultValue": false, "type": "bool" }, { diff --git a/plugins/deviceplugins/kodi/devicepluginkodi.json b/plugins/deviceplugins/kodi/devicepluginkodi.json index 98b350c6..7a24b65b 100644 --- a/plugins/deviceplugins/kodi/devicepluginkodi.json +++ b/plugins/deviceplugins/kodi/devicepluginkodi.json @@ -45,6 +45,7 @@ "idName": "connected", "name": "connected", "index": 0, + "defaultValue": false, "type": "bool" }, { @@ -53,6 +54,7 @@ "name": "mute", "index": 1, "type": "bool", + "defaultValue": true, "writable": true }, { @@ -64,6 +66,7 @@ "index": 2, "minValue": 0, "maxValue": 100, + "defaultValue": 50, "writable": true } ],