Improve rule creation

This commit is contained in:
Michael Zanetti 2019-08-31 00:12:25 +02:00
parent 8d8b72790b
commit 176baa8ede
29 changed files with 315 additions and 220 deletions

View File

@ -45,7 +45,7 @@ DeviceManager::DeviceManager(JsonRpcClient* jsonclient, QObject *parent) :
qWarning() << "received an event from a device we don't know..." << deviceId << event; qWarning() << "received an event from a device we don't know..." << deviceId << event;
return; return;
} }
qDebug() << "Event received" << deviceId.toString() << eventTypeId.toString(); // qDebug() << "Event received" << deviceId.toString() << eventTypeId.toString();
dev->eventTriggered(eventTypeId.toString(), event.value("params").toMap()); dev->eventTriggered(eventTypeId.toString(), event.value("params").toMap());
emit eventTriggered(deviceId.toString(), eventTypeId.toString(), event.value("params").toMap()); emit eventTriggered(deviceId.toString(), eventTypeId.toString(), event.value("params").toMap());

View File

@ -156,7 +156,6 @@ signals:
private: private:
Q_INVOKABLE void notificationReceived(const QVariantMap &data) { Q_INVOKABLE void notificationReceived(const QVariantMap &data) {
qDebug() << "event rece" << data;
emit eventReceived(data.value("params").toMap().value("event").toMap()); emit eventReceived(data.value("params").toMap().value("event").toMap());
} }

View File

@ -251,6 +251,7 @@ bool DevicesProxy::filterAcceptsRow(int source_row, const QModelIndex &source_pa
} }
} }
DeviceClass *deviceClass = m_engine->deviceManager()->deviceClasses()->getDeviceClass(device->deviceClassId()); DeviceClass *deviceClass = m_engine->deviceManager()->deviceClasses()->getDeviceClass(device->deviceClassId());
// qDebug() << "Checking device" << deviceClass->name() << deviceClass->interfaces();
if (!m_shownInterfaces.isEmpty()) { if (!m_shownInterfaces.isEmpty()) {
bool foundMatch = false; bool foundMatch = false;
foreach (const QString &filterInterface, m_shownInterfaces) { foreach (const QString &filterInterface, m_shownInterfaces) {

View File

@ -35,3 +35,13 @@ ParamDescriptors *EventDescriptorTemplate::paramDescriptors() const
{ {
return m_paramDescriptors; return m_paramDescriptors;
} }
QStringList EventDescriptorTemplates::interfaces() const
{
QStringList ret;
for (int i = 0; i < m_list.count(); i++) {
ret.append(m_list.at(i)->interfaceName());
}
ret.removeDuplicates();
return ret;
}

View File

@ -42,9 +42,11 @@ class EventDescriptorTemplates: public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT)
public: public:
EventDescriptorTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} EventDescriptorTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {}
QStringList interfaces() const;
int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); } 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(); } QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index); Q_UNUSED(role); return QVariant(); }
@ -63,6 +65,8 @@ public:
return m_list.at(index); return m_list.at(index);
} }
signals: signals:
void countChanged(); void countChanged();

View File

@ -36,3 +36,13 @@ RuleActionParamTemplates *RuleActionTemplate::ruleActionParamTemplates() const
{ {
return m_ruleActionParamTemplates; return m_ruleActionParamTemplates;
} }
QStringList RuleActionTemplates::interfaces() const
{
QStringList ret;
for (int i = 0; i < m_list.count(); i++) {
ret.append(m_list.at(i)->interfaceName());
}
ret.removeDuplicates();
return ret;
}

View File

