WIP: add support for rule templates

This commit is contained in:
Michael Zanetti 2018-07-03 19:18:45 +02:00
parent f5f73b4bea
commit b8fac8dd01
25 changed files with 1063 additions and 14 deletions

View File

@ -43,6 +43,12 @@
#include "tagsmanager.h"
#include "models/tagsproxymodel.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)
{
@ -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<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

View File

@ -61,6 +61,13 @@ SOURCES += \
models/tagsproxymodel.cpp \
tagsmanager.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 += \
engine.h \
@ -107,7 +114,13 @@ HEADERS += \
models/interfacesproxy.h \
tagsmanager.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 {
target.path = /usr/lib

View File

@ -51,7 +51,7 @@ Rules *RuleManager::rules() const
Rule *RuleManager::createNewRule()
{
return new Rule();
return new Rule(QUuid(), this);
}
void RuleManager::addRule(const QVariantMap params)
@ -154,7 +154,7 @@ void RuleManager::getRuleDetailsReply(const QVariantMap &params)
qDebug() << "Got rule details for a rule we don't know";
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);
parseRuleActions(ruleMap.value("actions").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()));
eventDescriptor->paramDescriptors()->addParamDescriptor(paramDescriptor);
}
qDebug() << "Adding eventdescriptor" << eventDescriptor->deviceId() << eventDescriptor->eventTypeId();
rule->eventDescriptors()->addEventDescriptor(eventDescriptor);
}
}
@ -242,7 +243,6 @@ StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluat
} else {
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);
foreach (const QVariant &childEvaluatorVariant, stateEvaluatorMap.value("childEvaluators").toList()) {

View 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;
}

View 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

View 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;
}

View 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

View 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;
}

View 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

View 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;
}

View 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

View 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;
}

View 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

View 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;
}

View 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

View File

