Merge PR #403: Improve irrigation view, add support for time based rule templates

This commit is contained in:
Jenkins nymea 2020-08-15 00:24:45 +02:00
commit 636b05cbb5
45 changed files with 1213 additions and 380 deletions

View File

@ -126,6 +126,11 @@ Devices *DeviceManager::devices() const
return m_devices;
}
Devices *DeviceManager::things() const
{
return m_devices;
}
DeviceClasses *DeviceManager::deviceClasses() const
{
return m_deviceClasses;

View File

@ -54,6 +54,7 @@ class DeviceManager : public JsonHandler
Q_OBJECT
Q_PROPERTY(Vendors* vendors READ vendors CONSTANT)
Q_PROPERTY(Plugins* plugins READ plugins CONSTANT)
Q_PROPERTY(Devices* things READ things CONSTANT)
Q_PROPERTY(Devices* devices READ devices CONSTANT)
Q_PROPERTY(DeviceClasses* deviceClasses READ deviceClasses CONSTANT)
Q_PROPERTY(IOConnections* ioConnections READ ioConnections CONSTANT)
@ -78,6 +79,7 @@ public:
Vendors* vendors() const;
Plugins* plugins() const;
Devices* devices() const;
Devices* things() const;
DeviceClasses* deviceClasses() const;
IOConnections* ioConnections() const;

View File

@ -308,116 +308,8 @@ Device* JsonTypes::unpackDevice(DeviceManager *deviceManager, const QVariantMap
return device;
}
QVariantMap JsonTypes::packRule(Rule *rule)
{
QVariantMap ret;
if (!rule->id().isNull()) {
ret.insert("ruleId", rule->id());
}
ret.insert("name", rule->name());
ret.insert("enabled", rule->enabled());
ret.insert("executable", rule->executable());
if (rule->actions()->rowCount() > 0) {
ret.insert("actions", packRuleActions(rule->actions()));
}
if (rule->exitActions()->rowCount() > 0) {
ret.insert("exitActions", packRuleActions(rule->exitActions()));
}
if (rule->eventDescriptors()->rowCount() > 0) {
ret.insert("eventDescriptors", packEventDescriptors(rule->eventDescriptors()));
}
if (rule->timeDescriptor()->timeEventItems()->rowCount() > 0 || rule->timeDescriptor()->calendarItems()->rowCount() > 0) {
ret.insert("timeDescriptor", packTimeDescriptor(rule->timeDescriptor()));
}
if (rule->stateEvaluator()) {
ret.insert("stateEvaluator", packStateEvaluator(rule->stateEvaluator()));
}
return ret;
}
QVariantList JsonTypes::packRuleActions(RuleActions *ruleActions)
{
QVariantList ret;
for (int i = 0; i < ruleActions->rowCount(); i++) {
QVariantMap ruleAction;
RuleAction *ra = ruleActions->get(i);
if (!ra->actionTypeId().isNull() && !ra->deviceId().isNull()) {
ruleAction.insert("deviceId", ra->deviceId());
ruleAction.insert("actionTypeId", ra->actionTypeId());
} else if (!ra->deviceId().isNull() && !ra->browserItemId().isEmpty()) {
ruleAction.insert("deviceId", ra->deviceId());
ruleAction.insert("browserItemId", ra->browserItemId());
} else {
ruleAction.insert("interface", ra->interfaceName());
ruleAction.insert("interfaceAction", ra->interfaceAction());
}
if (ra->ruleActionParams()->rowCount() > 0) {
QVariantList ruleActionParams;
for (int j = 0; j < ra->ruleActionParams()->rowCount(); j++) {
QVariantMap ruleActionParam;
RuleActionParam *rap = ruleActions->get(i)->ruleActionParams()->get(j);
if (!rap->paramTypeId().isNull()) {
ruleActionParam.insert("paramTypeId", rap->paramTypeId());
} else {
ruleActionParam.insert("paramName", rap->paramName());
}
if (rap->isValueBased()) {
ruleActionParam.insert("value", rap->value());
} else if (rap->isEventParamBased()) {
ruleActionParam.insert("eventTypeId", rap->eventTypeId());
ruleActionParam.insert("eventParamTypeId", rap->eventParamTypeId());
} else {
ruleActionParam.insert("stateDeviceId", rap->stateDeviceId());
ruleActionParam.insert("stateTypeId", rap->stateTypeId());
}
ruleActionParams.append(ruleActionParam);
}
ruleAction.insert("ruleActionParams", ruleActionParams);
}
ret.append(ruleAction);
}
return ret;
}
QVariantList JsonTypes::packEventDescriptors(EventDescriptors *eventDescriptors)
{
QVariantList ret;
for (int i = 0; i < eventDescriptors->rowCount(); i++) {
QVariantMap eventDescriptorMap;
EventDescriptor* eventDescriptor = eventDescriptors->get(i);
if (!eventDescriptor->deviceId().isNull() && !eventDescriptor->eventTypeId().isNull()) {
eventDescriptorMap.insert("eventTypeId", eventDescriptor->eventTypeId());
eventDescriptorMap.insert("deviceId", eventDescriptor->deviceId());
} else {
eventDescriptorMap.insert("interface", eventDescriptor->interfaceName());
eventDescriptorMap.insert("interfaceEvent", eventDescriptor->interfaceEvent());
}
if (eventDescriptor->paramDescriptors()->rowCount() > 0) {
QVariantList paramDescriptors;
for (int j = 0; j < eventDescriptor->paramDescriptors()->rowCount(); j++) {
QVariantMap paramDescriptor;
if (!eventDescriptor->paramDescriptors()->get(j)->paramTypeId().isEmpty()) {
paramDescriptor.insert("paramTypeId", eventDescriptor->paramDescriptors()->get(j)->paramTypeId());
} else {
paramDescriptor.insert("paramName", eventDescriptor->paramDescriptors()->get(j)->paramName());
}
paramDescriptor.insert("value", eventDescriptor->paramDescriptors()->get(j)->value());
QMetaEnum operatorEnum = QMetaEnum::fromType<ParamDescriptor::ValueOperator>();
paramDescriptor.insert("operator", operatorEnum.valueToKey(eventDescriptor->paramDescriptors()->get(j)->operatorType()));
paramDescriptors.append(paramDescriptor);
}
eventDescriptorMap.insert("paramDescriptors", paramDescriptors);
}
ret.append(eventDescriptorMap);
}
return ret;
}
QVariantMap JsonTypes::packParam(Param *param)
{
@ -427,92 +319,6 @@ QVariantMap JsonTypes::packParam(Param *param)
return ret;
}
QVariantMap JsonTypes::packStateEvaluator(StateEvaluator *stateEvaluator)
{
QVariantMap ret;
QMetaEnum stateOperatorEnum = QMetaEnum::fromType<StateEvaluator::StateOperator>();
ret.insert("operator", stateOperatorEnum.valueToKey(stateEvaluator->stateOperator()));
QVariantMap stateDescriptor;
if (!stateEvaluator->stateDescriptor()->deviceId().isNull() && !stateEvaluator->stateDescriptor()->stateTypeId().isNull()) {
stateDescriptor.insert("deviceId", stateEvaluator->stateDescriptor()->deviceId());
stateDescriptor.insert("stateTypeId", stateEvaluator->stateDescriptor()->stateTypeId());
} else {
stateDescriptor.insert("interface", stateEvaluator->stateDescriptor()->interfaceName());
stateDescriptor.insert("interfaceState", stateEvaluator->stateDescriptor()->interfaceState());
}
QMetaEnum valueOperatorEnum = QMetaEnum::fromType<StateDescriptor::ValueOperator>();
stateDescriptor.insert("operator", valueOperatorEnum.valueToKeys(stateEvaluator->stateDescriptor()->valueOperator()));
stateDescriptor.insert("value", stateEvaluator->stateDescriptor()->value());
ret.insert("stateDescriptor", stateDescriptor);
QVariantList childEvaluators;
for (int i = 0; i < stateEvaluator->childEvaluators()->rowCount(); i++) {
childEvaluators.append(packStateEvaluator(stateEvaluator->childEvaluators()->get(i)));
}
ret.insert("childEvaluators", childEvaluators);
return ret;
}
QVariantMap JsonTypes::packTimeDescriptor(TimeDescriptor *timeDescriptor)
{
QVariantMap ret;
QVariantList timeEventItems;
for (int i = 0; i < timeDescriptor->timeEventItems()->rowCount(); i++) {
timeEventItems.append(packTimeEventItem(timeDescriptor->timeEventItems()->get(i)));
}
if (!timeEventItems.isEmpty()) {
ret.insert("timeEventItems", timeEventItems);
}
QVariantList calendarItems;
for (int i = 0; i < timeDescriptor->calendarItems()->rowCount(); i++) {
calendarItems.append(packCalendarItem(timeDescriptor->calendarItems()->get(i)));
}
if (!calendarItems.isEmpty()) {
ret.insert("calendarItems", calendarItems);
}
return ret;
}
QVariantMap JsonTypes::packTimeEventItem(TimeEventItem *timeEventItem)
{
QVariantMap ret;
if (!timeEventItem->time().isNull()) {
ret.insert("time", timeEventItem->time().toString("hh:mm"));
}
if (!timeEventItem->dateTime().isNull()) {
ret.insert("datetime", timeEventItem->dateTime().toSecsSinceEpoch());
}
ret.insert("repeating", packRepeatingOption(timeEventItem->repeatingOption()));
return ret;
}
QVariantMap JsonTypes::packCalendarItem(CalendarItem *calendarItem)
{
QVariantMap ret;
ret.insert("duration", calendarItem->duration());
if (!calendarItem->dateTime().isNull()) {
ret.insert("datetime", calendarItem->dateTime().toSecsSinceEpoch());
}
if (!calendarItem->startTime().isNull()) {
ret.insert("startTime", calendarItem->startTime().toString("hh:mm"));
}
ret.insert("repeating", packRepeatingOption(calendarItem->repeatingOption()));
return ret;
}
QVariantMap JsonTypes::packRepeatingOption(RepeatingOption *repeatingOption)
{
QVariantMap ret;
QMetaEnum repeatingModeEnum = QMetaEnum::fromType<RepeatingOption::RepeatingMode>();
ret.insert("mode", repeatingModeEnum.valueToKey(repeatingOption->repeatingMode()));
if (!repeatingOption->weekDays().isEmpty()) {
ret.insert("weekDays", repeatingOption->weekDays());
}
if (!repeatingOption->monthDays().isEmpty()) {
ret.insert("monthDays", repeatingOption->monthDays());
}
return ret;
}
DeviceClass::SetupMethod JsonTypes::stringToSetupMethod(const QString &setupMethodString)
{
if (setupMethodString == "SetupMethodJustAdd") {

View File

@ -51,14 +51,6 @@ class DeviceManager;
class Device;
class DeviceClasses;
class Param;
class Rule;
class StateEvaluator;
class RuleActions;
class EventDescriptors;
class TimeDescriptor;
class TimeEventItem;
class CalendarItem;
class RepeatingOption;
class JsonTypes : public QObject
{
@ -76,15 +68,7 @@ public:
static ActionType *unpackActionType(const QVariantMap &actionTypeMap, QObject *parent);
static Device *unpackDevice(DeviceManager *deviceManager, const QVariantMap &deviceMap, DeviceClasses *deviceClasses, Device *oldDevice = nullptr);
static QVariantMap packRule(Rule* rule);
static QVariantList packRuleActions(RuleActions* ruleActions);
static QVariantList packEventDescriptors(EventDescriptors* eventDescriptors);
static QVariantMap packParam(Param *param);
static QVariantMap packStateEvaluator(StateEvaluator* stateEvaluator);
static QVariantMap packTimeDescriptor(TimeDescriptor* timeDescriptor);
static QVariantMap packTimeEventItem(TimeEventItem* timeEventItem);
static QVariantMap packCalendarItem(CalendarItem* calendarItem);
static QVariantMap packRepeatingOption(RepeatingOption* repeatingOption);
private:
static DeviceClass::SetupMethod stringToSetupMethod(const QString &setupMethodString);

View File

@ -83,6 +83,9 @@
#include "ruletemplates/ruletemplates.h"
#include "ruletemplates/ruletemplate.h"
#include "ruletemplates/eventdescriptortemplate.h"
#include "ruletemplates/timedescriptortemplate.h"
#include "ruletemplates/calendaritemtemplate.h"
#include "ruletemplates/timeeventitemtemplate.h"
#include "ruletemplates/stateevaluatortemplate.h"
#include "ruletemplates/statedescriptortemplate.h"
#include "ruletemplates/ruleactiontemplate.h"
@ -265,6 +268,11 @@ void registerQmlTypes() {
qmlRegisterUncreatableType<RuleTemplate>(uri, 1, 0, "RuleTemplate", "Get them from RuleTemplates");
qmlRegisterUncreatableType<EventDescriptorTemplates>(uri, 1, 0, "EventDescriptorTemplates", "Get it from RuleTemplate");
qmlRegisterUncreatableType<EventDescriptorTemplate>(uri, 1, 0, "EventDescriptorTemplate", "Get it from EventDescriptorTemplates");
qmlRegisterUncreatableType<TimeDescriptorTemplate>(uri, 1, 0, "TimeDescriptorTemplate", "Get it from RuleTemplate");
qmlRegisterUncreatableType<CalendarItemTemplates>(uri, 1, 0, "CalendarItemTemplates", "Get it from TimeDescriptorTemplate");
qmlRegisterUncreatableType<CalendarItemTemplate>(uri, 1, 0, "CalendarItemTemplate", "Get it from CalendarItemTemplates");
qmlRegisterUncreatableType<TimeEventItemTemplates>(uri, 1, 0, "TimeEventItemTemplates", "Get it from TimeDescriptorTemplate");
qmlRegisterUncreatableType<TimeEventItemTemplate>(uri, 1, 0, "TimeEventItemTemplate", "Get it from TimeEventItemTemplates");
qmlRegisterUncreatableType<StateEvaluatorTemplate>(uri, 1, 0, "StateEvaluatorTemplate", "Get it from RuleTemplate");
qmlRegisterUncreatableType<StateDescriptorTemplate>(uri, 1, 0, "StateDescriptorTemplate", "Get it from StateEvaluatorTemplate");
qmlRegisterUncreatableType<RuleActionTemplates>(uri, 1, 0, "RuleActionTemplates", "Get it from RuleTemplate");

View File

@ -27,6 +27,9 @@ INCLUDEPATH += $$top_srcdir/QtZeroConf
SOURCES += \
configuration/networkmanager.cpp \
engine.cpp \
ruletemplates/calendaritemtemplate.cpp \
ruletemplates/timedescriptortemplate.cpp \
ruletemplates/timeeventitemtemplate.cpp \
types/browseritem.cpp \
types/browseritems.cpp \
types/networkdevice.cpp \
@ -159,6 +162,9 @@ SOURCES += \
HEADERS += \
configuration/networkmanager.h \
engine.h \
ruletemplates/calendaritemtemplate.h \
ruletemplates/timedescriptortemplate.h \
ruletemplates/timeeventitemtemplate.h \
types/browseritem.h \
types/browseritems.h \
types/networkdevice.h \

View File

@ -71,8 +71,8 @@ QVariant LogsModel::data(const QModelIndex &index, int role) const
return m_list.at(index.row())->timestamp();
case RoleValue:
return m_list.at(index.row())->value();
case RoleDeviceId:
return m_list.at(index.row())->deviceId();
case RoleThingId:
return m_list.at(index.row())->thingId();
case RoleTypeId:
return m_list.at(index.row())->typeId();
case RoleSource:
@ -88,7 +88,7 @@ QHash<int, QByteArray> LogsModel::roleNames() const
QHash<int, QByteArray> roles;
roles.insert(RoleTimestamp, "timestamp");
roles.insert(RoleValue, "value");
roles.insert(RoleDeviceId, "deviceId");
roles.insert(RoleThingId, "deviceId");
roles.insert(RoleTypeId, "typeId");
roles.insert(RoleSource, "source");
roles.insert(RoleLoggingEventType, "loggingEventType");

View File

@ -57,7 +57,8 @@ public:
enum Roles {
RoleTimestamp,
RoleValue,
RoleDeviceId,
RoleThingId,
RoleDeviceId, // < JSONRPC 5.0
RoleTypeId,
RoleSource,
RoleLoggingEventType

View File

@ -70,8 +70,9 @@ QVariant LogsModelNg::data(const QModelIndex &index, int role) const
return m_list.at(index.row())->timestamp();
case RoleValue:
return m_list.at(index.row())->value();
case RoleThingId:
case RoleDeviceId:
return m_list.at(index.row())->deviceId();
return m_list.at(index.row())->thingId();
case RoleTypeId:
return m_list.at(index.row())->typeId();
case RoleSource:
@ -87,6 +88,7 @@ QHash<int, QByteArray> LogsModelNg::roleNames() const
QHash<int, QByteArray> roles;
roles.insert(RoleTimestamp, "timestamp");
roles.insert(RoleValue, "value");
roles.insert(RoleThingId, "thingId");
roles.insert(RoleDeviceId, "deviceId");
roles.insert(RoleTypeId, "typeId");
roles.insert(RoleSource, "source");
@ -112,16 +114,16 @@ void LogsModelNg::setLive(bool live)
}
}
QUuid LogsModelNg::deviceId() const
QUuid LogsModelNg::thingId() const
{
return m_deviceId;
return m_thingId;
}
void LogsModelNg::setDeviceId(const QUuid &deviceId)
void LogsModelNg::setThingId(const QUuid &thingId)
{
if (m_deviceId != deviceId) {
m_deviceId = deviceId;
emit deviceIdChanged();
if (m_thingId != thingId) {
m_thingId = thingId;
emit thingIdChanged();
}
}
@ -236,14 +238,19 @@ void LogsModelNg::logsReply(const QVariantMap &data)
foreach (const QVariant &logEntryVariant, logEntries) {
QVariantMap entryMap = logEntryVariant.toMap();
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
QString deviceId = entryMap.value("deviceId").toString();
QString thingId;
if (m_engine->jsonRpcClient()->ensureServerVersion("5.0")) {
thingId = entryMap.value("thingId").toString();
} else {
thingId = entryMap.value("deviceId").toString();
}
QString typeId = entryMap.value("typeId").toString();
QMetaEnum sourceEnum = QMetaEnum::fromType<LogEntry::LoggingSource>();
LogEntry::LoggingSource loggingSource = static_cast<LogEntry::LoggingSource>(sourceEnum.keyToValue(entryMap.value("source").toByteArray()));
QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType<LogEntry::LoggingEventType>();
LogEntry::LoggingEventType loggingEventType = static_cast<LogEntry::LoggingEventType>(loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray()));
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
LogEntry *entry = new LogEntry(timeStamp, value, deviceId, typeId, loggingSource, loggingEventType, this);
LogEntry *entry = new LogEntry(timeStamp, value, thingId, typeId, loggingSource, loggingEventType, this);
newBlock.append(entry);
}
@ -265,7 +272,7 @@ void LogsModelNg::logsReply(const QVariantMap &data)
for (int i = 0; i < newBlock.count(); i++) {
LogEntry *entry = newBlock.at(i);
m_list.insert(offset + i, entry);
Device *dev = m_engine->deviceManager()->devices()->getDevice(entry->deviceId());
Device *dev = m_engine->deviceManager()->devices()->getDevice(entry->thingId());
if (!dev) {
qWarning() << "Device not found in system. Cannot add item to graph series.";
continue;
@ -369,10 +376,14 @@ void LogsModelNg::fetchMore(const QModelIndex &parent)
emit busyChanged();
QVariantMap params;
if (!m_deviceId.isNull()) {
QVariantList deviceIds;
deviceIds.append(m_deviceId);
params.insert("deviceIds", deviceIds);
if (!m_thingId.isNull()) {
QVariantList thingIds;
thingIds.append(m_thingId);
if (m_engine->jsonRpcClient()->ensureServerVersion("5.0")) {
params.insert("thingIds", thingIds);
} else {
params.insert("deviceIds", thingIds);
}
}
if (!m_typeIds.isEmpty()) {
QVariantList typeIds;
@ -414,8 +425,13 @@ void LogsModelNg::newLogEntryReceived(const QVariantMap &data)
}
QVariantMap entryMap = data;
QUuid deviceId = entryMap.value("deviceId").toUuid();
if (!m_deviceId.isNull() && deviceId != m_deviceId) {
QUuid thingId;
if (m_engine->jsonRpcClient()->ensureServerVersion("5.0")) {
thingId = entryMap.value("deviceId").toUuid();
} else {
thingId = entryMap.value("thingId").toUuid();
}
if (!m_thingId.isNull() && thingId != m_thingId) {
return;
}
@ -431,11 +447,11 @@ void LogsModelNg::newLogEntryReceived(const QVariantMap &data)
QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType<LogEntry::LoggingEventType>();
LogEntry::LoggingEventType loggingEventType = static_cast<LogEntry::LoggingEventType>(loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray()));
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
LogEntry *entry = new LogEntry(timeStamp, value, deviceId, typeId, loggingSource, loggingEventType, this);
LogEntry *entry = new LogEntry(timeStamp, value, thingId, typeId, loggingSource, loggingEventType, this);
m_list.prepend(entry);
if (m_graphSeries) {
Device *dev = m_engine->deviceManager()->devices()->getDevice(entry->deviceId());
Device *dev = m_engine->thingManager()->devices()->getDevice(entry->thingId());
StateType *entryStateType = dev->deviceClass()->stateTypes()->getStateType(entry->typeId());

View File

@ -47,7 +47,8 @@ class LogsModelNg : public QAbstractListModel
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
Q_PROPERTY(QUuid thingId READ thingId WRITE setThingId NOTIFY thingIdChanged)
Q_PROPERTY(QUuid deviceId READ thingId WRITE setThingId NOTIFY thingIdChanged)
Q_PROPERTY(QStringList typeIds READ typeIds WRITE setTypeIds NOTIFY typeIdsChanged)
Q_PROPERTY(QDateTime startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
Q_PROPERTY(QDateTime endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged)
@ -61,7 +62,8 @@ public:
enum Roles {
RoleTimestamp,
RoleValue,
RoleDeviceId,
RoleThingId,
RoleDeviceId, // < JSONRPC 5.0
RoleTypeId,
RoleSource,
RoleLoggingEventType
@ -81,8 +83,8 @@ public:
bool live() const;
void setLive(bool live);
QUuid deviceId() const;
void setDeviceId(const QUuid &deviceId);
QUuid thingId() const;
void setThingId(const QUuid &thingId);
QStringList typeIds() const;
void setTypeIds(const QStringList &typeId);
@ -111,7 +113,7 @@ protected:
signals:
void busyChanged();
void liveChanged();
void deviceIdChanged();
void thingIdChanged();
void typeIdsChanged();
void countChanged();
void startTimeChanged();
@ -132,7 +134,7 @@ private:
Engine *m_engine = nullptr;
bool m_busy = false;
bool m_live = false;
QUuid m_deviceId;
QUuid m_thingId;
QList<QUuid> m_typeIds;
QDateTime m_startTime;
QDateTime m_endTime;

View File

@ -61,16 +61,16 @@ void RulesFilterModel::setRules(Rules *rules)
}
}
QString RulesFilterModel::filterDeviceId() const
QUuid RulesFilterModel::filterThingId() const
{
return m_filterDeviceId;
return m_filterThingId;
}
void RulesFilterModel::setFilterDeviceId(const QString &filterDeviceId)
void RulesFilterModel::setFilterThingId(const QUuid &filterThingId)
{
if (m_filterDeviceId != filterDeviceId) {
m_filterDeviceId = filterDeviceId;
emit filterDeviceIdChanged();
if (m_filterThingId != filterThingId) {
m_filterThingId = filterThingId;
emit filterThingIdChanged();
invalidateFilter();
emit countChanged();
}
@ -104,22 +104,22 @@ bool RulesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &sourc
return false;
}
bool found = true;
if (!m_filterDeviceId.isNull()) {
if (!m_filterThingId.isNull()) {
found = false;
for (int i = 0; i < rule->eventDescriptors()->rowCount(); i++) {
EventDescriptor *ed = rule->eventDescriptors()->get(i);
if (ed->deviceId() == m_filterDeviceId) {
if (ed->thingId() == m_filterThingId) {
found = true;
break;
}
}
if (!found && rule->stateEvaluator() && rule->stateEvaluator()->containsDevice(m_filterDeviceId)) {
if (!found && rule->stateEvaluator() && rule->stateEvaluator()->containsDevice(m_filterThingId)) {
found = true;
}
if (!found) {
for (int i = 0; i < rule->actions()->rowCount(); i++) {
RuleAction *ra = rule->actions()->get(i);
if (ra->deviceId() == m_filterDeviceId) {
if (ra->deviceId() == m_filterThingId) {
found = true;
break;
}
@ -128,7 +128,7 @@ bool RulesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &sourc
if (!found) {
for (int i = 0; i < rule->exitActions()->rowCount(); i++) {
RuleAction *ra = rule->exitActions()->get(i);
if (ra->deviceId() == m_filterDeviceId) {
if (ra->deviceId() == m_filterThingId) {
found = true;
break;
}

View File

@ -42,7 +42,8 @@ class RulesFilterModel : public QSortFilterProxyModel
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(Rules* rules READ rules WRITE setRules NOTIFY rulesChanged)
Q_PROPERTY(QString filterDeviceId READ filterDeviceId WRITE setFilterDeviceId NOTIFY filterDeviceIdChanged)
Q_PROPERTY(QUuid filterThingId READ filterThingId WRITE setFilterThingId NOTIFY filterThingIdChanged)
Q_PROPERTY(QUuid filterDeviceId READ filterThingId WRITE setFilterThingId NOTIFY filterThingIdChanged)
Q_PROPERTY(bool filterExecutable READ filterExecutable WRITE setFilterExecutable NOTIFY filterExecutableChanged)
public:
@ -51,8 +52,8 @@ public:
Rules* rules() const;
void setRules(Rules* rules);
QString filterDeviceId() const;
void setFilterDeviceId(const QString &filterDeviceId);
QUuid filterThingId() const;
void setFilterThingId(const QUuid &filterThingId);
bool filterExecutable() const;
void setFilterExecutable(bool filterExecutable);
@ -61,7 +62,7 @@ public:
signals:
void rulesChanged();
void filterDeviceIdChanged();
void filterThingIdChanged();
void filterExecutableChanged();
void countChanged();
@ -70,7 +71,7 @@ protected:
private:
Rules *m_rules = nullptr;
QString m_filterDeviceId;
QUuid m_filterThingId;
bool m_filterExecutable = false;
};

View File

@ -47,7 +47,11 @@ void TagsProxyModel::setTags(Tags *tags)
if (m_tags != tags) {
m_tags = tags;
setSourceModel(tags);
connect(tags, &Tags::countChanged, this, &TagsProxyModel::countChanged, Qt::QueuedConnection);
connect(tags, &Tags::countChanged, this, [=](){
qWarning() << "Tag count changed!";
invalidateFilter();
emit countChanged();
}, Qt::QueuedConnection);
setSortRole(Tags::RoleValue);
sort(0);
emit tagsChanged();
@ -70,27 +74,27 @@ void TagsProxyModel::setFilterTagId(const QString &filterTagId)
}
}
QString TagsProxyModel::filterDeviceId() const
QUuid TagsProxyModel::filterThingId() const
{
return m_filterDeviceId;
return m_filterThingId;
}
void TagsProxyModel::setFilterDeviceId(const QString &filterDeviceId)
void TagsProxyModel::setFilterThingId(const QUuid &filterThingId)
{
if (m_filterDeviceId != filterDeviceId) {
m_filterDeviceId = filterDeviceId;
emit filterDeviceIdChanged();
if (m_filterThingId != filterThingId) {
m_filterThingId = filterThingId;
emit filterThingIdChanged();
invalidateFilter();
emit countChanged();
}
}
QString TagsProxyModel::filterRuleId() const
QUuid TagsProxyModel::filterRuleId() const
{
return m_filterRuleId;
}
void TagsProxyModel::setFilterRuleId(const QString &filterRuleId)
void TagsProxyModel::setFilterRuleId(const QUuid &filterRuleId)
{
if (m_filterRuleId != filterRuleId) {
m_filterRuleId = filterRuleId;
@ -100,6 +104,21 @@ void TagsProxyModel::setFilterRuleId(const QString &filterRuleId)
}
}
QString TagsProxyModel::filterValue() const
{
return m_filterValue;
}
void TagsProxyModel::setFilterValue(const QString &filterValue)
{
if (m_filterValue != filterValue) {
m_filterValue = filterValue;
emit filterValueChanged();
invalidateFilter();
emit countChanged();
}
}
Tag *TagsProxyModel::get(int index) const
{
if (index < 0 || index > rowCount()) {
@ -129,13 +148,19 @@ bool TagsProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_
return false;
}
}
if (!m_filterDeviceId.isEmpty()) {
if (QUuid(tag->deviceId()) != QUuid(m_filterDeviceId)) {
if (!m_filterThingId.isNull()) {
if (tag->thingId() != m_filterThingId) {
return false;
}
}
if (!m_filterRuleId.isEmpty()) {
if (QUuid(tag->ruleId()) != QUuid(m_filterRuleId)) {
if (!m_filterRuleId.isNull()) {
if (tag->ruleId() != m_filterRuleId) {
return false;
}
}
if (!m_filterValue.isEmpty()) {
qDebug() << "**************************************************************" << tag->value() << m_filterValue;
if (tag->value() != m_filterValue) {
return false;
}
}

View File

@ -32,6 +32,7 @@
#define TAGSPROXYMODEL_H
#include <QSortFilterProxyModel>
#include <QUuid>
class Tag;
class Tags;
@ -42,8 +43,10 @@ class TagsProxyModel : public QSortFilterProxyModel
Q_PROPERTY(Tags* tags READ tags WRITE setTags NOTIFY tagsChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(QString filterTagId READ filterTagId WRITE setFilterTagId NOTIFY filterTagIdChanged)
Q_PROPERTY(QString filterDeviceId READ filterDeviceId WRITE setFilterDeviceId NOTIFY filterDeviceIdChanged)
Q_PROPERTY(QString filterRuleId READ filterRuleId WRITE setFilterRuleId NOTIFY filterRuleIdChanged)
Q_PROPERTY(QUuid filterThingId READ filterThingId WRITE setFilterThingId NOTIFY filterThingIdChanged)
Q_PROPERTY(QUuid filterDeviceId READ filterThingId WRITE setFilterThingId NOTIFY filterThingIdChanged)
Q_PROPERTY(QUuid filterRuleId READ filterRuleId WRITE setFilterRuleId NOTIFY filterRuleIdChanged)
Q_PROPERTY(QString filterValue READ filterValue WRITE setFilterValue NOTIFY filterValueChanged)
public:
explicit TagsProxyModel(QObject *parent = nullptr);
@ -54,11 +57,14 @@ public:
QString filterTagId() const;
void setFilterTagId(const QString &filterTagId);
QString filterDeviceId() const;
void setFilterDeviceId(const QString &filterDeviceId);
QUuid filterThingId() const;
void setFilterThingId(const QUuid &filterThingId);
QString filterRuleId() const;
void setFilterRuleId(const QString &filterRuleId);
QUuid filterRuleId() const;
void setFilterRuleId(const QUuid &filterRuleId);
QString filterValue() const;
void setFilterValue(const QString &filterValue);
Q_INVOKABLE Tag* get(int index) const;
Q_INVOKABLE Tag* findTag(const QString &tagId) const;
@ -70,16 +76,18 @@ protected:
signals:
void tagsChanged();
void filterTagIdChanged();
void filterDeviceIdChanged();
void filterThingIdChanged();
void filterRuleIdChanged();
void filterValueChanged();
void groupSameTagsChanged();
void countChanged();
private:
Tags *m_tags = nullptr;
QString m_filterTagId;
QString m_filterDeviceId;
QString m_filterRuleId;
QUuid m_filterThingId;
QUuid m_filterRuleId;
QString m_filterValue;
};
#endif // TAGSPROXYMODEL_H

View File

@ -84,16 +84,16 @@ Rule *RuleManager::createNewRule()
return new Rule(QUuid(), this);
}
void RuleManager::addRule(const QVariantMap params)
int RuleManager::addRule(const QVariantMap params)
{
m_jsonClient->sendCommand("Rules.AddRule", params, this, "onAddRuleReply");
return m_jsonClient->sendCommand("Rules.AddRule", params, this, "onAddRuleReply");
}
void RuleManager::addRule(Rule *rule)
int RuleManager::addRule(Rule *rule)
{
QVariantMap params = JsonTypes::packRule(rule);
QVariantMap params = packRule(rule);
qDebug() << "packed rule:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson(QJsonDocument::Indented));
m_jsonClient->sendCommand("Rules.AddRule", params, this, "onAddRuleReply");
return m_jsonClient->sendCommand("Rules.AddRule", params, this, "onAddRuleReply");
}
void RuleManager::removeRule(const QUuid &ruleId)
@ -105,7 +105,7 @@ void RuleManager::removeRule(const QUuid &ruleId)
void RuleManager::editRule(Rule *rule)
{
QVariantMap params = JsonTypes::packRule(rule);
QVariantMap params = packRule(rule);
qWarning() << "Packed rule:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson(QJsonDocument::Indented));
m_jsonClient->sendCommand("Rules.EditRule", params, this, "onEditRuleReply");
@ -159,7 +159,7 @@ void RuleManager::getRulesReply(const QVariantMap &params)
qWarning() << "Error getting rules:" << params.value("error").toString();
return;
}
// qDebug() << "Get Rules reply" << params;
// qDebug() << "Get Rules reply" << params;
foreach (const QVariant &ruleDescriptionVariant, params.value("params").toMap().value("ruleDescriptions").toList()) {
QUuid ruleId = ruleDescriptionVariant.toMap().value("id").toUuid();
QString name = ruleDescriptionVariant.toMap().value("name").toString();
@ -193,14 +193,18 @@ void RuleManager::getRuleDetailsReply(const QVariantMap &params)
parseRuleExitActions(ruleMap.value("exitActions").toList(), rule);
parseTimeDescriptor(ruleMap.value("timeDescriptor").toMap(), rule);
rule->setStateEvaluator(parseStateEvaluator(ruleMap.value("stateEvaluator").toMap()));
// qDebug() << "** Rule details received:" << rule;
// qDebug() << "Rule JSON:" << qUtf8Printable(QJsonDocument::fromVariant(ruleMap).toJson());
// qDebug() << "** Rule details received:" << rule;
// qDebug() << "Rule JSON:" << qUtf8Printable(QJsonDocument::fromVariant(ruleMap).toJson());
}
void RuleManager::onAddRuleReply(const QVariantMap &params)
{
qDebug() << "Add rule reply:" << params;//.value("params").toMap().value("ruleError").toString();
emit addRuleReply(params.value("params").toMap().value("ruleError").toString(), params.value("params").toMap().value("ruleId").toString());
if (params.value("params").toMap().value("ruleError").toString() != "RuleErrorNoError") {
qWarning() << "Failed to add rule:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson());
} else {
qDebug() << "Rule added successfully. Rule ID:" << params.value("params").toMap().value("ruleId").toString();
}
emit addRuleReply(params.value("id").toInt(), params.value("params").toMap().value("ruleError").toString(), params.value("params").toMap().value("ruleId").toString());
}
void RuleManager::removeRuleReply(const QVariantMap &params)
@ -249,7 +253,11 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList,
{
foreach (const QVariant &eventDescriptorVariant, eventDescriptorList) {
EventDescriptor *eventDescriptor = new EventDescriptor(rule);
eventDescriptor->setDeviceId(eventDescriptorVariant.toMap().value("deviceId").toString());
if (m_jsonClient->ensureServerVersion("5.0")) {
eventDescriptor->setThingId(eventDescriptorVariant.toMap().value("thingId").toString());
} else {
eventDescriptor->setThingId(eventDescriptorVariant.toMap().value("deviceId").toString());
}
eventDescriptor->setEventTypeId(eventDescriptorVariant.toMap().value("eventTypeId").toString());
eventDescriptor->setInterfaceName(eventDescriptorVariant.toMap().value("interface").toString());
eventDescriptor->setInterfaceEvent(eventDescriptorVariant.toMap().value("interfaceEvent").toString());
@ -262,14 +270,14 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList,
paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorEnum.keyToValue(paramDescriptorVariant.toMap().value("operator").toString().toLocal8Bit()));
eventDescriptor->paramDescriptors()->addParamDescriptor(paramDescriptor);
}
// qDebug() << "Adding eventdescriptor" << eventDescriptor->deviceId() << eventDescriptor->eventTypeId();
// qDebug() << "Adding eventdescriptor" << eventDescriptor->deviceId() << eventDescriptor->eventTypeId();
rule->eventDescriptors()->addEventDescriptor(eventDescriptor);
}
}
StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluatorMap)
{
// qDebug() << "Parsing state evaluator. Child count:" << stateEvaluatorMap.value("childEvaluators").toList().count();
// qDebug() << "Parsing state evaluator. Child count:" << stateEvaluatorMap.value("childEvaluators").toList().count();
if (!stateEvaluatorMap.contains("stateDescriptor")) {
return nullptr;
}
@ -280,7 +288,7 @@ StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluat
StateDescriptor *sd = nullptr;
if (sdMap.contains("deviceId") && sdMap.contains("stateTypeId")) {
sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), sdMap.value("stateTypeId").toUuid(), op, sdMap.value("value"), stateEvaluator);
sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), sdMap.value("stateTypeId").toUuid(), op, sdMap.value("value"), stateEvaluator);
} else {
sd = new StateDescriptor(sdMap.value("interface").toString(), sdMap.value("interfaceState").toString(), op, sdMap.value("value"), stateEvaluator);
}
@ -371,5 +379,206 @@ void RuleManager::parseTimeDescriptor(const QVariantMap &timeDescriptor, Rule *r
calendarItem->repeatingOption()->setMonthDays(repeatingOptionMap.value("monthDays").toList());
rule->timeDescriptor()->calendarItems()->addCalendarItem(calendarItem);
}
// rule->timeDescriptor()
// rule->timeDescriptor()
}
QVariantMap RuleManager::packRule(Rule *rule)
{
QVariantMap ret;
if (!rule->id().isNull()) {
ret.insert("ruleId", rule->id());
}
ret.insert("name", rule->name());
ret.insert("enabled", rule->enabled());
ret.insert("executable", rule->executable());
if (rule->actions()->rowCount() > 0) {
ret.insert("actions", packRuleActions(rule->actions()));
}
if (rule->exitActions()->rowCount() > 0) {
ret.insert("exitActions", packRuleActions(rule->exitActions()));
}
if (rule->eventDescriptors()->rowCount() > 0) {
ret.insert("eventDescriptors", packEventDescriptors(rule->eventDescriptors()));
}
if (rule->timeDescriptor()->timeEventItems()->rowCount() > 0 || rule->timeDescriptor()->calendarItems()->rowCount() > 0) {
ret.insert("timeDescriptor", packTimeDescriptor(rule->timeDescriptor()));
}
if (rule->stateEvaluator()) {
ret.insert("stateEvaluator", packStateEvaluator(rule->stateEvaluator()));
}
return ret;
}
QVariantList RuleManager::packEventDescriptors(EventDescriptors *eventDescriptors)
{
QVariantList ret;
for (int i = 0; i < eventDescriptors->rowCount(); i++) {
QVariantMap eventDescriptorMap;
EventDescriptor* eventDescriptor = eventDescriptors->get(i);
if (!eventDescriptor->thingId().isNull() && !eventDescriptor->eventTypeId().isNull()) {
eventDescriptorMap.insert("eventTypeId", eventDescriptor->eventTypeId());
if (m_jsonClient->ensureServerVersion("5.0")) {
eventDescriptorMap.insert("thingId", eventDescriptor->thingId());
} else {
eventDescriptorMap.insert("deviceId", eventDescriptor->thingId());
}
} else {
eventDescriptorMap.insert("interface", eventDescriptor->interfaceName());
eventDescriptorMap.insert("interfaceEvent", eventDescriptor->interfaceEvent());
}
if (eventDescriptor->paramDescriptors()->rowCount() > 0) {
QVariantList paramDescriptors;
for (int j = 0; j < eventDescriptor->paramDescriptors()->rowCount(); j++) {
QVariantMap paramDescriptor;
if (!eventDescriptor->paramDescriptors()->get(j)->paramTypeId().isEmpty()) {
paramDescriptor.insert("paramTypeId", eventDescriptor->paramDescriptors()->get(j)->paramTypeId());
} else {
paramDescriptor.insert("paramName", eventDescriptor->paramDescriptors()->get(j)->paramName());
}
paramDescriptor.insert("value", eventDescriptor->paramDescriptors()->get(j)->value());
QMetaEnum operatorEnum = QMetaEnum::fromType<ParamDescriptor::ValueOperator>();
paramDescriptor.insert("operator", operatorEnum.valueToKey(eventDescriptor->paramDescriptors()->get(j)->operatorType()));
paramDescriptors.append(paramDescriptor);
}
eventDescriptorMap.insert("paramDescriptors", paramDescriptors);
}
ret.append(eventDescriptorMap);
}
return ret;
}
QVariantMap RuleManager::packTimeDescriptor(TimeDescriptor *timeDescriptor)
{
QVariantMap ret;
QVariantList timeEventItems;
for (int i = 0; i < timeDescriptor->timeEventItems()->rowCount(); i++) {
timeEventItems.append(packTimeEventItem(timeDescriptor->timeEventItems()->get(i)));
}
if (!timeEventItems.isEmpty()) {
ret.insert("timeEventItems", timeEventItems);
}
QVariantList calendarItems;
for (int i = 0; i < timeDescriptor->calendarItems()->rowCount(); i++) {
calendarItems.append(packCalendarItem(timeDescriptor->calendarItems()->get(i)));
}
if (!calendarItems.isEmpty()) {
ret.insert("calendarItems", calendarItems);
}
return ret;
}
QVariantMap RuleManager::packTimeEventItem(TimeEventItem *timeEventItem)
{
QVariantMap ret;
if (!timeEventItem->time().isNull()) {
ret.insert("time", timeEventItem->time().toString("hh:mm"));
}
if (!timeEventItem->dateTime().isNull()) {
ret.insert("datetime", timeEventItem->dateTime().toSecsSinceEpoch());
}
ret.insert("repeating", packRepeatingOption(timeEventItem->repeatingOption()));
return ret;
}
QVariantMap RuleManager::packCalendarItem(CalendarItem *calendarItem)
{
QVariantMap ret;
ret.insert("duration", calendarItem->duration());
if (!calendarItem->dateTime().isNull()) {
ret.insert("datetime", calendarItem->dateTime().toSecsSinceEpoch());
}
if (!calendarItem->startTime().isNull()) {
ret.insert("startTime", calendarItem->startTime().toString("hh:mm"));
}
ret.insert("repeating", packRepeatingOption(calendarItem->repeatingOption()));
return ret;
}
QVariantMap RuleManager::packRepeatingOption(RepeatingOption *repeatingOption)
{
QVariantMap ret;
QMetaEnum repeatingModeEnum = QMetaEnum::fromType<RepeatingOption::RepeatingMode>();
ret.insert("mode", repeatingModeEnum.valueToKey(repeatingOption->repeatingMode()));
if (!repeatingOption->weekDays().isEmpty()) {
ret.insert("weekDays", repeatingOption->weekDays());
}
if (!repeatingOption->monthDays().isEmpty()) {
ret.insert("monthDays", repeatingOption->monthDays());
}
return ret;
}
QVariantList RuleManager::packRuleActions(RuleActions *ruleActions)
{
QVariantList ret;
for (int i = 0; i < ruleActions->rowCount(); i++) {
QVariantMap ruleAction;
RuleAction *ra = ruleActions->get(i);
if (!ra->actionTypeId().isNull() && !ra->deviceId().isNull()) {
ruleAction.insert("deviceId", ra->deviceId());
ruleAction.insert("actionTypeId", ra->actionTypeId());
} else if (!ra->deviceId().isNull() && !ra->browserItemId().isEmpty()) {
ruleAction.insert("deviceId", ra->deviceId());
ruleAction.insert("browserItemId", ra->browserItemId());
} else {
ruleAction.insert("interface", ra->interfaceName());
ruleAction.insert("interfaceAction", ra->interfaceAction());
}
if (ra->ruleActionParams()->rowCount() > 0) {
QVariantList ruleActionParams;
for (int j = 0; j < ra->ruleActionParams()->rowCount(); j++) {
QVariantMap ruleActionParam;
RuleActionParam *rap = ruleActions->get(i)->ruleActionParams()->get(j);
if (!rap->paramTypeId().isNull()) {
ruleActionParam.insert("paramTypeId", rap->paramTypeId());
} else {
ruleActionParam.insert("paramName", rap->paramName());
}
if (rap->isValueBased()) {
ruleActionParam.insert("value", rap->value());
} else if (rap->isEventParamBased()) {
ruleActionParam.insert("eventTypeId", rap->eventTypeId());
ruleActionParam.insert("eventParamTypeId", rap->eventParamTypeId());
} else {
ruleActionParam.insert("stateDeviceId", rap->stateDeviceId());
ruleActionParam.insert("stateTypeId", rap->stateTypeId());
}
ruleActionParams.append(ruleActionParam);
}
ruleAction.insert("ruleActionParams", ruleActionParams);
}
ret.append(ruleAction);
}
return ret;
}
QVariantMap RuleManager::packStateEvaluator(StateEvaluator *stateEvaluator)
{
QVariantMap ret;
QMetaEnum stateOperatorEnum = QMetaEnum::fromType<StateEvaluator::StateOperator>();
ret.insert("operator", stateOperatorEnum.valueToKey(stateEvaluator->stateOperator()));
QVariantMap stateDescriptor;
if (!stateEvaluator->stateDescriptor()->deviceId().isNull() && !stateEvaluator->stateDescriptor()->stateTypeId().isNull()) {
stateDescriptor.insert("deviceId", stateEvaluator->stateDescriptor()->deviceId());
stateDescriptor.insert("stateTypeId", stateEvaluator->stateDescriptor()->stateTypeId());
} else {
stateDescriptor.insert("interface", stateEvaluator->stateDescriptor()->interfaceName());
stateDescriptor.insert("interfaceState", stateEvaluator->stateDescriptor()->interfaceState());
}
QMetaEnum valueOperatorEnum = QMetaEnum::fromType<StateDescriptor::ValueOperator>();
stateDescriptor.insert("operator", valueOperatorEnum.valueToKeys(stateEvaluator->stateDescriptor()->valueOperator()));
stateDescriptor.insert("value", stateEvaluator->stateDescriptor()->value());
ret.insert("stateDescriptor", stateDescriptor);
QVariantList childEvaluators;
for (int i = 0; i < stateEvaluator->childEvaluators()->rowCount(); i++) {
childEvaluators.append(packStateEvaluator(stateEvaluator->childEvaluators()->get(i)));
}
ret.insert("childEvaluators", childEvaluators);
return ret;
}

View File

@ -37,8 +37,14 @@
#include "jsonrpc/jsonhandler.h"
class JsonRpcClient;
class EventDescriptors;
class TimeDescriptor;
class TimeEventItem;
class CalendarItem;
class RepeatingOption;
class StateEvaluator;
class RuleAction;
class RuleActions;
class RuleManager : public JsonHandler
{
@ -57,8 +63,8 @@ public:
Q_INVOKABLE Rule* createNewRule();
Q_INVOKABLE void addRule(const QVariantMap params);
Q_INVOKABLE void addRule(Rule *rule);
Q_INVOKABLE int addRule(const QVariantMap params);
Q_INVOKABLE int addRule(Rule *rule);
Q_INVOKABLE void removeRule(const QUuid &ruleId);
Q_INVOKABLE void editRule(Rule *rule);
Q_INVOKABLE void executeActions(const QString &ruleId);
@ -81,8 +87,17 @@ private:
RuleAction* parseRuleAction(const QVariantMap &ruleAction);
void parseTimeDescriptor(const QVariantMap &timeDescriptor, Rule *rule);
QVariantMap packRule(Rule *rule);
QVariantList packEventDescriptors(EventDescriptors *eventDescriptors);
QVariantMap packTimeDescriptor(TimeDescriptor *timeDescriptor);
QVariantMap packTimeEventItem(TimeEventItem *timeEventItem);
QVariantMap packCalendarItem(CalendarItem *calendarItem);
QVariantMap packRepeatingOption(RepeatingOption *repeatingOption);
QVariantList packRuleActions(RuleActions *ruleActions);
QVariantMap packStateEvaluator(StateEvaluator *stateEvaluator);
signals:
void addRuleReply(const QString &ruleError, const QString &ruleId);
void addRuleReply(int commandId, const QString &ruleError, const QString &ruleId);
void editRuleReply(const QString &ruleError);
private:

View File

@ -0,0 +1,50 @@
#include "calendaritemtemplate.h"
CalendarItemTemplate::CalendarItemTemplate(int duration, const QDateTime &dateTime, const QTime &startTime, RepeatingOption *repeatingOption, bool editable, QObject *parent):
QObject(parent),
m_duration(duration),
m_dateTime(dateTime),
m_startTime(startTime),
m_repeatingOption(repeatingOption),
m_editable(editable)
{
m_repeatingOption->setParent(this);
}
int CalendarItemTemplate::duration() const
{
return m_duration;
}
QDateTime CalendarItemTemplate::dateTime() const
{
return m_dateTime;
}
QTime CalendarItemTemplate::startTime() const
{
return m_startTime;
}
RepeatingOption *CalendarItemTemplate::repeatingOption()
{
return m_repeatingOption;
}
bool CalendarItemTemplate::editable() const
{
return m_editable;
}
CalendarItem *CalendarItemTemplate::createCalendarItem() const
{
CalendarItem *ret = new CalendarItem();
ret->setDateTime(m_dateTime);
ret->setDuration(m_duration);
ret->setStartTime(m_startTime);
ret->repeatingOption()->setWeekDays(m_repeatingOption->weekDays());
ret->repeatingOption()->setMonthDays(m_repeatingOption->monthDays());
ret->repeatingOption()->setRepeatingMode(m_repeatingOption->repeatingMode());
return ret;
}

View File

@ -0,0 +1,65 @@
#ifndef CALENDARITEMTEMPLATE_H
#define CALENDARITEMTEMPLATE_H
#include "types/repeatingoption.h"
#include "types/calendaritem.h"
#include <QObject>
#include <QAbstractListModel>
#include <QDateTime>
class CalendarItemTemplate : public QObject
{
Q_OBJECT
Q_PROPERTY(int duration READ duration CONSTANT)
Q_PROPERTY(QDateTime dateTime READ dateTime CONSTANT)
Q_PROPERTY(QTime startTime READ startTime CONSTANT)
Q_PROPERTY(RepeatingOption* repeatingOption READ repeatingOption CONSTANT)
Q_PROPERTY(bool editable READ editable CONSTANT)
public:
explicit CalendarItemTemplate(int duration, const QDateTime &dateTime, const QTime &startTime, RepeatingOption *repeatingOption, bool editable, QObject *parent = nullptr);
int duration() const;
QDateTime dateTime() const;
QTime startTime() const;
RepeatingOption* repeatingOption();
bool editable() const;
Q_INVOKABLE CalendarItem *createCalendarItem() const;
private:
int m_duration = 0;
QDateTime m_dateTime;
QTime m_startTime;
RepeatingOption *m_repeatingOption = nullptr;
bool m_editable = true;
};
class CalendarItemTemplates: public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount CONSTANT)
public:
CalendarItemTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {}
int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); }
QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index); Q_UNUSED(role); return QVariant(); }
Q_INVOKABLE CalendarItemTemplate* get(int index) const {
if (index < 0 || index >= m_list.count()) {
return nullptr;
}
return m_list.at(index);
}
void addCalendarItemTemplate(CalendarItemTemplate *calendarItemTemplate) {
calendarItemTemplate->setParent(this);
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
m_list.append(calendarItemTemplate);
endInsertRows();
}
private:
QList<CalendarItemTemplate*> m_list;
};
#endif // CALENDARITEMTEMPLATE_H

View File

@ -30,6 +30,7 @@
#include "ruletemplate.h"
#include "eventdescriptortemplate.h"
#include "timedescriptortemplate.h"
#include "stateevaluatortemplate.h"
#include "ruleactiontemplate.h"
@ -85,6 +86,20 @@ void RuleTemplate::setStateEvaluatorTemplate(StateEvaluatorTemplate *stateEvalua
m_stateEvaluatorTemplate = stateEvaluatorTemplate;
}
TimeDescriptorTemplate *RuleTemplate::timeDescriptorTemplate() const
{
return m_timeDescriptorTemplate;
}
void RuleTemplate::setTimeDescriptorTemplate(TimeDescriptorTemplate *timeDescriptorTemplate)
{
if (m_timeDescriptorTemplate) {
m_timeDescriptorTemplate->deleteLater();
}
timeDescriptorTemplate->setParent(this);
m_timeDescriptorTemplate = timeDescriptorTemplate;
}
RuleActionTemplates *RuleTemplate::ruleActionTemplates() const
{
return m_ruleActionTemplates;

View File

@ -36,6 +36,7 @@
class EventDescriptorTemplates;
class RuleActionTemplates;
class StateEvaluatorTemplate;
class TimeDescriptorTemplate;
class RuleTemplate : public QObject
{
@ -44,6 +45,7 @@ class RuleTemplate : public QObject
Q_PROPERTY(QString ruleNameTemplate READ ruleNameTemplate CONSTANT)
Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT)
Q_PROPERTY(EventDescriptorTemplates* eventDescriptorTemplates READ eventDescriptorTemplates CONSTANT)
Q_PROPERTY(TimeDescriptorTemplate* timeDescriptorTemplate READ timeDescriptorTemplate CONSTANT)
Q_PROPERTY(StateEvaluatorTemplate* stateEvaluatorTemplate READ stateEvaluatorTemplate CONSTANT)
Q_PROPERTY(RuleActionTemplates* ruleActionTemplates READ ruleActionTemplates CONSTANT)
Q_PROPERTY(RuleActionTemplates* ruleExitActionTemplates READ ruleExitActionTemplates CONSTANT)
@ -58,6 +60,8 @@ public:
EventDescriptorTemplates* eventDescriptorTemplates() const;
StateEvaluatorTemplate* stateEvaluatorTemplate() const;
void setStateEvaluatorTemplate(StateEvaluatorTemplate *stateEvaluatorTemplate);
TimeDescriptorTemplate* timeDescriptorTemplate() const;
void setTimeDescriptorTemplate(TimeDescriptorTemplate *timeDescriptorTemplate);
RuleActionTemplates* ruleActionTemplates() const;
RuleActionTemplates* ruleExitActionTemplates() const;
@ -67,6 +71,7 @@ private:
QString m_ruleNameTemplate;
EventDescriptorTemplates* m_eventDescriptorTemplates = nullptr;
StateEvaluatorTemplate* m_stateEvaluatorTemplate = nullptr;
TimeDescriptorTemplate* m_timeDescriptorTemplate = nullptr;
RuleActionTemplates *m_ruleActionTemplates = nullptr;
RuleActionTemplates *m_ruleExitActionTemplates = nullptr;
};

View File

@ -32,12 +32,16 @@
#include "ruletemplate.h"
#include "eventdescriptortemplate.h"
#include "timedescriptortemplate.h"
#include "calendaritemtemplate.h"
#include "timeeventitemtemplate.h"
#include "ruleactiontemplate.h"
#include "stateevaluatortemplate.h"
#include "ruleactionparamtemplate.h"
#include "types/ruleactionparam.h"
#include "types/ruleactionparams.h"
#include "types/repeatingoption.h"
#include "devicesproxy.h"
#include <QDebug>
@ -114,6 +118,12 @@ RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent)
t->setStateEvaluatorTemplate(loadStateEvaluatorTemplate(ruleTemplate.value("stateEvaluatorTemplate").toMap()));
}
// TimeDescriptorTemplate
if (ruleTemplate.contains("timeDescriptorTemplate")) {
t->setTimeDescriptorTemplate(loadTimeDescriptorTemplate(ruleTemplate.value("timeDescriptorTemplate").toMap()));
}
// RuleActionTemplates
foreach (const QVariant &ruleActionVariant, ruleTemplate.value("ruleActionTemplates").toList()) {
QVariantMap ruleActionTemplate = ruleActionVariant.toMap();
@ -240,6 +250,42 @@ StateEvaluatorTemplate *RuleTemplates::loadStateEvaluatorTemplate(const QVariant
return set;
}
TimeDescriptorTemplate *RuleTemplates::loadTimeDescriptorTemplate(const QVariantMap &timeDescriptorTemplate) const
{
TimeDescriptorTemplate *tdt = new TimeDescriptorTemplate();
foreach (const QVariant &childVariant, timeDescriptorTemplate.value("calendarItemTemplates").toList()) {
QVariantMap childMap = childVariant.toMap();
int duration = childMap.value("duration").toInt();
QDateTime dateTime = childMap.value("dateTime").toDateTime();
QTime startTime = childMap.value("startTime").toTime();
bool editable = childMap.value("editable", true).toBool();
RepeatingOption *repeatingOption = loadRepeatingOption(childMap.value("repeatingOption").toMap());
CalendarItemTemplate *cit = new CalendarItemTemplate(duration, dateTime, startTime, repeatingOption, editable, tdt);
tdt->calendarItemTemplates()->addCalendarItemTemplate(cit);
}
foreach (const QVariant &childVariant, timeDescriptorTemplate.value("timeEventItemTemplates").toList()) {
QVariantMap childMap = childVariant.toMap();
QDateTime dateTime = childMap.value("dateTime").toDateTime();
QTime time = childMap.value("time").toTime();
bool editable = childMap.value("editable", true).toBool();
RepeatingOption *repeatingOption = loadRepeatingOption(childMap.value("repeatingOption").toMap());
TimeEventItemTemplate *teit = new TimeEventItemTemplate(dateTime, time, repeatingOption, editable, tdt);
tdt->timeEventItemTemplates()->addTimeEventItemTemplate(teit);
}
return tdt;
}
RepeatingOption *RuleTemplates::loadRepeatingOption(const QVariantMap &repeatingOptionMap) const
{
RepeatingOption *repeatingOption = new RepeatingOption();
repeatingOption->setWeekDays(repeatingOptionMap.value("weekDays").toList());
repeatingOption->setMonthDays(repeatingOptionMap.value("monthDays").toList());
QMetaEnum repeatingModeEnum = QMetaEnum::fromType<RepeatingOption::RepeatingMode>();
repeatingOption->setRepeatingMode(static_cast<RepeatingOption::RepeatingMode>(repeatingModeEnum.keyToValue(repeatingOptionMap.value("repeatingMode").toString().toUtf8().data())));
return repeatingOption;
}
bool RuleTemplatesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent)

View File

@ -35,6 +35,8 @@
class RuleTemplate;
class StateEvaluatorTemplate;
class TimeDescriptorTemplate;
class RepeatingOption;
class DevicesProxy;
class RuleTemplates : public QAbstractListModel
@ -60,6 +62,8 @@ signals:
private:
StateEvaluatorTemplate* loadStateEvaluatorTemplate(const QVariantMap &stateEvaluatorTemplate) const;
TimeDescriptorTemplate* loadTimeDescriptorTemplate(const QVariantMap &timeDescriptorTemplate) const;
RepeatingOption* loadRepeatingOption(const QVariantMap &repeatingOptionMap) const;
private:
QList<RuleTemplate*> m_list;

View File

@ -0,0 +1,21 @@
#include "timedescriptortemplate.h"
#include "calendaritemtemplate.h"
#include "timeeventitemtemplate.h"
TimeDescriptorTemplate::TimeDescriptorTemplate(QObject *parent):
QObject(parent)
{
m_calendarItemTemplates = new CalendarItemTemplates(this);
m_timeEventItemTemplates = new TimeEventItemTemplates(this);
}
CalendarItemTemplates *TimeDescriptorTemplate::calendarItemTemplates() const
{
return m_calendarItemTemplates;
}
TimeEventItemTemplates *TimeDescriptorTemplate::timeEventItemTemplates() const
{
return m_timeEventItemTemplates;
}

View File

@ -0,0 +1,26 @@
#ifndef TIMEDESCRIPTORTEMPLATE_H
#define TIMEDESCRIPTORTEMPLATE_H
#include <QObject>
class CalendarItemTemplates;
class TimeEventItemTemplates;
class TimeDescriptorTemplate : public QObject
{
Q_OBJECT
Q_PROPERTY(CalendarItemTemplates* calendarItemTemplates READ calendarItemTemplates CONSTANT)
Q_PROPERTY(TimeEventItemTemplates* timeEventItemTemplates READ timeEventItemTemplates CONSTANT)
public:
explicit TimeDescriptorTemplate(QObject *parent = nullptr);
CalendarItemTemplates* calendarItemTemplates() const;
TimeEventItemTemplates* timeEventItemTemplates() const;
private:
CalendarItemTemplates *m_calendarItemTemplates = nullptr;
TimeEventItemTemplates *m_timeEventItemTemplates = nullptr;
};
#endif // TIMEDESCRIPTORTEMPLATE_H

View File

@ -0,0 +1,42 @@
#include "timeeventitemtemplate.h"
TimeEventItemTemplate::TimeEventItemTemplate(const QDateTime &dateTime, const QTime &time, RepeatingOption *repeatingOption, bool editable, QObject *parent):
QObject(parent),
m_dateTime(dateTime),
m_time(time),
m_repeatingOption(repeatingOption),
m_editable(editable)
{
m_repeatingOption->setParent(this);
}
QDateTime TimeEventItemTemplate::dateTime() const
{
return m_dateTime;
}
QTime TimeEventItemTemplate::time() const
{
return m_time;
}
RepeatingOption *TimeEventItemTemplate::repeatingOption() const
{
return m_repeatingOption;
}
bool TimeEventItemTemplate::editable() const
{
return m_editable;
}
TimeEventItem *TimeEventItemTemplate::createTimeEventItem() const
{
TimeEventItem *item = new TimeEventItem();
item->setDateTime(m_dateTime);
item->setTime(m_time);
item->repeatingOption()->setWeekDays(m_repeatingOption->weekDays());
item->repeatingOption()->setMonthDays(m_repeatingOption->monthDays());
item->repeatingOption()->setRepeatingMode(m_repeatingOption->repeatingMode());
return item;
}

View File

@ -0,0 +1,63 @@
#ifndef TIMEEVENTITEMTEMPLATE_H
#define TIMEEVENTITEMTEMPLATE_H
#include <QObject>
#include <QDateTime>
#include <QAbstractListModel>
#include "types/repeatingoption.h"
#include "types/timeeventitem.h"
class TimeEventItemTemplate : public QObject
{
Q_OBJECT
Q_PROPERTY(QDateTime dateTime READ dateTime CONSTANT)
Q_PROPERTY(QTime time READ time CONSTANT)
Q_PROPERTY(RepeatingOption* repeatingOption READ repeatingOption CONSTANT)
Q_PROPERTY(bool editable READ editable CONSTANT)
public:
explicit TimeEventItemTemplate(const QDateTime &dateTime, const QTime &time, RepeatingOption *repeatingOption, bool editable, QObject *parent = nullptr);
QDateTime dateTime() const;
QTime time() const;
RepeatingOption* repeatingOption() const;
bool editable() const;
Q_INVOKABLE TimeEventItem* createTimeEventItem() const;
private:
QDateTime m_dateTime;
QTime m_time;
RepeatingOption* m_repeatingOption = nullptr;
bool m_editable = true;
};
class TimeEventItemTemplates: public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount CONSTANT)
public:
TimeEventItemTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {}
int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent) return m_list.count(); }
QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index) Q_UNUSED(role) return QVariant(); }
Q_INVOKABLE TimeEventItemTemplate* get(int index) const {
if (index < 0 || index >= m_list.count()) {
return nullptr;
}
return m_list.at(index);
}
void addTimeEventItemTemplate(TimeEventItemTemplate *timeEventItemTemplate) {
timeEventItemTemplate->setParent(this);
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
m_list.append(timeEventItemTemplate);
endInsertRows();
}
private:
QList<TimeEventItemTemplate*> m_list;
};
#endif // TIMEEVENTITEMTEMPLATE_H

View File

@ -133,21 +133,31 @@ void TagsManager::handleTagsNotification(const QVariantMap &params)
} else if (notification == "Tags.TagRemoved") {
for (int i = 0; i < m_tags->rowCount(); i++) {
Tag* tag = m_tags->get(i);
if (tagMap.value("deviceId").toUuid() == tag->deviceId() &&
tagMap.value("ruleId").toUuid() == tag->ruleId() &&
tagMap.value("tagId").toString() == tag->tagId()) {
QUuid thingId;
if (m_jsonClient->ensureServerVersion("5.0")) {
thingId = tagMap.value("thingId").toUuid();
} else {
thingId = tagMap.value("deviceId").toUuid();
}
QUuid ruleId = tagMap.value("ruleId").toUuid();
QString tagId = tagMap.value("tagId").toString();
if (thingId == tag->thingId() && ruleId == tag->ruleId() && tagId == tag->tagId()) {
m_tags->removeTag(tag);
return;
}
}
} else if (notification == "Tags.TagValueChanged") {
qDebug() << "tag value changed";
for (int i = 0; i < m_tags->rowCount(); i++) {
Tag* tag = m_tags->get(i);
if (tagMap.value("deviceId").toUuid() == tag->deviceId() &&
tagMap.value("ruleId").toUuid() == tag->ruleId() &&
tagMap.value("tagId").toString() == tag->tagId()) {
qDebug() << "Found tag";
QUuid thingId;
if (m_jsonClient->ensureServerVersion("5.0")) {
thingId = tagMap.value("thingId").toUuid();
} else {
thingId = tagMap.value("deviceId").toUuid();
}
QUuid ruleId = tagMap.value("ruleId").toUuid();
QString tagId = tagMap.value("tagId").toString();
if (thingId == tag->thingId() && ruleId == tag->ruleId() && tagId == tag->tagId()) {
tag->setValue(tagMap.value("value").toString());
}
}
@ -181,14 +191,19 @@ void TagsManager::removeTagReply(const QVariantMap &params)
Tag* TagsManager::unpackTag(const QVariantMap &tagMap)
{
QString deviceId = tagMap.value("deviceId").toString();
QString thingId;
if (m_jsonClient->ensureServerVersion("5.0")) {
thingId = tagMap.value("thingId").toString();
} else {
thingId = tagMap.value("deviceId").toString();
}
QString ruleId = tagMap.value("ruleId").toString();
QString tagId = tagMap.value("tagId").toString();
QString value = tagMap.value("value").toString();
Tag *tag = nullptr;
if (!deviceId.isEmpty()) {
if (!thingId.isEmpty()) {
tag = new Tag(tagId, value);
tag->setDeviceId(deviceId);
tag->setThingId(thingId);
} else if (!ruleId.isEmpty()) {
tag = new Tag(tagId, value);
tag->setRuleId(ruleId);

View File

@ -36,25 +36,25 @@ EventDescriptor::EventDescriptor(QObject *parent) : QObject(parent)
m_paramDescriptors = new ParamDescriptors(this);
}
QString EventDescriptor::deviceId() const
QUuid EventDescriptor::thingId() const
{
return m_deviceId;
return m_thingId;
}
void EventDescriptor::setDeviceId(const QString &deviceId)
void EventDescriptor::setThingId(const QUuid &thingId)
{
if (m_deviceId != deviceId) {
m_deviceId = deviceId;
emit deviceIdChanged();
if (m_thingId != thingId) {
m_thingId = thingId;
emit thingIdChanged();
}
}
QString EventDescriptor::eventTypeId() const
QUuid EventDescriptor::eventTypeId() const
{
return m_eventTypeId;
}
void EventDescriptor::setEventTypeId(const QString &eventTypeId)
void EventDescriptor::setEventTypeId(const QUuid &eventTypeId)
{
if (m_eventTypeId != eventTypeId) {
m_eventTypeId = eventTypeId;
@ -96,7 +96,7 @@ ParamDescriptors *EventDescriptor::paramDescriptors() const
EventDescriptor *EventDescriptor::clone() const
{
EventDescriptor *ret = new EventDescriptor();
ret->setDeviceId(this->deviceId());
ret->setThingId(this->thingId());
ret->setEventTypeId(this->eventTypeId());
ret->setInterfaceName(this->interfaceName());
ret->setInterfaceEvent(this->interfaceEvent());
@ -110,7 +110,7 @@ EventDescriptor *EventDescriptor::clone() const
#define COMPARE_PTR(a, b) if (!a->operator==(b)) { qDebug() << a << "!=" << b; return false; }
bool EventDescriptor::operator==(EventDescriptor *other) const
{
COMPARE(m_deviceId, other->deviceId());
COMPARE(m_thingId, other->thingId());
COMPARE(m_eventTypeId, other->eventTypeId());
COMPARE(m_interfaceName, other->interfaceName());
COMPARE(m_interfaceEvent, other->interfaceEvent());

View File

@ -39,8 +39,9 @@
class EventDescriptor : public QObject
{
Q_OBJECT
Q_PROPERTY(QString deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
Q_PROPERTY(QString eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged)
Q_PROPERTY(QUuid thingId READ thingId WRITE setThingId NOTIFY thingIdChanged)
Q_PROPERTY(QUuid deviceId READ thingId WRITE setThingId NOTIFY thingIdChanged)
Q_PROPERTY(QUuid eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged)
Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName NOTIFY interfaceNameChanged)
Q_PROPERTY(QString interfaceEvent READ interfaceEvent WRITE setInterfaceEvent NOTIFY interfaceEventChanged)
@ -50,11 +51,11 @@ class EventDescriptor : public QObject
public:
explicit EventDescriptor(QObject *parent = nullptr);
QString deviceId() const;
void setDeviceId(const QString &deviceId);
QUuid thingId() const;
void setThingId(const QUuid &thingId);
QString eventTypeId() const;
void setEventTypeId(const QString &eventTypeId);
QUuid eventTypeId() const;
void setEventTypeId(const QUuid &eventTypeId);
QString interfaceName() const;
void setInterfaceName(const QString &interfaceName);
@ -68,14 +69,14 @@ public:
bool operator==(EventDescriptor* other) const;
signals:
void deviceIdChanged();
void thingIdChanged();
void eventTypeIdChanged();
void interfaceNameChanged();
void interfaceEventChanged();
private:
QString m_deviceId;
QString m_eventTypeId;
QUuid m_thingId;
QUuid m_eventTypeId;
QString m_interfaceName;
QString m_interfaceEvent;

View File

@ -48,8 +48,9 @@ int EventDescriptors::rowCount(const QModelIndex &parent) const
QVariant EventDescriptors::data(const QModelIndex &index, int role) const
{
switch (role) {
case RoleThingId:
case RoleDeviceId:
return m_list.at(index.row())->deviceId();
return m_list.at(index.row())->thingId();
case RoleEventTypeId:
return m_list.at(index.row())->eventTypeId();
}
@ -59,6 +60,7 @@ QVariant EventDescriptors::data(const QModelIndex &index, int role) const
QHash<int, QByteArray> EventDescriptors::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(RoleThingId, "thingId");
roles.insert(RoleDeviceId, "deviceId");
roles.insert(RoleEventTypeId, "eventId");
return roles;

View File

@ -41,6 +41,7 @@ class EventDescriptors : public QAbstractListModel
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
enum Roles {
RoleThingId,
RoleDeviceId,
RoleEventTypeId
};

View File

@ -32,11 +32,11 @@
#include <QDateTime>
LogEntry::LogEntry(const QDateTime &timestamp, const QVariant &value, const QUuid &deviceId, const QUuid &typeId, LoggingSource source, LoggingEventType loggingEventType, QObject *parent):
LogEntry::LogEntry(const QDateTime &timestamp, const QVariant &value, const QUuid &thingId, const QUuid &typeId, LoggingSource source, LoggingEventType loggingEventType, QObject *parent):
QObject(parent),
m_value(value),
m_timeStamp(timestamp),
m_deviceId(deviceId),
m_thingId(thingId),
m_typeId(typeId),
m_source(source),
m_loggingEventType(loggingEventType)
@ -54,9 +54,9 @@ QDateTime LogEntry::timestamp() const
return m_timeStamp;
}
QUuid LogEntry::deviceId() const
QUuid LogEntry::thingId() const
{
return m_deviceId;
return m_thingId;
}
QUuid LogEntry::typeId() const

View File

@ -40,7 +40,8 @@ class LogEntry : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant value READ value CONSTANT)
Q_PROPERTY(QUuid deviceId READ deviceId CONSTANT)
Q_PROPERTY(QUuid thingId READ thingId CONSTANT)
Q_PROPERTY(QUuid deviceId READ thingId CONSTANT)
Q_PROPERTY(QUuid typeId READ typeId CONSTANT)
Q_PROPERTY(LoggingSource source READ source CONSTANT)
Q_PROPERTY(LoggingEventType loggingEventType READ loggingEventType CONSTANT)
@ -70,11 +71,11 @@ public:
};
Q_ENUM(LoggingEventType)
explicit LogEntry(const QDateTime &timestamp, const QVariant &value, const QUuid &deviceId = QUuid(), const QUuid &typeId = QUuid(), LoggingSource source = LoggingSourceSystem, LoggingEventType loggingEventType = LoggingEventTypeTrigger, QObject *parent = nullptr);
explicit LogEntry(const QDateTime &timestamp, const QVariant &value, const QUuid &thingId = QUuid(), const QUuid &typeId = QUuid(), LoggingSource source = LoggingSourceSystem, LoggingEventType loggingEventType = LoggingEventTypeTrigger, QObject *parent = nullptr);
QVariant value() const;
QDateTime timestamp() const;
QUuid deviceId() const;
QUuid thingId() const;
QUuid typeId() const;
LoggingSource source() const;
LoggingEventType loggingEventType() const;
@ -86,7 +87,7 @@ public:
private:
QVariant m_value;
QDateTime m_timeStamp;
QUuid m_deviceId;
QUuid m_thingId;
QUuid m_typeId;
LoggingSource m_source;
LoggingEventType m_loggingEventType;

View File

@ -220,8 +220,8 @@ QDebug operator <<(QDebug &dbg, Rule *rule)
for (int i = 0; i < rule->eventDescriptors()->rowCount(); i++) {
EventDescriptor *ed = rule->eventDescriptors()->get(i);
dbg << " " << i << ":";
if (!ed->deviceId().isNull() && !ed->eventTypeId().isNull()) {
dbg << "Device ID:" << ed->deviceId() << "Event Type ID:" << ed->eventTypeId() << endl;
if (!ed->thingId().isNull() && !ed->eventTypeId().isNull()) {
dbg << "Thing ID:" << ed->thingId() << "Event Type ID:" << ed->eventTypeId() << endl;
} else {
dbg << "Interface Name:" << ed->interfaceName() << "Event Name:" << ed->interfaceEvent() << endl;
}

View File

@ -39,6 +39,7 @@ class RuleActionParams;
class RuleAction : public QObject
{
Q_OBJECT
Q_PROPERTY(QUuid thingId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
Q_PROPERTY(QUuid actionTypeId READ actionTypeId WRITE setActionTypeId NOTIFY actionTypeIdChanged)
Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName NOTIFY interfaceNameChanged)

View File

@ -40,14 +40,14 @@ Tag::Tag(const QString &tagId, const QString &value, QObject *parent):
}
QUuid Tag::deviceId() const
QUuid Tag::thingId() const
{
return m_deviceId;
return m_thingId;
}
void Tag::setDeviceId(const QUuid &deviceId)
void Tag::setThingId(const QUuid &thingId)
{
m_deviceId = deviceId;
m_thingId = thingId;
}
QUuid Tag::ruleId() const
@ -74,7 +74,7 @@ void Tag::setValue(const QString &value)
{
if (m_value != value) {
m_value = value;
qDebug() << "tags value changed" << m_deviceId << m_tagId << value;
qDebug() << "tags value changed" << m_thingId.toString() << m_tagId << value;
emit valueChanged();
}
}

View File

@ -37,7 +37,8 @@
class Tag : public QObject
{
Q_OBJECT
Q_PROPERTY(QUuid deviceId READ deviceId CONSTANT)
Q_PROPERTY(QUuid thingId READ thingId CONSTANT)
Q_PROPERTY(QUuid deviceId READ thingId CONSTANT)
Q_PROPERTY(QUuid ruleId READ ruleId CONSTANT)
Q_PROPERTY(QString tagId READ tagId CONSTANT)
Q_PROPERTY(QString value READ value NOTIFY valueChanged)
@ -45,8 +46,8 @@ class Tag : public QObject
public:
explicit Tag(const QString &tagId, const QString &value, QObject *parent = nullptr);
QUuid deviceId() const;
void setDeviceId(const QUuid &deviceId);
QUuid thingId() const;
void setThingId(const QUuid &thingId);
QUuid ruleId() const;
void setRuleId(const QUuid &ruleId);
@ -60,7 +61,7 @@ signals:
void valueChanged();
private:
QUuid m_deviceId;
QUuid m_thingId;
QUuid m_ruleId;
QString m_tagId;
QString m_value;

View File

@ -47,8 +47,9 @@ int Tags::rowCount(const QModelIndex &parent) const
QVariant Tags::data(const QModelIndex &index, int role) const
{
switch (role) {
case RoleThingId:
case RoleDeviceId:
return m_list.at(index.row())->deviceId();
return m_list.at(index.row())->thingId();
case RoleRuleId:
return m_list.at(index.row())->ruleId();
case RoleTagId:
@ -62,6 +63,7 @@ QVariant Tags::data(const QModelIndex &index, int role) const
QHash<int, QByteArray> Tags::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(RoleThingId, "thingId");
roles.insert(RoleDeviceId, "deviceId");
roles.insert(RoleRuleId, "ruleId");
roles.insert(RoleTagId, "tagId");
@ -111,19 +113,27 @@ void Tags::removeTag(Tag *tag)
Tag *Tags::get(int index) const
{
if (index < 0 || index >= m_list.count()) {
return nullptr;
}
return m_list.at(index);
}
Tag *Tags::findDeviceTag(const QUuid &deviceId, const QString &tagId) const
Tag *Tags::findThingTag(const QUuid &thingId, const QString &tagId) const
{
foreach (Tag *tag, m_list) {
if (tag->deviceId() == deviceId && tag->tagId() == tagId) {
if (tag->thingId() == thingId && tag->tagId() == tagId) {
return tag;
}
}
return nullptr;
}
Tag *Tags::findDeviceTag(const QUuid &deviceId, const QString &tagId) const
{
return findThingTag(deviceId, tagId);
}
Tag *Tags::findRuleTag(const QString &ruleId, const QString &tagId) const
{
foreach (Tag *tag, m_list) {

View File

@ -41,6 +41,7 @@ class Tags: public QAbstractListModel
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
enum Roles {
RoleThingId,
RoleDeviceId,
RoleRuleId,
RoleTagId,
@ -58,8 +59,9 @@ public:
void addTags(QList<Tag*> tags);
void removeTag(Tag *tag);
Tag* get(int index) const;
Q_INVOKABLE Tag* get(int index) const;
Q_INVOKABLE Tag* findThingTag(const QUuid &thingId, const QString &tagId) const;
Q_INVOKABLE Tag* findDeviceTag(const QUuid &deviceId, const QString &tagId) const;
Q_INVOKABLE Tag* findRuleTag(const QString &ruleId, const QString &tagId) const;

View File

@ -9,5 +9,7 @@
<file>ruletemplates/thermostattemplates.json</file>
<file>ruletemplates/mediatemplates.json</file>
<file>ruletemplates/doorbellruletemplates.json</file>
<file>ruletemplates/irrigationtemplates.json</file>
<file>ruletemplates/lighttemplates.json</file>
</qresource>
</RCC>

View File

@ -0,0 +1,46 @@
{
"templates": [
{
"description": "Schedule an irrigation",
"ruleNameTemplate": "Schedule for %0",
"timeDescriptorTemplate": {
"calendarItemTemplates": [
{
"startTime": "07:00",
"duration": 20,
"repeatingOption": {
"repeatingMode": "RepeatingModeDaily"
},
"editable": true
}
]
},
"ruleActionTemplates": [
{
"interfaceName": "irrigation",
"interfaceAction": "power",
"selectionId": 0,
"params": [
{
"name": "power",
"value": true
}
]
}
],
"ruleExitActionTemplates": [
{
"interfaceName": "irrigation",
"interfaceAction": "power",
"selectionId": 0,
"params": [
{
"name": "power",
"value": false
}
]
}
]
}
]
}

View File

@ -0,0 +1,38 @@
{
"templates": [
{
"description": "Wake up with light",
"ruleNameTemplate": "Wake up with %0",
"timeDescriptorTemplate": {
"timeEventItemTemplates": [
{
"time": "07:00",
"repeatingOption": {
"repeatingMode": "RepeatingModeWeekly",
"weekDays": [1, 2, 3, 4, 5]
},
"editable": true
}
]
},
"ruleActionTemplates": [
{
"interfaceName": "dimmablelight",
"interfaceAction": "power",
"selectionId": 0,
"params": [
{
"name": "power",
"value": true
}
]
},
{
"interfaceName": "dimmablelight",
"interfaceAction": "brightness",
"selectionId": 0
}
]
}
]
}

View File

@ -38,41 +38,141 @@ import "../components"
DevicePageBase {
id: root
readonly property var powerStateType: deviceClass.stateTypes.findByName("power")
readonly property var powerState: device.states.getState(powerStateType.id)
readonly property var powerActionType: deviceClass.actionTypes.findByName("power");
readonly property var powerStateType: thing.thingClass.stateTypes.findByName("power")
readonly property var powerState: thing.states.getState(powerStateType.id)
readonly property var powerActionType: thing.thingClass.actionTypes.findByName("power");
readonly property bool isOn: powerState && powerState.value === true
QtObject {
id: d
property var pendingRuleCreationId: -1
property var now: new Date()
}
Timer {
running: true
repeat: true
interval: 5000
onTriggered: {
d.now = new Date()
}
}
Component.onCompleted: {
cleanupRules();
}
function waterFor(minutes) {
var rule = engine.ruleManager.createNewRule();
var now = new Date();
var offDate = new Date(now.getTime() + (minutes * 60000));
rule.name = qsTr("Turn %1 off at %2").arg(root.thing.name).arg(Qt.formatDateTime(offDate))
var timeEvent = rule.timeDescriptor.timeEventItems.createNewTimeEventItem();
timeEvent.dateTime = offDate;
timeEvent.repeatingOption.repeatingMode = RepeatingOption.RepeatingModeNone;
rule.timeDescriptor.timeEventItems.addTimeEventItem(timeEvent);
var ruleAction = rule.actions.createNewRuleAction();
ruleAction.thingId = root.thing.id;
ruleAction.interfaceName = "power";
ruleAction.interfaceAction = "power"
ruleAction.ruleActionParams.setRuleActionParamByName("power", false);
rule.actions.addRuleAction(ruleAction)
d.pendingRuleCreationId = engine.ruleManager.addRule(rule);
}
function cleanupRules() {
print("cleaning up stale oneshot watering rules")
for (var i = 0; i < engine.tagsManager.tags.count; i++) {
var tag = engine.tagsManager.tags.get(i);
if (tag.tagId === "oneshot-watering") {
print("have a oneshot-watering tag")
// Delete it if the timer expired already
var rule = engine.ruleManager.rules.getRule(tag.ruleId)
if (rule.timeDescriptor.timeEventItems.get(0).dateTime < new Date()) {
print("need to cleanup rule:", tag.ruleId, rule.timeDescriptor.timeEventItems.get(0).dateTime)
engine.ruleManager.removeRule(tag.ruleId)
} else {
print("Rule still pending:", tag.ruleId)
}
// Also delete it if the irrigation is off already
if (root.powerState.value === false) {
engine.ruleManager.removeRule(tag.ruleId);
}
}
}
}
Connections {
target: engine.ruleManager
onAddRuleReply: {
if (commandId == d.pendingRuleCreationId) {
d.pendingRuleCreationId = -1
if (ruleError != "RuleErrorNoError") {
var comp = Qt.createComponent("../components/ErrorDialog.qml")
var popup = comp.createObject(app, {errorCode: ruleError})
popup.open();
return;
}
// Tag the rule so we can clean identify it
engine.tagsManager.tagRule(ruleId, "oneshot-watering", root.thing.id)
// Off rule has been added. Turning on now
if (root.powerState.value === false) {
engine.thingManager.executeAction(root.thing.id, root.powerActionType.id, [{paramTypeId: root.powerActionType.id, value: true}])
}
}
}
}
Connections {
target: root.powerState
onValueChanged: cleanupRules()
}
LogsModelNg {
id: history
engine: _engine
thingId: root.thing.id
typeIds: [root.powerStateType.id]
property var lastWatering: count > 0 ? get(0).timestamp : null
live: true
}
TagsProxyModel {
id: tagsProxy
tags: engine.tagsManager.tags
filterTagId: "oneshot-watering"
filterValue: root.thing.id
}
GridLayout {
id: mainGrid
anchors.fill: parent
anchors.margins: app.margins
columns: app.landscape ? 2 : 1
rowSpacing: app.margins
columnSpacing: app.margins
Layout.alignment: Qt.AlignCenter
Item {
Layout.preferredWidth: Math.max(app.iconSize * 6, parent.width / 5)
Layout.preferredHeight: width
Layout.topMargin: app.margins
Layout.bottomMargin: app.landscape ? app.margins : 0
Layout.alignment: Qt.AlignCenter
Layout.rowSpan: app.landscape ? 4 : 1
Layout.fillHeight: true
Layout.preferredWidth: app.landscape ? parent.width * .4 : parent.width
Layout.preferredHeight: app.landscape ? parent.height : parent.height *.4
AbstractButton {
height: Math.min(parent.height, parent.width)
height: Math.min(Math.min(parent.height, parent.width), app.iconSize * 5)
width: height
anchors.centerIn: parent
Rectangle {
anchors.fill: parent
color: "transparent"
border.color: root.powerState.value === true ? app.accentColor : bulbIcon.keyColor
border.color: root.powerState.value === true ? app.accentColor : irrigationIcon.keyColor
border.width: 4
radius: width / 2
}
ColorIcon {
id: bulbIcon
id: irrigationIcon
anchors.fill: parent
anchors.margins: app.margins * 1.5
name: "../images/irrigation.svg"
@ -84,9 +184,157 @@ DevicePageBase {
param["paramTypeId"] = root.powerActionType.paramTypes.get(0).id;
param["value"] = !root.powerState.value;
params.push(param)
engine.deviceManager.executeAction(root.device.id, root.powerStateType.id, params);
engine.thingManager.executeAction(root.device.id, root.powerStateType.id, params);
PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackSelection)
}
}
}
ColumnLayout {
Layout.preferredWidth: app.landscape ? parent.width * .6 : parent.width
Layout.preferredHeight: app.landscape ? parent.height : parent.height * .6
Item { Layout.fillWidth: true; Layout.fillHeight: true }
Label {
Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
horizontalAlignment: Text.AlignHCenter
text: root.isOn ? qsTr("Watering since")
: history.lastWatering ? qsTr("Last watering")
: qsTr("This irrigation has not been used yet")
}
Label {
Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
horizontalAlignment: Text.AlignHCenter
text: history.lastWatering ? Qt.formatDateTime(history.lastWatering) : ""
font.pixelSize: app.largeFont
color: app.accentColor
}
Label {
Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.bottomMargin: app.margins
horizontalAlignment: Text.AlignHCenter
font.pixelSize: app.smallFont
text: {
if (!history.lastWatering) {
return ""
}
var n = Math.floor((d.now - history.lastWatering) / 60 / 1000)
n = Math.max(0, n)
if (root.isOn) {
if (n < 60) {
return qsTr("%n minute(s)", "", n);
}
n /= 60;
if (n < 24) {
return qsTr("%n hour(s)", "", n);
}
n /= 24;
return qsTr("%n day(s)", "", n);
}
if (n < 60) {
return qsTr("%n minute(s) ago", "", n);
}
n /= 60;
if (n < 24) {
return qsTr("%n hour(s) ago", "", n);
}
n /= 24;
return qsTr("%n day(s) ago", "", n);
}
}
Label {
Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.topMargin: app.margins
horizontalAlignment: Text.AlignHCenter
text: tagsProxy.count > 0 ?
//: Irrigation will be turned of at, e.g. 09:00
qsTr("Watering until")
//: Turn on irrigation for, e.g. 5 minutes
: root.isOn ? qsTr("Turn off in") : qsTr("Water for")
}
GridLayout {
columns: 3
visible: tagsProxy.count == 0
Button {
Layout.fillWidth: true
text: qsTr("1 minute")
onClicked: root.waterFor(1)
}
Button {
Layout.fillWidth: true
text: qsTr("2 minutes")
onClicked: root.waterFor(2)
}
Button {
Layout.fillWidth: true
text: qsTr("5 minutes")
onClicked: root.waterFor(5)
}
Button {
Layout.fillWidth: true
text: qsTr("15 minutes")
onClicked: root.waterFor(15)
}
Button {
Layout.fillWidth: true
text: qsTr("30 minutes")
onClicked: root.waterFor(30)
}
Button {
Layout.fillWidth: true
text: qsTr("1 hour")
onClicked: root.waterFor(60)
}
}
Label {
Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
horizontalAlignment: Text.AlignHCenter
visible: tagsProxy.count > 0
font.pixelSize: app.largeFont
color: app.accentColor
text: tagsProxy.count == 0 ? "" : Qt.formatDateTime(engine.ruleManager.rules.getRule(tagsProxy.get(0).ruleId).timeDescriptor.timeEventItems.get(0).dateTime)
}
Label {
Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.bottomMargin: app.margins
horizontalAlignment: Text.AlignHCenter
visible: tagsProxy.count > 0
font.pixelSize: app.smallFont
text: {
if (tagsProxy.count == 0) {
return ""
}
var end = engine.ruleManager.rules.getRule(tagsProxy.get(0).ruleId).timeDescriptor.timeEventItems.get(0).dateTime
var n = Math.floor((end - d.now) / 60 / 1000)
n = Math.max(0, n);
if (n < 60) {
return qsTr("%n minute(s) left", "", n);
}
n /= 60;
if (n < 24) {
return qsTr("%n hour(s) left", "", n);
}
n /= 24;
return qsTr("%n day(s) left", "", n);
}
}
Item { Layout.fillWidth: true; Layout.fillHeight: true }
}
}
}

View File

@ -43,9 +43,9 @@ Page {
property bool busy: false
readonly property bool isEventBased: rule.eventDescriptors.count > 0 || rule.timeDescriptor.timeEventItems.count > 0
readonly property bool isStateBased: (rule.stateEvaluator !== null || rule.timeDescriptor.calendarItems.count > 0) && !isEventBased
readonly property bool isStateBased: (rule.stateEvaluator !== null || rule.timeDescriptor.calendarItems.count > 0)
readonly property bool actionsVisible: true
readonly property bool exitActionsVisible: (engine.jsonRpcClient.ensureServerVersion(1.7) && !isEmpty) || isStateBased
readonly property bool exitActionsVisible: engine.jsonRpcClient.ensureServerVersion("1.7") && isStateBased
readonly property bool hasActions: rule.actions.count > 0
readonly property bool hasExitActions: rule.exitActions.count > 0
readonly property bool isEmpty: !isEventBased && !isStateBased && !hasActions
@ -445,12 +445,10 @@ Page {
}
}
}
}
}
ThinDivider { visible: !root.isStateBased }
ThinDivider { visible: root.isEmpty || root.isEventBased }
Label {
Layout.fillWidth: true
@ -460,7 +458,7 @@ Page {
text: eventsRepeater.count === 0 && timeEventRepeater.count === 0 && actionsRepeater.count === 0 ?
qsTr("Execute actions when something happens.") :
qsTr("When any of these events happen...")
visible: !root.isStateBased
visible: root.isEmpty || root.isEventBased
font.bold: true
}
Label {
@ -502,7 +500,7 @@ Page {
Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.bottomMargin: app.margins
text: eventsRepeater.count == 0 && timeEventRepeater.count === 0 ? qsTr("Configure...") : qsTr("Add another...")
visible: !root.isStateBased
visible: root.isEmpty || root.isEventBased
onClicked: {
if (root.initialDeviceToBeAdded !== null) {
var eventDescriptor = root.rule.eventDescriptors.createNewEventDescriptor();
@ -617,10 +615,10 @@ Page {
ThinDivider { visible: root.actionsVisible }
Label {
text: root.isEmpty ? qsTr("Create a scene.") :
root.isStateBased ?
(root.rule.stateEvaluator === 0 ? qsTr("...come true, execute those actions:") : qsTr("...comes true, execute those actions:")) :
qsTr("...execute those actions:")
text: root.isEmpty ? qsTr("Create a scene.")
: root.isEventBased ? qsTr("...execute those actions:")
: root.isStateBased ? qsTr("...come true, execute those actions:")
: qsTr("Execute those actions:")
font.pixelSize: app.mediumFont
Layout.fillWidth: true
Layout.margins: app.margins
@ -674,8 +672,8 @@ Page {
ThinDivider { visible: root.exitActionsVisible }
Label {
text: root.isStateBased ? qsTr("...isn't met any more, execute those actions:") :
qsTr("If the condition isn't met, execute those actions instead:")
text: root.isEventBased ? qsTr("If the condition isn't met, execute those actions instead:") : qsTr("When the condition isn't met any more, execute those actions:")
Layout.fillWidth: true
Layout.margins: app.margins
wrapMode: Text.WordWrap
@ -699,7 +697,7 @@ Page {
Button {
Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.bottomMargin: app.margins
text: actionsRepeater.count == 0 ? qsTr("Add an action...") : qsTr("Add another action...")
text: exitActionsRepeater.count == 0 ? qsTr("Add an action...") : qsTr("Add another action...")
onClicked: {
var page = pageStack.push(ruleActionQuestionPageComponent, {exitAction: true});
}

View File

@ -93,6 +93,48 @@ Page {
return;
}
// Fill in TimeDescriptor
if (ruleTemplate.timeDescriptorTemplate !== null) {
print("RuleFromTemplate: Filling timeDescriptor.", rule.timeDescriptor.calendarItems.count, ruleTemplate.timeDescriptorTemplate.calendarItemTemplates.count);
for (var i = rule.timeDescriptor.calendarItems.count; i < ruleTemplate.timeDescriptorTemplate.calendarItemTemplates.count; i++) {
print("Need more CalendarItems");
var calendarItemTemplate = ruleTemplate.timeDescriptorTemplate.calendarItemTemplates.get(i);
var calendarItem = calendarItemTemplate.createCalendarItem();
if (!calendarItemTemplate.editable) {
rule.timeDescriptor.calendarItems.addCalendarItem(calendarItem);
fillRuleFromTemplate(rule, ruleTemplate);
return;
}
var page = pageStack.push(Qt.resolvedUrl("EditCalendarItemPage.qml"), {calendarItem: calendarItem})
page.done.connect(function() {
rule.timeDescriptor.calendarItems.addCalendarItem(calendarItem);
fillRuleFromTemplate(rule, ruleTemplate);
});
page.backPressed.connect(function() {rule.destroy(); root.done();});
return;
}
for (var i = rule.timeDescriptor.timeEventItems.count; i < ruleTemplate.timeDescriptorTemplate.timeEventItemTemplates.count; i++) {
print("Need more TimeEventItems");
var timeEventItemTemplate = ruleTemplate.timeDescriptorTemplate.timeEventItemTemplates.get(i);
var timeEventItem = timeEventItemTemplate.createTimeEventItem();
if (!timeEventItemTemplate.editable) {
rule.timeDescriptor.timeEventItems.addTimeEventItem(timeEventItem);
fillRuleFromTemplate(rule, ruleTemplate);
return;
}
var page = pageStack.push(Qt.resolvedUrl("EditTimeEventItemPage.qml"), {timeEventItem: timeEventItem});
page.done.connect(function() {
rule.timeDescriptor.timeEventItems.addTimeEventItem(timeEventItem);
fillRuleFromTemplate(rule, ruleTemplate);
})
page.backPressed.connect(function() {rule.destroy(); root.done()});
return;
}
}
// Fill in StateEvaluator
if (ruleTemplate.stateEvaluatorTemplate !== null) {
print("RuleFromTemplate: Filling stateEvaluator")