@ -44,10 +44,12 @@ class RuleActionTemplates: public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT)
public: public:
RuleActionTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} RuleActionTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {}
int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); } 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(); } QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index); Q_UNUSED(role); return QVariant(); }
QStringList interfaces() const;
void addRuleActionTemplate(RuleActionTemplate* ruleActionTemplate) { void addRuleActionTemplate(RuleActionTemplate* ruleActionTemplate) {
ruleActionTemplate->setParent(this); ruleActionTemplate->setParent(this);

View File

@ -14,11 +14,6 @@ RuleTemplate::RuleTemplate(const QString &interfaceName, const QString &descript
{ {
} }
QString RuleTemplate::interfaceName() const
{
return m_interfaceName;
}
QString RuleTemplate::description() const QString RuleTemplate::description() const
{ {
return m_description; return m_description;
@ -29,6 +24,18 @@ QString RuleTemplate::ruleNameTemplate() const
return m_ruleNameTemplate; return m_ruleNameTemplate;
} }
QStringList RuleTemplate::interfaces() const
{
QStringList ret;
ret.append(m_eventDescriptorTemplates->interfaces());
if (m_stateEvaluatorTemplate) {
ret.append(m_stateEvaluatorTemplate->interfaces());
}
ret.append(m_ruleActionTemplates->interfaces());
ret.append(m_ruleExitActionTemplates->interfaces());
return ret;
}
EventDescriptorTemplates *RuleTemplate::eventDescriptorTemplates() const EventDescriptorTemplates *RuleTemplate::eventDescriptorTemplates() const
{ {
return m_eventDescriptorTemplates; return m_eventDescriptorTemplates;

View File

@ -10,9 +10,9 @@ class StateEvaluatorTemplate;
class RuleTemplate : public QObject class RuleTemplate : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString interfaceName READ interfaceName CONSTANT)
Q_PROPERTY(QString description READ description CONSTANT) Q_PROPERTY(QString description READ description CONSTANT)
Q_PROPERTY(QString ruleNameTemplate READ ruleNameTemplate CONSTANT) Q_PROPERTY(QString ruleNameTemplate READ ruleNameTemplate CONSTANT)
Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT)
Q_PROPERTY(EventDescriptorTemplates* eventDescriptorTemplates READ eventDescriptorTemplates CONSTANT) Q_PROPERTY(EventDescriptorTemplates* eventDescriptorTemplates READ eventDescriptorTemplates CONSTANT)
Q_PROPERTY(StateEvaluatorTemplate* stateEvaluatorTemplate READ stateEvaluatorTemplate CONSTANT) Q_PROPERTY(StateEvaluatorTemplate* stateEvaluatorTemplate READ stateEvaluatorTemplate CONSTANT)
Q_PROPERTY(RuleActionTemplates* ruleActionTemplates READ ruleActionTemplates CONSTANT) Q_PROPERTY(RuleActionTemplates* ruleActionTemplates READ ruleActionTemplates CONSTANT)
@ -21,9 +21,9 @@ class RuleTemplate : public QObject
public: public:
explicit RuleTemplate(const QString &interfaceName, const QString &description, const QString &ruleNameTemplate, QObject *parent = nullptr); explicit RuleTemplate(const QString &interfaceName, const QString &description, const QString &ruleNameTemplate, QObject *parent = nullptr);
QString interfaceName() const;
QString description() const; QString description() const;
QString ruleNameTemplate() const; QString ruleNameTemplate() const;
QStringList interfaces() const;
EventDescriptorTemplates* eventDescriptorTemplates() const; EventDescriptorTemplates* eventDescriptorTemplates() const;
StateEvaluatorTemplate* stateEvaluatorTemplate() const; StateEvaluatorTemplate* stateEvaluatorTemplate() const;

View File

@ -8,6 +8,7 @@
#include "types/ruleactionparam.h" #include "types/ruleactionparam.h"
#include "types/ruleactionparams.h" #include "types/ruleactionparams.h"
#include "devicesproxy.h"
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
@ -167,6 +168,8 @@ QVariant RuleTemplates::data(const QModelIndex &index, int role) const
switch (role) { switch (role) {
case RoleDescription: case RoleDescription:
return m_list.at(index.row())->description(); return m_list.at(index.row())->description();
case RoleInterfaces:
return m_list.at(index.row())->interfaces();
} }
return QVariant(); return QVariant();
} }
@ -175,6 +178,7 @@ QHash<int, QByteArray> RuleTemplates::roleNames() const
{ {
QHash<int, QByteArray> roles; QHash<int, QByteArray> roles;
roles.insert(RoleDescription, "description"); roles.insert(RoleDescription, "description");
roles.insert(RoleInterfaces, "interfaces");
return roles; return roles;
} }
@ -193,40 +197,38 @@ bool RuleTemplatesFilterModel::filterAcceptsRow(int source_row, const QModelInde
return false; return false;
} }
RuleTemplate *t = m_ruleTemplates->get(source_row); RuleTemplate *t = m_ruleTemplates->get(source_row);
// qDebug() << "Checking interface" << t->description() << t->interfaceName() << "for usage with:" << m_filterInterfaceNames; // qDebug() << "Checking interface" << t->description() << t->interfaces() << "for usage with:" << m_filterInterfaceNames;
// Make sure we have a device to be used with any of the template's interfaces
if (m_filterDevicesProxy) {
foreach (const QString &toBeFound, t->interfaces()) {
bool found = false;
for (int i = 0; i < m_filterDevicesProxy->rowCount(); i++) {
// qDebug() << "Checking device:" << m_filterDevicesProxy->get(i)->deviceClass()->interfaces();
if (m_filterDevicesProxy->get(i)->deviceClass()->interfaces().contains(toBeFound)) {
found = true;
break;
}
}
if (!found) {
qDebug() << "Filtering out" << t->description() << "because required devices are not provided in filter proxy";
return false;
}
}
}
if (!m_filterInterfaceNames.isEmpty()) { if (!m_filterInterfaceNames.isEmpty()) {
if (!m_filterInterfaceNames.contains(t->interfaceName())) { bool found = false;
foreach (const QString toBeFound, m_filterInterfaceNames) {
if (t->interfaces().contains(toBeFound)) {
found = true;
break;
}
}
if (!found) {
return false; return false;
} }
// 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; return true;
} }

View File

