diff --git a/server/guhcore.cpp b/server/guhcore.cpp index 71dc5ae7..6c14e028 100644 --- a/server/guhcore.cpp +++ b/server/guhcore.cpp @@ -88,6 +88,19 @@ GuhCore::GuhCore(QObject *parent) : void GuhCore::gotEvent(const Event &event) { foreach (const Action &action, m_ruleEngine->evaluateEvent(event)) { - m_deviceManager->executeAction(action); + qDebug() << "executing action" << action.actionTypeId(); + DeviceManager::DeviceError status = m_deviceManager->executeAction(action); + switch(status) { + case DeviceManager::DeviceErrorNoError: + break; + case DeviceManager::DeviceErrorSetupFailed: + qDebug() << "Error executing action. Device setup failed."; + break; + case DeviceManager::DeviceErrorActionParameterError: + qDebug() << "Error executing action. Invalid action parameter."; + break; + default: + qDebug() << "Error executing action:" << status; + } } } diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index ebfe137d..505b1a80 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -83,7 +83,7 @@ void JsonTypes::init() // Event s_event.insert("eventTypeId", "uuid"); s_event.insert("deviceId", "uuid"); - s_event.insert("params", QVariantList() << paramRef()); + s_event.insert("o:params", QVariantList() << paramRef()); // ActionType s_actionType.insert("id", "uuid"); @@ -122,7 +122,7 @@ void JsonTypes::init() s_rule.insert("id", "uuid"); s_rule.insert("ruleType", ruleTypesRef()); - s_rule.insert("event", eventRef()); + s_rule.insert("events", QVariantList() << eventRef()); s_rule.insert("actions", QVariantList() << actionRef()); s_rule.insert("states", QVariantList() << stateRef()); @@ -256,8 +256,14 @@ QVariantMap JsonTypes::packRule(const Rule &rule) { QVariantMap ruleMap; ruleMap.insert("id", rule.id()); -// ruleMap.insert("event", JsonTypes::packEvent(rule.event())); + QVariantList eventList; + foreach (const Event &event, rule.events()) { + eventList.append(JsonTypes::packEvent(event)); + } + ruleMap.insert("events", eventList); + ruleMap.insert("ruleType", s_ruleTypes.at(rule.ruleType())); + QVariantList actionList; foreach (const Action &action, rule.actions()) { actionList.append(JsonTypes::packAction(action)); @@ -277,7 +283,9 @@ QPair JsonTypes::validateMap(const QVariantMap &templateMap, cons strippedKey.remove(QRegExp("^o:")); if (!key.startsWith("o:") && !map.contains(strippedKey)) { - qDebug() << "missing key" << key << templateMap << map; + qDebug() << "*** missing key" << key; + qDebug() << "Expected:" << templateMap; + qDebug() << "Got:" << map; QJsonDocument jsonDoc = QJsonDocument::fromVariant(map); return report(false, QString("Missing key \"%1\" in %2").arg(key).arg(QString(jsonDoc.toJson()))); } @@ -346,6 +354,7 @@ QPair JsonTypes::validateVariant(const QVariant &templateVariant, return result; } } else if (refName == JsonTypes::eventRef()) { + qDebug() << "validating event"; QPair result = validateMap(eventDescription(), variant.toMap()); if (!result.first) { qDebug() << "event not valid"; diff --git a/server/jsonrpc/ruleshandler.cpp b/server/jsonrpc/ruleshandler.cpp index d1bb04bc..6752f86e 100644 --- a/server/jsonrpc/ruleshandler.cpp +++ b/server/jsonrpc/ruleshandler.cpp @@ -105,6 +105,7 @@ QVariantMap RulesHandler::AddRule(const QVariantMap ¶ms) switch(GuhCore::instance()->ruleEngine()->addRule(event, actions)) { case RuleEngine::RuleErrorNoError: returns.insert("success", true); + returns.insert("errorMessage", ""); break; case RuleEngine::RuleErrorDeviceNotFound: returns.insert("success", false); diff --git a/server/rule.cpp b/server/rule.cpp index 22a84926..d4db85e4 100644 --- a/server/rule.cpp +++ b/server/rule.cpp @@ -52,7 +52,7 @@ \l{Rule::RuleTypeAll}.*/ Rule::Rule(const QUuid &id, const Event &event, const QList &states, const QList &actions): m_id(id), - m_event(event), + m_events(QList() << event), m_states(states), m_actions(actions), m_ruleType(RuleTypeAll) @@ -66,9 +66,9 @@ QUuid Rule::id() const } /*! Returns the \l{Event} that events this Rule.*/ -Event Rule::event() const +QList Rule::events() const { - return m_event; + return m_events; } /*! Returns the \l{State}{States} that need to be matching in order for this to Rule apply. */ diff --git a/server/rule.h b/server/rule.h index 6b9b8a51..e2388f22 100644 --- a/server/rule.h +++ b/server/rule.h @@ -37,7 +37,7 @@ public: Rule(const QUuid &id, const Event &event, const QList &states, const QList &actions); QUuid id() const; - Event event() const; + QList events() const; QList states() const; QList actions() const; @@ -46,7 +46,7 @@ public: private: QUuid m_id; - Event m_event; + QList m_events; QList m_states; StateEvaluator stateEvaluator; QList m_actions; diff --git a/server/ruleengine.cpp b/server/ruleengine.cpp index 5cf67329..81ea4e56 100644 --- a/server/ruleengine.cpp +++ b/server/ruleengine.cpp @@ -120,28 +120,28 @@ RuleEngine::RuleEngine(QObject *parent) : QList RuleEngine::evaluateEvent(const Event &event) { QList actions; -// for (int i = 0; i < m_rules.count(); ++i) { -// if (m_rules.at(i).events().contains(event)) { -// bool statesMatching = true; -// qDebug() << "checking states"; -// foreach (const State &state, m_rules.at(i).stateChanges()) { -// Device *device = GuhCore::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; -// } -// } + for (int i = 0; i < m_rules.count(); ++i) { + if (m_rules.at(i).events().contains(event)) { + bool statesMatching = true; + qDebug() << "checking states"; + foreach (const State &state, m_rules.at(i).states()) { + Device *device = GuhCore::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; + } + } -// qDebug() << "states matching" << statesMatching; -// if (statesMatching) { -// actions.append(m_rules.at(i).actions()); -// } -// } -// } + qDebug() << "states matching" << statesMatching; + if (statesMatching) { + actions.append(m_rules.at(i).actions()); + } + } + } qDebug() << "found" << actions.count() << "actions"; return actions; } diff --git a/tests/scripts/addrule.sh b/tests/scripts/addrule.sh index 3ed30ae4..aa187f97 100755 --- a/tests/scripts/addrule.sh +++ b/tests/scripts/addrule.sh @@ -1,9 +1,12 @@ #!/bin/bash if test -z $5; then - echo "usage: $0 host sourceDevice eventTypeId targetDeviceId actionTypeId" + echo "usage: $0 host sourceDevice eventTypeId targetDeviceId actionTypeId [paramname paramvalue]" +elif test -z $6; then + (echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "$3", "deviceId":"'$2'"}, "actions": [ { "deviceId":"'$4'", "actionTypeId":"'$5'"}]}}'; sleep 1) | nc $1 1234 +elif test -z $7; then + echo "usage: $0 host sourceDevice eventTypeId targetDeviceId actionTypeId [paramname paramvalue]" else - (echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "$3", "deviceId":"'$2'"}, "actions": [ { "deviceId":"'$4'", "actionTypeId":"'$5'", "params":{"power":"true"}}]}}'; sleep 1) | nc $1 1234 -# (echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "'$3'", "deviceId":"'$2'"}, "actions": [ { "deviceId":"'$4'", "actionTypeId":"'$5'", "params":{"power":"true"}}]}}'; sleep 1) | nc $1 1234 + (echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "'$3'", "deviceId":"'$2'"}, "actions": [ { "deviceId":"'$4'", "actionTypeId":"'$5'", "params":{"'$6'":"'$7'"}}]}}'; sleep 1) | nc $1 1234 # (echo '{"id":1, "method":"Rules.AddRule", "params":{"event": {"eventTypeId": "'$2'", "deviceId":"'$3'", "params":{"power":"false"}}, "actions": [ { "deviceId":"'$4'", "name":"rule 1", "params":{"power":"false"}},{ "deviceId":"'$5'", "name":"rule 1", "params":{"power":"true"}}]}}'; sleep 1) | nc $1 1234 fi