make use of states in ruleengine

pull/1/head
Michael Zanetti 2014-01-04 03:31:18 +01:00
parent cb12231c44
commit c54b14e8ef
9 changed files with 150 additions and 31 deletions

View File

@ -62,3 +62,25 @@ void Device::setStates(const QList<State> &states)
{
m_states = states;
}
QVariant Device::stateValue(const QUuid &stateTypeId) const
{
foreach (const State &state, m_states) {
if (state.stateTypeId() == stateTypeId) {
return state.value();
}
}
return QVariant();
}
void Device::setStateValue(const QUuid &stateTypeId, const QVariant &value)
{
for (int i = 0; i < m_states.count(); ++i) {
if (m_states.at(i).stateTypeId() == stateTypeId) {
State newState(stateTypeId, m_id);
newState.setValue(value);
m_states[i] = newState;
return;
}
}
}

View File

@ -27,6 +27,9 @@ public:
QList<State> states() const;
void setStates(const QList<State> &states);
QVariant stateValue(const QUuid &stateTypeId) const;
void setStateValue(const QUuid &stateTypeId, const QVariant &value);
private:
Device(const QUuid &pluginId, const QUuid &id, const QUuid &deviceClassId, QObject *parent = 0);
Device(const QUuid &pluginId, const QUuid &deviceClassId, QObject *parent = 0);

View File

@ -1,5 +1,25 @@
#include "state.h"
State::State(const QUuid &stateTypeId)
State::State(const QUuid &stateTypeId, const QUuid &deviceId)
{
}
QUuid State::stateTypeId() const
{
return m_stateTypeId;
}
QUuid State::deviceId() const
{
return m_deviceId;
}
QVariant State::value() const
{
return m_value;
}
void State::setValue(const QVariant &value)
{
m_value = value;
}

View File

@ -7,15 +7,17 @@
class State
{
public:
State(const QUuid &stateTypeId);
State(const QUuid &stateTypeId, const QUuid &deviceId);
QUuid stateTypeId() const;
QUuid deviceId() const;
QVariant value() const;
void setValue(const QVariant &value);
private:
QUuid m_stateTypeId;
QUuid m_deviceId;
QVariant m_value;
};

View File

