update plugins and add state desciptor validation
This commit is contained in:
parent
057c1cf065
commit
02a6e2cb96
2
guh.pri
2
guh.pri
@ -2,7 +2,7 @@
|
|||||||
GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"')
|
GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"')
|
||||||
|
|
||||||
# define protocol versions
|
# define protocol versions
|
||||||
JSON_PROTOCOL_VERSION=33
|
JSON_PROTOCOL_VERSION=34
|
||||||
REST_API_VERSION=1
|
REST_API_VERSION=1
|
||||||
|
|
||||||
DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" \
|
DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" \
|
||||||
|
|||||||
@ -37,7 +37,6 @@
|
|||||||
The \a value parameter describes the new value of the State.
|
The \a value parameter describes the new value of the State.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "types/event.h"
|
#include "types/event.h"
|
||||||
#include "loggingcategories.h"
|
#include "loggingcategories.h"
|
||||||
@ -187,9 +186,13 @@ void Device::setStateValue(const StateTypeId &stateTypeId, const QVariant &value
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < m_states.count(); ++i) {
|
for (int i = 0; i < m_states.count(); ++i) {
|
||||||
if (m_states.at(i).stateTypeId() == stateTypeId) {
|
if (m_states.at(i).stateTypeId() == stateTypeId) {
|
||||||
if (m_states.at(i).value() == value) {
|
if (m_states.at(i).value() == value)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
|
// TODO: check min/max value + possible values
|
||||||
|
// to prevent an invalid state type
|
||||||
|
|
||||||
State newState(stateTypeId, m_id);
|
State newState(stateTypeId, m_id);
|
||||||
newState.setValue(value);
|
newState.setValue(value);
|
||||||
m_states[i] = newState;
|
m_states[i] = newState;
|
||||||
|
|||||||
@ -251,25 +251,30 @@ QList<DeviceClass> DevicePlugin::supportedDevices() const
|
|||||||
stateType.setType(t);
|
stateType.setType(t);
|
||||||
stateType.setUnit(unitStringToUnit(st.value("unit").toString()));
|
stateType.setUnit(unitStringToUnit(st.value("unit").toString()));
|
||||||
stateType.setDefaultValue(st.value("defaultValue").toVariant());
|
stateType.setDefaultValue(st.value("defaultValue").toVariant());
|
||||||
|
if (st.contains("minValue"))
|
||||||
|
stateType.setMinValue(st.value("minValue").toVariant());
|
||||||
|
|
||||||
|
if (st.contains("maxValue"))
|
||||||
|
stateType.setMaxValue(st.value("maxValue").toVariant());
|
||||||
|
|
||||||
|
if (st.contains("possibleValues")) {
|
||||||
|
QVariantList possibleValues;
|
||||||
|
foreach (const QJsonValue &possibleValueJson, st.value("possibleValues").toArray()) {
|
||||||
|
possibleValues.append(possibleValueJson.toVariant());
|
||||||
|
}
|
||||||
|
stateType.setPossibleValues(possibleValues);
|
||||||
|
}
|
||||||
stateTypes.append(stateType);
|
stateTypes.append(stateType);
|
||||||
|
|
||||||
// create ActionType if this StateType is writable
|
// create ActionType if this StateType is writable
|
||||||
if (st.contains("writable")) {
|
if (st.contains("writable") && st.value("writable").toBool()) {
|
||||||
ActionType actionType(st.value("id").toString());
|
|
||||||
actionType.setName("set " + st.value("name").toString());
|
|
||||||
// Note: fields already checked in StateType
|
// Note: fields already checked in StateType
|
||||||
ParamType paramType(st.value("name").toString(), t, st.value("defaultValue").toVariant());
|
ActionType actionType(ActionTypeId(stateType.id().toString()));
|
||||||
if (st.value("writable").toObject().contains("allowedValues")) {
|
actionType.setName("set " + stateType.name());
|
||||||
QVariantList allowedValues;
|
ParamType paramType(stateType.name(), t, stateType.defaultValue());
|
||||||
foreach (const QJsonValue &allowedTypesJson, st.value("writable").toObject().value("allowedValues").toArray()) {
|
paramType.setAllowedValues(stateType.possibleValues());
|
||||||
allowedValues.append(allowedTypesJson.toVariant());
|
paramType.setUnit(stateType.unit());
|
||||||
}
|
paramType.setLimits(stateType.minValue(), stateType.maxValue());
|
||||||
paramType.setAllowedValues(allowedValues);
|
|
||||||
}
|
|
||||||
paramType.setInputType(inputTypeStringToInputType(st.value("writable").toObject().value("inputType").toString()));
|
|
||||||
paramType.setUnit(unitStringToUnit(st.value("unit").toString()));
|
|
||||||
paramType.setLimits(st.value("writable").toObject().value("minValue").toVariant(),
|
|
||||||
st.value("writable").toObject().value("maxValue").toVariant());
|
|
||||||
actionType.setParamTypes(QList<ParamType>() << paramType);
|
actionType.setParamTypes(QList<ParamType>() << paramType);
|
||||||
actionTypes.append(actionType);
|
actionTypes.append(actionType);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -212,7 +212,7 @@
|
|||||||
"type": "double",
|
"type": "double",
|
||||||
"unit": "DegreeCelsius",
|
"unit": "DegreeCelsius",
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
"writable": {}
|
"writable": true
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -375,7 +375,7 @@
|
|||||||
"unit": "DegreeCelsius",
|
"unit": "DegreeCelsius",
|
||||||
"type": "double",
|
"type": "double",
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
"writable": {}
|
"writable": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "576da571-9a65-478f-96bf-19256c8b9ece",
|
"id": "576da571-9a65-478f-96bf-19256c8b9ece",
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
"name": "state",
|
"name": "state",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": false,
|
"defaultValue": false,
|
||||||
"writable": {}
|
"writable": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -41,7 +41,7 @@
|
|||||||
"idName": "mute",
|
"idName": "mute",
|
||||||
"name": "mute",
|
"name": "mute",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"writable": {}
|
"writable": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "9dfe5d78-4c3f-497c-bab1-bb9fdf7e93a9",
|
"id": "9dfe5d78-4c3f-497c-bab1-bb9fdf7e93a9",
|
||||||
@ -49,10 +49,9 @@
|
|||||||
"name": "volume",
|
"name": "volume",
|
||||||
"unit": "Percentage",
|
"unit": "Percentage",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"writable": {
|
"minValue": 0,
|
||||||
"minValue": 0,
|
"maxValue": 100,
|
||||||
"maxValue": 100
|
"writable": true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"eventTypes": [
|
"eventTypes": [
|
||||||
|
|||||||
@ -234,7 +234,7 @@
|
|||||||
"name": "color",
|
"name": "color",
|
||||||
"type": "QColor",
|
"type": "QColor",
|
||||||
"defaultValue": "#000000",
|
"defaultValue": "#000000",
|
||||||
"writable": {}
|
"writable": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "72981c04-267a-4ba0-a59e-9921d2f3af9c",
|
"id": "72981c04-267a-4ba0-a59e-9921d2f3af9c",
|
||||||
@ -243,10 +243,9 @@
|
|||||||
"type": "int",
|
"type": "int",
|
||||||
"unit": "Percentage",
|
"unit": "Percentage",
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
"writable": {
|
"minValue": 0,
|
||||||
"minValue": 0,
|
"maxValue": 100,
|
||||||
"maxValue": 100
|
"writable": true
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "05f63f9c-f61e-4dcf-ad55-3f13fde2765b",
|
"id": "05f63f9c-f61e-4dcf-ad55-3f13fde2765b",
|
||||||
@ -254,14 +253,13 @@
|
|||||||
"name": "allowed values",
|
"name": "allowed values",
|
||||||
"type": "QString",
|
"type": "QString",
|
||||||
"defaultValue": "String value 1",
|
"defaultValue": "String value 1",
|
||||||
"writable": {
|
"possibleValues": [
|
||||||
"allowedValues": [
|
"String value 1",
|
||||||
"String value 1",
|
"String value 2",
|
||||||
"String value 2",
|
"String value 3",
|
||||||
"String value 3",
|
"String value 4"
|
||||||
"String value 4"
|
],
|
||||||
]
|
"writable": true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"actionTypes": [
|
"actionTypes": [
|
||||||
|
|||||||
@ -116,7 +116,7 @@
|
|||||||
"name": "power",
|
"name": "power",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": false,
|
"defaultValue": false,
|
||||||
"writable": {}
|
"writable": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "c0f4206f-f219-4f06-93c4-4ca515a56f79",
|
"id": "c0f4206f-f219-4f06-93c4-4ca515a56f79",
|
||||||
@ -125,10 +125,9 @@
|
|||||||
"type": "int",
|
"type": "int",
|
||||||
"unit": "Mired",
|
"unit": "Mired",
|
||||||
"defaultValue": 170,
|
"defaultValue": 170,
|
||||||
"writable": {
|
"minValue": 153,
|
||||||
"minValue": 153,
|
"maxValue": 500,
|
||||||
"maxValue": 500
|
"writable": true
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "d25423e7-b924-4b20-80b6-77eecc65d089",
|
"id": "d25423e7-b924-4b20-80b6-77eecc65d089",
|
||||||
@ -136,7 +135,7 @@
|
|||||||
"name": "color",
|
"name": "color",
|
||||||
"type": "QColor",
|
"type": "QColor",
|
||||||
"defaultValue": "#000000",
|
"defaultValue": "#000000",
|
||||||
"writable": {}
|
"writable": true
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -146,10 +145,10 @@
|
|||||||
"type": "int",
|
"type": "int",
|
||||||
"unit": "Percentage",
|
"unit": "Percentage",
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
"writable": {
|
"minValue": 0,
|
||||||
"minValue": 0,
|
"maxValue": 100,
|
||||||
"maxValue": 100
|
"writable": true
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "0b7cdd8d-4db8-4183-abe2-f3c01d1c9afc",
|
"id": "0b7cdd8d-4db8-4183-abe2-f3c01d1c9afc",
|
||||||
@ -157,13 +156,11 @@
|
|||||||
"name": "effect",
|
"name": "effect",
|
||||||
"type": "QString",
|
"type": "QString",
|
||||||
"defaultValue": "none",
|
"defaultValue": "none",
|
||||||
"writable": {
|
"possibleValues": [
|
||||||
"allowedValues": [
|
"none",
|
||||||
"none",
|
"color loop"
|
||||||
"color loop"
|
],
|
||||||
]
|
"writable": true
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"actionTypes": [
|
"actionTypes": [
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
"name": "active",
|
"name": "active",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": false,
|
"defaultValue": false,
|
||||||
"writable": {}
|
"writable": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "cb8a89c2-dc12-4965-b047-57896058b421",
|
"id": "cb8a89c2-dc12-4965-b047-57896058b421",
|
||||||
@ -64,10 +64,9 @@
|
|||||||
"type": "int",
|
"type": "int",
|
||||||
"unit": "Percentage",
|
"unit": "Percentage",
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
"writable": {
|
"minValue": 0,
|
||||||
"minValue": 0,
|
"maxValue": 100,
|
||||||
"maxValue": 100
|
"writable": true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -124,7 +123,7 @@
|
|||||||
"name": "power",
|
"name": "power",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
"writable": {}
|
"writable": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "677cd9ec-c264-47ee-9d2e-d3662237792c",
|
"id": "677cd9ec-c264-47ee-9d2e-d3662237792c",
|
||||||
@ -133,10 +132,9 @@
|
|||||||
"type": "int",
|
"type": "int",
|
||||||
"unit": "Percentage",
|
"unit": "Percentage",
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
"writable": {
|
"minValue": 0,
|
||||||
"minValue": 0,
|
"maxValue": 100,
|
||||||
"maxValue": 100
|
"writable": true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@
|
|||||||
"name": "power",
|
"name": "power",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": false,
|
"defaultValue": false,
|
||||||
"writable": {}
|
"writable": true
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -104,14 +104,15 @@ def extractStateTypes(deviceClassMap):
|
|||||||
print("duplicated variable name \"%s\" for StateTypeId %s -> skipping") % (variableName, stateType["id"])
|
print("duplicated variable name \"%s\" for StateTypeId %s -> skipping") % (variableName, stateType["id"])
|
||||||
# create ActionTypeId if the state is writable
|
# create ActionTypeId if the state is writable
|
||||||
if 'writable' in stateType:
|
if 'writable' in stateType:
|
||||||
vName = "%sActionTypeId" % (stateType["idName"])
|
if stateType['writable']:
|
||||||
if not vName in variableNames:
|
vName = "%sActionTypeId" % (stateType["idName"])
|
||||||
variableNames.append(vName)
|
if not vName in variableNames:
|
||||||
print("define ActionTypeId %s for writable StateType %s = %s" % (vName, variableName, stateType["id"]))
|
variableNames.append(vName)
|
||||||
writePluginInfo("ActionTypeId %s = ActionTypeId(\"%s\");" % (vName, stateType["id"]))
|
print("define ActionTypeId %s for writable StateType %s = %s" % (vName, variableName, stateType["id"]))
|
||||||
createExternDefinition("ActionTypeId", vName)
|
writePluginInfo("ActionTypeId %s = ActionTypeId(\"%s\");" % (vName, stateType["id"]))
|
||||||
else:
|
createExternDefinition("ActionTypeId", vName)
|
||||||
print("duplicated variable name \"%s\" for ActionTypeId %s -> skipping") % (variableName, stateType["id"])
|
else:
|
||||||
|
print("duplicated variable name \"%s\" for ActionTypeId %s -> skipping") % (variableName, stateType["id"])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
|
|||||||
@ -227,7 +227,6 @@ void JsonTypes::init()
|
|||||||
s_ruleDescription.insert("active", basicTypeToString(Bool));
|
s_ruleDescription.insert("active", basicTypeToString(Bool));
|
||||||
s_ruleDescription.insert("executable", basicTypeToString(Bool));
|
s_ruleDescription.insert("executable", basicTypeToString(Bool));
|
||||||
|
|
||||||
|
|
||||||
// LogEntry
|
// LogEntry
|
||||||
s_logEntry.insert("timestamp", basicTypeToString(Int));
|
s_logEntry.insert("timestamp", basicTypeToString(Int));
|
||||||
s_logEntry.insert("loggingLevel", loggingLevelRef());
|
s_logEntry.insert("loggingLevel", loggingLevelRef());
|
||||||
@ -411,9 +410,17 @@ QVariantMap JsonTypes::packStateType(const StateType &stateType)
|
|||||||
variantMap.insert("type", basicTypeToString(stateType.type()));
|
variantMap.insert("type", basicTypeToString(stateType.type()));
|
||||||
variantMap.insert("defaultValue", stateType.defaultValue());
|
variantMap.insert("defaultValue", stateType.defaultValue());
|
||||||
|
|
||||||
if(stateType.unit() != Types::UnitNone) {
|
if (stateType.maxValue().isValid())
|
||||||
|
variantMap.insert("maxValue", stateType.maxValue());
|
||||||
|
|
||||||
|
if (stateType.minValue().isValid())
|
||||||
|
variantMap.insert("minValue", stateType.minValue());
|
||||||
|
|
||||||
|
if (!stateType.possibleValues().isEmpty())
|
||||||
|
variantMap.insert("possibleValues", stateType.possibleValues());
|
||||||
|
|
||||||
|
if(stateType.unit() != Types::UnitNone)
|
||||||
variantMap.insert("unit", s_unit.at(stateType.unit()));
|
variantMap.insert("unit", s_unit.at(stateType.unit()));
|
||||||
}
|
|
||||||
|
|
||||||
return variantMap;
|
return variantMap;
|
||||||
}
|
}
|
||||||
@ -851,9 +858,8 @@ ParamList JsonTypes::unpackParams(const QVariantList ¶mList)
|
|||||||
|
|
||||||
RuleActionParam JsonTypes::unpackRuleActionParam(const QVariantMap &ruleActionParamMap)
|
RuleActionParam JsonTypes::unpackRuleActionParam(const QVariantMap &ruleActionParamMap)
|
||||||
{
|
{
|
||||||
if (ruleActionParamMap.keys().count() == 0) {
|
if (ruleActionParamMap.keys().count() == 0)
|
||||||
return RuleActionParam();
|
return RuleActionParam();
|
||||||
}
|
|
||||||
|
|
||||||
QString name = ruleActionParamMap.value("name").toString();
|
QString name = ruleActionParamMap.value("name").toString();
|
||||||
QVariant value = ruleActionParamMap.value("value");
|
QVariant value = ruleActionParamMap.value("value");
|
||||||
|
|||||||
@ -222,6 +222,11 @@ JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
|||||||
// Check and unpack stateEvaluator
|
// Check and unpack stateEvaluator
|
||||||
qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
||||||
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
||||||
|
if (!stateEvaluator.isValid()) {
|
||||||
|
QVariantMap returns;
|
||||||
|
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidStateEvaluatorValue));
|
||||||
|
return createReply(returns);
|
||||||
|
}
|
||||||
|
|
||||||
// Check and unpack actions
|
// Check and unpack actions
|
||||||
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
||||||
@ -277,6 +282,11 @@ JsonReply *RulesHandler::EditRule(const QVariantMap ¶ms)
|
|||||||
// Check and unpack stateEvaluator
|
// Check and unpack stateEvaluator
|
||||||
qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
||||||
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
||||||
|
if (!stateEvaluator.isValid()) {
|
||||||
|
QVariantMap returns;
|
||||||
|
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidStateEvaluatorValue));
|
||||||
|
return createReply(returns);
|
||||||
|
}
|
||||||
|
|
||||||
// Check and unpack actions
|
// Check and unpack actions
|
||||||
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
||||||
|
|||||||
@ -259,6 +259,8 @@ HttpReply *RulesResource::addRule(const QByteArray &payload) const
|
|||||||
// Check and unpack stateEvaluator
|
// Check and unpack stateEvaluator
|
||||||
qCDebug(dcRest) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
qCDebug(dcRest) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
||||||
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
||||||
|
if (!stateEvaluator.isValid())
|
||||||
|
return createRuleErrorReply(HttpReply::BadRequest, RuleEngine::RuleErrorInvalidStateEvaluatorValue);
|
||||||
|
|
||||||
// Check and unpack actions
|
// Check and unpack actions
|
||||||
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
||||||
@ -362,6 +364,8 @@ HttpReply *RulesResource::editRule(const RuleId &ruleId, const QByteArray &paylo
|
|||||||
// Check and unpack stateEvaluator
|
// Check and unpack stateEvaluator
|
||||||
qCDebug(dcRest) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
qCDebug(dcRest) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
||||||
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
||||||
|
if (!stateEvaluator.isValid())
|
||||||
|
return createRuleErrorReply(HttpReply::BadRequest, RuleEngine::RuleErrorInvalidStateEvaluatorValue);
|
||||||
|
|
||||||
// Check and unpack actions
|
// Check and unpack actions
|
||||||
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
||||||
|
|||||||
@ -104,7 +104,7 @@ RuleEngine::RuleEngine(QObject *parent) :
|
|||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
GuhSettings settings(GuhSettings::SettingsRoleRules);
|
GuhSettings settings(GuhSettings::SettingsRoleRules);
|
||||||
qCDebug(dcRuleEngine) << "laoding rules from" << settings.fileName();
|
qCDebug(dcRuleEngine) << "loading rules from" << settings.fileName();
|
||||||
foreach (const QString &idString, settings.childGroups()) {
|
foreach (const QString &idString, settings.childGroups()) {
|
||||||
settings.beginGroup(idString);
|
settings.beginGroup(idString);
|
||||||
|
|
||||||
@ -217,9 +217,8 @@ QList<Rule> RuleEngine::evaluateEvent(const Event &event)
|
|||||||
QList<Rule> rules;
|
QList<Rule> rules;
|
||||||
foreach (const RuleId &id, m_ruleIds) {
|
foreach (const RuleId &id, m_ruleIds) {
|
||||||
Rule rule = m_rules.value(id);
|
Rule rule = m_rules.value(id);
|
||||||
if (!rule.enabled()) {
|
if (!rule.enabled())
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (rule.eventDescriptors().isEmpty()) {
|
if (rule.eventDescriptors().isEmpty()) {
|
||||||
// This rule seems to have only states, check on state changed
|
// This rule seems to have only states, check on state changed
|
||||||
@ -269,9 +268,9 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
|
|||||||
*/
|
*/
|
||||||
RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actions, const QList<RuleAction> &exitActions, bool enabled, bool executable, bool fromEdit)
|
RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actions, const QList<RuleAction> &exitActions, bool enabled, bool executable, bool fromEdit)
|
||||||
{
|
{
|
||||||
if (ruleId.isNull()) {
|
if (ruleId.isNull())
|
||||||
return RuleErrorInvalidRuleId;
|
return RuleErrorInvalidRuleId;
|
||||||
}
|
|
||||||
if (!findRule(ruleId).id().isNull()) {
|
if (!findRule(ruleId).id().isNull()) {
|
||||||
qCWarning(dcRuleEngine) << "Already have a rule with this id!";
|
qCWarning(dcRuleEngine) << "Already have a rule with this id!";
|
||||||
return RuleErrorInvalidRuleId;
|
return RuleErrorInvalidRuleId;
|
||||||
@ -298,6 +297,7 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach (const RuleAction &action, actions) {
|
foreach (const RuleAction &action, actions) {
|
||||||
Device *device = GuhCore::instance()->findConfiguredDevice(action.deviceId());
|
Device *device = GuhCore::instance()->findConfiguredDevice(action.deviceId());
|
||||||
if (!device) {
|
if (!device) {
|
||||||
@ -322,11 +322,10 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
if (actions.count() > 0)
|
||||||
if (actions.count() > 0) {
|
|
||||||
qCDebug(dcRuleEngine) << "actions" << actions.last().actionTypeId() << actions.last().ruleActionParams();
|
qCDebug(dcRuleEngine) << "actions" << actions.last().actionTypeId() << actions.last().ruleActionParams();
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const RuleAction &action, exitActions) {
|
foreach (const RuleAction &action, exitActions) {
|
||||||
Device *device = GuhCore::instance()->findConfiguredDevice(action.deviceId());
|
Device *device = GuhCore::instance()->findConfiguredDevice(action.deviceId());
|
||||||
@ -351,9 +350,9 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exitActions.count() > 0) {
|
|
||||||
|
if (exitActions.count() > 0)
|
||||||
qCDebug(dcRuleEngine) << "exit actions" << exitActions.last().actionTypeId() << exitActions.last().ruleActionParams();
|
qCDebug(dcRuleEngine) << "exit actions" << exitActions.last().actionTypeId() << exitActions.last().ruleActionParams();
|
||||||
}
|
|
||||||
|
|
||||||
Rule rule = Rule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions);
|
Rule rule = Rule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions);
|
||||||
rule.setEnabled(enabled);
|
rule.setEnabled(enabled);
|
||||||
@ -475,6 +474,7 @@ RuleEngine::RuleError RuleEngine::disableRule(const RuleId &ruleId)
|
|||||||
qCWarning(dcRuleEngine) << "Rule not found. Can't disable it";
|
qCWarning(dcRuleEngine) << "Rule not found. Can't disable it";
|
||||||
return RuleErrorRuleNotFound;
|
return RuleErrorRuleNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rule rule = m_rules.value(ruleId);
|
Rule rule = m_rules.value(ruleId);
|
||||||
rule.setEnabled(false);
|
rule.setEnabled(false);
|
||||||
m_rules[ruleId] = rule;
|
m_rules[ruleId] = rule;
|
||||||
@ -538,7 +538,6 @@ RuleEngine::RuleError RuleEngine::executeExitActions(const RuleId &ruleId)
|
|||||||
return RuleErrorNoError;
|
return RuleErrorNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Returns the \l{Rule} with the given \a ruleId. If the \l{Rule} does not exist, it will return \l{Rule::Rule()} */
|
/*! Returns the \l{Rule} with the given \a ruleId. If the \l{Rule} does not exist, it will return \l{Rule::Rule()} */
|
||||||
Rule RuleEngine::findRule(const RuleId &ruleId)
|
Rule RuleEngine::findRule(const RuleId &ruleId)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
#include "types/event.h"
|
#include "types/event.h"
|
||||||
|
#include "plugin/deviceclass.h"
|
||||||
#include "stateevaluator.h"
|
#include "stateevaluator.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@ -44,11 +45,13 @@ public:
|
|||||||
RuleErrorRuleNotFound,
|
RuleErrorRuleNotFound,
|
||||||
RuleErrorDeviceNotFound,
|
RuleErrorDeviceNotFound,
|
||||||
RuleErrorEventTypeNotFound,
|
RuleErrorEventTypeNotFound,
|
||||||
|
RuleErrorStateTypeNotFound,
|
||||||
RuleErrorActionTypeNotFound,
|
RuleErrorActionTypeNotFound,
|
||||||
RuleErrorInvalidParameter,
|
RuleErrorInvalidParameter,
|
||||||
RuleErrorInvalidRuleFormat,
|
RuleErrorInvalidRuleFormat,
|
||||||
RuleErrorMissingParameter,
|
RuleErrorMissingParameter,
|
||||||
RuleErrorInvalidRuleActionParameter,
|
RuleErrorInvalidRuleActionParameter,
|
||||||
|
RuleErrorInvalidStateEvaluatorValue,
|
||||||
RuleErrorTypesNotMatching,
|
RuleErrorTypesNotMatching,
|
||||||
RuleErrorNotExecutable,
|
RuleErrorNotExecutable,
|
||||||
RuleErrorContainsEventBasesAction,
|
RuleErrorContainsEventBasesAction,
|
||||||
|
|||||||
@ -47,7 +47,6 @@ StateEvaluator::StateEvaluator(const StateDescriptor &stateDescriptor):
|
|||||||
m_stateDescriptor(stateDescriptor),
|
m_stateDescriptor(stateDescriptor),
|
||||||
m_operatorType(Types::StateOperatorAnd)
|
m_operatorType(Types::StateOperatorAnd)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Constructs a new StateEvaluator for the given \a childEvaluators and \a stateOperator. */
|
/*! Constructs a new StateEvaluator for the given \a childEvaluators and \a stateOperator. */
|
||||||
@ -136,9 +135,9 @@ bool StateEvaluator::evaluate() const
|
|||||||
/*! Returns true if this \l StateEvaluator has a \l Device in it with the given \a deviceId. */
|
/*! Returns true if this \l StateEvaluator has a \l Device in it with the given \a deviceId. */
|
||||||
bool StateEvaluator::containsDevice(const DeviceId &deviceId) const
|
bool StateEvaluator::containsDevice(const DeviceId &deviceId) const
|
||||||
{
|
{
|
||||||
if (m_stateDescriptor.deviceId() == deviceId) {
|
if (m_stateDescriptor.deviceId() == deviceId)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
foreach (const StateEvaluator &childEvaluator, m_childEvaluators) {
|
foreach (const StateEvaluator &childEvaluator, m_childEvaluators) {
|
||||||
if (childEvaluator.containsDevice(deviceId)) {
|
if (childEvaluator.containsDevice(deviceId)) {
|
||||||
return true;
|
return true;
|
||||||
@ -150,9 +149,9 @@ bool StateEvaluator::containsDevice(const DeviceId &deviceId) const
|
|||||||
/*! Removes a \l Device with the given \a deviceId from this \l StateEvaluator. */
|
/*! Removes a \l Device with the given \a deviceId from this \l StateEvaluator. */
|
||||||
void StateEvaluator::removeDevice(const DeviceId &deviceId)
|
void StateEvaluator::removeDevice(const DeviceId &deviceId)
|
||||||
{
|
{
|
||||||
if (m_stateDescriptor.deviceId() == deviceId) {
|
if (m_stateDescriptor.deviceId() == deviceId)
|
||||||
m_stateDescriptor = StateDescriptor();
|
m_stateDescriptor = StateDescriptor();
|
||||||
}
|
|
||||||
for (int i = 0; i < m_childEvaluators.count(); i++) {
|
for (int i = 0; i < m_childEvaluators.count(); i++) {
|
||||||
m_childEvaluators[i].removeDevice(deviceId);
|
m_childEvaluators[i].removeDevice(deviceId);
|
||||||
}
|
}
|
||||||
@ -207,4 +206,74 @@ StateEvaluator StateEvaluator::loadFromSettings(GuhSettings &settings, const QSt
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Returns true, if all child evaluators are valid, the devices exist and all descriptors are in allowed paramerters.*/
|
||||||
|
bool StateEvaluator::isValid() const
|
||||||
|
{
|
||||||
|
if (m_stateDescriptor.isValid()) {
|
||||||
|
Device *device = GuhCore::instance()->findConfiguredDevice(m_stateDescriptor.deviceId());
|
||||||
|
if (!device) {
|
||||||
|
qCWarning(dcRuleEngine) << "State evaluator device does not exist!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device->hasState(m_stateDescriptor.stateTypeId())) {
|
||||||
|
qCWarning(dcRuleEngine) << "State evaluator device found, but it does not appear to have such a state!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceClass deviceClass = GuhCore::instance()->findDeviceClass(device->deviceClassId());
|
||||||
|
foreach (const StateType &stateType, deviceClass.stateTypes()) {
|
||||||
|
if (stateType.id() == m_stateDescriptor.stateTypeId()) {
|
||||||
|
|
||||||
|
if (!m_stateDescriptor.stateValue().canConvert(stateType.type())) {
|
||||||
|
qCWarning(dcRuleEngine) << "Wrong state value for state descriptor" << m_stateDescriptor.stateTypeId() << " Got:" << m_stateDescriptor.stateValue() << " Expected:" << QVariant::typeToName(stateType.type());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_stateDescriptor.stateValue().convert(stateType.type())) {
|
||||||
|
qCWarning(dcRuleEngine) << "Could not convert value of state descriptor" << m_stateDescriptor.stateTypeId() << " to:" << QVariant::typeToName(stateType.type()) << " Got:" << m_stateDescriptor.stateValue();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateType.maxValue().isValid() && m_stateDescriptor.stateValue() > stateType.maxValue()) {
|
||||||
|
qCWarning(dcRuleEngine) << "Value out of range for state descriptor" << m_stateDescriptor.stateTypeId() << " Got:" << m_stateDescriptor.stateValue() << " Max:" << stateType.maxValue();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateType.minValue().isValid() && m_stateDescriptor.stateValue() < stateType.minValue()) {
|
||||||
|
qCWarning(dcRuleEngine) << "Value out of range for state descriptor" << m_stateDescriptor.stateTypeId() << " Got:" << m_stateDescriptor.stateValue() << " Min:" << stateType.minValue();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stateType.possibleValues().isEmpty() && !stateType.possibleValues().contains(m_stateDescriptor.stateValue())) {
|
||||||
|
QStringList possibleValues;
|
||||||
|
foreach (const QVariant &value, stateType.possibleValues()) {
|
||||||
|
possibleValues.append(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
qCWarning(dcRuleEngine) << "Value not in possible values for state type" << m_stateDescriptor.stateTypeId() << " Got:" << m_stateDescriptor.stateValue() << " Possible values:" << possibleValues.join(", ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_operatorType == Types::StateOperatorOr) {
|
||||||
|
foreach (const StateEvaluator &stateEvaluator, m_childEvaluators) {
|
||||||
|
if (stateEvaluator.isValid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const StateEvaluator &stateEvaluator, m_childEvaluators) {
|
||||||
|
if (!stateEvaluator.isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,8 @@ public:
|
|||||||
void dumpToSettings(GuhSettings &settings, const QString &groupName) const;
|
void dumpToSettings(GuhSettings &settings, const QString &groupName) const;
|
||||||
static StateEvaluator loadFromSettings(GuhSettings &settings, const QString &groupPrefix);
|
static StateEvaluator loadFromSettings(GuhSettings &settings, const QString &groupPrefix);
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StateDescriptor m_stateDescriptor;
|
StateDescriptor m_stateDescriptor;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
33
|
34
|
||||||
{
|
{
|
||||||
"methods": {
|
"methods": {
|
||||||
"Actions.ExecuteAction": {
|
"Actions.ExecuteAction": {
|
||||||
@ -756,11 +756,13 @@
|
|||||||
"RuleErrorRuleNotFound",
|
"RuleErrorRuleNotFound",
|
||||||
"RuleErrorDeviceNotFound",
|
"RuleErrorDeviceNotFound",
|
||||||
"RuleErrorEventTypeNotFound",
|
"RuleErrorEventTypeNotFound",
|
||||||
|
"RuleErrorStateTypeNotFound",
|
||||||
"RuleErrorActionTypeNotFound",
|
"RuleErrorActionTypeNotFound",
|
||||||
"RuleErrorInvalidParameter",
|
"RuleErrorInvalidParameter",
|
||||||
"RuleErrorInvalidRuleFormat",
|
"RuleErrorInvalidRuleFormat",
|
||||||
"RuleErrorMissingParameter",
|
"RuleErrorMissingParameter",
|
||||||
"RuleErrorInvalidRuleActionParameter",
|
"RuleErrorInvalidRuleActionParameter",
|
||||||
|
"RuleErrorInvalidStateEvaluatorValue",
|
||||||
"RuleErrorTypesNotMatching",
|
"RuleErrorTypesNotMatching",
|
||||||
"RuleErrorNotExecutable",
|
"RuleErrorNotExecutable",
|
||||||
"RuleErrorContainsEventBasesAction",
|
"RuleErrorContainsEventBasesAction",
|
||||||
|
|||||||
Reference in New Issue
Block a user