diff --git a/libguh-core/guhcore.cpp b/libguh-core/guhcore.cpp index e43d6b78..967ca75d 100644 --- a/libguh-core/guhcore.cpp +++ b/libguh-core/guhcore.cpp @@ -481,7 +481,7 @@ void GuhCore::gotEvent(const Event &event) QList eventBasedActions; foreach (const Rule &rule, m_ruleEngine->evaluateEvent(event)) { // Event based - if (rule.eventDescriptors().count() > 0) { + if (!rule.eventDescriptors().isEmpty()) { m_logger->logRuleTriggered(rule); // check if we have an event based action or a normal action foreach (const RuleAction &action, rule.actions()) { diff --git a/libguh-core/ruleengine.cpp b/libguh-core/ruleengine.cpp index d2665c84..a7653d1f 100644 --- a/libguh-core/ruleengine.cpp +++ b/libguh-core/ruleengine.cpp @@ -350,7 +350,7 @@ QList RuleEngine::evaluateEvent(const Event &event) } // If this rule does not base on an event, evaluate the rule - if (rule.eventDescriptors().isEmpty()) { + if (rule.eventDescriptors().isEmpty() && rule.timeDescriptor().timeEventItems().isEmpty()) { if (rule.timeActive() && rule.statesActive()) { if (!m_activeRules.contains(rule.id())) { qCDebug(dcRuleEngine) << "Rule" << rule.id().toString() << "active."; @@ -409,7 +409,7 @@ QList RuleEngine::evaluateTime(const QDateTime &dateTime) rule.setTimeActive(rule.timeDescriptor().evaluate(m_lastEvaluationTime, dateTime)); m_rules[rule.id()] = rule; - if (rule.timeDescriptor().timeEventItems().isEmpty()) { + if (rule.timeDescriptor().timeEventItems().isEmpty() && rule.eventDescriptors().isEmpty()) { if (rule.timeActive() && rule.statesActive()) { if (!m_activeRules.contains(rule.id())) { diff --git a/libguh-core/time/timeeventitem.cpp b/libguh-core/time/timeeventitem.cpp index bfc89e9a..0f3016bb 100644 --- a/libguh-core/time/timeeventitem.cpp +++ b/libguh-core/time/timeeventitem.cpp @@ -97,6 +97,7 @@ bool TimeEventItem::evaluate(const QDateTime &lastEvaluationTime, const QDateTim switch (m_repeatingOption.mode()) { // If there is no repeating option, we assume it is meant daily. case RepeatingOption::RepeatingModeNone: + return lastEvaluationTime.time() < m_time && m_time <= dateTime.time(); case RepeatingOption::RepeatingModeDaily: return lastEvaluationTime.time() < m_time && m_time <= dateTime.time(); case RepeatingOption::RepeatingModeHourly: { diff --git a/tests/auto/timemanager/testtimemanager.cpp b/tests/auto/timemanager/testtimemanager.cpp index ef06c96a..8ba08841 100644 --- a/tests/auto/timemanager/testtimemanager.cpp +++ b/tests/auto/timemanager/testtimemanager.cpp @@ -97,6 +97,9 @@ private slots: void testEventItemYearly_data(); void testEventItemYearly(); + void testEventItemStates_data(); + void testEventItemStates(); + void testEnableDisableTimeRule(); private: @@ -1716,6 +1719,88 @@ void TestTimeManager::testEventItemYearly() verifyRuleError(response); } + +void TestTimeManager::testEventItemStates_data() +{ + initTimeManager(); + + GuhCore::instance()->timeManager()->setTime(QDateTime(QDate::currentDate(), QTime(7,59))); + + // Action (without params) + QVariantMap action; + action.insert("actionTypeId", mockActionIdNoParams); + action.insert("deviceId", m_mockDeviceId); + action.insert("ruleActionParams", QVariantList()); + + // Time descriptor + QVariantMap timeEventItem1 = createTimeEventItem("08:00"); + QVariantMap timeEventItem2 = createTimeEventItem("09:00"); + QVariantMap timeDescriptor; + timeDescriptor.insert("timeEventItems", QVariantList() << timeEventItem1 << timeEventItem2); + + // State evaluator + QVariantMap stateDescriptorBool; + stateDescriptorBool.insert("deviceId", m_mockDeviceId); + stateDescriptorBool.insert("operator", JsonTypes::valueOperatorToString(Types::ValueOperatorEquals)); + stateDescriptorBool.insert("stateTypeId", mockBoolStateId); + stateDescriptorBool.insert("value", true); + + QVariantMap stateEvaluator; + stateEvaluator.insert("stateDescriptor", stateDescriptorBool); + + // The rule + QVariantMap ruleMap; + ruleMap.insert("name", "Time and state and event based daily calendar rule"); + ruleMap.insert("actions", QVariantList() << action); + ruleMap.insert("stateEvaluator", stateEvaluator); + ruleMap.insert("timeDescriptor", timeDescriptor); + + QVariant response = injectAndWait("Rules.AddRule", ruleMap); + verifyRuleError(response); + RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString()); + + QVariantMap params; + params.insert("ruleId", ruleId); + response = injectAndWait("Rules.GetRuleDetails", params); + + QTest::addColumn("dateTime"); + QTest::addColumn("boolValue"); + QTest::addColumn("trigger"); + + QTest::newRow("TimeEvent 07:59 | state false | not trigger") << QDateTime(QDate::currentDate(), QTime(7,59)) << false << false; + QTest::newRow("TimeEvent 07:59 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(7,59)) << true << false; + QTest::newRow("TimeEvent 08:00 | state false | not trigger") << QDateTime(QDate::currentDate(), QTime(8,0)) << false << false; + QTest::newRow("TimeEvent 07:59 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(7,59)) << true << false; + QTest::newRow("TimeEvent 08:00 | state true | trigger") << QDateTime(QDate::currentDate(), QTime(8,0)) << true << true; + QTest::newRow("TimeEvent 08:01 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(8,1)) << true << false; + QTest::newRow("TimeEvent 08:01 | state false | not trigger") << QDateTime(QDate::currentDate(), QTime(8,1)) << true << false; + QTest::newRow("TimeEvent 08:30 | state true | not trigger") << QDateTime(QDate::currentDate(), QTime(8,30)) << true << false; + QTest::newRow("TimeEvent 09:00 | state true | trigger") << QDateTime(QDate::currentDate(), QTime(9,0)) << true << true; + + +} + +void TestTimeManager::testEventItemStates() +{ + QFETCH(QDateTime, dateTime); + QFETCH(bool, boolValue); + QFETCH(bool, trigger); + + // Set state + setBoolState(boolValue); + + // Set time + GuhCore::instance()->timeManager()->setTime(dateTime); + + if (trigger) { + verifyRuleExecuted(mockActionIdNoParams); + cleanupMockHistory(); + } else { + verifyRuleNotExecuted(); + } +} + + void TestTimeManager::testEnableDisableTimeRule() { initTimeManager();