WIP: add support for rule templates
This commit is contained in:
parent
f5f73b4bea
commit
b8fac8dd01
@ -43,6 +43,12 @@
|
|||||||
#include "tagsmanager.h"
|
#include "tagsmanager.h"
|
||||||
#include "models/tagsproxymodel.h"
|
#include "models/tagsproxymodel.h"
|
||||||
#include "types/tag.h"
|
#include "types/tag.h"
|
||||||
|
#include "ruletemplates/ruletemplates.h"
|
||||||
|
#include "ruletemplates/ruletemplate.h"
|
||||||
|
#include "ruletemplates/eventdescriptortemplate.h"
|
||||||
|
#include "ruletemplates/stateevaluatortemplate.h"
|
||||||
|
#include "ruletemplates/statedescriptortemplate.h"
|
||||||
|
#include "ruletemplates/ruleactiontemplate.h"
|
||||||
|
|
||||||
static QObject* interfacesModel_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
static QObject* interfacesModel_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||||
{
|
{
|
||||||
@ -162,6 +168,15 @@ void registerQmlTypes() {
|
|||||||
qmlRegisterUncreatableType<WirelessAccessPoints>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance.");
|
qmlRegisterUncreatableType<WirelessAccessPoints>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance.");
|
||||||
qmlRegisterUncreatableType<WirelessAccessPointsProxy>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance.");
|
qmlRegisterUncreatableType<WirelessAccessPointsProxy>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance.");
|
||||||
|
|
||||||
|
qmlRegisterType<RuleTemplates>(uri, 1, 0, "RuleTemplates");
|
||||||
|
qmlRegisterType<RuleTemplatesFilterModel>(uri, 1, 0, "RuleTemplatesFilterModel");
|
||||||
|
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<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");
|
||||||
|
qmlRegisterUncreatableType<RuleActionTemplate>(uri, 1, 0, "RuleActionTemplate", "Get it from RuleActionTemplates");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // LIBNYMEAAPPCORE_H
|
#endif // LIBNYMEAAPPCORE_H
|
||||||
|
|||||||
@ -61,6 +61,13 @@ SOURCES += \
|
|||||||
models/tagsproxymodel.cpp \
|
models/tagsproxymodel.cpp \
|
||||||
tagsmanager.cpp \
|
tagsmanager.cpp \
|
||||||
wifisetup/wirelessaccesspointsproxy.cpp \
|
wifisetup/wirelessaccesspointsproxy.cpp \
|
||||||
|
models/tagsproxymodel.cpp \
|
||||||
|
ruletemplates/ruletemplate.cpp \
|
||||||
|
ruletemplates/ruletemplates.cpp \
|
||||||
|
ruletemplates/eventdescriptortemplate.cpp \
|
||||||
|
ruletemplates/ruleactiontemplate.cpp \
|
||||||
|
ruletemplates/stateevaluatortemplate.cpp \
|
||||||
|
ruletemplates/statedescriptortemplate.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
engine.h \
|
engine.h \
|
||||||
@ -107,7 +114,13 @@ HEADERS += \
|
|||||||
models/interfacesproxy.h \
|
models/interfacesproxy.h \
|
||||||
tagsmanager.h \
|
tagsmanager.h \
|
||||||
models/tagsproxymodel.h \
|
models/tagsproxymodel.h \
|
||||||
wifisetup/wirelessaccesspointsproxy.h
|
wifisetup/wirelessaccesspointsproxy.h \
|
||||||
|
ruletemplates/ruletemplate.h \
|
||||||
|
ruletemplates/ruletemplates.h \
|
||||||
|
ruletemplates/eventdescriptortemplate.h \
|
||||||
|
ruletemplates/ruleactiontemplate.h \
|
||||||
|
ruletemplates/stateevaluatortemplate.h \
|
||||||
|
ruletemplates/statedescriptortemplate.h
|
||||||
|
|
||||||
unix {
|
unix {
|
||||||
target.path = /usr/lib
|
target.path = /usr/lib
|
||||||
|
|||||||
@ -51,7 +51,7 @@ Rules *RuleManager::rules() const
|
|||||||
|
|
||||||
Rule *RuleManager::createNewRule()
|
Rule *RuleManager::createNewRule()
|
||||||
{
|
{
|
||||||
return new Rule();
|
return new Rule(QUuid(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuleManager::addRule(const QVariantMap params)
|
void RuleManager::addRule(const QVariantMap params)
|
||||||
@ -154,7 +154,7 @@ void RuleManager::getRuleDetailsReply(const QVariantMap ¶ms)
|
|||||||
qDebug() << "Got rule details for a rule we don't know";
|
qDebug() << "Got rule details for a rule we don't know";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// qDebug() << "got rule details for rule" << ruleMap;
|
qDebug() << "got rule details for rule" << qUtf8Printable(QJsonDocument::fromVariant(ruleMap).toJson());
|
||||||
parseEventDescriptors(ruleMap.value("eventDescriptors").toList(), rule);
|
parseEventDescriptors(ruleMap.value("eventDescriptors").toList(), rule);
|
||||||
parseRuleActions(ruleMap.value("actions").toList(), rule);
|
parseRuleActions(ruleMap.value("actions").toList(), rule);
|
||||||
parseRuleExitActions(ruleMap.value("exitActions").toList(), rule);
|
parseRuleExitActions(ruleMap.value("exitActions").toList(), rule);
|
||||||
@ -222,6 +222,7 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList,
|
|||||||
paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorEnum.keyToValue(paramDescriptorVariant.toMap().value("operator").toString().toLocal8Bit()));
|
paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorEnum.keyToValue(paramDescriptorVariant.toMap().value("operator").toString().toLocal8Bit()));
|
||||||
eventDescriptor->paramDescriptors()->addParamDescriptor(paramDescriptor);
|
eventDescriptor->paramDescriptors()->addParamDescriptor(paramDescriptor);
|
||||||
}
|
}
|
||||||
|
qDebug() << "Adding eventdescriptor" << eventDescriptor->deviceId() << eventDescriptor->eventTypeId();
|
||||||
rule->eventDescriptors()->addEventDescriptor(eventDescriptor);
|
rule->eventDescriptors()->addEventDescriptor(eventDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,7 +243,6 @@ StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluat
|
|||||||
} else {
|
} else {
|
||||||
sd = new StateDescriptor(sdMap.value("interface").toString(), sdMap.value("interfaceState").toString(), op, sdMap.value("value"), stateEvaluator);
|
sd = new StateDescriptor(sdMap.value("interface").toString(), sdMap.value("interfaceState").toString(), op, sdMap.value("value"), stateEvaluator);
|
||||||
}
|
}
|
||||||
qDebug() << "Created StateDescriptor:" << sd->interfaceName() << sd->interfaceState() << sd->deviceId() << sd->stateTypeId();
|
|
||||||
stateEvaluator->setStateDescriptor(sd);
|
stateEvaluator->setStateDescriptor(sd);
|
||||||
|
|
||||||
foreach (const QVariant &childEvaluatorVariant, stateEvaluatorMap.value("childEvaluators").toList()) {
|
foreach (const QVariant &childEvaluatorVariant, stateEvaluatorMap.value("childEvaluators").toList()) {
|
||||||
|
|||||||
31
libnymea-app-core/ruletemplates/eventdescriptortemplate.cpp
Normal file
31
libnymea-app-core/ruletemplates/eventdescriptortemplate.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "eventdescriptortemplate.h"
|
||||||
|
|
||||||
|
EventDescriptorTemplate::EventDescriptorTemplate(const QString &interfaceName, const QString &interfaceEvent, int selectionId, SelectionMode selectionMode, QObject *parent):
|
||||||
|
QObject(parent),
|
||||||
|
m_interfaceName(interfaceName),
|
||||||
|
m_interfaceEvent(interfaceEvent),
|
||||||
|
m_selectionId(selectionId),
|
||||||
|
m_selectionMode(selectionMode)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EventDescriptorTemplate::interfaceName() const
|
||||||
|
{
|
||||||
|
return m_interfaceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EventDescriptorTemplate::interfaceEvent() const
|
||||||
|
{
|
||||||
|
return m_interfaceEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EventDescriptorTemplate::selectionId() const
|
||||||
|
{
|
||||||
|
return m_selectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventDescriptorTemplate::SelectionMode EventDescriptorTemplate::selectionMode() const
|
||||||
|
{
|
||||||
|
return m_selectionMode;
|
||||||
|
}
|
||||||
68
libnymea-app-core/ruletemplates/eventdescriptortemplate.h
Normal file
68
libnymea-app-core/ruletemplates/eventdescriptortemplate.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#ifndef EVENTDESCRIPTORTEMPLATE_H
|
||||||
|
#define EVENTDESCRIPTORTEMPLATE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class EventDescriptorTemplate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString interfaceName READ interfaceName CONSTANT)
|
||||||
|
Q_PROPERTY(QString interfaceEvent READ interfaceEvent CONSTANT)
|
||||||
|
Q_PROPERTY(int selectionId READ selectionId CONSTANT)
|
||||||
|
Q_PROPERTY(SelectionMode selectionMode READ selectionMode CONSTANT)
|
||||||
|
public:
|
||||||
|
enum SelectionMode {
|
||||||
|
SelectionModeAny,
|
||||||
|
SelectionModeDevice,
|
||||||
|
SelectionModeInterface,
|
||||||
|
};
|
||||||
|
Q_ENUM(SelectionMode)
|
||||||
|
|
||||||
|
explicit EventDescriptorTemplate(const QString &interfaceName, const QString &interfaceEvent, int selectionId, SelectionMode selectionMode = SelectionModeAny, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QString interfaceName() const;
|
||||||
|
QString interfaceEvent() const;
|
||||||
|
int selectionId() const;
|
||||||
|
SelectionMode selectionMode() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_interfaceName;
|
||||||
|
QString m_interfaceEvent;
|
||||||
|
int m_selectionId = 0;
|
||||||
|
SelectionMode m_selectionMode = SelectionModeAny;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
class EventDescriptorTemplates: public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||||
|
public:
|
||||||
|
EventDescriptorTemplates(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(); }
|
||||||
|
|
||||||
|
void addEventDescriptorTemplate(EventDescriptorTemplate *eventDescriptorTemplate) {
|
||||||
|
eventDescriptorTemplate->setParent(this);
|
||||||
|
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
|
||||||
|
m_list.append(eventDescriptorTemplate);
|
||||||
|
endInsertRows();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE EventDescriptorTemplate* get(int index) const {
|
||||||
|
if (index < 0 || index >= m_list.count()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_list.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void countChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<EventDescriptorTemplate*> m_list;
|
||||||
|
};
|
||||||
|
#endif // EVENTDESCRIPTORTEMPLATE_H
|
||||||
38
libnymea-app-core/ruletemplates/ruleactiontemplate.cpp
Normal file
38
libnymea-app-core/ruletemplates/ruleactiontemplate.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include "ruleactiontemplate.h"
|
||||||
|
|
||||||
|
|
||||||
|
RuleActionTemplate::RuleActionTemplate(const QString &interfaceName, const QString &interfaceAction, int selectionId, SelectionMode selectionMode, QObject *parent):
|
||||||
|
QObject(parent),
|
||||||
|
m_interfaceName(interfaceName),
|
||||||
|
m_interfaceAction(interfaceAction),
|
||||||
|
m_selectionId(selectionId),
|
||||||
|
m_selectionMode(selectionMode),
|
||||||
|
m_ruleActionParams(new RuleActionParams(this))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RuleActionTemplate::interfaceName() const
|
||||||
|
{
|
||||||
|
return m_interfaceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RuleActionTemplate::interfaceAction() const
|
||||||
|
{
|
||||||
|
return m_interfaceAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RuleActionTemplate::selectionId() const
|
||||||
|
{
|
||||||
|
return m_selectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuleActionTemplate::SelectionMode RuleActionTemplate::selectionMode() const
|
||||||
|
{
|
||||||
|
return m_selectionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuleActionParams *RuleActionTemplate::ruleActionParams() const
|
||||||
|
{
|
||||||
|
return m_ruleActionParams;
|
||||||
|
}
|
||||||
74
libnymea-app-core/ruletemplates/ruleactiontemplate.h
Normal file
74
libnymea-app-core/ruletemplates/ruleactiontemplate.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#ifndef RULEACTIONTEMPLATE_H
|
||||||
|
#define RULEACTIONTEMPLATE_H
|
||||||
|
|
||||||
|
#include "types/ruleactionparams.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class RuleActionTemplate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString interfaceName READ interfaceName CONSTANT)
|
||||||
|
Q_PROPERTY(QString interfaceAction READ interfaceAction CONSTANT)
|
||||||
|
Q_PROPERTY(int selectionId READ selectionId CONSTANT)
|
||||||
|
Q_PROPERTY(SelectionMode selectionMode READ selectionMode CONSTANT)
|
||||||
|
Q_PROPERTY(RuleActionParams* ruleActionParams READ ruleActionParams CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum SelectionMode {
|
||||||
|
SelectionModeAny,
|
||||||
|
SelectionModeDevice,
|
||||||
|
SelectionModeInterface
|
||||||
|
};
|
||||||
|
Q_ENUM(SelectionMode)
|
||||||
|
|
||||||
|
explicit RuleActionTemplate(const QString &interfaceName, const QString &interfaceAction, int selectionId, SelectionMode selectionMode = SelectionModeAny, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QString interfaceName() const;
|
||||||
|
QString interfaceAction() const;
|
||||||
|
int selectionId() const;
|
||||||
|
SelectionMode selectionMode() const;
|
||||||
|
RuleActionParams* ruleActionParams() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_interfaceName;
|
||||||
|
QString m_interfaceAction;
|
||||||
|
int m_selectionId = 0;
|
||||||
|
SelectionMode m_selectionMode = SelectionModeAny;
|
||||||
|
RuleActionParams* m_ruleActionParams = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
class RuleActionTemplates: public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||||
|
public:
|
||||||
|
RuleActionTemplates(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(); }
|
||||||
|
|
||||||
|
void addRuleActionTemplate(RuleActionTemplate* ruleActionTemplate) {
|
||||||
|
ruleActionTemplate->setParent(this);
|
||||||
|
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
|
||||||
|
m_list.append(ruleActionTemplate);
|
||||||
|
endInsertRows();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE RuleActionTemplate* get(int index) const {
|
||||||
|
if (index < 0 || index >= m_list.count()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_list.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void countChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<RuleActionTemplate*> m_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RULEACTIONTEMPLATE_H
|
||||||
53
libnymea-app-core/ruletemplates/ruletemplate.cpp
Normal file
53
libnymea-app-core/ruletemplates/ruletemplate.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include "ruletemplate.h"
|
||||||
|
#include "eventdescriptortemplate.h"
|
||||||
|
#include "stateevaluatortemplate.h"
|
||||||
|
#include "ruleactiontemplate.h"
|
||||||
|
|
||||||
|
RuleTemplate::RuleTemplate(const QString &description, const QString &ruleNameTemplate, QObject *parent):
|
||||||
|
QObject(parent),
|
||||||
|
m_description(description),
|
||||||
|
m_ruleNameTemplate(ruleNameTemplate),
|
||||||
|
m_eventDescriptorTemplates(new EventDescriptorTemplates(this)),
|
||||||
|
m_ruleActionTemplates(new RuleActionTemplates(this)),
|
||||||
|
m_ruleExitActionTemplates(new RuleActionTemplates(this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RuleTemplate::description() const
|
||||||
|
{
|
||||||
|
return m_description;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RuleTemplate::ruleNameTemplate() const
|
||||||
|
{
|
||||||
|
return m_ruleNameTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventDescriptorTemplates *RuleTemplate::eventDescriptorTemplates() const
|
||||||
|
{
|
||||||
|
return m_eventDescriptorTemplates;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateEvaluatorTemplate *RuleTemplate::stateEvaluatorTemplate() const
|
||||||
|
{
|
||||||
|
return m_stateEvaluatorTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuleTemplate::setStateEvaluatorTemplate(StateEvaluatorTemplate *stateEvaluatorTemplate)
|
||||||
|
{
|
||||||
|
if (m_stateEvaluatorTemplate) {
|
||||||
|
m_stateEvaluatorTemplate->deleteLater();
|
||||||
|
}
|
||||||
|
stateEvaluatorTemplate->setParent(this);
|
||||||
|
m_stateEvaluatorTemplate = stateEvaluatorTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuleActionTemplates *RuleTemplate::ruleActionTemplates() const
|
||||||
|
{
|
||||||
|
return m_ruleActionTemplates;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuleActionTemplates *RuleTemplate::ruleExitActionTemplates() const
|
||||||
|
{
|
||||||
|
return m_ruleExitActionTemplates;
|
||||||
|
}
|
||||||
41
libnymea-app-core/ruletemplates/ruletemplate.h
Normal file
41
libnymea-app-core/ruletemplates/ruletemplate.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef RULETEMPLATE_H
|
||||||
|
#define RULETEMPLATE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class EventDescriptorTemplates;
|
||||||
|
class RuleActionTemplates;
|
||||||
|
class StateEvaluatorTemplate;
|
||||||
|
|
||||||
|
class RuleTemplate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString description READ description CONSTANT)
|
||||||
|
Q_PROPERTY(QString ruleNameTemplate READ ruleNameTemplate CONSTANT)
|
||||||
|
Q_PROPERTY(EventDescriptorTemplates* eventDescriptorTemplates READ eventDescriptorTemplates CONSTANT)
|
||||||
|
Q_PROPERTY(StateEvaluatorTemplate* stateEvaluatorTemplate READ stateEvaluatorTemplate CONSTANT)
|
||||||
|
Q_PROPERTY(RuleActionTemplates* ruleActionTemplates READ ruleActionTemplates CONSTANT)
|
||||||
|
Q_PROPERTY(RuleActionTemplates* ruleExitActionTemplates READ ruleExitActionTemplates CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RuleTemplate(const QString &description, const QString &ruleNameTemplate, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QString description() const;
|
||||||
|
QString ruleNameTemplate() const;
|
||||||
|
|
||||||
|
EventDescriptorTemplates* eventDescriptorTemplates() const;
|
||||||
|
StateEvaluatorTemplate* stateEvaluatorTemplate() const;
|
||||||
|
void setStateEvaluatorTemplate(StateEvaluatorTemplate *stateEvaluatorTemplate);
|
||||||
|
RuleActionTemplates* ruleActionTemplates() const;
|
||||||
|
RuleActionTemplates* ruleExitActionTemplates() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_description;
|
||||||
|
QString m_ruleNameTemplate;
|
||||||
|
EventDescriptorTemplates* m_eventDescriptorTemplates = nullptr;
|
||||||
|
StateEvaluatorTemplate* m_stateEvaluatorTemplate = nullptr;
|
||||||
|
RuleActionTemplates *m_ruleActionTemplates = nullptr;
|
||||||
|
RuleActionTemplates *m_ruleExitActionTemplates = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RULETEMPLATE_H
|
||||||
141
libnymea-app-core/ruletemplates/ruletemplates.cpp
Normal file
141
libnymea-app-core/ruletemplates/ruletemplates.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include "ruletemplates.h"
|
||||||
|
|
||||||
|
#include "ruletemplate.h"
|
||||||
|
#include "eventdescriptortemplate.h"
|
||||||
|
#include "ruleactiontemplate.h"
|
||||||
|
#include "stateevaluatortemplate.h"
|
||||||
|
|
||||||
|
#include "types/ruleactionparam.h"
|
||||||
|
#include "types/ruleactionparams.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
RuleTemplate* t;
|
||||||
|
EventDescriptorTemplate* evt;
|
||||||
|
StateEvaluatorTemplate* set;
|
||||||
|
RuleActionTemplate* rat;
|
||||||
|
RuleActionTemplate* reat; // exit
|
||||||
|
|
||||||
|
t = new RuleTemplate("Switch a light", "%0 switches %1", this);
|
||||||
|
evt = new EventDescriptorTemplate("button", "pressed", 0, EventDescriptorTemplate::SelectionModeDevice);
|
||||||
|
t->eventDescriptorTemplates()->addEventDescriptorTemplate(evt);
|
||||||
|
set = new StateEvaluatorTemplate(new StateDescriptorTemplate("light", "power", 1, StateDescriptorTemplate::ValueOperatorEquals, false));
|
||||||
|
t->setStateEvaluatorTemplate(set);
|
||||||
|
rat = new RuleActionTemplate("light", "power", 1, RuleActionTemplate::SelectionModeDevice);
|
||||||
|
rat->ruleActionParams()->setRuleActionParamByName("power", true);
|
||||||
|
t->ruleActionTemplates()->addRuleActionTemplate(rat);
|
||||||
|
reat = new RuleActionTemplate("light", "power", 1, RuleActionTemplate::SelectionModeDevice);
|
||||||
|
reat->ruleActionParams()->setRuleActionParamByName("power", false);
|
||||||
|
t->ruleExitActionTemplates()->addRuleActionTemplate(reat);
|
||||||
|
m_list.append(t);
|
||||||
|
|
||||||
|
t = new RuleTemplate("Intelligent blinds", "Intelligent blinds %1", this);
|
||||||
|
set = new StateEvaluatorTemplate(new StateDescriptorTemplate("temperaturesensor", "temperature", 0, StateDescriptorTemplate::ValueOperatorGreater, 20));
|
||||||
|
t->setStateEvaluatorTemplate(set);
|
||||||
|
rat = new RuleActionTemplate("simpleclosable", "close", 1, RuleActionTemplate::SelectionModeDevice);
|
||||||
|
t->ruleActionTemplates()->addRuleActionTemplate(rat);
|
||||||
|
reat = new RuleActionTemplate("simpleclosable", "open", 1, RuleActionTemplate::SelectionModeDevice);
|
||||||
|
t->ruleExitActionTemplates()->addRuleActionTemplate(reat);
|
||||||
|
m_list.append(t);
|
||||||
|
|
||||||
|
t = new RuleTemplate("Leave home - This will turn of everything when you press a button.", "Leave home", this);
|
||||||
|
evt = new EventDescriptorTemplate("button", "pressed", 0, EventDescriptorTemplate::SelectionModeDevice);
|
||||||
|
t->eventDescriptorTemplates()->addEventDescriptorTemplate(evt);
|
||||||
|
rat = new RuleActionTemplate("power", "power", 1, RuleActionTemplate::SelectionModeInterface);
|
||||||
|
t->ruleActionTemplates()->addRuleActionTemplate(rat);
|
||||||
|
m_list.append(t);
|
||||||
|
|
||||||
|
|
||||||
|
t = new RuleTemplate("Remind me to water my plant", "Remind me to water my %0 plant", this);
|
||||||
|
evt = new EventDescriptorTemplate("humiditysensor", "humidity", 0, EventDescriptorTemplate::SelectionModeDevice);
|
||||||
|
t->eventDescriptorTemplates()->addEventDescriptorTemplate(evt);
|
||||||
|
m_list.append(t);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int RuleTemplates::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
return m_list.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RuleTemplates::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case RoleDescription:
|
||||||
|
return m_list.at(index.row())->description();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> RuleTemplates::roleNames() const
|
||||||
|
{
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
roles.insert(RoleDescription, "description");
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuleTemplate *RuleTemplates::get(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= m_list.count()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_list.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RuleTemplatesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(source_parent)
|
||||||
|
if (!m_ruleTemplates) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RuleTemplate *t = m_ruleTemplates->get(source_row);
|
||||||
|
qDebug() << "---------------" << t->description() << m_filterInterfaceNames;
|
||||||
|
if (!m_filterInterfaceNames.isEmpty()) {
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < t->eventDescriptorTemplates()->rowCount(); i++) {
|
||||||
|
if (m_filterInterfaceNames.contains(t->eventDescriptorTemplates()->get(i)->interfaceName())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found && t->stateEvaluatorTemplate() && stateEvaluatorTemplateContainsInterface(t->stateEvaluatorTemplate(), m_filterInterfaceNames)) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
for (int i = 0; i < t->ruleActionTemplates()->rowCount(); i++) {
|
||||||
|
if (m_filterInterfaceNames.contains(t->ruleActionTemplates()->get(i)->interfaceName())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
for (int i = 0; i < t->ruleExitActionTemplates()->rowCount(); i++) {
|
||||||
|
if (m_filterInterfaceNames.contains(t->ruleExitActionTemplates()->get(i)->interfaceName())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RuleTemplatesFilterModel::stateEvaluatorTemplateContainsInterface(StateEvaluatorTemplate *stateEvaluatorTemplate, const QStringList &interfaceNames) const
|
||||||
|
{
|
||||||
|
if (interfaceNames.contains(stateEvaluatorTemplate->stateDescriptorTemplate()->interfaceName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < stateEvaluatorTemplate->childEvaluatorTemplates()->rowCount(); i++) {
|
||||||
|
if (stateEvaluatorTemplateContainsInterface(stateEvaluatorTemplate->childEvaluatorTemplates()->get(i), interfaceNames)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
64
libnymea-app-core/ruletemplates/ruletemplates.h
Normal file
64
libnymea-app-core/ruletemplates/ruletemplates.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef RULETEMPLATES_H
|
||||||
|
#define RULETEMPLATES_H
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
class RuleTemplate;
|
||||||
|
class StateEvaluatorTemplate;
|
||||||
|
|
||||||
|
class RuleTemplates : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||||
|
public:
|
||||||
|
enum Roles {
|
||||||
|
RoleDescription
|
||||||
|
};
|
||||||
|
Q_ENUM(Roles)
|
||||||
|
|
||||||
|
explicit RuleTemplates(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
Q_INVOKABLE RuleTemplate* get(int index) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void countChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<RuleTemplate*> m_list;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
class RuleTemplatesFilterModel: public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(RuleTemplates* ruleTemplates READ ruleTemplates WRITE setRuleTemplates NOTIFY ruleTemplatesChanged)
|
||||||
|
Q_PROPERTY(QStringList filterInterfaceNames READ filterInterfaceNames WRITE setFilterInterfaceNames NOTIFY filterInterfaceNamesChanged)
|
||||||
|
public:
|
||||||
|
RuleTemplatesFilterModel(QObject *parent = nullptr): QSortFilterProxyModel(parent) {}
|
||||||
|
RuleTemplates* ruleTemplates() const { return m_ruleTemplates; }
|
||||||
|
void setRuleTemplates(RuleTemplates* ruleTemplates) { if (m_ruleTemplates != ruleTemplates) { m_ruleTemplates = ruleTemplates; setSourceModel(ruleTemplates); emit ruleTemplatesChanged(); invalidateFilter();}}
|
||||||
|
QStringList filterInterfaceNames() const { return m_filterInterfaceNames; }
|
||||||
|
void setFilterInterfaceNames(const QStringList &filterInterfaceNames) { if (m_filterInterfaceNames != filterInterfaceNames) m_filterInterfaceNames = filterInterfaceNames; emit filterInterfaceNamesChanged(); invalidateFilter();}
|
||||||
|
Q_INVOKABLE RuleTemplate* get(int index) {
|
||||||
|
if (index < 0 || index >= rowCount()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_ruleTemplates->get(mapToSource(this->index(index, 0)).row());
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||||
|
bool stateEvaluatorTemplateContainsInterface(StateEvaluatorTemplate *stateEvaluatorTemplate, const QStringList &interfaceNames) const;
|
||||||
|
signals:
|
||||||
|
void ruleTemplatesChanged();
|
||||||
|
void filterInterfaceNamesChanged();
|
||||||
|
private:
|
||||||
|
RuleTemplates* m_ruleTemplates = nullptr;
|
||||||
|
QStringList m_filterInterfaceNames;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RULETEMPLATES_H
|
||||||
37
libnymea-app-core/ruletemplates/statedescriptortemplate.cpp
Normal file
37
libnymea-app-core/ruletemplates/statedescriptortemplate.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "statedescriptortemplate.h"
|
||||||
|
|
||||||
|
StateDescriptorTemplate::StateDescriptorTemplate(const QString &interfaceName, const QString &interfaceState, int selectionId, StateDescriptorTemplate::ValueOperator valueOperator, const QVariant &value, QObject *parent):
|
||||||
|
QObject(parent),
|
||||||
|
m_interfaceName(interfaceName),
|
||||||
|
m_interfaceState(interfaceState),
|
||||||
|
m_selectionId(selectionId),
|
||||||
|
m_valueOperator(valueOperator),
|
||||||
|
m_value(value)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString StateDescriptorTemplate::interfaceName() const
|
||||||
|
{
|
||||||
|
return m_interfaceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString StateDescriptorTemplate::interfaceState() const
|
||||||
|
{
|
||||||
|
return m_interfaceState;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StateDescriptorTemplate::selectionId() const
|
||||||
|
{
|
||||||
|
return m_selectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateDescriptorTemplate::ValueOperator StateDescriptorTemplate::valueOperator() const
|
||||||
|
{
|
||||||
|
return m_valueOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant StateDescriptorTemplate::value() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
43
libnymea-app-core/ruletemplates/statedescriptortemplate.h
Normal file
43
libnymea-app-core/ruletemplates/statedescriptortemplate.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef STATEDESCRIPTORTEMPLATE_H
|
||||||
|
#define STATEDESCRIPTORTEMPLATE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
class StateDescriptorTemplate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString interfaceName READ interfaceName CONSTANT)
|
||||||
|
Q_PROPERTY(QString interfaceState READ interfaceState CONSTANT)
|
||||||
|
Q_PROPERTY(int selectionId READ selectionId CONSTANT)
|
||||||
|
Q_PROPERTY(ValueOperator valueOperator READ valueOperator CONSTANT)
|
||||||
|
Q_PROPERTY(QVariant value READ value CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ValueOperator {
|
||||||
|
ValueOperatorEquals,
|
||||||
|
ValueOperatorNotEquals,
|
||||||
|
ValueOperatorLess,
|
||||||
|
ValueOperatorGreater,
|
||||||
|
ValueOperatorLessOrEqual,
|
||||||
|
ValueOperatorGreaterOrEqual
|
||||||
|
};
|
||||||
|
Q_ENUM(ValueOperator)
|
||||||
|
|
||||||
|
explicit StateDescriptorTemplate(const QString &interfaceName, const QString &interfaceState, int selectionId, ValueOperator valueOperator = ValueOperatorEquals, const QVariant &value = QVariant(), QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QString interfaceName() const;
|
||||||
|
QString interfaceState() const;
|
||||||
|
int selectionId() const;
|
||||||
|
ValueOperator valueOperator() const;
|
||||||
|
QVariant value() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_interfaceName;
|
||||||
|
QString m_interfaceState;
|
||||||
|
ValueOperator m_valueOperator = ValueOperatorEquals;
|
||||||
|
QVariant m_value;
|
||||||
|
int m_selectionId = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STATEDESCRIPTORTEMPLATE_H
|
||||||
25
libnymea-app-core/ruletemplates/stateevaluatortemplate.cpp
Normal file
25
libnymea-app-core/ruletemplates/stateevaluatortemplate.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "stateevaluatortemplate.h"
|
||||||
|
|
||||||
|
StateEvaluatorTemplate::StateEvaluatorTemplate(StateDescriptorTemplate *stateDescriptorTemplate, StateOperator stateOperator, QObject *parent):
|
||||||
|
QObject(parent),
|
||||||
|
m_stateDescriptorTemplate(stateDescriptorTemplate),
|
||||||
|
m_stateOperator(stateOperator),
|
||||||
|
m_childEvaluatorTemplates(new StateEvaluatorTemplates(this))
|
||||||
|
{
|
||||||
|
stateDescriptorTemplate->setParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
StateDescriptorTemplate *StateEvaluatorTemplate::stateDescriptorTemplate() const
|
||||||
|
{
|
||||||
|
return m_stateDescriptorTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateEvaluatorTemplate::StateOperator StateEvaluatorTemplate::stateOperator() const
|
||||||
|
{
|
||||||
|
return m_stateOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateEvaluatorTemplates *StateEvaluatorTemplate::childEvaluatorTemplates() const
|
||||||
|
{
|
||||||
|
return m_childEvaluatorTemplates;
|
||||||
|
}
|
||||||
65
libnymea-app-core/ruletemplates/stateevaluatortemplate.h
Normal file
65
libnymea-app-core/ruletemplates/stateevaluatortemplate.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#ifndef STATEEVALUATORTEMPLATE_H
|
||||||
|
#define STATEEVALUATORTEMPLATE_H
|
||||||
|
|
||||||
|
#include "statedescriptortemplate.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class StateEvaluatorTemplates;
|
||||||
|
|
||||||
|
class StateEvaluatorTemplate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(StateDescriptorTemplate* stateDescriptorTemplate READ stateDescriptorTemplate CONSTANT)
|
||||||
|
Q_PROPERTY(StateOperator stateOperator READ stateOperator CONSTANT)
|
||||||
|
Q_PROPERTY(StateEvaluatorTemplates* childEvaluatorTemplates READ childEvaluatorTemplates CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum StateOperator {
|
||||||
|
StateOperatorAnd,
|
||||||
|
StateOperatorOr
|
||||||
|
};
|
||||||
|
Q_ENUM(StateOperator)
|
||||||
|
|
||||||
|
explicit StateEvaluatorTemplate(StateDescriptorTemplate* stateDescriptorTemplate, StateOperator stateOperator = StateOperatorAnd, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
StateDescriptorTemplate* stateDescriptorTemplate() const;
|
||||||
|
StateOperator stateOperator() const;
|
||||||
|
StateEvaluatorTemplates* childEvaluatorTemplates() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StateDescriptorTemplate* m_stateDescriptorTemplate = nullptr;
|
||||||
|
StateOperator m_stateOperator = StateOperatorAnd;
|
||||||
|
StateEvaluatorTemplates *m_childEvaluatorTemplates = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
class StateEvaluatorTemplates: public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int count READ rowCount CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
StateEvaluatorTemplates(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 StateEvaluatorTemplate* get(int index) const {
|
||||||
|
if (index < 0 || index >= m_list.count()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_list.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addStateEvaluatorTemplate(StateEvaluatorTemplate *stateEvaluatorTemplate) {
|
||||||
|
stateEvaluatorTemplate->setParent(this);
|
||||||
|
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
|
||||||
|
m_list.append(stateEvaluatorTemplate);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
QList<StateEvaluatorTemplate*> m_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STATEEVALUATORTEMPLATE_H
|
||||||
@ -111,7 +111,6 @@ void TagsManager::handleTagsNotification(const QVariantMap ¶ms)
|
|||||||
|
|
||||||
void TagsManager::getTagsReply(const QVariantMap ¶ms)
|
void TagsManager::getTagsReply(const QVariantMap ¶ms)
|
||||||
{
|
{
|
||||||
qDebug() << "Have tags" << params;
|
|
||||||
foreach (const QVariant &tagVariant, params.value("params").toMap().value("tags").toList()) {
|
foreach (const QVariant &tagVariant, params.value("params").toMap().value("tags").toList()) {
|
||||||
addTagInternal(tagVariant.toMap());
|
addTagInternal(tagVariant.toMap());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ EventDescriptor *EventDescriptors::get(int index) const
|
|||||||
|
|
||||||
EventDescriptor *EventDescriptors::createNewEventDescriptor()
|
EventDescriptor *EventDescriptors::createNewEventDescriptor()
|
||||||
{
|
{
|
||||||
return new EventDescriptor();
|
return new EventDescriptor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventDescriptors::addEventDescriptor(EventDescriptor *eventDescriptor)
|
void EventDescriptors::addEventDescriptor(EventDescriptor *eventDescriptor)
|
||||||
|
|||||||
@ -103,7 +103,6 @@ StateType *StateTypes::findByName(const QString &name) const
|
|||||||
void StateTypes::clearModel()
|
void StateTypes::clearModel()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
qDebug() << "StateTypes: delete all stateTypes";
|
|
||||||
qDeleteAll(m_stateTypes);
|
qDeleteAll(m_stateTypes);
|
||||||
m_stateTypes.clear();
|
m_stateTypes.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
|||||||
@ -90,3 +90,6 @@ BR=$$BRANDING
|
|||||||
|
|
||||||
target.path = /usr/bin
|
target.path = /usr/bin
|
||||||
INSTALLS += target
|
INSTALLS += target
|
||||||
|
|
||||||
|
DISTFILES += \
|
||||||
|
ui/magic/NewThingMagicPage.qml
|
||||||
|
|||||||
@ -226,5 +226,6 @@
|
|||||||
<file>ui/images/awning/awning-070.svg</file>
|
<file>ui/images/awning/awning-070.svg</file>
|
||||||
<file>ui/images/awning/awning-080.svg</file>
|
<file>ui/images/awning/awning-080.svg</file>
|
||||||
<file>ui/images/awning/awning-090.svg</file>
|
<file>ui/images/awning/awning-090.svg</file>
|
||||||
|
<file>ui/magic/NewThingMagicPage.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -109,6 +109,9 @@ ApplicationWindow {
|
|||||||
objectName: "pageStack"
|
objectName: "pageStack"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
initialItem: Page {}
|
initialItem: Page {}
|
||||||
|
onDepthChanged: {
|
||||||
|
print("stackview depth changed", pageStack.depth)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClosing: {
|
onClosing: {
|
||||||
@ -244,6 +247,17 @@ ApplicationWindow {
|
|||||||
return "grey";
|
return "grey";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function interfaceToDisplayName(name) {
|
||||||
|
switch (name) {
|
||||||
|
case "light":
|
||||||
|
return qsTr("light")
|
||||||
|
case "button":
|
||||||
|
return "button";
|
||||||
|
case "sensor":
|
||||||
|
return qsTr("sensor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function interfaceListToDevicePage(interfaceList) {
|
function interfaceListToDevicePage(interfaceList) {
|
||||||
var page;
|
var page;
|
||||||
if (interfaceList.indexOf("media") >= 0) {
|
if (interfaceList.indexOf("media") >= 0) {
|
||||||
|
|||||||
@ -9,6 +9,9 @@ Page {
|
|||||||
|
|
||||||
property var device: null
|
property var device: null
|
||||||
|
|
||||||
|
Component.onCompleted: print("+++ created devicerulespage")
|
||||||
|
Component.onDestruction: print("--- destroying devicerulespage")
|
||||||
|
|
||||||
header: GuhHeader {
|
header: GuhHeader {
|
||||||
text: qsTr("Magic involving %1").arg(root.device.name)
|
text: qsTr("Magic involving %1").arg(root.device.name)
|
||||||
onBackPressed: pageStack.pop()
|
onBackPressed: pageStack.pop()
|
||||||
@ -24,7 +27,14 @@ Page {
|
|||||||
// This Page will take ownership of the rule and delete it eventually.
|
// This Page will take ownership of the rule and delete it eventually.
|
||||||
function addRule(rule) {
|
function addRule(rule) {
|
||||||
if (rule === null || rule === undefined) {
|
if (rule === null || rule === undefined) {
|
||||||
rule = Engine.ruleManager.createNewRule();
|
d.editRulePage = pageStack.push(Qt.resolvedUrl("NewThingMagicPage.qml"), {device: root.device});
|
||||||
|
d.editRulePage.manualCreation.connect(function() {
|
||||||
|
pageStack.pop();
|
||||||
|
rule = Engine.ruleManager.createNewRule();
|
||||||
|
addRule(rule)
|
||||||
|
})
|
||||||
|
d.editRulePage.done.connect(function() {pageStack.pop(root);});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
d.editRulePage = pageStack.push(Qt.resolvedUrl("EditRulePage.qml"), {rule: rule});
|
d.editRulePage = pageStack.push(Qt.resolvedUrl("EditRulePage.qml"), {rule: rule});
|
||||||
d.editRulePage.StackView.onRemoved.connect(function() {
|
d.editRulePage.StackView.onRemoved.connect(function() {
|
||||||
@ -95,8 +105,11 @@ Page {
|
|||||||
|
|
||||||
onDeleteClicked: Engine.ruleManager.removeRule(model.id)
|
onDeleteClicked: Engine.ruleManager.removeRule(model.id)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
print("clicked")
|
||||||
var newRule = rulesFilterModel.get(index).clone();
|
var newRule = rulesFilterModel.get(index).clone();
|
||||||
|
print("rule cloned")
|
||||||
d.editRulePage = pageStack.push(Qt.resolvedUrl("EditRulePage.qml"), {rule: newRule })
|
d.editRulePage = pageStack.push(Qt.resolvedUrl("EditRulePage.qml"), {rule: newRule })
|
||||||
|
print("page pushed")
|
||||||
d.editRulePage.StackView.onRemoved.connect(function() {
|
d.editRulePage.StackView.onRemoved.connect(function() {
|
||||||
newRule.destroy();
|
newRule.destroy();
|
||||||
})
|
})
|
||||||
|
|||||||
@ -13,7 +13,7 @@ Page {
|
|||||||
readonly property bool isEventBased: rule.eventDescriptors.count > 0 || rule.timeDescriptor.timeEventItems.count > 0
|
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) && !isEventBased
|
||||||
readonly property bool actionsVisible: true
|
readonly property bool actionsVisible: true
|
||||||
readonly property bool exitActionsVisible: actionsVisible && isStateBased
|
readonly property bool exitActionsVisible: (Engine.jsonRpcClient.ensureServerVersion(1.7) && !isEmpty) || isStateBased
|
||||||
readonly property bool hasActions: rule.actions.count > 0
|
readonly property bool hasActions: rule.actions.count > 0
|
||||||
readonly property bool hasExitActions: rule.exitActions.count > 0
|
readonly property bool hasExitActions: rule.exitActions.count > 0
|
||||||
readonly property bool isEmpty: !isEventBased && !isStateBased && !hasActions
|
readonly property bool isEmpty: !isEventBased && !isStateBased && !hasActions
|
||||||
@ -24,6 +24,9 @@ Page {
|
|||||||
signal accept();
|
signal accept();
|
||||||
signal cancel();
|
signal cancel();
|
||||||
|
|
||||||
|
Component.onCompleted: print("+++ created editrulepage")
|
||||||
|
Component.onDestruction: print("--- destroying editrulepage")
|
||||||
|
|
||||||
function addEventDescriptor(interfaceMode) {
|
function addEventDescriptor(interfaceMode) {
|
||||||
if (interfaceMode === undefined) {
|
if (interfaceMode === undefined) {
|
||||||
interfaceMode = false;
|
interfaceMode = false;
|
||||||
@ -396,9 +399,10 @@ Page {
|
|||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: eventsRepeater
|
id: eventsRepeater
|
||||||
model: root.hasExitActions ? null : root.rule.eventDescriptors
|
model: root.rule.eventDescriptors
|
||||||
delegate: EventDescriptorDelegate {
|
delegate: EventDescriptorDelegate {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
implicitWidth: parent.width
|
||||||
eventDescriptor: root.rule.eventDescriptors.get(index)
|
eventDescriptor: root.rule.eventDescriptors.get(index)
|
||||||
onRemoveEventDescriptor: root.rule.eventDescriptors.removeEventDescriptor(index)
|
onRemoveEventDescriptor: root.rule.eventDescriptors.removeEventDescriptor(index)
|
||||||
}
|
}
|
||||||
@ -552,6 +556,7 @@ Page {
|
|||||||
model: root.actionsVisible ? root.rule.actions : null
|
model: root.actionsVisible ? root.rule.actions : null
|
||||||
delegate: RuleActionDelegate {
|
delegate: RuleActionDelegate {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
implicitWidth: parent.width
|
||||||
ruleAction: root.rule.actions.get(index)
|
ruleAction: root.rule.actions.get(index)
|
||||||
onRemoveRuleAction: root.rule.actions.removeRuleAction(index)
|
onRemoveRuleAction: root.rule.actions.removeRuleAction(index)
|
||||||
}
|
}
|
||||||
@ -574,7 +579,8 @@ Page {
|
|||||||
ThinDivider { visible: root.exitActionsVisible }
|
ThinDivider { visible: root.exitActionsVisible }
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("...isn't met any more, execute those actions:")
|
text: root.isStateBased ? qsTr("...isn't met any more, execute those actions:") :
|
||||||
|
qsTr("If the condition isn't met, execute those actions instead:")
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: app.margins
|
Layout.margins: app.margins
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
@ -589,6 +595,7 @@ Page {
|
|||||||
model: root.exitActionsVisible ? root.rule.exitActions : null
|
model: root.exitActionsVisible ? root.rule.exitActions : null
|
||||||
delegate: RuleActionDelegate {
|
delegate: RuleActionDelegate {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
implicitWidth: parent.width
|
||||||
ruleAction: root.rule.exitActions.get(index)
|
ruleAction: root.rule.exitActions.get(index)
|
||||||
onClicked: root.rule.exitActions.removeRuleAction(index)
|
onClicked: root.rule.exitActions.removeRuleAction(index)
|
||||||
}
|
}
|
||||||
|
|||||||
297
nymea-app/ui/magic/NewThingMagicPage.qml
Normal file
297
nymea-app/ui/magic/NewThingMagicPage.qml
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import Nymea 1.0
|
||||||
|
import "../components"
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var device: null
|
||||||
|
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||||
|
property bool busy: false
|
||||||
|
|
||||||
|
signal done();
|
||||||
|
signal manualCreation();
|
||||||
|
|
||||||
|
function fillRuleFromTemplate(rule, ruleTemplate, selectedThings) {
|
||||||
|
if (selectedThings === undefined) {
|
||||||
|
selectedThings = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in all EventDescriptors
|
||||||
|
for (var i = rule.eventDescriptors.count; i < ruleTemplate.eventDescriptorTemplates.count; i++) {
|
||||||
|
var eventDescriptorTemplate = ruleTemplate.eventDescriptorTemplates.get(i);
|
||||||
|
// If we already have a thing selected for this selectionIndex, use that
|
||||||
|
if (selectedThings.length > eventDescriptorTemplate.selectionId) {
|
||||||
|
var device = Engine.deviceManager.devices.getDevice(selectedThings[eventDescriptorTemplate.selectionId]);
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
var eventDescriptor = rule.eventDescriptors.createNewEventDescriptor();
|
||||||
|
eventDescriptor.deviceId = device.id
|
||||||
|
eventDescriptor.eventTypeId = deviceClass.eventTypes.findByName(eventDescriptorTemplate.interfaceEvent).id
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Ok, we didn't pick a thing for this selectionId before. Did we already use the one we opened this page from?
|
||||||
|
if (selectedThings.indexOf(root.device.id) === -1 && root.deviceClass.interfaces.indexOf(eventDescriptorTemplate.interfaceName) >= 0) {
|
||||||
|
var eventDescriptor = rule.eventDescriptors.createNewEventDescriptor();
|
||||||
|
eventDescriptor.deviceId = root.device.id;
|
||||||
|
eventDescriptor.eventTypeId = root.deviceClass.eventTypes.findByName(eventDescriptorTemplate.interfaceEvent).id
|
||||||
|
rule.eventDescriptors.addEventDescriptor(eventDescriptor);
|
||||||
|
selectedThings.push(root.device.id);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to pick a thing
|
||||||
|
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [eventDescriptorTemplate.interfaceName]});
|
||||||
|
page.thingSelected.connect(function(device) {
|
||||||
|
var eventDescriptor = rule.eventDescriptors.createNewEventDescriptor();
|
||||||
|
eventDescriptor.deviceId = device.id;
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
eventDescriptor.eventTypeId = deviceClass.eventTypes.findByName(eventDescriptorTemplate.interfaceEvent).id;
|
||||||
|
rule.eventDescriptors.addEventDescriptor(eventDescriptor);
|
||||||
|
selectedThings.push(device.id);
|
||||||
|
fullRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
page.backPressed.connect(function() {rule.destroy(); root.done();})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in StateEvaluator
|
||||||
|
if (ruleTemplate.stateEvaluatorTemplate !== null) {
|
||||||
|
if (rule.stateEvaluator === null) {
|
||||||
|
var stateEvaluator = rule.createStateEvaluator();
|
||||||
|
rule.setStateEvaluator(stateEvaluator);
|
||||||
|
fillStateEvaluatorFromTemplate(rule, ruleTemplate, stateEvaluator, ruleTemplate.stateEvaluatorTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var more = fillStateEvaluatorFromTemplate(rule, ruleTemplate, rule.stateEvaluator, ruleTemplate.stateEvaluatorTemplate, selectedThings);
|
||||||
|
if (more) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = rule.actions.count; i < ruleTemplate.ruleActionTemplates.count; i++) {
|
||||||
|
var ruleActionTemplate = ruleTemplate.ruleActionTemplates.get(i);
|
||||||
|
|
||||||
|
// Did we pick a thing for this index before?
|
||||||
|
if (selectedThings.length > ruleActionTemplate.selectionId) {
|
||||||
|
var ruleAction = rule.actions.createNewRuleAction();
|
||||||
|
var deviceId = selectedThings[ruleActionTemplate.selectionId];
|
||||||
|
var device = Engine.deviceManager.devices.getDevice(deviceId);
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
ruleAction.deviceId = deviceId;
|
||||||
|
ruleAction.actionTypeId = deviceClass.actionTypes.findByName(ruleActionTemplate.interfaceAction).id
|
||||||
|
for (var j = 0; j < ruleActionTemplate.ruleActionParams.count; j++) {
|
||||||
|
var ruleActionParam = ruleActionTemplate.ruleActionParams.get(j)
|
||||||
|
var actionType = deviceClass.actionTypes.getActionType(ruleAction.actionTypeId);
|
||||||
|
var paramType = actionType.paramTypes.findByName(ruleActionParam.paramName);
|
||||||
|
ruleAction.ruleActionParams.setRuleActionParam(paramType.id, ruleActionParam.value)
|
||||||
|
}
|
||||||
|
rule.actions.addRuleAction(ruleAction);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did we already use the thing we opened this page from?
|
||||||
|
if (selectedThings.indexOf(root.device.id) === -1 && root.deviceClass.interfaces.indexOf(ruleActionTemplate.interfaceName) >= 0) {
|
||||||
|
var ruleAction = rule.actions.createNewRuleAction();
|
||||||
|
ruleAction.deviceId = root.device.id;
|
||||||
|
ruleAction.actionTypeId = root.deviceClass.actionTypes.findByName(ruleActionTemplate.interfaceAction).id
|
||||||
|
for (var j = 0; j < ruleActionTemplate.ruleActionParams.count; j++) {
|
||||||
|
var ruleActionParam = ruleActionTemplate.ruleActionParams.get(j)
|
||||||
|
var actionType = deviceClass.actionTypes.getActionType(ruleAction.actionTypeId);
|
||||||
|
var paramType = actionType.paramTypes.findByName(ruleActionParam.paramName);
|
||||||
|
ruleAction.ruleActionParams.setRuleActionParam(paramType.id, ruleActionParam.value)
|
||||||
|
}
|
||||||
|
rule.actions.addRuleAction(ruleAction);
|
||||||
|
selectedThings.push(root.device.id);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok, we need to pick a thing
|
||||||
|
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [ruleActionTemplate.interfaceName]});
|
||||||
|
page.thingSelected.connect(function(device) {
|
||||||
|
var ruleAction = rule.actions.createNewRuleAction();
|
||||||
|
ruleAction.deviceId = device.id;
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
ruleAction.actionTypeId = deviceClass.actionTypes.findByName(ruleActionTemplate.interfaceAction).id;
|
||||||
|
for (var j = 0; j < ruleActionTemplate.ruleActionParams.count; j++) {
|
||||||
|
var ruleActionParam = ruleActionTemplate.ruleActionParams.get(j)
|
||||||
|
var actionType = deviceClass.actionTypes.getActionType(ruleAction.actionTypeId);
|
||||||
|
var paramType = actionType.paramTypes.findByName(ruleActionParam.paramName);
|
||||||
|
ruleAction.ruleActionParams.setRuleActionParam(paramType.id, ruleActionParam.value)
|
||||||
|
}
|
||||||
|
rule.actions.addRuleAction(ruleAction);
|
||||||
|
selectedThings.push(device.id);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
page.backPressed.connect(function() {rule.destroy(); root.done();})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (var i = rule.exitActions.count; i < ruleTemplate.ruleExitActionTemplates.count; i++) {
|
||||||
|
var ruleExitActionTemplate = ruleTemplate.ruleExitActionTemplates.get(i);
|
||||||
|
|
||||||
|
// Did we pick a thing for this index before?
|
||||||
|
if (selectedThings.length > ruleExitActionTemplate.selectionId) {
|
||||||
|
var ruleAction = rule.exitActions.createNewRuleAction();
|
||||||
|
var deviceId = selectedThings[ruleExitActionTemplate.selectionId];
|
||||||
|
var device = Engine.deviceManager.devices.getDevice(deviceId);
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
ruleAction.deviceId = deviceId;
|
||||||
|
ruleAction.actionTypeId = deviceClass.actionTypes.findByName(ruleExitActionTemplate.interfaceAction).id
|
||||||
|
for (var j = 0; j < ruleExitActionTemplate.ruleActionParams.count; j++) {
|
||||||
|
var ruleActionParam = ruleExitActionTemplate.ruleActionParams.get(j)
|
||||||
|
var actionType = deviceClass.actionTypes.getActionType(ruleAction.actionTypeId);
|
||||||
|
var paramType = actionType.paramTypes.findByName(ruleActionParam.paramName);
|
||||||
|
ruleAction.ruleActionParams.setRuleActionParam(paramType.id, ruleActionParam.value)
|
||||||
|
}
|
||||||
|
rule.exitActions.addRuleAction(ruleAction);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did we already use the thing we opened this page from?
|
||||||
|
if (selectedThings.indexOf(root.device.id) === -1 && root.deviceClass.interfaces.indexOf(ruleExitActionTemplate.interfaceName) >= 0) {
|
||||||
|
var ruleAction = rule.exitActions.createNewRuleAction();
|
||||||
|
ruleAction.deviceId = root.device.id;
|
||||||
|
ruleAction.actionTypeId = root.deviceClass.actionTypes.findByName(ruleExitActionTemplate.interfaceAction).id
|
||||||
|
for (var j = 0; j < ruleExitActionTemplate.ruleActionParams.count; j++) {
|
||||||
|
var ruleActionParam = ruleExitActionTemplate.ruleActionParams.get(j)
|
||||||
|
var actionType = deviceClass.actionTypes.getActionType(ruleAction.actionTypeId);
|
||||||
|
var paramType = actionType.paramTypes.findByName(ruleActionParam.paramName);
|
||||||
|
ruleAction.ruleActionParams.setRuleActionParam(paramType.id, ruleActionParam.value)
|
||||||
|
}
|
||||||
|
rule.exitActions.addRuleAction(ruleAction);
|
||||||
|
selectedThings.push(root.device.id);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok, we need to pick a thing
|
||||||
|
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [ruleExitActionTemplate.interfaceName]});
|
||||||
|
page.thingSelected.connect(function(device) {
|
||||||
|
var ruleAction = rule.exitActions.createNewRuleAction();
|
||||||
|
ruleAction.deviceId = device.id;
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
ruleAction.actionTypeId = deviceClass.actionTypes.findByName(ruleExitActionTemplate.interfaceAction).id;
|
||||||
|
for (var j = 0; j < ruleExitActionTemplate.ruleActionParams.count; j++) {
|
||||||
|
var ruleActionParam = ruleExitActionTemplate.ruleActionParams.get(j)
|
||||||
|
var actionType = deviceClass.actionTypes.getActionType(ruleAction.actionTypeId);
|
||||||
|
var paramType = actionType.paramTypes.findByName(ruleActionParam.paramName);
|
||||||
|
ruleAction.ruleActionParams.setRuleActionParam(paramType.id, ruleActionParam.value)
|
||||||
|
}
|
||||||
|
rule.exitActions.addRuleAction(ruleAction);
|
||||||
|
selectedThings.push(device.id);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
page.backPressed.connect(function() {rule.destroy(); root.done();})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rule.name = ruleTemplate.ruleNameTemplate;
|
||||||
|
for (var i = 0; i < selectedThings.length; i++) {
|
||||||
|
var device = Engine.deviceManager.devices.getDevice(selectedThings[i]);
|
||||||
|
rule.name = rule.name.arg(device.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Rule complete!")
|
||||||
|
Engine.ruleManager.addRule(rule);
|
||||||
|
rule.destroy();
|
||||||
|
root.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
function fillStateEvaluatorFromTemplate(rule, ruleTemplate, stateEvaluator, stateEvaluatorTemplate, selectedThings) {
|
||||||
|
if (stateEvaluatorTemplate.stateDescriptorTemplate !== null && selectedThings.indexOf(stateEvaluator.stateDescriptor.deviceId) === -1) {
|
||||||
|
// need to fill stateDescriptor
|
||||||
|
// did we pick a thing for this index before?
|
||||||
|
if (selectedThings.length > stateEvaluatorTemplate.stateDescriptorTemplate.selectionId) {
|
||||||
|
var deviceId = selectedThings[stateEvaluatorTemplate.stateDescriptorTemplate.selectionId]
|
||||||
|
var device = Engine.deviceManager.devices.getDevice(deviceId)
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
stateEvaluator.stateDescriptor.deviceId = deviceId;
|
||||||
|
stateEvaluator.stateDescriptor.stateTypeId = deviceClass.stateTypes.findByName(stateEvaluatorTemplate.stateDescriptorTemplate.interfaceState).id
|
||||||
|
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
|
||||||
|
stateEvaluator.stateDescriptor.value = stateEvaluatorTemplate.stateDescriptorTemplate.value;
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (selectedThings.indexOf(root.device.id) === -1 && root.deviceClass.interfaces.indexOf(stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName) >= 0) {
|
||||||
|
stateEvaluator.stateDescriptor.deviceId = root.device.id;
|
||||||
|
stateEvaluator.stateDescriptor.stateTypeId = root.deviceClass.stateTypes.findByName(stateEvaluatorTemplate.stateDescriptorTemplate.interfaceState).id
|
||||||
|
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
|
||||||
|
stateEvaluator.stateDescriptor.value = stateEvaluatorTemplate.stateDescriptorTemplate.value;
|
||||||
|
selectedThings.push(root.device.id);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName]});
|
||||||
|
page.thingSelected.connect(function(device) {
|
||||||
|
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||||
|
stateEvaluator.stateDescriptor.deviceId = device.id;
|
||||||
|
stateEvaluator.stateDescriptor.stateTypeId = deviceClass.stateTypes.findByName(stateEvaluatorTemplate.stateDescriptorTemplate.interfaceState).id;
|
||||||
|
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
|
||||||
|
stateEvaluator.stateDescriptor.value = stateEvaluatorTemplate.stateDescriptorTemplate.value;
|
||||||
|
selectedThings.push(device.id);
|
||||||
|
fillRuleFromTemplate(rule, ruleTemplate, selectedThings)
|
||||||
|
})
|
||||||
|
page.backPressed.connect(function() {rule.destroy(); root.done();})
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
stateEvaluator.stateOperator = stateEvaluatorTemplate.stateOperator;
|
||||||
|
if (stateEvaluatorTemplate.childEvaluatorTemplates.count > stateEvaluator.childEvaluators.count) {
|
||||||
|
var childEvaluator = rule.createStateEvaluator();
|
||||||
|
var more = fillStateEvaluatorFromTemplate(rule, ruleTemplate, childEvaluator, stateEvaluatorTemplate.childEvaluatorTemplates.get(stateEvaluator.childEvaluators.count))
|
||||||
|
stateEvaluator.childEvaluators.addStateEvaluator(childEvaluator);
|
||||||
|
return more;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
header: GuhHeader {
|
||||||
|
text: qsTr("New magic")
|
||||||
|
onBackPressed: root.done()
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
ListView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
model: RuleTemplatesFilterModel {
|
||||||
|
id: ruleTemplatesModel
|
||||||
|
ruleTemplates: RuleTemplates {}
|
||||||
|
filterInterfaceNames: root.deviceClass ? root.deviceClass.interfaces : []
|
||||||
|
}
|
||||||
|
delegate: MeaListItemDelegate {
|
||||||
|
width: parent.width
|
||||||
|
text: model.description
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var ruleTemplate = ruleTemplatesModel.get(index);
|
||||||
|
var rule = Engine.ruleManager.createNewRule();
|
||||||
|
root.fillRuleFromTemplate(rule, ruleTemplate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThinDivider {}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.margins: app.margins
|
||||||
|
text: qsTr("Create some magic manually")
|
||||||
|
onClicked: {
|
||||||
|
root.manualCreation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,9 +15,12 @@ Page {
|
|||||||
property alias showEvents: interfacesProxy.showEvents
|
property alias showEvents: interfacesProxy.showEvents
|
||||||
property alias showActions: interfacesProxy.showActions
|
property alias showActions: interfacesProxy.showActions
|
||||||
property alias showStates: interfacesProxy.showStates
|
property alias showStates: interfacesProxy.showStates
|
||||||
|
property alias shownInterfaces: devicesProxy.shownInterfaces
|
||||||
|
|
||||||
header: GuhHeader {
|
header: GuhHeader {
|
||||||
text: root.selectInterface ? qsTr("Select a kind of things") : qsTr("Select a thing")
|
text: root.selectInterface ?
|
||||||
|
qsTr("Select a kind of things") :
|
||||||
|
root.shownInterfaces.length > 0 ? qsTr("Select a %1").arg(app.interfaceToDisplayName(root.shownInterfaces[0])) : qsTr("Select a thing")
|
||||||
onBackPressed: root.backPressed()
|
onBackPressed: root.backPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,13 +29,18 @@ Page {
|
|||||||
devicesFilter: Engine.deviceManager.devices
|
devicesFilter: Engine.deviceManager.devices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DevicesProxy {
|
||||||
|
id: devicesProxy
|
||||||
|
devices: Engine.deviceManager.devices
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
model: root.selectInterface ? interfacesProxy : Engine.deviceManager.devices
|
model: root.selectInterface ? interfacesProxy : devicesProxy
|
||||||
clip: true
|
clip: true
|
||||||
delegate: MeaListItemDelegate {
|
delegate: MeaListItemDelegate {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@ -42,7 +50,7 @@ Page {
|
|||||||
if (root.selectInterface) {
|
if (root.selectInterface) {
|
||||||
root.interfaceSelected(interfacesProxy.get(index).name)
|
root.interfaceSelected(interfacesProxy.get(index).name)
|
||||||
} else {
|
} else {
|
||||||
root.thingSelected(Engine.deviceManager.devices.get(index))
|
root.thingSelected(devicesProxy.get(index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user