add store load timeDescriptor

This commit is contained in:
Simon Stürz 2016-04-07 23:44:12 +02:00 committed by Michael Zanetti
parent 83ef72e254
commit d713e3ba29
4 changed files with 347 additions and 9 deletions

View File

@ -209,6 +209,26 @@ QStringList GuhSettings::allKeys() const
return m_settings->allKeys();
}
void GuhSettings::beginWriteArray(const QString &prefix)
{
m_settings->beginWriteArray(prefix);
}
void GuhSettings::setArrayIndex(int i)
{
m_settings->setArrayIndex(i);
}
int GuhSettings::beginReadArray(const QString &prefix)
{
return m_settings->beginReadArray(prefix);
}
void GuhSettings::endArray()
{
m_settings->endArray();
}
/*! Begins a new group with the given \a prefix.*/
void GuhSettings::beginGroup(const QString &prefix)
{

View File

@ -52,6 +52,11 @@ public:
// forwarded QSettings methods
QStringList allKeys() const;
void beginWriteArray(const QString &prefix);
void setArrayIndex(int i);
int beginReadArray(const QString &prefix);
void endArray();
void beginGroup(const QString &prefix);
QStringList childGroups() const;
QStringList childKeys() const;

View File

@ -99,13 +99,15 @@
#include "ruleengine.h"
#include "loggingcategories.h"
#include "types/paramdescriptor.h"
#include "types/eventdescriptor.h"
#include "guhsettings.h"
#include "guhcore.h"
#include "loggingcategories.h"
#include "time/calendaritem.h"
#include "time/repeatingoption.h"
#include "time/timeeventitem.h"
#include "types/eventdescriptor.h"
#include "types/paramdescriptor.h"
#include "guhsettings.h"
#include "devicemanager.h"
#include "plugin/device.h"
@ -133,9 +135,93 @@ RuleEngine::RuleEngine(QObject *parent) :
qCDebug(dcRuleEngine) << "load rule" << name << idString;
// Load timeDescriptor
TimeDescriptor timeDescriptor;
QList<CalendarItem> calendarItems;
QList<TimeEventItem> timeEventItems;
settings.beginGroup("timeDescriptor");
settings.beginGroup("calendarItems");
foreach (const QString &childGroup, settings.childGroups()) {
settings.beginGroup(childGroup);
CalendarItem calendarItem;
calendarItem.setDateTime(QDateTime::fromTime_t(settings.value("dateTime", 0).toUInt()));
calendarItem.setStartTime(QTime::fromString(settings.value("startTime").toString()));
calendarItem.setDuration(settings.value("duration", 0).toUInt());
QList<int> weekDays;
QList<int> monthDays;
RepeatingOption::RepeatingMode mode = (RepeatingOption::RepeatingMode)settings.value("mode", 0).toInt();
// Load weekDays
int weekDaysCount = settings.beginReadArray("weekDays");
for (int i = 0; i < weekDaysCount; ++i) {
settings.setArrayIndex(i);
weekDays.append(settings.value("weekDay", 0).toInt());
}
settings.endArray();
// Load weekDays
int monthDaysCount = settings.beginReadArray("monthDays");
for (int i = 0; i < monthDaysCount; ++i) {
settings.setArrayIndex(i);
monthDays.append(settings.value("monthDay", 0).toInt());
}
settings.endArray();
settings.endGroup();
calendarItem.setRepeatingOption(RepeatingOption(mode, weekDays, monthDays));
calendarItems.append(calendarItem);
}
settings.endGroup();
timeDescriptor.setCalendarItems(calendarItems);
settings.beginGroup("timeEventItems");
foreach (const QString &childGroup, settings.childGroups()) {
settings.beginGroup(childGroup);
TimeEventItem timeEventItem;
timeEventItem.setDateTime(settings.value("dateTime", 0).toUInt());
timeEventItem.setTime(QTime::fromString(settings.value("time").toString()));
QList<int> weekDays;
QList<int> monthDays;
RepeatingOption::RepeatingMode mode = (RepeatingOption::RepeatingMode)settings.value("mode", 0).toInt();
// Load weekDays
int weekDaysCount = settings.beginReadArray("weekDays");
for (int i = 0; i < weekDaysCount; ++i) {
settings.setArrayIndex(i);
weekDays.append(settings.value("weekDay", 0).toInt());
}
settings.endArray();
// Load weekDays
int monthDaysCount = settings.beginReadArray("monthDays");
for (int i = 0; i < monthDaysCount; ++i) {
settings.setArrayIndex(i);
monthDays.append(settings.value("monthDay", 0).toInt());
}
settings.endArray();
settings.endGroup();
timeEventItem.setRepeatingOption(RepeatingOption(mode, weekDays, monthDays));
timeEventItems.append(timeEventItem);
}
settings.endGroup();
settings.endGroup();
timeDescriptor.setTimeEventItems(timeEventItems);
// Load events
QList<EventDescriptor> eventDescriptorList;
settings.beginGroup("events");
foreach (QString eventGroupName, settings.childGroups()) {
if (eventGroupName.startsWith("EventDescriptor-")) {
settings.beginGroup(eventGroupName);
@ -160,8 +246,12 @@ RuleEngine::RuleEngine(QObject *parent) :
}
settings.endGroup();
settings.endGroup();
// Load stateEvaluator
StateEvaluator stateEvaluator = StateEvaluator::loadFromSettings(settings, "stateEvaluator");
// Load actions
QList<RuleAction> actions;
settings.beginGroup("ruleActions");
foreach (const QString &actionNumber, settings.childGroups()) {
@ -190,6 +280,7 @@ RuleEngine::RuleEngine(QObject *parent) :
}
settings.endGroup();
// Load exit actions
QList<RuleAction> exitActions;
settings.beginGroup("ruleExitActions");
foreach (const QString &actionNumber, settings.childGroups()) {
@ -216,6 +307,7 @@ RuleEngine::RuleEngine(QObject *parent) :
Rule rule;
rule.setId(RuleId(idString));
rule.setName(name);
rule.setTimeDescriptor(timeDescriptor);
rule.setEventDescriptors(eventDescriptorList);
rule.setStateEvaluator(stateEvaluator);
rule.setActions(actions);
@ -917,12 +1009,75 @@ void RuleEngine::appendRule(const Rule &rule)
void RuleEngine::saveRule(const Rule &rule)
{
// Save Events / EventDescriptors
GuhSettings settings(GuhSettings::SettingsRoleRules);
settings.beginGroup(rule.id().toString());
settings.setValue("name", rule.name());
settings.setValue("enabled", rule.enabled());
settings.setValue("executable", rule.executable());
// Save timeDescriptor
settings.beginGroup("timeDescriptor");
if (!rule.timeDescriptor().isEmpty()) {
settings.beginGroup("calendarItems");
for (int i = 0; i < rule.timeDescriptor().calendarItems().count(); i++) {
const CalendarItem &calendarItem = rule.timeDescriptor().calendarItems().at(i);
settings.beginGroup("CalendarItem-" + QString::number(i));
settings.setValue("dateTime", calendarItem.dateTime().toTime_t());
settings.setValue("startTime", calendarItem.startTime().toString("hh:mm"));
settings.setValue("duration", calendarItem.duration());
settings.setValue("mode", calendarItem.repeatingOption().mode());
// Save weekDays
settings.beginWriteArray("weekDays");
for (int i = 0; i < calendarItem.repeatingOption().weekDays().count(); ++i) {
settings.setArrayIndex(i);
settings.setValue("weekDay", calendarItem.repeatingOption().weekDays().at(i));
}
settings.endArray();
// Save monthDays
settings.beginWriteArray("monthDays");
for (int i = 0; i < calendarItem.repeatingOption().monthDays().count(); ++i) {
settings.setArrayIndex(i);
settings.setValue("monthDay", calendarItem.repeatingOption().monthDays().at(i));
}
settings.endArray();
settings.endGroup();
}
settings.endGroup();
settings.beginGroup("timeEventItems");
for (int i = 0; i < rule.timeDescriptor().timeEventItems().count(); i++) {
const TimeEventItem &timeEventItem = rule.timeDescriptor().timeEventItems().at(i);
settings.beginGroup("TimeEventItem-" + QString::number(i));
settings.setValue("dateTime", timeEventItem.dateTime().toTime_t());
settings.setValue("time", timeEventItem.time().toString("hh:mm"));
settings.setValue("mode", timeEventItem.repeatingOption().mode());
// Save weekDays
settings.beginWriteArray("weekDays");
for (int i = 0; i < timeEventItem.repeatingOption().weekDays().count(); ++i) {
settings.setArrayIndex(i);
settings.setValue("weekDay", timeEventItem.repeatingOption().weekDays().at(i));
}
settings.endArray();
// Save monthDays
settings.beginWriteArray("monthDays");
for (int i = 0; i < timeEventItem.repeatingOption().monthDays().count(); ++i) {
settings.setArrayIndex(i);
settings.setValue("monthDay", timeEventItem.repeatingOption().monthDays().at(i));
}
settings.endArray();
settings.endGroup();
}
settings.endGroup();
}
settings.endGroup();
// Save Events / EventDescriptors
settings.beginGroup("events");
for (int i = 0; i < rule.eventDescriptors().count(); i++) {
const EventDescriptor &eventDescriptor = rule.eventDescriptors().at(i);

View File

@ -30,6 +30,7 @@
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QTimeZone>
#include <QDateTime>
@ -43,6 +44,9 @@ private slots:
void changeTimeZone_data();
void changeTimeZone();
void loadSaveTimeDescriptor_data();
void loadSaveTimeDescriptor();
void addTimeDescriptor_data();
void addTimeDescriptor();
@ -84,6 +88,8 @@ private slots:
void testEventItemYearly_data();
void testEventItemYearly();
void testEnableDisableTimeRule();
private:
void initTimeManager();
@ -140,6 +146,95 @@ void TestTimeManager::changeTimeZone()
}
void TestTimeManager::loadSaveTimeDescriptor_data()
{
// Repeating options
QVariantMap repeatingOptionWeekly;
repeatingOptionWeekly.insert("mode", "RepeatingModeWeekly");
repeatingOptionWeekly.insert("weekDays", QVariantList() << 2 << 4 << 5);
QVariantMap repeatingOptionMonthly;
repeatingOptionMonthly.insert("mode", "RepeatingModeMonthly");
repeatingOptionMonthly.insert("monthDays", QVariantList() << 20 << 14 << 5);
QVariantMap repeatingOptionYearly;
repeatingOptionYearly.insert("mode", "RepeatingModeYearly");
QVariantList calendarItems;
calendarItems.append(createCalendarItem("12:10", 20, repeatingOptionWeekly));
calendarItems.append(createCalendarItem("23:33", 11, repeatingOptionMonthly));
calendarItems.append(createCalendarItem(QDateTime::currentDateTime().toTime_t(), 50, repeatingOptionYearly));
QVariantList timeEventItems;
timeEventItems.append(createTimeEventItem(QDateTime::currentDateTime().toTime_t(), repeatingOptionYearly));
timeEventItems.append(createTimeEventItem("13:12", repeatingOptionWeekly));
timeEventItems.append(createTimeEventItem("18:45", repeatingOptionMonthly));
QTest::addColumn<QVariantMap>("timeDescriptor");
QTest::newRow("calendarItems") << createTimeDescriptorCalendar(calendarItems);
QTest::newRow("timeEventItems") << createTimeDescriptorTimeEvent(timeEventItems);
}
void TestTimeManager::loadSaveTimeDescriptor()
{
QFETCH(QVariantMap, timeDescriptor);
initTimeManager();
// Action (without params)
QVariantMap ruleMap; QVariantMap action; QVariantMap exitAction;
action.insert("actionTypeId", mockActionIdNoParams);
action.insert("deviceId", m_mockDeviceId);
action.insert("ruleActionParams", QVariantList());
// Exit action (with params)
QVariantList actionParams;
QVariantMap param1;
param1.insert("name", "mockActionParam1");
param1.insert("value", 12);
actionParams.append(param1);
QVariantMap param2;
param2.insert("name", "mockActionParam2");
param2.insert("value", true);
actionParams.append(param2);
exitAction.insert("actionTypeId", mockActionIdWithParams);
exitAction.insert("deviceId", m_mockDeviceId);
exitAction.insert("ruleActionParams", actionParams);
// Create the rule map
ruleMap.insert("name", "Time based weekly calendar rule");
ruleMap.insert("timeDescriptor", timeDescriptor);
ruleMap.insert("actions", QVariantList() << action);
ruleMap.insert("exitActions", QVariantList() << exitAction);
// Add the rule
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);
verifyRuleError(response);
QVariantMap timeDescriptorMap = response.toMap().value("params").toMap().value("rule").toMap().value("timeDescriptor").toMap();
qDebug() << QJsonDocument::fromVariant(timeDescriptorMap).toJson();
// Restart the server
restartServer();
// Get the loaded rule
response = injectAndWait("Rules.GetRuleDetails", params);
verifyRuleError(response);
QVariantMap timeDescriptorMapLoaded = response.toMap().value("params").toMap().value("rule").toMap().value("timeDescriptor").toMap();
qDebug() << QJsonDocument::fromVariant(timeDescriptorMapLoaded).toJson();
QCOMPARE(timeDescriptorMap, timeDescriptorMapLoaded);
}
void TestTimeManager::addTimeDescriptor_data()
{
// valid RepeatingOptions
@ -267,7 +362,6 @@ void TestTimeManager::addTimeDescriptor()
if (error != RuleEngine::RuleErrorNoError)
return;
// Print rule
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
// REMOVE rule
@ -1363,6 +1457,70 @@ void TestTimeManager::testEventItemYearly()
verifyRuleError(response);
}
void TestTimeManager::testEnableDisableTimeRule()
{
initTimeManager();
QDateTime dateTime(QDate::currentDate(), QTime(10,15));
// Repeating option
QVariantMap repeatingOptionDaily;
repeatingOptionDaily.insert("mode", "RepeatingModeDaily");
// Action
QVariantMap action;
action.insert("actionTypeId", mockActionIdNoParams);
action.insert("deviceId", m_mockDeviceId);
action.insert("ruleActionParams", QVariantList());
QVariantMap ruleMap;
ruleMap.insert("name", "Time based daily event rule");
ruleMap.insert("actions", QVariantList() << action);
ruleMap.insert("timeDescriptor", createTimeDescriptorTimeEvent(createTimeEventItem(dateTime.time().toString("hh:mm"), repeatingOptionDaily)));
QVariant response = injectAndWait("Rules.AddRule", ruleMap);
verifyRuleError(response);
RuleId ruleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
// not triggering
GuhCore::instance()->timeManager()->setTime(dateTime.addMSecs(-60));
verifyRuleNotExecuted();
// trigger
GuhCore::instance()->timeManager()->setTime(dateTime);
verifyRuleExecuted(mockActionIdNoParams);
cleanupMockHistory();
// not triggering
GuhCore::instance()->timeManager()->setTime(dateTime.addMSecs(60));
verifyRuleNotExecuted();
// Now DISABLE the rule
QVariantMap enableDisableParams;
enableDisableParams.insert("ruleId", ruleId.toString());
response = injectAndWait("Rules.DisableRule", enableDisableParams);
verifyRuleError(response);
// trigger
GuhCore::instance()->timeManager()->setTime(dateTime);
verifyRuleNotExecuted();
// Now ENABLE the rule again
response.clear();
response = injectAndWait("Rules.EnableRule", enableDisableParams);
verifyRuleError(response);
// trigger
GuhCore::instance()->timeManager()->setTime(dateTime);
verifyRuleExecuted(mockActionIdNoParams);
cleanupMockHistory();
// REMOVE rule
QVariantMap removeParams;
removeParams.insert("ruleId", ruleId);
response = injectAndWait("Rules.RemoveRule", removeParams);
verifyRuleError(response);
}
void TestTimeManager::initTimeManager()
{
GuhCore::instance()->timeManager()->stopTimer();