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"')
|
||||
|
||||
# define protocol versions
|
||||
JSON_PROTOCOL_VERSION=33
|
||||
JSON_PROTOCOL_VERSION=34
|
||||
REST_API_VERSION=1
|
||||
|
||||
DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" \
|
||||
|
||||
@ -37,7 +37,6 @@
|
||||
The \a value parameter describes the new value of the State.
|
||||
*/
|
||||
|
||||
|
||||
#include "device.h"
|
||||
#include "types/event.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) {
|
||||
if (m_states.at(i).stateTypeId() == stateTypeId) {
|
||||
if (m_states.at(i).value() == value) {
|
||||
if (m_states.at(i).value() == value)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// TODO: check min/max value + possible values
|
||||
// to prevent an invalid state type
|
||||
|
||||
State newState(stateTypeId, m_id);
|
||||
newState.setValue(value);
|
||||
m_states[i] = newState;
|
||||
|
||||
@ -251,25 +251,30 @@ QList<DeviceClass> DevicePlugin::supportedDevices() const
|
||||
stateType.setType(t);
|
||||
stateType.setUnit(unitStringToUnit(st.value("unit").toString()));
|
||||
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);
|
||||
|
||||
// create ActionType if this StateType is writable
|
||||
if (st.contains("writable")) {
|
||||
ActionType actionType(st.value("id").toString());
|
||||
actionType.setName("set " + st.value("name").toString());
|
||||
if (st.contains("writable") && st.value("writable").toBool()) {
|
||||
// Note: fields already checked in StateType
|
||||
ParamType paramType(st.value("name").toString(), t, st.value("defaultValue").toVariant());
|
||||
if (st.value("writable").toObject().contains("allowedValues")) {
|
||||
QVariantList allowedValues;
|
||||
foreach (const QJsonValue &allowedTypesJson, st.value("writable").toObject().value("allowedValues").toArray()) {
|
||||
allowedValues.append(allowedTypesJson.toVariant());
|
||||
}
|
||||
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 actionType(ActionTypeId(stateType.id().toString()));
|
||||
actionType.setName("set " + stateType.name());
|
||||
ParamType paramType(stateType.name(), t, stateType.defaultValue());
|
||||
paramType.setAllowedValues(stateType.possibleValues());
|
||||
paramType.setUnit(stateType.unit());
|
||||
paramType.setLimits(stateType.minValue(), stateType.maxValue());
|
||||
actionType.setParamTypes(QList<ParamType>() << paramType);
|
||||
actionTypes.append(actionType);
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0,
|
||||
"writable": {}
|
||||
"writable": true
|
||||
|
||||
},
|
||||
{
|
||||
@ -375,7 +375,7 @@
|
||||
"unit": "DegreeCelsius",
|
||||
"type": "double",
|
||||
"defaultValue": 0,
|
||||
"writable": {}
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "576da571-9a65-478f-96bf-19256c8b9ece",
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
"name": "state",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": {}
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
"idName": "mute",
|
||||
"name": "mute",
|
||||
"type": "bool",
|
||||
"writable": {}
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "9dfe5d78-4c3f-497c-bab1-bb9fdf7e93a9",
|
||||
@ -49,10 +49,9 @@
|
||||
"name": "volume",
|
||||
"unit": "Percentage",
|
||||
"type": "int",
|
||||
"writable": {
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
}
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
}
|
||||
],
|
||||
"eventTypes": [
|
||||
|
||||
@ -234,7 +234,7 @@
|
||||
"name": "color",
|
||||
"type": "QColor",
|
||||
"defaultValue": "#000000",
|
||||
"writable": {}
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "72981c04-267a-4ba0-a59e-9921d2f3af9c",
|
||||
@ -243,10 +243,9 @@
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"writable": {
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
}
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "05f63f9c-f61e-4dcf-ad55-3f13fde2765b",
|
||||
@ -254,14 +253,13 @@
|
||||
"name": "allowed values",
|
||||
"type": "QString",
|
||||
"defaultValue": "String value 1",
|
||||
"writable": {
|
||||
"allowedValues": [
|
||||
"String value 1",
|
||||
"String value 2",
|
||||
"String value 3",
|
||||
"String value 4"
|
||||
]
|
||||
}
|
||||
"possibleValues": [
|
||||
"String value 1",
|
||||
"String value 2",
|
||||
"String value 3",
|
||||
"String value 4"
|
||||
],
|
||||
"writable": true
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
|
||||
@ -116,7 +116,7 @@
|
||||
"name": "power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": {}
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "c0f4206f-f219-4f06-93c4-4ca515a56f79",
|
||||
@ -125,10 +125,9 @@
|
||||
"type": "int",
|
||||
"unit": "Mired",
|
||||
"defaultValue": 170,
|
||||
"writable": {
|
||||
"minValue": 153,
|
||||
"maxValue": 500
|
||||
}
|
||||
"minValue": 153,
|
||||
"maxValue": 500,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "d25423e7-b924-4b20-80b6-77eecc65d089",
|
||||
@ -136,7 +135,7 @@
|
||||
"name": "color",
|
||||
"type": "QColor",
|
||||
"defaultValue": "#000000",
|
||||
"writable": {}
|
||||
"writable": true
|
||||
|
||||
},
|
||||
{
|
||||
@ -146,10 +145,10 @@
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"writable": {
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
}
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
|
||||
},
|
||||
{
|
||||
"id": "0b7cdd8d-4db8-4183-abe2-f3c01d1c9afc",
|
||||
@ -157,13 +156,11 @@
|
||||
"name": "effect",
|
||||
"type": "QString",
|
||||
"defaultValue": "none",
|
||||
"writable": {
|
||||
"allowedValues": [
|
||||
"none",
|
||||
"color loop"
|
||||
]
|
||||
}
|
||||
|
||||
"possibleValues": [
|
||||
"none",
|
||||
"color loop"
|
||||
],
|
||||
"writable": true
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
"name": "active",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": {}
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "cb8a89c2-dc12-4965-b047-57896058b421",
|
||||
@ -64,10 +64,9 @@
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"writable": {
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
}
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -124,7 +123,7 @@
|
||||
"name": "power",
|
||||
"type": "bool",
|
||||
"defaultValue": 0,
|
||||
"writable": {}
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "677cd9ec-c264-47ee-9d2e-d3662237792c",
|
||||
@ -133,10 +132,9 @@
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"defaultValue": 0,
|
||||
"writable": {
|
||||
"minValue": 0,
|
||||
"maxValue": 100
|
||||
}
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
"name": "power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": {}
|
||||
"writable": true
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
@ -104,14 +104,15 @@ def extractStateTypes(deviceClassMap):
|
||||
print("duplicated variable name \"%s\" for StateTypeId %s -> skipping") % (variableName, stateType["id"])
|
||||
# create ActionTypeId if the state is writable
|
||||
if 'writable' in stateType:
|
||||
vName = "%sActionTypeId" % (stateType["idName"])
|
||||
if not vName in variableNames:
|
||||
variableNames.append(vName)
|
||||
print("define ActionTypeId %s for writable StateType %s = %s" % (vName, variableName, stateType["id"]))
|
||||
writePluginInfo("ActionTypeId %s = ActionTypeId(\"%s\");" % (vName, stateType["id"]))
|
||||
createExternDefinition("ActionTypeId", vName)
|
||||
else:
|
||||
print("duplicated variable name \"%s\" for ActionTypeId %s -> skipping") % (variableName, stateType["id"])
|
||||
if stateType['writable']:
|
||||
vName = "%sActionTypeId" % (stateType["idName"])
|
||||
if not vName in variableNames:
|
||||
variableNames.append(vName)
|
||||
print("define ActionTypeId %s for writable StateType %s = %s" % (vName, variableName, stateType["id"]))
|
||||
writePluginInfo("ActionTypeId %s = ActionTypeId(\"%s\");" % (vName, stateType["id"]))
|
||||
createExternDefinition("ActionTypeId", vName)
|
||||
else:
|
||||
print("duplicated variable name \"%s\" for ActionTypeId %s -> skipping") % (variableName, stateType["id"])
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
|
||||
@ -227,7 +227,6 @@ void JsonTypes::init()
|
||||
s_ruleDescription.insert("active", basicTypeToString(Bool));
|
||||
s_ruleDescription.insert("executable", basicTypeToString(Bool));
|
||||
|
||||
|
||||
// LogEntry
|
||||
s_logEntry.insert("timestamp", basicTypeToString(Int));
|
||||
s_logEntry.insert("loggingLevel", loggingLevelRef());
|
||||
@ -411,9 +410,17 @@ QVariantMap JsonTypes::packStateType(const StateType &stateType)
|
||||
variantMap.insert("type", basicTypeToString(stateType.type()));
|
||||
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()));
|
||||
}
|
||||
|
||||
return variantMap;
|
||||
}
|
||||
@ -851,9 +858,8 @@ ParamList JsonTypes::unpackParams(const QVariantList ¶mList)
|
||||
|
||||
RuleActionParam JsonTypes::unpackRuleActionParam(const QVariantMap &ruleActionParamMap)
|
||||
{
|
||||
if (ruleActionParamMap.keys().count() == 0) {
|
||||
if (ruleActionParamMap.keys().count() == 0)
|
||||
return RuleActionParam();
|
||||
}
|
||||
|
||||
QString name = ruleActionParamMap.value("name").toString();
|
||||
QVariant value = ruleActionParamMap.value("value");
|
||||
|
||||
@ -222,6 +222,11 @@ JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
||||
// Check and unpack stateEvaluator
|
||||
qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << 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
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
||||
@ -277,6 +282,11 @@ JsonReply *RulesHandler::EditRule(const QVariantMap ¶ms)
|
||||
// Check and unpack stateEvaluator
|
||||
qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << 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
|
||||
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
|
||||
qCDebug(dcRest) << "unpacking stateEvaluator:" << 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
|
||||
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
|
||||
qCDebug(dcRest) << "unpacking stateEvaluator:" << 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
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList);
|
||||
|
||||
@ -104,7 +104,7 @@ RuleEngine::RuleEngine(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
GuhSettings settings(GuhSettings::SettingsRoleRules);
|
||||
qCDebug(dcRuleEngine) << "laoding rules from" << settings.fileName();
|
||||
qCDebug(dcRuleEngine) << "loading rules from" << settings.fileName();
|
||||
foreach (const QString &idString, settings.childGroups()) {
|
||||
settings.beginGroup(idString);
|
||||
|
||||
@ -217,9 +217,8 @@ QList<Rule> RuleEngine::evaluateEvent(const Event &event)
|
||||
QList<Rule> rules;
|
||||
foreach (const RuleId &id, m_ruleIds) {
|
||||
Rule rule = m_rules.value(id);
|
||||
if (!rule.enabled()) {
|
||||
if (!rule.enabled())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rule.eventDescriptors().isEmpty()) {
|
||||
// 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)
|
||||
{
|
||||
if (ruleId.isNull()) {
|
||||
if (ruleId.isNull())
|
||||
return RuleErrorInvalidRuleId;
|
||||
}
|
||||
|
||||
if (!findRule(ruleId).id().isNull()) {
|
||||
qCWarning(dcRuleEngine) << "Already have a rule with this id!";
|
||||
return RuleErrorInvalidRuleId;
|
||||
@ -298,6 +297,7 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach (const RuleAction &action, actions) {
|
||||
Device *device = GuhCore::instance()->findConfiguredDevice(action.deviceId());
|
||||
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();
|
||||
}
|
||||
|
||||
foreach (const RuleAction &action, exitActions) {
|
||||
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();
|
||||
}
|
||||
|
||||
Rule rule = Rule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions);
|
||||
rule.setEnabled(enabled);
|
||||
@ -475,6 +474,7 @@ RuleEngine::RuleError RuleEngine::disableRule(const RuleId &ruleId)
|
||||
qCWarning(dcRuleEngine) << "Rule not found. Can't disable it";
|
||||
return RuleErrorRuleNotFound;
|
||||
}
|
||||
|
||||
Rule rule = m_rules.value(ruleId);
|
||||
rule.setEnabled(false);
|
||||
m_rules[ruleId] = rule;
|
||||
@ -538,7 +538,6 @@ RuleEngine::RuleError RuleEngine::executeExitActions(const RuleId &ruleId)
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
|
||||
|
||||
/*! 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)
|
||||
{
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include "rule.h"
|
||||
#include "types/event.h"
|
||||
#include "plugin/deviceclass.h"
|
||||
#include "stateevaluator.h"
|
||||
|
||||
#include <QObject>
|
||||
@ -44,11 +45,13 @@ public:
|
||||
RuleErrorRuleNotFound,
|
||||
RuleErrorDeviceNotFound,
|
||||
RuleErrorEventTypeNotFound,
|
||||
RuleErrorStateTypeNotFound,
|
||||
RuleErrorActionTypeNotFound,
|
||||
RuleErrorInvalidParameter,
|
||||
RuleErrorInvalidRuleFormat,
|
||||
RuleErrorMissingParameter,
|
||||
RuleErrorInvalidRuleActionParameter,
|
||||
RuleErrorInvalidStateEvaluatorValue,
|
||||
RuleErrorTypesNotMatching,
|
||||
RuleErrorNotExecutable,
|
||||
RuleErrorContainsEventBasesAction,
|
||||
|
||||
@ -47,7 +47,6 @@ StateEvaluator::StateEvaluator(const StateDescriptor &stateDescriptor):
|
||||
m_stateDescriptor(stateDescriptor),
|
||||
m_operatorType(Types::StateOperatorAnd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! 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. */
|
||||
bool StateEvaluator::containsDevice(const DeviceId &deviceId) const
|
||||
{
|
||||
if (m_stateDescriptor.deviceId() == deviceId) {
|
||||
if (m_stateDescriptor.deviceId() == deviceId)
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (const StateEvaluator &childEvaluator, m_childEvaluators) {
|
||||
if (childEvaluator.containsDevice(deviceId)) {
|
||||
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. */
|
||||
void StateEvaluator::removeDevice(const DeviceId &deviceId)
|
||||
{
|
||||
if (m_stateDescriptor.deviceId() == deviceId) {
|
||||
if (m_stateDescriptor.deviceId() == deviceId)
|
||||
m_stateDescriptor = StateDescriptor();
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_childEvaluators.count(); i++) {
|
||||
m_childEvaluators[i].removeDevice(deviceId);
|
||||
}
|
||||
@ -207,4 +206,74 @@ StateEvaluator StateEvaluator::loadFromSettings(GuhSettings &settings, const QSt
|
||||
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;
|
||||
static StateEvaluator loadFromSettings(GuhSettings &settings, const QString &groupPrefix);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
StateDescriptor m_stateDescriptor;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
33
|
||||
34
|
||||
{
|
||||
"methods": {
|
||||
"Actions.ExecuteAction": {
|
||||
@ -756,11 +756,13 @@
|
||||
"RuleErrorRuleNotFound",
|
||||
"RuleErrorDeviceNotFound",
|
||||
"RuleErrorEventTypeNotFound",
|
||||
"RuleErrorStateTypeNotFound",
|
||||
"RuleErrorActionTypeNotFound",
|
||||
"RuleErrorInvalidParameter",
|
||||
"RuleErrorInvalidRuleFormat",
|
||||
"RuleErrorMissingParameter",
|
||||
"RuleErrorInvalidRuleActionParameter",
|
||||
"RuleErrorInvalidStateEvaluatorValue",
|
||||
"RuleErrorTypesNotMatching",
|
||||
"RuleErrorNotExecutable",
|
||||
"RuleErrorContainsEventBasesAction",
|
||||
|
||||
Reference in New Issue
Block a user