add Rules.EditRule method and Rules.CRuleConfigurationChanged notification

This commit is contained in:
Simon Stürz 2015-06-29 12:58:35 +02:00 committed by Michael Zanetti
parent f125511994
commit 85ba7af29c
7 changed files with 369 additions and 189 deletions

View File

@ -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}\\\"

View File

@ -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);
}

View File

@ -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:

View File

@ -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 &params)
JsonReply* RulesHandler::AddRule(const QVariantMap &params)
{
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 &params)
{
// 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 &params)
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 &params)
{
// 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 &params)
{
// 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 &params, 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 &params)
{
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);
}

View File

@ -36,6 +36,7 @@ public:
Q_INVOKABLE JsonReply* GetRuleDetails(const QVariantMap &params);
Q_INVOKABLE JsonReply* AddRule(const QVariantMap &params);
Q_INVOKABLE JsonReply* EditRule(const QVariantMap &params);
Q_INVOKABLE JsonReply* RemoveRule(const QVariantMap &params);
Q_INVOKABLE JsonReply* FindRules(const QVariantMap &params);
@ -46,6 +47,7 @@ signals:
void RuleRemoved(const QVariantMap &params);
void RuleAdded(const QVariantMap &params);
void RuleActiveChanged(const QVariantMap &params);
void RuleConfigurationChanged(const QVariantMap &params);
private:
QVariant::Type getActionParamType(const ActionTypeId &actionTypeId, const QString &paramName);
@ -53,10 +55,16 @@ private:
bool checkEventDescriptors(const QList<EventDescriptor> eventDescriptors, const EventTypeId &eventTypeId);
RuleEngine::RuleError verifyRuleConsistency(const QVariantMap &params);
QPair<QList<EventDescriptor>, RuleEngine::RuleError> verifyEventDescriptors(const QVariantMap &params);
QPair<QList<RuleAction>, RuleEngine::RuleError> verifyActions(const QVariantMap &params, const QList<EventDescriptor> &eventDescriptorList);
QPair<QList<RuleAction>, RuleEngine::RuleError> verifyExitActions(const QVariantMap &params);
private slots:
void ruleRemovedNotification(const RuleId &ruleId);
void ruleAddedNotification(const Rule &rule);
void ruleActiveChangedNotification(const Rule &rule);
void ruleConfigurationChangedNotification(const Rule &rule);
};

View File

@ -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 &paramDescriptor, 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 &param, 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 &param, 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 &paramDescriptor, 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 &param, 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 &param, action.ruleActionParams()) {
settings.beginGroup("RuleActionParam-" + param.name());
settings.setValue("value", param.value());
settings.endGroup();
}
i++;
settings.endGroup();
}
settings.endGroup();
}

View File

@ -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;