@ -111,7 +111,6 @@ void TagsManager::handleTagsNotification(const QVariantMap &params)
void TagsManager::getTagsReply(const QVariantMap &params)
{
qDebug() << "Have tags" << params;
foreach (const QVariant &tagVariant, params.value("params").toMap().value("tags").toList()) {
addTagInternal(tagVariant.toMap());
}

View File

@ -42,7 +42,7 @@ EventDescriptor *EventDescriptors::get(int index) const
EventDescriptor *EventDescriptors::createNewEventDescriptor()
{
return new EventDescriptor();
return new EventDescriptor(this);
}
void EventDescriptors::addEventDescriptor(EventDescriptor *eventDescriptor)

View File

@ -103,7 +103,6 @@ StateType *StateTypes::findByName(const QString &name) const
void StateTypes::clearModel()
{
beginResetModel();
qDebug() << "StateTypes: delete all stateTypes";
qDeleteAll(m_stateTypes);
m_stateTypes.clear();
endResetModel();

View File

@ -90,3 +90,6 @@ BR=$$BRANDING
target.path = /usr/bin
INSTALLS += target
DISTFILES += \
ui/magic/NewThingMagicPage.qml

View File

@ -226,5 +226,6 @@
<file>ui/images/awning/awning-070.svg</file>
<file>ui/images/awning/awning-080.svg</file>
<file>ui/images/awning/awning-090.svg</file>
<file>ui/magic/NewThingMagicPage.qml</file>
</qresource>
</RCC>

View File

@ -109,6 +109,9 @@ ApplicationWindow {
objectName: "pageStack"
anchors.fill: parent
initialItem: Page {}
onDepthChanged: {
print("stackview depth changed", pageStack.depth)
}
}
onClosing: {
@ -244,6 +247,17 @@ ApplicationWindow {
return "grey";
}
function interfaceToDisplayName(name) {
switch (name) {
case "light":
return qsTr("light")
case "button":
return "button";
case "sensor":
return qsTr("sensor")
}
}
function interfaceListToDevicePage(interfaceList) {
var page;
if (interfaceList.indexOf("media") >= 0) {

View File

@ -9,6 +9,9 @@ Page {
property var device: null
Component.onCompleted: print("+++ created devicerulespage")
Component.onDestruction: print("--- destroying devicerulespage")
header: GuhHeader {
text: qsTr("Magic involving %1").arg(root.device.name)
onBackPressed: pageStack.pop()
@ -24,7 +27,14 @@ Page {
// This Page will take ownership of the rule and delete it eventually.
function addRule(rule) {
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.StackView.onRemoved.connect(function() {
@ -95,8 +105,11 @@ Page {
onDeleteClicked: Engine.ruleManager.removeRule(model.id)
onClicked: {
print("clicked")
var newRule = rulesFilterModel.get(index).clone();
print("rule cloned")
d.editRulePage = pageStack.push(Qt.resolvedUrl("EditRulePage.qml"), {rule: newRule })
print("page pushed")
d.editRulePage.StackView.onRemoved.connect(function() {
newRule.destroy();
})

View File

@ -13,7 +13,7 @@ Page {
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 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 hasExitActions: rule.exitActions.count > 0
readonly property bool isEmpty: !isEventBased && !isStateBased && !hasActions
@ -24,6 +24,9 @@ Page {
signal accept();
signal cancel();
Component.onCompleted: print("+++ created editrulepage")
Component.onDestruction: print("--- destroying editrulepage")
function addEventDescriptor(interfaceMode) {
if (interfaceMode === undefined) {
interfaceMode = false;
@ -396,9 +399,10 @@ Page {
Repeater {
id: eventsRepeater
model: root.hasExitActions ? null : root.rule.eventDescriptors
model: root.rule.eventDescriptors
delegate: EventDescriptorDelegate {
Layout.fillWidth: true
implicitWidth: parent.width
eventDescriptor: root.rule.eventDescriptors.get(index)
onRemoveEventDescriptor: root.rule.eventDescriptors.removeEventDescriptor(index)
}
@ -552,6 +556,7 @@ Page {
model: root.actionsVisible ? root.rule.actions : null
delegate: RuleActionDelegate {
Layout.fillWidth: true
implicitWidth: parent.width
ruleAction: root.rule.actions.get(index)
onRemoveRuleAction: root.rule.actions.removeRuleAction(index)
}
@ -574,7 +579,8 @@ Page {
ThinDivider { visible: root.exitActionsVisible }
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.margins: app.margins
wrapMode: Text.WordWrap
@ -589,6 +595,7 @@ Page {
model: root.exitActionsVisible ? root.rule.exitActions : null
delegate: RuleActionDelegate {
Layout.fillWidth: true
implicitWidth: parent.width
ruleAction: root.rule.exitActions.get(index)
onClicked: root.rule.exitActions.removeRuleAction(index)
}

View 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();
}
}
}
}

View File

@ -15,9 +15,12 @@ Page {
property alias showEvents: interfacesProxy.showEvents
property alias showActions: interfacesProxy.showActions
property alias showStates: interfacesProxy.showStates
property alias shownInterfaces: devicesProxy.shownInterfaces
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()
}
@ -26,13 +29,18 @@ Page {
devicesFilter: Engine.deviceManager.devices
}
DevicesProxy {
id: devicesProxy
devices: Engine.deviceManager.devices
}
ColumnLayout {
anchors.fill: parent
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
model: root.selectInterface ? interfacesProxy : Engine.deviceManager.devices
model: root.selectInterface ? interfacesProxy : devicesProxy
clip: true
delegate: MeaListItemDelegate {
width: parent.width
@ -42,7 +50,7 @@ Page {
if (root.selectInterface) {
root.interfaceSelected(interfacesProxy.get(index).name)
} else {
root.thingSelected(Engine.deviceManager.devices.get(index))
root.thingSelected(devicesProxy.get(index))
}
}
}