Merge PR #403: Improve irrigation view, add support for time based rule templates
This commit is contained in:
commit
636b05cbb5
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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") {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -57,7 +57,8 @@ public:
|
||||
enum Roles {
|
||||
RoleTimestamp,
|
||||
RoleValue,
|
||||
RoleDeviceId,
|
||||
RoleThingId,
|
||||
RoleDeviceId, // < JSONRPC 5.0
|
||||
RoleTypeId,
|
||||
RoleSource,
|
||||
RoleLoggingEventType
|
||||
|
||||
@ -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());
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 ¶ms)
|
||||
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 ¶ms)
|
||||
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 ¶ms)
|
||||
{
|
||||
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 ¶ms)
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
50
libnymea-app/ruletemplates/calendaritemtemplate.cpp
Normal file
50
libnymea-app/ruletemplates/calendaritemtemplate.cpp
Normal 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;
|
||||
}
|
||||
65
libnymea-app/ruletemplates/calendaritemtemplate.h
Normal file
65
libnymea-app/ruletemplates/calendaritemtemplate.h
Normal 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
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
21
libnymea-app/ruletemplates/timedescriptortemplate.cpp
Normal file
21
libnymea-app/ruletemplates/timedescriptortemplate.cpp
Normal 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;
|
||||
}
|
||||
26
libnymea-app/ruletemplates/timedescriptortemplate.h
Normal file
26
libnymea-app/ruletemplates/timedescriptortemplate.h
Normal 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
|
||||
42
libnymea-app/ruletemplates/timeeventitemtemplate.cpp
Normal file
42
libnymea-app/ruletemplates/timeeventitemtemplate.cpp
Normal 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;
|
||||
}
|
||||
63
libnymea-app/ruletemplates/timeeventitemtemplate.h
Normal file
63
libnymea-app/ruletemplates/timeeventitemtemplate.h
Normal 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
|
||||
@ -133,21 +133,31 @@ void TagsManager::handleTagsNotification(const QVariantMap ¶ms)
|
||||
} 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 ¶ms)
|
||||
|
||||
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);
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -41,6 +41,7 @@ class EventDescriptors : public QAbstractListModel
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
public:
|
||||
enum Roles {
|
||||
RoleThingId,
|
||||
RoleDeviceId,
|
||||
RoleEventTypeId
|
||||
};
|
||||
|
||||
@ -32,11 +32,11 @@
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
LogEntry::LogEntry(const QDateTime ×tamp, const QVariant &value, const QUuid &deviceId, const QUuid &typeId, LoggingSource source, LoggingEventType loggingEventType, QObject *parent):
|
||||
LogEntry::LogEntry(const QDateTime ×tamp, 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
|
||||
|
||||
@ -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 ×tamp, const QVariant &value, const QUuid &deviceId = QUuid(), const QUuid &typeId = QUuid(), LoggingSource source = LoggingSourceSystem, LoggingEventType loggingEventType = LoggingEventTypeTrigger, QObject *parent = nullptr);
|
||||
explicit LogEntry(const QDateTime ×tamp, 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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
46
nymea-app/ruletemplates/irrigationtemplates.json
Normal file
46
nymea-app/ruletemplates/irrigationtemplates.json
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
38
nymea-app/ruletemplates/lighttemplates.json
Normal file
38
nymea-app/ruletemplates/lighttemplates.json
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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});
|
||||
}
|
||||
|
||||
@ -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")
|
||||
|
||||
Reference in New Issue
Block a user