add Rules.EditRule method and Rules.CRuleConfigurationChanged notification
This commit is contained in:
parent
f125511994
commit
85ba7af29c
2
guh.pri
2
guh.pri
@ -2,7 +2,7 @@
|
||||
GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"')
|
||||
|
||||
# define JSON protocol version
|
||||
JSON_PROTOCOL_VERSION=26
|
||||
JSON_PROTOCOL_VERSION=27
|
||||
|
||||
DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" JSON_PROTOCOL_VERSION=\\\"$${JSON_PROTOCOL_VERSION}\\\"
|
||||
|
||||
|
||||
@ -339,6 +339,11 @@ RuleEngine::RuleError GuhCore::addRule(const RuleId &id, const QString &name, co
|
||||
return m_ruleEngine->addRule(id, name, eventDescriptorList, stateEvaluator, actionList, exitActionList, enabled);
|
||||
}
|
||||
|
||||
RuleEngine::RuleError GuhCore::editRule(const RuleId &id, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actionList, const QList<RuleAction> &exitActionList, bool enabled)
|
||||
{
|
||||
return m_ruleEngine->editRule(id, name, eventDescriptorList, stateEvaluator, actionList, exitActionList, enabled);
|
||||
}
|
||||
|
||||
/*! Calls the metheod RuleEngine::removeRule(\a id).
|
||||
* \sa RuleEngine, */
|
||||
RuleEngine::RuleError GuhCore::removeRule(const RuleId &id)
|
||||
@ -406,6 +411,7 @@ GuhCore::GuhCore(QObject *parent) :
|
||||
|
||||
connect(m_ruleEngine, &RuleEngine::ruleAdded, this, &GuhCore::ruleAdded);
|
||||
connect(m_ruleEngine, &RuleEngine::ruleRemoved, this, &GuhCore::ruleRemoved);
|
||||
connect(m_ruleEngine, &RuleEngine::ruleConfigurationChanged, this, &GuhCore::ruleConfigurationChanged);
|
||||
|
||||
m_logger->logSystemEvent(true);
|
||||
}
|
||||
|
||||
@ -82,6 +82,7 @@ public:
|
||||
QList<RuleId> ruleIds() const;
|
||||
Rule findRule(const RuleId &ruleId);
|
||||
RuleEngine::RuleError addRule(const RuleId &id, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actionList, const QList<RuleAction> &exitActionList, bool enabled = true);
|
||||
RuleEngine::RuleError editRule(const RuleId &id, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actionList, const QList<RuleAction> &exitActionList, bool enabled = true);
|
||||
RuleEngine::RuleError removeRule(const RuleId &id);
|
||||
QList<RuleId> findRules(const DeviceId &deviceId);
|
||||
RuleEngine::RuleError enableRule(const RuleId &ruleId);
|
||||
@ -105,6 +106,7 @@ signals:
|
||||
void ruleRemoved(const RuleId &ruleId);
|
||||
void ruleAdded(const Rule &rule);
|
||||
void ruleActiveChanged(const Rule &rule);
|
||||
void ruleConfigurationChanged(const Rule &rule);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -66,6 +66,25 @@ RulesHandler::RulesHandler(QObject *parent) :
|
||||
returns.insert("o:ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
setReturns("AddRule", returns);
|
||||
|
||||
params.clear(); returns.clear(); actions.clear();
|
||||
setDescription("EditRule", "Edit the parameters of a rule. The configuration of the rule with the given ruleId "
|
||||
"will be replaced with the new given configuration. In ordert to enable or disable a Rule, please use the "
|
||||
"methods \"Rules.EnableRule\" and \"Rules.DisableRule\". If successfull, the notification \"Rule.RuleConfigurationChanged\" "
|
||||
"will be emitted.");
|
||||
params.insert("ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef());
|
||||
params.insert("o:eventDescriptorList", QVariantList() << JsonTypes::eventDescriptorRef());
|
||||
params.insert("o:stateEvaluator", JsonTypes::stateEvaluatorRef());
|
||||
params.insert("o:exitActions", QVariantList() << JsonTypes::ruleActionRef());
|
||||
params.insert("o:enabled", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
actions.append(JsonTypes::ruleActionRef());
|
||||
params.insert("actions", actions);
|
||||
setParams("EditRule", params);
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorRef());
|
||||
returns.insert("o:rule", JsonTypes::ruleRef());
|
||||
setReturns("EditRule", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("RemoveRule", "Remove a rule");
|
||||
params.insert("ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
@ -81,14 +100,16 @@ RulesHandler::RulesHandler(QObject *parent) :
|
||||
setReturns("FindRules", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("EnableRule", "Enabled a rule that has previously been disabled.");
|
||||
setDescription("EnableRule", "Enabled a rule that has previously been disabled."
|
||||
"If successfull, the notification \"Rule.RuleConfigurationChanged\" will be emitted.");
|
||||
params.insert("ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
setParams("EnableRule", params);
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorRef());
|
||||
setReturns("EnableRule", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("DisableRule", "Disable a rule. The rule won't be triggered by it's events or state changes while it is disabled.");
|
||||
setDescription("DisableRule", "Disable a rule. The rule won't be triggered by it's events or state changes while it is disabled. "
|
||||
"If successfull, the notification \"Rule.RuleConfigurationChanged\" will be emitted.");
|
||||
params.insert("ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
setParams("DisableRule", params);
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorRef());
|
||||
@ -111,9 +132,15 @@ RulesHandler::RulesHandler(QObject *parent) :
|
||||
params.insert("active", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||
setParams("RuleActiveChanged", params);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("RuleConfigurationChanged", "Emitted whenever the configuration of a Rule changed.");
|
||||
params.insert("rule", JsonTypes::ruleRef());
|
||||
setParams("RuleConfigurationChanged", params);
|
||||
|
||||
connect(GuhCore::instance(), &GuhCore::ruleAdded, this, &RulesHandler::ruleAddedNotification);
|
||||
connect(GuhCore::instance(), &GuhCore::ruleRemoved, this, &RulesHandler::ruleRemovedNotification);
|
||||
connect(GuhCore::instance(), &GuhCore::ruleActiveChanged, this, &RulesHandler::ruleActiveChangedNotification);
|
||||
connect(GuhCore::instance(), &GuhCore::ruleConfigurationChanged, this, &RulesHandler::ruleConfigurationChangedNotification);
|
||||
}
|
||||
|
||||
QString RulesHandler::name() const
|
||||
@ -149,35 +176,76 @@ JsonReply *RulesHandler::GetRuleDetails(const QVariantMap ¶ms)
|
||||
|
||||
JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
||||
{
|
||||
if (params.contains("eventDescriptor") && params.contains("eventDescriptorList")) {
|
||||
// check rule consistency
|
||||
RuleEngine::RuleError ruleConsistencyError = verifyRuleConsistency(params);
|
||||
if (ruleConsistencyError != RuleEngine::RuleErrorNoError) {
|
||||
QVariantMap returns;
|
||||
qCWarning(dcJsonRpc) << "Only one of eventDesciptor or eventDescriptorList may be used.";
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidParameter));
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(ruleConsistencyError));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
if (params.contains("eventDescriptor") || params.contains("eventDescriptorList")) {
|
||||
if (params.contains("exitActions")) {
|
||||
QVariantMap returns;
|
||||
qCWarning(dcJsonRpc) << "The exitActions will never be executed if the rule contains an eventDescriptor.";
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleFormat));
|
||||
return createReply(returns);
|
||||
}
|
||||
// Check and upack eventDescriptorList
|
||||
QPair<QList<EventDescriptor>, RuleEngine::RuleError> eventDescriptorVerification = verifyEventDescriptors(params);
|
||||
QList<EventDescriptor> eventDescriptorList = eventDescriptorVerification.first;
|
||||
if (eventDescriptorVerification.second != RuleEngine::RuleErrorNoError) {
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(eventDescriptorVerification.second));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
// Check and unpack eventDescriptors
|
||||
QList<EventDescriptor> eventDescriptorList;
|
||||
if (params.contains("eventDescriptor")) {
|
||||
QVariantMap eventMap = params.value("eventDescriptor").toMap();
|
||||
qCDebug(dcJsonRpc) << "unpacking eventDescriptor" << eventMap;
|
||||
eventDescriptorList.append(JsonTypes::unpackEventDescriptor(eventMap));
|
||||
} else if (params.contains("eventDescriptorList")) {
|
||||
QVariantList eventDescriptors = params.value("eventDescriptorList").toList();
|
||||
qCDebug(dcJsonRpc) << "unpacking eventDescriptorList:" << eventDescriptors;
|
||||
foreach (const QVariant &eventVariant, eventDescriptors) {
|
||||
QVariantMap eventMap = eventVariant.toMap();
|
||||
eventDescriptorList.append(JsonTypes::unpackEventDescriptor(eventMap));
|
||||
}
|
||||
|
||||
// Check and unpack stateEvaluator
|
||||
qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap();
|
||||
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
||||
|
||||
// Check and unpack actions
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = verifyActions(params, eventDescriptorList);
|
||||
QList<RuleAction> actions = actionsVerification.first;
|
||||
if (actionsVerification.second != RuleEngine::RuleErrorNoError) {
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(actionsVerification.second));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
// Check and unpack exitActions
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> exitActionsVerification = verifyExitActions(params);
|
||||
QList<RuleAction> exitActions = exitActionsVerification.first;
|
||||
if (exitActionsVerification.second != RuleEngine::RuleErrorNoError) {
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(exitActionsVerification.second));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
QString name = params.value("name", QString()).toString();
|
||||
bool enabled = params.value("enabled", true).toBool();
|
||||
|
||||
RuleId newRuleId = RuleId::createRuleId();
|
||||
RuleEngine::RuleError status = GuhCore::instance()->addRule(newRuleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled);
|
||||
QVariantMap returns;
|
||||
if (status == RuleEngine::RuleErrorNoError) {
|
||||
returns.insert("ruleId", newRuleId.toString());
|
||||
}
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(status));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *RulesHandler::EditRule(const QVariantMap ¶ms)
|
||||
{
|
||||
// check rule consistency
|
||||
RuleEngine::RuleError ruleConsistencyError = verifyRuleConsistency(params);
|
||||
if (ruleConsistencyError != RuleEngine::RuleErrorNoError) {
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(ruleConsistencyError));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
// Check and upack eventDescriptorList
|
||||
QPair<QList<EventDescriptor>, RuleEngine::RuleError> eventDescriptorVerification = verifyEventDescriptors(params);
|
||||
QList<EventDescriptor> eventDescriptorList = eventDescriptorVerification.first;
|
||||
if (eventDescriptorVerification.second != RuleEngine::RuleErrorNoError) {
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(eventDescriptorVerification.second));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
// Check and unpack stateEvaluator
|
||||
@ -185,97 +253,31 @@ JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
||||
StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap());
|
||||
|
||||
// Check and unpack actions
|
||||
QList<RuleAction> actions;
|
||||
QVariantList actionList = params.value("actions").toList();
|
||||
qCDebug(dcJsonRpc) << "unpacking actions:" << actionList;
|
||||
foreach (const QVariant &actionVariant, actionList) {
|
||||
QVariantMap actionMap = actionVariant.toMap();
|
||||
RuleAction action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString()));
|
||||
RuleActionParamList actionParamList = JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList());
|
||||
foreach (const RuleActionParam &ruleActionParam, actionParamList) {
|
||||
if (!ruleActionParam.isValid()) {
|
||||
qCWarning(dcJsonRpc) << "got an actionParam with value AND eventTypeId!";
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
|
||||
return createReply(returns);
|
||||
}
|
||||
}
|
||||
|
||||
action.setRuleActionParams(actionParamList);
|
||||
actions.append(action);
|
||||
}
|
||||
|
||||
// check possible eventTypeIds in params
|
||||
foreach (const RuleAction &ruleAction, actions) {
|
||||
if (ruleAction.isEventBased()) {
|
||||
foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) {
|
||||
if (ruleActionParam.eventTypeId() != EventTypeId()) {
|
||||
// We have an eventTypeId
|
||||
if (eventDescriptorList.isEmpty()) {
|
||||
QVariantMap returns;
|
||||
qCWarning(dcJsonRpc) << "RuleAction" << ruleAction.actionTypeId() << "contains an eventTypeId, but there are no eventDescriptors.";
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
|
||||
return createReply(returns);
|
||||
}
|
||||
// now check if this eventType is in the eventDescriptorList of this rule
|
||||
if (!checkEventDescriptors(eventDescriptorList, ruleActionParam.eventTypeId())) {
|
||||
QVariantMap returns;
|
||||
qCWarning(dcJsonRpc) << "eventTypeId from RuleAction" << ruleAction.actionTypeId() << "missing in eventDescriptors.";
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
// check if the param type of the event and the action match
|
||||
QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamName());
|
||||
QVariant::Type actionParamType = getActionParamType(ruleAction.actionTypeId(), ruleActionParam.name());
|
||||
if (eventParamType != actionParamType) {
|
||||
QVariantMap returns;
|
||||
qCWarning(dcJsonRpc) << "RuleActionParam" << ruleActionParam.name() << " and given event param " << ruleActionParam.eventParamName() << "have not the same type:";
|
||||
qCWarning(dcJsonRpc) << " -> actionParamType:" << actionParamType;
|
||||
qCWarning(dcJsonRpc) << " -> eventParamType:" << eventParamType;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorTypesNotMatching));
|
||||
return createReply(returns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QVariantMap returns;
|
||||
if (actions.count() == 0) {
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorMissingParameter));
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> actionsVerification = verifyActions(params, eventDescriptorList);
|
||||
QList<RuleAction> actions = actionsVerification.first;
|
||||
if (actionsVerification.second != RuleEngine::RuleErrorNoError) {
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(actionsVerification.second));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
// Check and unpack exitActions
|
||||
QList<RuleAction> exitActions;
|
||||
if (params.contains("exitActions")) {
|
||||
QVariantList exitActionList = params.value("exitActions").toList();
|
||||
qCDebug(dcJsonRpc) << "unpacking exitActions:" << exitActionList;
|
||||
foreach (const QVariant &actionVariant, exitActionList) {
|
||||
QVariantMap actionMap = actionVariant.toMap();
|
||||
RuleAction action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString()));
|
||||
if (action.isEventBased()) {
|
||||
qCWarning(dcJsonRpc) << "got exitAction with a param value containing an eventTypeId!";
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleActionParameter));
|
||||
return createReply(returns);
|
||||
}
|
||||
action.setRuleActionParams(JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList()));
|
||||
qCDebug(dcJsonRpc) << "params in exitAction" << action.ruleActionParams();
|
||||
exitActions.append(action);
|
||||
}
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> exitActionsVerification = verifyExitActions(params);
|
||||
QList<RuleAction> exitActions = exitActionsVerification.first;
|
||||
if (exitActionsVerification.second != RuleEngine::RuleErrorNoError) {
|
||||
QVariantMap returns;
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(exitActionsVerification.second));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
|
||||
QString name = params.value("name", QString()).toString();
|
||||
bool enabled = params.value("enabled", true).toBool();
|
||||
|
||||
RuleId newRuleId = RuleId::createRuleId();
|
||||
RuleEngine::RuleError status = GuhCore::instance()->addRule(newRuleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled);
|
||||
RuleId ruleId = RuleId(params.value("ruleId").toString());
|
||||
RuleEngine::RuleError status = GuhCore::instance()->editRule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled);
|
||||
QVariantMap returns;
|
||||
if (status == RuleEngine::RuleErrorNoError) {
|
||||
returns.insert("ruleId", newRuleId.toString());
|
||||
returns.insert("ruleId", ruleId.toString());
|
||||
}
|
||||
returns.insert("ruleError", JsonTypes::ruleErrorToString(status));
|
||||
return createReply(returns);
|
||||
@ -358,6 +360,125 @@ bool RulesHandler::checkEventDescriptors(const QList<EventDescriptor> eventDescr
|
||||
return false;
|
||||
}
|
||||
|
||||
RuleEngine::RuleError RulesHandler::verifyRuleConsistency(const QVariantMap ¶ms)
|
||||
{
|
||||
// check if there are an eventDescriptor and an eventDescriptorList
|
||||
if (params.contains("eventDescriptor") && params.contains("eventDescriptorList")) {
|
||||
qCWarning(dcJsonRpc) << "Only one of eventDesciptor or eventDescriptorList may be used.";
|
||||
return RuleEngine::RuleErrorInvalidParameter;
|
||||
}
|
||||
|
||||
// check if this rules is based on any event and contains exit actions
|
||||
if (params.contains("eventDescriptor") || params.contains("eventDescriptorList")) {
|
||||
if (params.contains("exitActions")) {
|
||||
qCWarning(dcJsonRpc) << "The exitActions will never be executed if the rule contains an eventDescriptor.";
|
||||
return RuleEngine::RuleErrorInvalidRuleFormat;
|
||||
}
|
||||
}
|
||||
|
||||
// check if there are any actions
|
||||
if (params.value("actions").toList().isEmpty()) {
|
||||
qCWarning(dcJsonRpc) << "Rule actions missing. A rule without actions has no effect.";
|
||||
return RuleEngine::RuleErrorMissingParameter;
|
||||
}
|
||||
|
||||
// TODO: check if events and stateEvaluators are missing
|
||||
|
||||
return RuleEngine::RuleErrorNoError;
|
||||
}
|
||||
|
||||
QPair<QList<EventDescriptor>, RuleEngine::RuleError> RulesHandler::verifyEventDescriptors(const QVariantMap ¶ms)
|
||||
{
|
||||
// Check and unpack eventDescriptors
|
||||
QList<EventDescriptor> eventDescriptorList = QList<EventDescriptor>();
|
||||
if (params.contains("eventDescriptor")) {
|
||||
QVariantMap eventMap = params.value("eventDescriptor").toMap();
|
||||
qCDebug(dcJsonRpc) << "unpacking eventDescriptor" << eventMap;
|
||||
eventDescriptorList.append(JsonTypes::unpackEventDescriptor(eventMap));
|
||||
} else if (params.contains("eventDescriptorList")) {
|
||||
QVariantList eventDescriptors = params.value("eventDescriptorList").toList();
|
||||
qCDebug(dcJsonRpc) << "unpacking eventDescriptorList:" << eventDescriptors;
|
||||
foreach (const QVariant &eventVariant, eventDescriptors) {
|
||||
QVariantMap eventMap = eventVariant.toMap();
|
||||
eventDescriptorList.append(JsonTypes::unpackEventDescriptor(eventMap));
|
||||
}
|
||||
}
|
||||
return QPair<QList<EventDescriptor>, RuleEngine::RuleError>(eventDescriptorList, RuleEngine::RuleErrorNoError);
|
||||
}
|
||||
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> RulesHandler::verifyActions(const QVariantMap ¶ms, const QList<EventDescriptor> &eventDescriptorList)
|
||||
{
|
||||
QList<RuleAction> actions;
|
||||
QVariantList actionList = params.value("actions").toList();
|
||||
qCDebug(dcJsonRpc) << "unpacking actions:" << actionList;
|
||||
foreach (const QVariant &actionVariant, actionList) {
|
||||
QVariantMap actionMap = actionVariant.toMap();
|
||||
RuleAction action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString()));
|
||||
RuleActionParamList actionParamList = JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList());
|
||||
foreach (const RuleActionParam &ruleActionParam, actionParamList) {
|
||||
if (!ruleActionParam.isValid()) {
|
||||
qCWarning(dcJsonRpc) << "got an actionParam with value AND eventTypeId!";
|
||||
return QPair<QList<RuleAction>, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorInvalidRuleActionParameter);
|
||||
}
|
||||
}
|
||||
qCDebug(dcJsonRpc) << "params in exitAction" << action.ruleActionParams();
|
||||
action.setRuleActionParams(actionParamList);
|
||||
actions.append(action);
|
||||
}
|
||||
|
||||
// check possible eventTypeIds in params
|
||||
foreach (const RuleAction &ruleAction, actions) {
|
||||
if (ruleAction.isEventBased()) {
|
||||
foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) {
|
||||
if (ruleActionParam.eventTypeId() != EventTypeId()) {
|
||||
// We have an eventTypeId
|
||||
if (eventDescriptorList.isEmpty()) {
|
||||
qCWarning(dcJsonRpc) << "RuleAction" << ruleAction.actionTypeId() << "contains an eventTypeId, but there are no eventDescriptors.";
|
||||
return QPair<QList<RuleAction>, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorInvalidRuleActionParameter);
|
||||
}
|
||||
// now check if this eventType is in the eventDescriptorList of this rule
|
||||
if (!checkEventDescriptors(eventDescriptorList, ruleActionParam.eventTypeId())) {
|
||||
qCWarning(dcJsonRpc) << "eventTypeId from RuleAction" << ruleAction.actionTypeId() << "missing in eventDescriptors.";
|
||||
return QPair<QList<RuleAction>, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorInvalidRuleActionParameter);
|
||||
}
|
||||
|
||||
// check if the param type of the event and the action match
|
||||
QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamName());
|
||||
QVariant::Type actionParamType = getActionParamType(ruleAction.actionTypeId(), ruleActionParam.name());
|
||||
if (eventParamType != actionParamType) {
|
||||
qCWarning(dcJsonRpc) << "RuleActionParam" << ruleActionParam.name() << " and given event param " << ruleActionParam.eventParamName() << "have not the same type:";
|
||||
qCWarning(dcJsonRpc) << " -> actionParamType:" << actionParamType;
|
||||
qCWarning(dcJsonRpc) << " -> eventParamType:" << eventParamType;
|
||||
return QPair<QList<RuleAction>, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorTypesNotMatching);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return QPair<QList<RuleAction>, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorNoError);
|
||||
}
|
||||
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> RulesHandler::verifyExitActions(const QVariantMap ¶ms)
|
||||
{
|
||||
QList<RuleAction> exitActions;
|
||||
if (params.contains("exitActions")) {
|
||||
QVariantList exitActionList = params.value("exitActions").toList();
|
||||
qCDebug(dcJsonRpc) << "unpacking exitActions:" << exitActionList;
|
||||
foreach (const QVariant &actionVariant, exitActionList) {
|
||||
QVariantMap actionMap = actionVariant.toMap();
|
||||
RuleAction action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString()));
|
||||
if (action.isEventBased()) {
|
||||
qCWarning(dcJsonRpc) << "got exitAction with a param value containing an eventTypeId!";
|
||||
return QPair<QList<RuleAction>, RuleEngine::RuleError>(exitActions, RuleEngine::RuleErrorInvalidRuleActionParameter);
|
||||
}
|
||||
qCDebug(dcJsonRpc) << "params in exitAction" << action.ruleActionParams();
|
||||
action.setRuleActionParams(JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList()));
|
||||
exitActions.append(action);
|
||||
}
|
||||
}
|
||||
return QPair<QList<RuleAction>, RuleEngine::RuleError>(exitActions, RuleEngine::RuleErrorNoError);
|
||||
}
|
||||
|
||||
void RulesHandler::ruleRemovedNotification(const RuleId &ruleId)
|
||||
{
|
||||
QVariantMap params;
|
||||
@ -382,3 +503,11 @@ void RulesHandler::ruleActiveChangedNotification(const Rule &rule)
|
||||
|
||||
emit RuleActiveChanged(params);
|
||||
}
|
||||
|
||||
void RulesHandler::ruleConfigurationChangedNotification(const Rule &rule)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("rule", JsonTypes::packRule(rule));
|
||||
|
||||
emit RuleConfigurationChanged(params);
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ public:
|
||||
Q_INVOKABLE JsonReply* GetRuleDetails(const QVariantMap ¶ms);
|
||||
|
||||
Q_INVOKABLE JsonReply* AddRule(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply* EditRule(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply* RemoveRule(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply* FindRules(const QVariantMap ¶ms);
|
||||
|
||||
@ -46,6 +47,7 @@ signals:
|
||||
void RuleRemoved(const QVariantMap ¶ms);
|
||||
void RuleAdded(const QVariantMap ¶ms);
|
||||
void RuleActiveChanged(const QVariantMap ¶ms);
|
||||
void RuleConfigurationChanged(const QVariantMap ¶ms);
|
||||
|
||||
private:
|
||||
QVariant::Type getActionParamType(const ActionTypeId &actionTypeId, const QString ¶mName);
|
||||
@ -53,10 +55,16 @@ private:
|
||||
|
||||
bool checkEventDescriptors(const QList<EventDescriptor> eventDescriptors, const EventTypeId &eventTypeId);
|
||||
|
||||
RuleEngine::RuleError verifyRuleConsistency(const QVariantMap ¶ms);
|
||||
QPair<QList<EventDescriptor>, RuleEngine::RuleError> verifyEventDescriptors(const QVariantMap ¶ms);
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> verifyActions(const QVariantMap ¶ms, const QList<EventDescriptor> &eventDescriptorList);
|
||||
QPair<QList<RuleAction>, RuleEngine::RuleError> verifyExitActions(const QVariantMap ¶ms);
|
||||
|
||||
private slots:
|
||||
void ruleRemovedNotification(const RuleId &ruleId);
|
||||
void ruleAddedNotification(const Rule &rule);
|
||||
void ruleActiveChangedNotification(const Rule &rule);
|
||||
void ruleConfigurationChangedNotification(const Rule &rule);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -42,6 +42,10 @@
|
||||
\a ruleId holds the id of the removed rule. You should remove any references
|
||||
or copies you hold for this rule.*/
|
||||
|
||||
/*! \fn void RuleEngine::ruleConfigurationChanged(const RuleId &ruleId)
|
||||
Will be emitted whenever a \l{Rule} changed his enable/disable status.
|
||||
\a ruleId holds the id of the changed rule.*/
|
||||
|
||||
/*! \enum RuleEngine::RuleError
|
||||
\value RuleErrorNoError
|
||||
No error happened. Everything is fine.
|
||||
@ -255,8 +259,10 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
|
||||
return addRule(ruleId, name, eventDescriptorList, StateEvaluator(), actions, QList<RuleAction>(), enabled);
|
||||
}
|
||||
|
||||
/*! Add a new \l{Rule} with the given \a ruleId, \a name, \a eventDescriptorList, \a stateEvaluator, the list of \a actions the list of \a exitActions and the \a enabled value to the engine.*/
|
||||
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)
|
||||
/*! Add a new \l{Rule} with the given \a ruleId, \a name, \a eventDescriptorList, \a stateEvaluator, the list of \a actions the list of \a exitActions and the \a enabled value to the engine.
|
||||
If \a fromEdit is true, the notification Rules.RuleAdded will not be emitted.
|
||||
*/
|
||||
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 fromEdit)
|
||||
{
|
||||
if (ruleId.isNull()) {
|
||||
return RuleErrorInvalidRuleId;
|
||||
@ -266,8 +272,6 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
|
||||
return RuleErrorInvalidRuleId;
|
||||
}
|
||||
|
||||
// TODO: check rule name for duplicated rulesnames
|
||||
|
||||
foreach (const EventDescriptor &eventDescriptor, eventDescriptorList) {
|
||||
Device *device = GuhCore::instance()->findConfiguredDevice(eventDescriptor.deviceId());
|
||||
if (!device) {
|
||||
@ -337,70 +341,37 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n
|
||||
Rule rule = Rule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions);
|
||||
rule.setEnabled(enabled);
|
||||
appendRule(rule);
|
||||
emit ruleAdded(rule);
|
||||
saveRule(rule);
|
||||
if (!fromEdit)
|
||||
emit ruleAdded(rule);
|
||||
|
||||
// Save Events / EventDescriptors
|
||||
QSettings settings(m_settingsFile);
|
||||
settings.beginGroup(rule.id().toString());
|
||||
settings.setValue("name", name);
|
||||
settings.setValue("enabled", enabled);
|
||||
settings.beginGroup("events");
|
||||
for (int i = 0; i < eventDescriptorList.count(); i++) {
|
||||
const EventDescriptor &eventDescriptor = eventDescriptorList.at(i);
|
||||
settings.beginGroup("EventDescriptor-" + QString::number(i));
|
||||
settings.setValue("deviceId", eventDescriptor.deviceId().toString());
|
||||
settings.setValue("eventTypeId", eventDescriptor.eventTypeId().toString());
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
|
||||
foreach (const ParamDescriptor ¶mDescriptor, eventDescriptor.paramDescriptors()) {
|
||||
settings.beginGroup("ParamDescriptor-" + paramDescriptor.name());
|
||||
settings.setValue("value", paramDescriptor.value());
|
||||
settings.setValue("operator", paramDescriptor.operatorType());
|
||||
settings.endGroup();
|
||||
}
|
||||
settings.endGroup();
|
||||
RuleEngine::RuleError RuleEngine::editRule(const RuleId &ruleId, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actions, const QList<RuleAction> &exitActions, bool enabled)
|
||||
{
|
||||
if (ruleId.isNull()) {
|
||||
return RuleErrorInvalidRuleId;
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
// Save StateEvaluator
|
||||
stateEvaluator.dumpToSettings(settings, "stateEvaluator");
|
||||
|
||||
// Save ruleActions
|
||||
int i = 0;
|
||||
settings.beginGroup("ruleActions");
|
||||
foreach (const RuleAction &action, rule.actions()) {
|
||||
settings.beginGroup(QString::number(i));
|
||||
settings.setValue("deviceId", action.deviceId().toString());
|
||||
settings.setValue("actionTypeId", action.actionTypeId().toString());
|
||||
foreach (const RuleActionParam ¶m, action.ruleActionParams()) {
|
||||
settings.beginGroup("RuleActionParam-" + param.name());
|
||||
settings.setValue("value", param.value());
|
||||
if (param.eventTypeId() != EventTypeId()) {
|
||||
settings.setValue("eventTypeId", param.eventTypeId().toString());
|
||||
settings.setValue("eventParamName", param.eventParamName());
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
i++;
|
||||
settings.endGroup();
|
||||
if (findRule(ruleId).id().isNull()) {
|
||||
qCWarning(dcRuleEngine) << "Cannot edit rule. There is no rule with id:" << ruleId.toString();
|
||||
return RuleErrorRuleNotFound;
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
// Save ruleExitActions
|
||||
settings.beginGroup("ruleExitActions");
|
||||
i = 0;
|
||||
foreach (const RuleAction &action, rule.exitActions()) {
|
||||
settings.beginGroup(QString::number(i));
|
||||
settings.setValue("deviceId", action.deviceId().toString());
|
||||
settings.setValue("actionTypeId", action.actionTypeId().toString());
|
||||
foreach (const RuleActionParam ¶m, action.ruleActionParams()) {
|
||||
settings.beginGroup("RuleActionParam-" + param.name());
|
||||
settings.setValue("value", param.value());
|
||||
settings.endGroup();
|
||||
}
|
||||
i++;
|
||||
settings.endGroup();
|
||||
// first remove old rule with this id
|
||||
RuleError removeResult = removeRule(ruleId, true);
|
||||
if (removeResult != RuleErrorNoError) {
|
||||
return removeResult;
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
// the rule is removed, now add it with the same id and new vonfiguration
|
||||
RuleError addResult = addRule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled, true);
|
||||
if (addResult != RuleErrorNoError) {
|
||||
return addResult;
|
||||
}
|
||||
|
||||
emit ruleConfigurationChanged(m_rules.value(ruleId));
|
||||
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
@ -422,8 +393,10 @@ QList<RuleId> RuleEngine::ruleIds() const
|
||||
|
||||
/*! Removes the \l{Rule} with the given \a ruleId from the Engine.
|
||||
Returns \l{RuleError} which describes whether the operation
|
||||
was successful or not. */
|
||||
RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId)
|
||||
was successful or not. If \a fromEdit is true, the notification Rules.RuleRemoved
|
||||
will not be emitted.
|
||||
*/
|
||||
RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId, bool fromEdit)
|
||||
{
|
||||
int index = m_ruleIds.indexOf(ruleId);
|
||||
|
||||
@ -439,7 +412,9 @@ RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId)
|
||||
settings.remove("");
|
||||
settings.endGroup();
|
||||
|
||||
emit ruleRemoved(ruleId);
|
||||
if (!fromEdit)
|
||||
emit ruleRemoved(ruleId);
|
||||
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
|
||||
@ -454,13 +429,9 @@ RuleEngine::RuleError RuleEngine::enableRule(const RuleId &ruleId)
|
||||
Rule rule = m_rules.value(ruleId);
|
||||
rule.setEnabled(true);
|
||||
m_rules[ruleId] = rule;
|
||||
QSettings settings(m_settingsFile);
|
||||
settings.beginGroup(ruleId.toString());
|
||||
if (!settings.value("enabled", true).toBool()) {
|
||||
settings.setValue("enabled", true);
|
||||
emit ruleChanged(ruleId);
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
saveRule(rule);
|
||||
emit ruleConfigurationChanged(rule);
|
||||
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
@ -476,14 +447,8 @@ RuleEngine::RuleError RuleEngine::disableRule(const RuleId &ruleId)
|
||||
Rule rule = m_rules.value(ruleId);
|
||||
rule.setEnabled(false);
|
||||
m_rules[ruleId] = rule;
|
||||
QSettings settings(m_settingsFile);
|
||||
settings.beginGroup(ruleId.toString());
|
||||
if (settings.value("enabled", true).toBool()) {
|
||||
settings.setValue("enabled", false);
|
||||
emit ruleChanged(ruleId);
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
saveRule(rule);
|
||||
emit ruleConfigurationChanged(rule);
|
||||
return RuleErrorNoError;
|
||||
}
|
||||
|
||||
@ -591,3 +556,69 @@ void RuleEngine::appendRule(const Rule &rule)
|
||||
m_rules.insert(rule.id(), rule);
|
||||
m_ruleIds.append(rule.id());
|
||||
}
|
||||
|
||||
void RuleEngine::saveRule(const Rule &rule)
|
||||
{
|
||||
// Save Events / EventDescriptors
|
||||
QSettings settings(m_settingsFile);
|
||||
settings.beginGroup(rule.id().toString());
|
||||
settings.setValue("name", rule.name());
|
||||
settings.setValue("enabled", rule.enabled());
|
||||
settings.beginGroup("events");
|
||||
for (int i = 0; i < rule.eventDescriptors().count(); i++) {
|
||||
const EventDescriptor &eventDescriptor = rule.eventDescriptors().at(i);
|
||||
settings.beginGroup("EventDescriptor-" + QString::number(i));
|
||||
settings.setValue("deviceId", eventDescriptor.deviceId().toString());
|
||||
settings.setValue("eventTypeId", eventDescriptor.eventTypeId().toString());
|
||||
|
||||
foreach (const ParamDescriptor ¶mDescriptor, eventDescriptor.paramDescriptors()) {
|
||||
settings.beginGroup("ParamDescriptor-" + paramDescriptor.name());
|
||||
settings.setValue("value", paramDescriptor.value());
|
||||
settings.setValue("operator", paramDescriptor.operatorType());
|
||||
settings.endGroup();
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
// Save StateEvaluator
|
||||
rule.stateEvaluator().dumpToSettings(settings, "stateEvaluator");
|
||||
|
||||
// Save ruleActions
|
||||
int i = 0;
|
||||
settings.beginGroup("ruleActions");
|
||||
foreach (const RuleAction &action, rule.actions()) {
|
||||
settings.beginGroup(QString::number(i));
|
||||
settings.setValue("deviceId", action.deviceId().toString());
|
||||
settings.setValue("actionTypeId", action.actionTypeId().toString());
|
||||
foreach (const RuleActionParam ¶m, action.ruleActionParams()) {
|
||||
settings.beginGroup("RuleActionParam-" + param.name());
|
||||
settings.setValue("value", param.value());
|
||||
if (param.eventTypeId() != EventTypeId()) {
|
||||
settings.setValue("eventTypeId", param.eventTypeId().toString());
|
||||
settings.setValue("eventParamName", param.eventParamName());
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
i++;
|
||||
settings.endGroup();
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
// Save ruleExitActions
|
||||
settings.beginGroup("ruleExitActions");
|
||||
i = 0;
|
||||
foreach (const RuleAction &action, rule.exitActions()) {
|
||||
settings.beginGroup(QString::number(i));
|
||||
settings.setValue("deviceId", action.deviceId().toString());
|
||||
settings.setValue("actionTypeId", action.actionTypeId().toString());
|
||||
foreach (const RuleActionParam ¶m, action.ruleActionParams()) {
|
||||
settings.beginGroup("RuleActionParam-" + param.name());
|
||||
settings.setValue("value", param.value());
|
||||
settings.endGroup();
|
||||
}
|
||||
i++;
|
||||
settings.endGroup();
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
@ -60,11 +60,14 @@ public:
|
||||
QList<Rule> evaluateEvent(const Event &event);
|
||||
|
||||
RuleError addRule(const RuleId &ruleId, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const QList<RuleAction> &actions, bool enabled = true);
|
||||
RuleError addRule(const RuleId &ruleId, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actions, const QList<RuleAction> &exitActions, bool enabled = true);
|
||||
RuleError addRule(const RuleId &ruleId, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actions, const QList<RuleAction> &exitActions, bool enabled = true, bool fromEdit = false);
|
||||
RuleError editRule(const RuleId &ruleId, const QString &name, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<RuleAction> &actions, const QList<RuleAction> &exitActions, bool enabled = true);
|
||||
|
||||
|
||||
QList<Rule> rules() const;
|
||||
QList<RuleId> ruleIds() const;
|
||||
|
||||
RuleError removeRule(const RuleId &ruleId);
|
||||
RuleError removeRule(const RuleId &ruleId, bool fromEdit = false);
|
||||
|
||||
RuleError enableRule(const RuleId &ruleId);
|
||||
RuleError disableRule(const RuleId &ruleId);
|
||||
@ -77,13 +80,14 @@ public:
|
||||
signals:
|
||||
void ruleAdded(const Rule &rule);
|
||||
void ruleRemoved(const RuleId &ruleId);
|
||||
void ruleChanged(const RuleId &ruleId);
|
||||
void ruleConfigurationChanged(const Rule &rule);
|
||||
|
||||
private:
|
||||
bool containsEvent(const Rule &rule, const Event &event);
|
||||
bool containsState(const StateEvaluator &stateEvaluator, const Event &stateChangeEvent);
|
||||
|
||||
void appendRule(const Rule &rule);
|
||||
void saveRule(const Rule &rule);
|
||||
|
||||
private:
|
||||
QString m_settingsFile;
|
||||
|
||||
Reference in New Issue
Block a user