@ -5,6 +5,7 @@
class RuleTemplate; class RuleTemplate;
class StateEvaluatorTemplate; class StateEvaluatorTemplate;
class DevicesProxy;
class RuleTemplates : public QAbstractListModel class RuleTemplates : public QAbstractListModel
{ {
@ -12,7 +13,8 @@ class RuleTemplates : public QAbstractListModel
Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public: public:
enum Roles { enum Roles {
RoleDescription RoleDescription,
RoleInterfaces
}; };
Q_ENUM(Roles) Q_ENUM(Roles)
@ -39,12 +41,16 @@ class RuleTemplatesFilterModel: public QSortFilterProxyModel
Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(RuleTemplates* ruleTemplates READ ruleTemplates WRITE setRuleTemplates NOTIFY ruleTemplatesChanged) Q_PROPERTY(RuleTemplates* ruleTemplates READ ruleTemplates WRITE setRuleTemplates NOTIFY ruleTemplatesChanged)
Q_PROPERTY(QStringList filterInterfaceNames READ filterInterfaceNames WRITE setFilterInterfaceNames NOTIFY filterInterfaceNamesChanged) Q_PROPERTY(QStringList filterInterfaceNames READ filterInterfaceNames WRITE setFilterInterfaceNames NOTIFY filterInterfaceNamesChanged)
Q_PROPERTY(DevicesProxy* filterByDevices READ filterByDevices WRITE setFilterByDevices NOTIFY filterByDevicesChanged)
public: public:
RuleTemplatesFilterModel(QObject *parent = nullptr): QSortFilterProxyModel(parent) {} RuleTemplatesFilterModel(QObject *parent = nullptr): QSortFilterProxyModel(parent) {}
RuleTemplates* ruleTemplates() const { return m_ruleTemplates; } RuleTemplates* ruleTemplates() const { return m_ruleTemplates; }
void setRuleTemplates(RuleTemplates* ruleTemplates) { if (m_ruleTemplates != ruleTemplates) { m_ruleTemplates = ruleTemplates; setSourceModel(ruleTemplates); emit ruleTemplatesChanged(); invalidateFilter(); emit countChanged();}} void setRuleTemplates(RuleTemplates* ruleTemplates) { if (m_ruleTemplates != ruleTemplates) { m_ruleTemplates = ruleTemplates; setSourceModel(ruleTemplates); emit ruleTemplatesChanged(); invalidateFilter(); emit countChanged();}}
QStringList filterInterfaceNames() const { return m_filterInterfaceNames; } QStringList filterInterfaceNames() const { return m_filterInterfaceNames; }
void setFilterInterfaceNames(const QStringList &filterInterfaceNames) { if (m_filterInterfaceNames != filterInterfaceNames) { m_filterInterfaceNames = filterInterfaceNames; emit filterInterfaceNamesChanged(); invalidateFilter(); emit countChanged(); }} void setFilterInterfaceNames(const QStringList &filterInterfaceNames) { if (m_filterInterfaceNames != filterInterfaceNames) { m_filterInterfaceNames = filterInterfaceNames; emit filterInterfaceNamesChanged(); invalidateFilter(); emit countChanged(); }}
DevicesProxy* filterByDevices() const { return m_filterDevicesProxy; }
void setFilterByDevices(DevicesProxy* filterDevicesProxy) {if (m_filterDevicesProxy != filterDevicesProxy) { m_filterDevicesProxy = filterDevicesProxy; emit filterByDevicesChanged(); invalidateFilter(); }}
Q_INVOKABLE RuleTemplate* get(int index) { Q_INVOKABLE RuleTemplate* get(int index) {
if (index < 0 || index >= rowCount()) { if (index < 0 || index >= rowCount()) {
return nullptr; return nullptr;
@ -57,10 +63,12 @@ protected:
signals: signals:
void ruleTemplatesChanged(); void ruleTemplatesChanged();
void filterInterfaceNamesChanged(); void filterInterfaceNamesChanged();
void filterByDevicesChanged();
void countChanged(); void countChanged();
private: private:
RuleTemplates* m_ruleTemplates = nullptr; RuleTemplates* m_ruleTemplates = nullptr;
QStringList m_filterInterfaceNames; QStringList m_filterInterfaceNames;
DevicesProxy* m_filterDevicesProxy = nullptr;
}; };
#endif // RULETEMPLATES_H #endif // RULETEMPLATES_H

View File

@ -23,3 +23,19 @@ StateEvaluatorTemplates *StateEvaluatorTemplate::childEvaluatorTemplates() const
{ {
return m_childEvaluatorTemplates; return m_childEvaluatorTemplates;
} }
QStringList StateEvaluatorTemplate::interfaces() const
{
QStringList ret;
if (m_stateDescriptorTemplate) {
ret.append(stateDescriptorTemplate()->interfaceName());
}
for (int i = 0; i < m_childEvaluatorTemplates->rowCount(); i++) {
ret.append(m_childEvaluatorTemplates->get(i)->interfaces());
}
ret.removeDuplicates();
return ret;
}

View File

@ -13,6 +13,7 @@ class StateEvaluatorTemplate : public QObject
Q_PROPERTY(StateDescriptorTemplate* stateDescriptorTemplate READ stateDescriptorTemplate CONSTANT) Q_PROPERTY(StateDescriptorTemplate* stateDescriptorTemplate READ stateDescriptorTemplate CONSTANT)
Q_PROPERTY(StateOperator stateOperator READ stateOperator CONSTANT) Q_PROPERTY(StateOperator stateOperator READ stateOperator CONSTANT)
Q_PROPERTY(StateEvaluatorTemplates* childEvaluatorTemplates READ childEvaluatorTemplates CONSTANT) Q_PROPERTY(StateEvaluatorTemplates* childEvaluatorTemplates READ childEvaluatorTemplates CONSTANT)
Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT)
public: public:
enum StateOperator { enum StateOperator {
@ -26,6 +27,7 @@ public:
StateDescriptorTemplate* stateDescriptorTemplate() const; StateDescriptorTemplate* stateDescriptorTemplate() const;
StateOperator stateOperator() const; StateOperator stateOperator() const;
StateEvaluatorTemplates* childEvaluatorTemplates() const; StateEvaluatorTemplates* childEvaluatorTemplates() const;
QStringList interfaces() const;
private: private:
StateDescriptorTemplate* m_stateDescriptorTemplate = nullptr; StateDescriptorTemplate* m_stateDescriptorTemplate = nullptr;

View File

@ -1,6 +1,8 @@
#include "paramdescriptors.h" #include "paramdescriptors.h"
#include "paramdescriptor.h" #include "paramdescriptor.h"
#include <QDebug>
ParamDescriptors::ParamDescriptors(QObject *parent) : QAbstractListModel(parent) ParamDescriptors::ParamDescriptors(QObject *parent) : QAbstractListModel(parent)
{ {
@ -99,6 +101,30 @@ void ParamDescriptors::clear()
emit countChanged(); emit countChanged();
} }
ParamDescriptor *ParamDescriptors::getParamDescriptor(const QString &paramTypeId) const
{
qDebug() << "getParamDescriptor" << paramTypeId;
for (int i = 0; i < m_list.count(); i++) {
qDebug() << "have param descriptor:" << m_list.at(i)->paramTypeId();
if (m_list.at(i)->paramTypeId() == paramTypeId) {
return m_list.at(i);
}
}
return nullptr;
}
ParamDescriptor *ParamDescriptors::getParamDescriptorByName(const QString &paramName) const
{
qDebug() << "getParamDescriptorByName" << paramName;
for (int i = 0; i < m_list.count(); i++) {
qDebug() << "have param descriptor:" << m_list.at(i)->paramName();
if (m_list.at(i)->paramName() == paramName) {
return m_list.at(i);
}
}
return nullptr;
}
bool ParamDescriptors::operator==(ParamDescriptors *other) const bool ParamDescriptors::operator==(ParamDescriptors *other) const
{ {
if (rowCount() != other->rowCount()) { if (rowCount() != other->rowCount()) {

View File

@ -42,6 +42,9 @@ public:
Q_INVOKABLE void setParamDescriptorByName(const QString &paramName, const QVariant &value, ValueOperator operatorType); Q_INVOKABLE void setParamDescriptorByName(const QString &paramName, const QVariant &value, ValueOperator operatorType);
Q_INVOKABLE void clear(); Q_INVOKABLE void clear();
Q_INVOKABLE ParamDescriptor *getParamDescriptor(const QString &paramTypeId) const;
Q_INVOKABLE ParamDescriptor *getParamDescriptorByName(const QString &paramName) const;
bool operator==(ParamDescriptors *other) const; bool operator==(ParamDescriptors *other) const;
signals: signals:

View File

@ -194,5 +194,6 @@
<file>ui/components/NavigationPad.qml</file> <file>ui/components/NavigationPad.qml</file>
<file>ui/components/KeypadButton.qml</file> <file>ui/components/KeypadButton.qml</file>
<file>ui/devicepages/DoorbellDevicePage.qml</file> <file>ui/devicepages/DoorbellDevicePage.qml</file>
<file>ui/magic/NewMagicPage.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -1,31 +1,15 @@
{ {
"templates": [ "templates": [
{ {
"interfaceName": "simplemultibutton", "description": "Turn on a light",
"description": "Switch a light", "ruleNameTemplate": "%0 turns on %1",
"ruleNameTemplate": "%0 switches %1",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [
{ {
"interfaceName": "simplemultibutton", "interfaceName": "button",
"interfaceEvent": "pressed", "interfaceEvent": "pressed",
"selectionId": 0, "selectionId": 0
"params": [
{
"name": "buttonName"
}
]
} }
], ],
"stateEvaluatorTemplate": {
"stateDescriptorTemplate": {
"interfaceName": "light",
"interfaceState": "power",
"operator": "ValueOperatorEquals",
"value": false,
"selectionId": 1,
"selectionMode": "SelectionModeDevice"
}
},
"ruleActionTemplates": [ "ruleActionTemplates": [
{ {
"interfaceName": "light", "interfaceName": "light",
@ -39,8 +23,19 @@
} }
] ]
} }
]
},
{
"description": "Turn off a light",
"ruleNameTemplate": "%0 turns off %1",
"eventDescriptorTemplates": [
{
"interfaceName": "button",
"interfaceEvent": "pressed",
"selectionId": 0
}
], ],
"ruleExitActionTemplates": [ "ruleActionTemplates": [
{ {
"interfaceName": "light", "interfaceName": "light",
"interfaceAction": "power", "interfaceAction": "power",
@ -56,12 +51,11 @@
] ]
}, },
{ {
"interfaceName": "simplebutton",
"description": "Switch a light", "description": "Switch a light",
"ruleNameTemplate": "%0 switches %1", "ruleNameTemplate": "%0 switches %1",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [
{ {
"interfaceName": "simplebutton", "interfaceName": "button",
"interfaceEvent": "pressed", "interfaceEvent": "pressed",
"selectionId": 0 "selectionId": 0
} }
@ -106,44 +100,12 @@
] ]
}, },
{ {
"interfaceName": "simplemultibutton", "interfaceName": "button",
"description": "Turn off all lights", "description": "Turn off all lights",
"ruleNameTemplate": "Turn off everything with %0", "ruleNameTemplate": "Turn off everything with %0",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [
{ {
"interfaceName": "simplemultibutton", "interfaceName": "button",
"interfaceEvent": "pressed",
"selectionId": 0,
"selectionMode": "SelectionModeDevice",
"params": [
{
"name": "buttonName"
}
]
}
],
"ruleActionTemplates": [
{
"interfaceName": "light",
"interfaceAction": "power",
"selectionId": 1,
"selectionMode": "SelectionModeInterface",
"params": [
{
"name": "power",
"value": false
}
]
}
]
},
{
"interfaceName": "simplebutton",
"description": "Turn off all lights",
"ruleNameTemplate": "Turn off everything with %0",
"eventDescriptorTemplates": [
{
"interfaceName": "simplebutton",
"interfaceEvent": "pressed", "interfaceEvent": "pressed",
"selectionId": 0, "selectionId": 0,
"selectionMode": "SelectionModeDevice" "selectionMode": "SelectionModeDevice"

View File

@ -15,7 +15,7 @@
}, },
"ruleActionTemplates": [ "ruleActionTemplates": [
{ {
"interfaceName": "power", "interfaceName": "light",
"interfaceAction": "power", "interfaceAction": "power",
"selectionId": 1, "selectionId": 1,
"params": [ "params": [
@ -28,7 +28,7 @@
], ],
"ruleExitActionTemplates": [ "ruleExitActionTemplates": [
{ {
"interfaceName": "power", "interfaceName": "light",
"interfaceAction": "power", "interfaceAction": "power",
"selectionId": 1, "selectionId": 1,
"params": [ "params": [
@ -43,7 +43,7 @@
{ {
"interfaceName": "daylightsensor", "interfaceName": "daylightsensor",
"description": "Turn on a light when it gets dark outside.", "description": "Turn on a light when it gets dark outside.",
"ruleNameTemplate": "Turn on %1 it gets dark outside (%0).", "ruleNameTemplate": "Turn on %1 when it gets dark outside (%0).",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [
{ {
"interfaceName": "daylightsensor", "interfaceName": "daylightsensor",

View File

@ -1,7 +1,6 @@
{ {
"templates": [ "templates": [
{ {
"interfaceName": "doorbell",
"description": "Alert on doorbell ring", "description": "Alert on doorbell ring",
"ruleNameTemplate": "Alert %1 when someone is at %0", "ruleNameTemplate": "Alert %1 when someone is at %0",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [

View File

@ -1,85 +1,3 @@
{ {
"templates": [
{
"interfaceName": "power",
"description": "Turn on while its dark outside.",
"ruleNameTemplate": "Turn on %1 while it's dark outside",
"stateEvaluatorTemplate": {
"stateDescriptorTemplate": {
"interfaceName": "daylightsensor",
"interfaceState": "daylight",
"selectionId": 0,
"operator": "ValueOperatorEquals",
"value": false
}
},
"ruleActionTemplates": [
{
"interfaceName": "power",
"interfaceAction": "power",
"selectionId": 1,
"params": [
{
"name": "power",
"value": "true"
}
]
}
],
"ruleExitActionTemplates": [
{
"interfaceName": "power",
"interfaceAction": "power",
"selectionId": 1,
"params": [
{
"name": "power",
"value": "false"
}
]
}
]
},
{
"interfaceName": "power",
"description": "Turn on while someone is around.",
"ruleNameTemplate": "Turn on %1 while %0 is present",
"stateEvaluatorTemplate": {
"stateDescriptorTemplate": {
"interfaceName": "presencesensor",
"interfaceState": "isPresent",
"selectionId": 0,
"operator": "ValueOperatorEquals",
"value": true
}
},
"ruleActionTemplates": [
{
"interfaceName": "power",
"interfaceAction": "power",
"selectionId": 1,
"params": [
{
"name": "power",
"value": "true"
}
]
}
],
"ruleExitActionTemplates": [
{
"interfaceName": "power",
"interfaceAction": "power",
"selectionId": 1,
"params": [
{
"name": "power",
"value": "false"
}
]
}
]
}
]
} }

View File

@ -1,8 +1,7 @@
{ {
"templates": [ "templates": [
{ {
"interfaceName": "notifications", "description": "Notify me when a device runs out of battery.",
"description": "Notify me when a device runs out of battery",
"ruleNameTemplate": "Low battery alert for %0", "ruleNameTemplate": "Low battery alert for %0",
"stateEvaluatorTemplate": { "stateEvaluatorTemplate": {
"stateDescriptorTemplate": { "stateDescriptorTemplate": {
@ -33,8 +32,38 @@
] ]
}, },
{ {
"interfaceName": "notifications", "description": "Notify me when something runs dry.",
"description": "Notify me when a thing gets disconnected", "ruleNameTemplate": "Notify %1 when %0 runs dry",
"stateEvaluatorTemplate": {
"stateDescriptorTemplate": {
"interfaceName": "moisturesensor",
"interfaceState": "moisture",
"operator": "ValueOperatorLess",
"selectionId": 0,
"value": 20
}
},
"ruleActionTemplates": [
{
"interfaceName": "notifications",
"interfaceAction": "notify",
"selectionId": 1,
"selectionMode": "SelectionModeDevice",
"params": [
{
"name": "title",
"value": "Water alert"
},
{
"name": "body",
"value": "%0 runs dry"
}
]
}
]
},
{
"description": "Notify me when a thing gets disconnected.",
"ruleNameTemplate": "Disconnect alert for %0", "ruleNameTemplate": "Disconnect alert for %0",
"stateEvaluatorTemplate": { "stateEvaluatorTemplate": {
"stateDescriptorTemplate": { "stateDescriptorTemplate": {
@ -67,7 +96,7 @@
}, },
{ {
"interfaceName": "notifications", "interfaceName": "notifications",
"description": "Notify me when a thing connects", "description": "Notify me when a thing connects.",
"ruleNameTemplate": "Connection notification for %0", "ruleNameTemplate": "Connection notification for %0",
"stateEvaluatorTemplate": { "stateEvaluatorTemplate": {
"stateDescriptorTemplate": { "stateDescriptorTemplate": {
@ -88,7 +117,7 @@
"params": [ "params": [
{ {
"name": "title", "name": "title",
"value": "Thin connected" "value": "Thing connected"
}, },
{ {
"name": "body", "name": "body",

View File

@ -2,8 +2,8 @@
"templates": [ "templates": [
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
"description": "Turn on something while this device is present...", "description": "Turn on something while being present.",
"ruleNameTemplate": "Turn on %1 while %0 is present", "ruleNameTemplate": "Turn on %1 while %0 reports presence",
"stateEvaluatorTemplate": { "stateEvaluatorTemplate": {
"stateDescriptorTemplate": { "stateDescriptorTemplate": {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
@ -42,8 +42,8 @@
}, },
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
"description": "Turn off something when this device leaves...", "description": "Turn off something when leaving.",
"ruleNameTemplate": "Turn off %1 when %0 leaves", "ruleNameTemplate": "Turn off %1 when %0 reports leaving",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
@ -74,8 +74,8 @@
}, },
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
"description": "Turn off everything when this device leaves...", "description": "Turn off everything when leaving.",
"ruleNameTemplate": "Turn off everything when %0 leaves", "ruleNameTemplate": "Turn off everything when %0 reports leaving",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
@ -107,8 +107,8 @@
}, },
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
"description": "Turn off all lights when this device leaves...", "description": "Turn off all lights when leaving.",
"ruleNameTemplate": "Turn off all lights when %0 leaves", "ruleNameTemplate": "Turn off all lights when %0 reports leaving",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
@ -140,8 +140,8 @@
}, },
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",
"description": "Turn on something when this device arrives...", "description": "Turn on something when arriving.",
"ruleNameTemplate": "Turn on %1 when %0 arrives", "ruleNameTemplate": "Turn on %1 when %0 reports arriving",
"eventDescriptorTemplates": [ "eventDescriptorTemplates": [
{ {
"interfaceName": "presencesensor", "interfaceName": "presencesensor",

View File

@ -1,7 +1,6 @@
{ {
"templates": [ "templates": [
{ {
"interfaceName": "",
"description": "", "description": "",
"ruleNameTemplate": "%0 ...", "ruleNameTemplate": "%0 ...",
"eventDescriptorTemplates": [ // optional "eventDescriptorTemplates": [ // optional

View File

@ -18,7 +18,32 @@ Page {
} }
} }
RuleTemplatesFilterModel {
id: ruleTemplatesModel
ruleTemplates: RuleTemplates {}
readonly property var deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(root.device.deviceClassId) : null
filterByDevices: DevicesProxy { engine: _engine }
filterInterfaceNames: deviceClass ? deviceClass.interfaces : []
}
function addRule() { function addRule() {
if (ruleTemplatesModel.count > 0) {
d.editRulePage = pageStack.push(Qt.resolvedUrl("magic/NewThingMagicPage.qml"))
d.editRulePage.done.connect(function() {
print("add rule done")
pageStack.pop(root);
})
d.editRulePage.manualCreation.connect(function() {
pageStack.pop(root);
manualAddRule();
})
} else {
manualAddRule();
}
}
function manualAddRule() {
var newRule = engine.ruleManager.createNewRule(); var newRule = engine.ruleManager.createNewRule();
d.editRulePage = pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: newRule }); d.editRulePage = pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: newRule });
d.editRulePage.StackView.onRemoved.connect(function() { d.editRulePage.StackView.onRemoved.connect(function() {
@ -41,20 +66,19 @@ Page {
Connections { Connections {
target: engine.ruleManager target: engine.ruleManager
onAddRuleReply: { onAddRuleReply: {
d.editRulePage.busy = false;
if (ruleError == "RuleErrorNoError") { if (ruleError == "RuleErrorNoError") {
// print("should tag rule now:", d.editRulePage.rule.id, d.editRulePage.ruleIcon, d.editRulePage.ruleColor) // print("should tag rule now:", d.editRulePage.rule.id, d.editRulePage.ruleIcon, d.editRulePage.ruleColor)
engine.tagsManager.tagRule(ruleId, "color", d.editRulePage.ruleColor) // engine.tagsManager.tagRule(ruleId, "color", d.editRulePage.ruleColor)
engine.tagsManager.tagRule(ruleId, "icon", d.editRulePage.ruleIcon) // engine.tagsManager.tagRule(ruleId, "icon", d.editRulePage.ruleIcon)
pageStack.pop(); pageStack.pop(root);
} else { } else {
var popup = errorDialog.createObject(app, {errorCode: ruleError }) var popup = errorDialog.createObject(app, {errorCode: ruleError })
popup.open(); popup.open();
} }
d.editRulePage.busy = false;
} }
onEditRuleReply: { onEditRuleReply: {
d.editRulePage.busy = false;
if (ruleError == "RuleErrorNoError") { if (ruleError == "RuleErrorNoError") {
// print("should tag rule now:", d.editRulePage.ruleIcon, d.editRulePage.ruleColor) // print("should tag rule now:", d.editRulePage.ruleIcon, d.editRulePage.ruleColor)
engine.tagsManager.tagRule(d.editRulePage.rule.id, "color", d.editRulePage.ruleColor) engine.tagsManager.tagRule(d.editRulePage.rule.id, "color", d.editRulePage.ruleColor)
@ -64,6 +88,7 @@ Page {
var popup = errorDialog.createObject(app, {errorCode: ruleError }) var popup = errorDialog.createObject(app, {errorCode: ruleError })
popup.open(); popup.open();
} }
d.editRulePage.busy = false;
} }
} }

View File

@ -147,6 +147,7 @@ ApplicationWindow {
case "light": case "light":
case "colorlight": case "colorlight":
case "dimmablelight": case "dimmablelight":
case "colortemperaturelight":
return Qt.resolvedUrl("images/light-on.svg") return Qt.resolvedUrl("images/light-on.svg")
case "sensor": case "sensor":
return Qt.resolvedUrl("images/sensors.svg") return Qt.resolvedUrl("images/sensors.svg")
@ -232,6 +233,8 @@ ApplicationWindow {
return Qt.resolvedUrl("images/notification.svg") return Qt.resolvedUrl("images/notification.svg")
case "connectable": case "connectable":
return Qt.resolvedUrl("images/stock_link.svg") return Qt.resolvedUrl("images/stock_link.svg")
case "power":
return Qt.resolvedUrl("images/system-shutdown.svg")
default: default:
console.warn("InterfaceToIcon: Unhandled interface", name) console.warn("InterfaceToIcon: Unhandled interface", name)
} }
@ -293,6 +296,17 @@ ApplicationWindow {
return qsTr("doorbell") return qsTr("doorbell")
case "alert": case "alert":
return qsTr("alert") return qsTr("alert")
case "simplemultibutton":
case "simplebutton":
return qsTr("button")
case "accesscotrol":
return qsTr("access control")
case "smartmeter":
case "smartmeterproducer":
case "smartmeterconsumer":
case "extendedsmartmeterproducer":
case "extendedsmartmeterconsumer":
return qsTr("smart meter");
default: default:
console.warn("Unhandled interfaceToDisplayName:", name) console.warn("Unhandled interfaceToDisplayName:", name)
} }

View File

@ -27,6 +27,7 @@ Page {
id: ruleTemplatesModel id: ruleTemplatesModel
ruleTemplates: RuleTemplates {} ruleTemplates: RuleTemplates {}
readonly property var deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(root.device.deviceClassId) : null readonly property var deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(root.device.deviceClassId) : null
filterByDevices: DevicesProxy { engine: _engine }
filterInterfaceNames: deviceClass ? deviceClass.interfaces : [] filterInterfaceNames: deviceClass ? deviceClass.interfaces : []
} }

View File

@ -0,0 +1,37 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import Nymea 1.0
import "../components"
Page {
id: root
header: NymeaHeader {
text: qsTr("New magic")
onBackPressed: pageStack.pop()
}
RuleTemplates {
id: ruleTemplates
}
ColumnLayout {
anchors.fill: parent
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
model: RuleTemplatesFilterModel {
ruleTemplates: ruleTemplates
}
delegate: NymeaListItemDelegate {
width: parent.width
text: model.description
}
}
}
}

View File

@ -7,8 +7,8 @@ import "../components"
Page { Page {
id: root id: root
property var device: null property Device device: null
readonly property var deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null readonly property DeviceClass deviceClass: device ? device.deviceClass : null
property bool busy: false property bool busy: false
signal done(); signal done();
@ -27,7 +27,7 @@ Page {
property var selectedInterfaces: ({}) property var selectedInterfaces: ({})
function fillRuleFromTemplate(rule, ruleTemplate) { function fillRuleFromTemplate(rule, ruleTemplate) {
print("Filling rule") print("***** Filling rule")
// Fill in all EventDescriptors // Fill in all EventDescriptors
for (var i = rule.eventDescriptors.count; i < ruleTemplate.eventDescriptorTemplates.count; i++) { for (var i = rule.eventDescriptors.count; i < ruleTemplate.eventDescriptorTemplates.count; i++) {
@ -36,17 +36,20 @@ Page {
// If we already have a thing selected for this selectionIndex, use that // If we already have a thing selected for this selectionIndex, use that
if (eventDescriptorTemplate.selectionId in selectedThings) { if (eventDescriptorTemplate.selectionId in selectedThings) {
var device = engine.deviceManager.devices.getDevice(selectedThings[eventDescriptorTemplate.selectionId]); var device = engine.deviceManager.devices.getDevice(selectedThings[eventDescriptorTemplate.selectionId]);
print("Already have a device for selectionId", eventDescriptorTemplate.selectionId, ":", device.name)
createEventDescriptor(rule, ruleTemplate, device, eventDescriptorTemplate) createEventDescriptor(rule, ruleTemplate, device, eventDescriptorTemplate)
return; return;
} }
// Ok, we didn't pick a thing for this selectionId before. Did we already use the one we opened this page from? // Ok, we didn't pick a thing for this selectionId before. Did we already use the one we opened this page from?
if (!deviceIsUsed(root.device.id) && root.deviceClass.interfaces.indexOf(eventDescriptorTemplate.interfaceName) >= 0 && eventDescriptorTemplate.interfaceName === ruleTemplate.interfaceName) { if (root.device && !deviceIsUsed(root.device.id) && root.deviceClass.interfaces.indexOf(eventDescriptorTemplate.interfaceName) >= 0) {
print("Root device is matching and not used. Using for selectionId", eventDescriptorTemplate.selectionId, ":", root.device.name)
selectedThings[eventDescriptorTemplate.selectionId] = root.device.id; selectedThings[eventDescriptorTemplate.selectionId] = root.device.id;
createEventDescriptor(rule, ruleTemplate, root.device, eventDescriptorTemplate) createEventDescriptor(rule, ruleTemplate, root.device, eventDescriptorTemplate)
return; return;
} }
// We need to pick a thing // We need to pick a thing
print("We need to pick a new device for selectionId", eventDescriptorTemplate.selectionId)
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [eventDescriptorTemplate.interfaceName]}); var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [eventDescriptorTemplate.interfaceName]});
page.thingSelected.connect(function(device) { page.thingSelected.connect(function(device) {
selectedThings[eventDescriptorTemplate.selectionId] = device.id; selectedThings[eventDescriptorTemplate.selectionId] = device.id;
@ -59,6 +62,7 @@ Page {
// Fill in StateEvaluator // Fill in StateEvaluator
if (ruleTemplate.stateEvaluatorTemplate !== null) { if (ruleTemplate.stateEvaluatorTemplate !== null) {
print("RuleFromTemplate: Filling stateEvaluator")
if (rule.stateEvaluator === null) { if (rule.stateEvaluator === null) {
var stateEvaluator = rule.createStateEvaluator(); var stateEvaluator = rule.createStateEvaluator();
rule.setStateEvaluator(stateEvaluator); rule.setStateEvaluator(stateEvaluator);
@ -73,6 +77,7 @@ Page {
for (var i = rule.actions.count; i < ruleTemplate.ruleActionTemplates.count; i++) { for (var i = rule.actions.count; i < ruleTemplate.ruleActionTemplates.count; i++) {
var ruleActionTemplate = ruleTemplate.ruleActionTemplates.get(i); var ruleActionTemplate = ruleTemplate.ruleActionTemplates.get(i);
print("RuleFromTemplate: Filling ruleAction:", ruleActionTemplate.interfaceName, ruleActionTemplate.interfaceAction, ruleActionTemplate.selectionId)
if (ruleActionTemplate.selectionMode === RuleActionTemplate.SelectionModeInterface) { if (ruleActionTemplate.selectionMode === RuleActionTemplate.SelectionModeInterface) {
// TODO: Implement blacklist for interface based actions // TODO: Implement blacklist for interface based actions
@ -92,19 +97,21 @@ Page {
// Did we pick a thing for this index before? // Did we pick a thing for this index before?
if (ruleActionTemplate.selectionId in selectedThings) { if (ruleActionTemplate.selectionId in selectedThings) {
var device = engine.deviceManager.devices.getDevice(selectedThings[ruleActionTemplate.selectionId]); var device = engine.deviceManager.devices.getDevice(selectedThings[ruleActionTemplate.selectionId]);
print("Already have a device for selectionId", ruleActionTemplate.selectionId, ":", device.name)
createRuleAction(rule, ruleTemplate, rule.actions, device, ruleActionTemplate) createRuleAction(rule, ruleTemplate, rule.actions, device, ruleActionTemplate)
return; return;
} }
// Did we already use the thing we opened this page from? // Did we already use the thing we opened this page from?
if (!deviceIsUsed(root.device.id) && root.deviceClass.interfaces.indexOf(ruleActionTemplate.interfaceName) >= 0 && ruleActionTemplate.interfaceName === ruleTemplate.interfaceName) { if (root.device && !deviceIsUsed(root.device.id) && root.deviceClass.interfaces.indexOf(ruleActionTemplate.interfaceName) >= 0) {
print("Root device is matching and not used. Using for selectionId", ruleActionTemplate.selectionId, ":", root.device.name)
selectedThings[ruleActionTemplate.selectionId] = root.device.id; selectedThings[ruleActionTemplate.selectionId] = root.device.id;
createRuleAction(rule, ruleTemplate, rule.actions, root.device, ruleActionTemplate) createRuleAction(rule, ruleTemplate, rule.actions, root.device, ruleActionTemplate)
return; return;
} }
// Ok, we need to pick a thing // Ok, we need to pick a thing
print("Need to select a thing") // print("Need to select a thing.")
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [ruleActionTemplate.interfaceName]}); var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [ruleActionTemplate.interfaceName]});
page.thingSelected.connect(function(device) { page.thingSelected.connect(function(device) {
selectedThings[ruleActionTemplate.selectionId] = device.id; selectedThings[ruleActionTemplate.selectionId] = device.id;
@ -142,7 +149,7 @@ Page {
} }
// Did we already use the thing we opened this page from? // Did we already use the thing we opened this page from?
if (!deviceIsUsed(root.device.id) && root.deviceClass.interfaces.indexOf(ruleExitActionTemplate.interfaceName) >= 0 && ruleExitActionTemplate.interfaceName === ruleTemplate.interfaceName) { if (root.device && !deviceIsUsed(root.device.id) && root.deviceClass.interfaces.indexOf(ruleExitActionTemplate.interfaceName) >= 0) {
selectedThings[ruleExitActionTemplate.selectionId] = root.device.id; selectedThings[ruleExitActionTemplate.selectionId] = root.device.id;
createRuleAction(rule, ruleTemplate, rule.exitActions, root.device, ruleExitActionTemplate); createRuleAction(rule, ruleTemplate, rule.exitActions, root.device, ruleExitActionTemplate);
return; return;
@ -194,6 +201,7 @@ Page {
print("Rule complete!") print("Rule complete!")
engine.ruleManager.addRule(rule); engine.ruleManager.addRule(rule);
rule.destroy(); rule.destroy();
print("emitting done")
root.done(); root.done();
} }
@ -224,7 +232,7 @@ Page {
fillRuleFromTemplate(rule, ruleTemplate); fillRuleFromTemplate(rule, ruleTemplate);
return true; return true;
} }
if (!deviceIsUsed(root.device.id) && root.deviceClass.interfaces.indexOf(stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName) >= 0 && stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName === ruleTemplate.interfaceName) { if (root.device && !deviceIsUsed(root.device.id) && root.deviceClass.interfaces.indexOf(stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName) >= 0) {
stateEvaluator.stateDescriptor.deviceId = root.device.id; stateEvaluator.stateDescriptor.deviceId = root.device.id;
stateEvaluator.stateDescriptor.stateTypeId = root.deviceClass.stateTypes.findByName(stateEvaluatorTemplate.stateDescriptorTemplate.interfaceState).id stateEvaluator.stateDescriptor.stateTypeId = root.deviceClass.stateTypes.findByName(stateEvaluatorTemplate.stateDescriptorTemplate.interfaceState).id
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator; stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
@ -272,15 +280,20 @@ Page {
var deviceClass = engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId); var deviceClass = engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
eventDescriptor.eventTypeId = deviceClass.eventTypes.findByName(eventDescriptorTemplate.interfaceEvent).id eventDescriptor.eventTypeId = deviceClass.eventTypes.findByName(eventDescriptorTemplate.interfaceEvent).id
var needsParams = false; var needsParams = false;
for (var j = 0; j < eventDescriptorTemplate.paramDescriptors.count; j++) {
var paramDescriptorTemplate = eventDescriptorTemplate.paramDescriptors.get(j); var eventType = deviceClass.eventTypes.getEventType(eventDescriptor.eventTypeId);
if (paramDescriptorTemplate.value !== undefined) { for (var j = 0; j < eventType.paramTypes.count; j++) {
print("Adding operator:", paramDescriptorTemplate.operatorType) var paramType = eventType.paramTypes.get(j);
var paramDescriptorTemplate = eventDescriptorTemplate.paramDescriptors.getParamDescriptorByName(paramType.name)
// has the template a value for this? If so, set it, otherwise flag as needsParams
print("template:", paramType.id, eventDescriptorTemplate.paramDescriptors.count)
if (paramDescriptorTemplate && paramDescriptorTemplate.value !== undefined) {
eventDescriptor.paramDescriptors.setParamDescriptorByName(paramDescriptorTemplate.paramName, paramDescriptorTemplate.value, paramDescriptorTemplate.operatorType); eventDescriptor.paramDescriptors.setParamDescriptorByName(paramDescriptorTemplate.paramName, paramDescriptorTemplate.value, paramDescriptorTemplate.operatorType);
} else { } else {
needsParams = true; needsParams = true;
} }
} }
if (needsParams) { if (needsParams) {
var page = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), { eventDescriptor: eventDescriptor }) var page = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), { eventDescriptor: eventDescriptor })
page.completed.connect(function() { page.completed.connect(function() {
@ -373,7 +386,7 @@ Page {
} }
header: NymeaHeader { header: NymeaHeader {
text: qsTr("New magic") text: root.device ? qsTr("New magic for %1").arg(root.device.name) : qsTr("New magic")
onBackPressed: root.done() onBackPressed: root.done()
} }
@ -382,14 +395,20 @@ Page {
ListView { ListView {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
clip: true
model: RuleTemplatesFilterModel { model: RuleTemplatesFilterModel {
id: ruleTemplatesModel id: ruleTemplatesModel
ruleTemplates: RuleTemplates {} ruleTemplates: RuleTemplates {}
filterInterfaceNames: root.deviceClass ? root.deviceClass.interfaces : [] filterByDevices: DevicesProxy {
engine: _engine
}
filterInterfaceNames: root.device ? root.device.deviceClass.interfaces : []
} }
delegate: NymeaListItemDelegate { delegate: NymeaListItemDelegate {
width: parent.width width: parent.width
text: model.description text: model.description
iconName: app.interfacesToIcon(model.interfaces)
onClicked: { onClicked: {
var ruleTemplate = ruleTemplatesModel.get(index); var ruleTemplate = ruleTemplatesModel.get(index);

View File

@ -58,6 +58,7 @@ MainPageTile {
if (model.name === "uncategorized") { if (model.name === "uncategorized") {
pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {hiddenInterfaces: app.supportedInterfaces}) pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {hiddenInterfaces: app.supportedInterfaces})
} else { } else {
print("<entering for shown interfaces:", model.name)
pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {shownInterfaces: [model.name]}) pageStack.push(Qt.resolvedUrl("../devicelistpages/" + page), {shownInterfaces: [model.name]})
} }
} }