@ -129,7 +129,12 @@ void JsonRPCServer::handleRulesMessage(int clientId, int commandId, const QStrin
QVariantMap ruleMap;
ruleMap.insert("id", rule.id());
ruleMap.insert("trigger", packTrigger(rule.trigger()));
ruleMap.insert("action", packAction(rule.action()));
QVariantList actionList;
foreach (const Action &action, rule.actions()) {
actionList.append(packAction(action));
}
ruleMap.insert("actions", actionList);
rulesList.append(ruleMap);
}
QVariantMap rspParams;
@ -143,12 +148,17 @@ void JsonRPCServer::handleRulesMessage(int clientId, int commandId, const QStrin
QVariantMap triggerParams = triggerMap.value("params").toMap();
Trigger trigger(triggerTypeId, triggerDeviceId, triggerParams);
QVariantMap actionMap = params.value("action").toMap();
Action action(actionMap.value("deviceId").toString());
action.setName(actionMap.value("name").toString());
action.setParams(actionMap.value("params").toMap());
QList<Action> actions;
QVariantList actionList = params.value("actions").toList();
foreach (const QVariant &actionVariant, actionList) {
QVariantMap actionMap = actionVariant.toMap();
Action action(actionMap.value("deviceId").toString());
action.setName(actionMap.value("name").toString());
action.setParams(actionMap.value("params").toMap());
actions.append(action);
}
switch(HiveCore::instance()->ruleEngine()->addRule(trigger, action)) {
switch(HiveCore::instance()->ruleEngine()->addRule(trigger, actions)) {
case RuleEngine::RuleErrorNoError:
sendResponse(clientId, commandId);
break;

View File

@ -1,9 +1,10 @@
#include "rule.h"
Rule::Rule(const QUuid &id, const Trigger &trigger, const Action &action):
Rule::Rule(const QUuid &id, const Trigger &trigger, const QList<State> states, const QList<Action> &actions):
m_id(id),
m_trigger(trigger),
m_action(action)
m_states(states),
m_actions(actions)
{
}
@ -17,7 +18,12 @@ Trigger Rule::trigger() const
return m_trigger;
}
Action Rule::action() const
QList<State> Rule::states() const
{
return m_action;
return m_states;
}
QList<Action> Rule::actions() const
{
return m_actions;
}

View File

@ -1,6 +1,7 @@
#ifndef RULE_H
#define RULE_H
#include "state.h"
#include "action.h"
#include "trigger.h"
@ -9,16 +10,18 @@
class Rule
{
public:
Rule(const QUuid &id, const Trigger &trigger, const Action &action);
Rule(const QUuid &id, const Trigger &trigger, const QList<State> states, const QList<Action> &actions);
QUuid id() const;
Trigger trigger() const;
Action action() const;
QList<State> states() const;
QList<Action> actions() const;
private:
QUuid m_id;
Trigger m_trigger;
Action m_action;
QList<State> m_states;
QList<Action> m_actions;
};
#endif // RULE_H

View File

@ -25,14 +25,31 @@ RuleEngine::RuleEngine(QObject *parent) :
Trigger trigger(settings.value("triggerTypeId").toUuid(), settings.value("deviceId").toUuid(), settings.value("params").toMap());
settings.endGroup();
settings.beginGroup("action");
Action action = Action(settings.value("deviceId").toUuid(), settings.value("id").toUuid());
action.setName(settings.value("name").toString());
action.setParams(settings.value("params").toMap());
settings.endGroup();
settings.beginGroup("states");
QList<State> states;
foreach (const QString &stateTypeIdString, settings.childGroups()) {
settings.beginGroup(stateTypeIdString);
State state(stateTypeIdString, settings.value("deviceId").toUuid());
state.setValue(settings.value("value"));
settings.endGroup();
states.append(state);
}
settings.endGroup();
Rule rule = Rule(QUuid(idString), trigger, action);
settings.beginGroup("actions");
QList<Action> actions;
foreach (const QString &actionIdString, settings.childGroups()) {
settings.beginGroup(actionIdString);
Action action = Action(settings.value("deviceId").toUuid(), settings.value("id").toUuid());
action.setName(settings.value("name").toString());
action.setParams(settings.value("params").toMap());
settings.endGroup();
}
settings.endGroup();
settings.endGroup();
Rule rule = Rule(QUuid(idString), trigger, states, actions);
m_rules.append(rule);
}
@ -43,15 +60,35 @@ QList<Action> RuleEngine::evaluateTrigger(const Trigger &trigger)
QList<Action> actions;
for (int i = 0; i < m_rules.count(); ++i) {
if (m_rules.at(i).trigger() == trigger) {
actions << m_rules.at(i).action();
bool statesMatching = true;
foreach (const State &state, m_rules.at(i).states()) {
Device *device = HiveCore::instance()->deviceManager()->findConfiguredDevice(state.deviceId());
if (!device) {
qWarning() << "Device referenced in rule cannot be found";
break;
}
if (state.value() != device->stateValue(state.stateTypeId())) {
statesMatching = false;
break;
}
}
if (statesMatching) {
actions.append(m_rules.at(i).actions());
}
}
}
return actions;
}
RuleEngine::RuleError RuleEngine::addRule(const Trigger &trigger, const Action &action)
RuleEngine::RuleError RuleEngine::addRule(const Trigger &trigger, const QList<Action> &actions)
{
qDebug() << "adding rule: Trigger:" << trigger.triggerTypeId() << "deviceid:" << action.deviceId();
return addRule(trigger, QList<State>(), actions);
}
RuleEngine::RuleError RuleEngine::addRule(const Trigger &trigger, const QList<State> states, const QList<Action> &actions)
{
qDebug() << "adding rule: Trigger:" << trigger.triggerTypeId() << "with" << actions.count() << "actions";
DeviceClass triggerDeviceClass = HiveCore::instance()->deviceManager()->findDeviceClassforTrigger(trigger.triggerTypeId());
Device *device = HiveCore::instance()->deviceManager()->findConfiguredDevice(trigger.deviceId());
@ -73,7 +110,7 @@ RuleEngine::RuleError RuleEngine::addRule(const Trigger &trigger, const Action &
return RuleErrorTriggerTypeNotFound;
}
Rule rule = Rule(QUuid::createUuid(), trigger, action);
Rule rule = Rule(QUuid::createUuid(), trigger, states, actions);
m_rules.append(rule);
QSettings settings(rulesFileName);
@ -83,11 +120,26 @@ RuleEngine::RuleError RuleEngine::addRule(const Trigger &trigger, const Action &
settings.setValue("deviceId", trigger.deviceId());
settings.setValue("params", trigger.params());
settings.endGroup();
settings.beginGroup("action");
settings.setValue("id", rule.action().id());
settings.setValue("deviceId", rule.action().deviceId());
settings.setValue("name", rule.action().name());
settings.setValue("params", rule.action().params());
settings.beginGroup("states");
foreach (const State &state, states) {
settings.beginGroup(state.stateTypeId().toString());
settings.setValue("deviceId", state.deviceId());
settings.setValue("value", state.value());
settings.endGroup();
}
settings.endGroup();
settings.beginGroup("actions");
foreach (const Action &action, rule.actions()) {
settings.beginGroup(action.id().toString());
settings.setValue("deviceId", action.deviceId());
settings.setValue("name", action.name());
settings.setValue("params", action.params());
settings.endGroup();
}
settings.endGroup();
return RuleErrorNoError;

View File

@ -22,7 +22,8 @@ public:
QList<Action> evaluateTrigger(const Trigger &trigger);
RuleError addRule(const Trigger &trigger, const Action &action);
RuleError addRule(const Trigger &trigger, const QList<Action> &actions);
RuleError addRule(const Trigger &trigger, const QList<State> states, const QList<Action> &actions);
QList<Rule> rules() const;
private: