Add a rule template for automatic night mode

Also adjusts rule templates filtering to be able to deal with
optional states/events/actions in interfaces
pull/478/head
Michael Zanetti 2020-12-09 00:14:34 +01:00
parent d36aecb5d1
commit 68983e2fec
14 changed files with 282 additions and 57 deletions

View File

@ -203,6 +203,51 @@ void DevicesProxy::setNameFilter(const QString &nameFilter)
}
}
QString DevicesProxy::requiredEventName() const
{
return m_requiredEventName;
}
void DevicesProxy::setRequiredEventName(const QString &requiredEventName)
{
if (m_requiredEventName != requiredEventName) {
m_requiredEventName = requiredEventName;
emit requiredEventNameChanged();
invalidateFilter();
emit countChanged();
}
}
QString DevicesProxy::requiredStateName() const
{
return m_requiredStateName;
}
void DevicesProxy::setRequiredStateName(const QString &requiredStateName)
{
if (m_requiredStateName != requiredStateName) {
m_requiredStateName = requiredStateName;
emit requiredStateNameChanged();
invalidateFilter();
emit countChanged();
}
}
QString DevicesProxy::requiredActionName() const
{
return m_requiredActionName;
}
void DevicesProxy::setRequiredActionName(const QString &requiredActionName)
{
if (m_requiredActionName != requiredActionName) {
m_requiredActionName = requiredActionName;
emit requiredActionNameChanged();
invalidateFilter();
emit countChanged();
}
}
bool DevicesProxy::showDigitalInputs() const
{
return m_showDigitalInputs;
@ -489,5 +534,22 @@ bool DevicesProxy::filterAcceptsRow(int source_row, const QModelIndex &source_pa
return false;
}
}
if (!m_requiredEventName.isEmpty()) {
if (!device->thingClass()->eventTypes()->findByName(m_requiredEventName)) {
return false;
}
}
if (!m_requiredStateName.isEmpty()) {
if (!device->thingClass()->stateTypes()->findByName(m_requiredStateName)) {
return false;
}
}
if (!m_requiredActionName.isEmpty()) {
if (!device->thingClass()->actionTypes()->findByName(m_requiredActionName)) {
return false;
}
}
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}

View File

@ -53,6 +53,10 @@ class DevicesProxy : public QSortFilterProxyModel
Q_PROPERTY(QStringList hiddenInterfaces READ hiddenInterfaces WRITE setHiddenInterfaces NOTIFY hiddenInterfacesChanged)
Q_PROPERTY(QString nameFilter READ nameFilter WRITE setNameFilter NOTIFY nameFilterChanged)
Q_PROPERTY(QString requiredEventName READ requiredEventName WRITE setRequiredEventName NOTIFY requiredEventNameChanged)
Q_PROPERTY(QString requiredStateName READ requiredStateName WRITE setRequiredStateName NOTIFY requiredStateNameChanged)
Q_PROPERTY(QString requiredActionName READ requiredActionName WRITE setRequiredActionName NOTIFY requiredActionNameChanged)
// Setting one of those to true will hide those set to false. If all of those are false no IO filtering will be done
Q_PROPERTY(bool showDigitalInputs READ showDigitalInputs WRITE setShowDigitalInputs NOTIFY showDigitalInputsChanged)
Q_PROPERTY(bool showDigitalOutputs READ showDigitalOutputs WRITE setShowDigitalOutputs NOTIFY showDigitalOutputsChanged)
@ -101,6 +105,15 @@ public:
QString nameFilter() const;
void setNameFilter(const QString &nameFilter);
QString requiredEventName() const;
void setRequiredEventName(const QString &requiredEventName);
QString requiredStateName() const;
void setRequiredStateName(const QString &requiredStateName);
QString requiredActionName() const;
void setRequiredActionName(const QString &requiredActionName);
bool showDigitalInputs() const;
void setShowDigitalInputs(bool showDigitalInputs);
@ -142,6 +155,9 @@ signals:
void shownInterfacesChanged();
void hiddenInterfacesChanged();
void nameFilterChanged();
void requiredEventNameChanged();
void requiredStateNameChanged();
void requiredActionNameChanged();
void showDigitalInputsChanged();
void showDigitalOutputsChanged();
void showAnalogInputsChanged();
@ -166,6 +182,10 @@ private:
QStringList m_hiddenInterfaces;
QString m_nameFilter;
QString m_requiredEventName;
QString m_requiredStateName;
QString m_requiredActionName;
bool m_showDigitalInputs = false;
bool m_showDigitalOutputs = false;
bool m_showAnalogInputs = false;

View File

@ -30,10 +30,10 @@
#include "eventdescriptortemplate.h"
EventDescriptorTemplate::EventDescriptorTemplate(const QString &interfaceName, const QString &interfaceEvent, int selectionId, SelectionMode selectionMode, QObject *parent):
EventDescriptorTemplate::EventDescriptorTemplate(const QString &interfaceName, const QString &eventName, int selectionId, SelectionMode selectionMode, QObject *parent):
QObject(parent),
m_interfaceName(interfaceName),
m_interfaceEvent(interfaceEvent),
m_eventName(eventName),
m_selectionId(selectionId),
m_selectionMode(selectionMode),
m_paramDescriptors(new ParamDescriptors(this))
@ -46,9 +46,9 @@ QString EventDescriptorTemplate::interfaceName() const
return m_interfaceName;
}
QString EventDescriptorTemplate::interfaceEvent() const
QString EventDescriptorTemplate::eventName() const
{
return m_interfaceEvent;
return m_eventName;
}
int EventDescriptorTemplate::selectionId() const

View File

@ -38,7 +38,7 @@ class EventDescriptorTemplate : public QObject
{
Q_OBJECT
Q_PROPERTY(QString interfaceName READ interfaceName CONSTANT)
Q_PROPERTY(QString interfaceEvent READ interfaceEvent CONSTANT)
Q_PROPERTY(QString eventName READ eventName CONSTANT)
Q_PROPERTY(int selectionId READ selectionId CONSTANT)
Q_PROPERTY(SelectionMode selectionMode READ selectionMode CONSTANT)
Q_PROPERTY(ParamDescriptors* paramDescriptors READ paramDescriptors CONSTANT)
@ -50,17 +50,17 @@ public:
};
Q_ENUM(SelectionMode)
explicit EventDescriptorTemplate(const QString &interfaceName, const QString &interfaceEvent, int selectionId, SelectionMode selectionMode = SelectionModeAny, QObject *parent = nullptr);
explicit EventDescriptorTemplate(const QString &interfaceName, const QString &eventName, int selectionId, SelectionMode selectionMode = SelectionModeAny, QObject *parent = nullptr);
QString interfaceName() const;
QString interfaceEvent() const;
QString eventName() const;
int selectionId() const;
SelectionMode selectionMode() const;
ParamDescriptors* paramDescriptors() const;
private:
QString m_interfaceName;
QString m_interfaceEvent;
QString m_eventName;
int m_selectionId = 0;
SelectionMode m_selectionMode = SelectionModeAny;
ParamDescriptors *m_paramDescriptors = nullptr;

View File

@ -31,10 +31,10 @@
#include "ruleactiontemplate.h"
#include "ruleactionparamtemplate.h"
RuleActionTemplate::RuleActionTemplate(const QString &interfaceName, const QString &interfaceAction, int selectionId, RuleActionTemplate::SelectionMode selectionMode, RuleActionParamTemplates *params, QObject *parent):
RuleActionTemplate::RuleActionTemplate(const QString &interfaceName, const QString &actionName, int selectionId, RuleActionTemplate::SelectionMode selectionMode, RuleActionParamTemplates *params, QObject *parent):
QObject(parent),
m_interfaceName(interfaceName),
m_interfaceAction(interfaceAction),
m_actionName(actionName),
m_selectionId(selectionId),
m_selectionMode(selectionMode),
m_ruleActionParamTemplates(params ? params : new RuleActionParamTemplates())
@ -47,9 +47,9 @@ QString RuleActionTemplate::interfaceName() const
return m_interfaceName;
}
QString RuleActionTemplate::interfaceAction() const
QString RuleActionTemplate::actionName() const
{
return m_interfaceAction;
return m_actionName;
}
int RuleActionTemplate::selectionId() const

View File

@ -39,7 +39,7 @@ class RuleActionTemplate : public QObject
{
Q_OBJECT
Q_PROPERTY(QString interfaceName READ interfaceName CONSTANT)
Q_PROPERTY(QString interfaceAction READ interfaceAction CONSTANT)
Q_PROPERTY(QString actionName READ actionName CONSTANT)
Q_PROPERTY(int selectionId READ selectionId CONSTANT)
Q_PROPERTY(SelectionMode selectionMode READ selectionMode CONSTANT)
Q_PROPERTY(RuleActionParamTemplates* ruleActionParamTemplates READ ruleActionParamTemplates CONSTANT)
@ -53,17 +53,17 @@ public:
};
Q_ENUM(SelectionMode)
explicit RuleActionTemplate(const QString &interfaceName, const QString &interfaceAction, int selectionId, SelectionMode selectionMode = SelectionModeAny, RuleActionParamTemplates *params = nullptr, QObject *parent = nullptr);
explicit RuleActionTemplate(const QString &interfaceName, const QString &actionName, int selectionId, SelectionMode selectionMode = SelectionModeAny, RuleActionParamTemplates *params = nullptr, QObject *parent = nullptr);
QString interfaceName() const;
QString interfaceAction() const;
QString actionName() const;
int selectionId() const;
SelectionMode selectionMode() const;
RuleActionParamTemplates* ruleActionParamTemplates() const;
private:
QString m_interfaceName;
QString m_interfaceAction;
QString m_actionName;
int m_selectionId = 0;
SelectionMode m_selectionMode = SelectionModeAny;
RuleActionParamTemplates* m_ruleActionParamTemplates = nullptr;

View File

@ -296,22 +296,10 @@ bool RuleTemplatesFilterModel::filterAcceptsRow(int source_row, const QModelInde
// 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)->thingClass()->interfaces().contains(toBeFound)) {
found = true;
break;
}
}
if (!found) {
qDebug() << "Filtering out" << t->description() << "because required no device in the provided filter proxy implements" << toBeFound;
return false;
}
}
// Make sure we have all the things to satisfy all of the templates events/states/actions
if (m_filterDevicesProxy && !thingsSatisfyRuleTemplate(t, m_filterDevicesProxy)) {
qDebug() << "Filtering out" << t->description() << "because required no thing in the provided filter proxy satisfies definitions";
return false;
}
if (!m_filterInterfaceNames.isEmpty()) {
@ -341,3 +329,107 @@ bool RuleTemplatesFilterModel::stateEvaluatorTemplateContainsInterface(StateEval
}
return false;
}
bool RuleTemplatesFilterModel::thingsSatisfyRuleTemplate(RuleTemplate *ruleTemplate, DevicesProxy *things) const
{
// For improved performance it would be better to just cycle things once and flag satisfied states/events/actions
// instead of looping over all things for every entry, but for the amount of templates we have right now
// this is good enough. If needed, here's low hanging fruit to collect...
// First check if all interfaces are around
foreach (const QString &interfaceName, ruleTemplate->interfaces()) {
bool haveThing = false;
for (int i = 0; i < things->rowCount(); i++) {
Device *thing = things->get(i);
if (thing->thingClass()->interfaces().contains(interfaceName)) {
haveThing = true;
break;
}
}
if (!haveThing) {
qDebug() << "No thing to satisfy interface" << interfaceName;
return false;
}
}
// Given optional states/actions/events in interfaces, we also need to check for them
for (int i = 0; i < ruleTemplate->eventDescriptorTemplates()->rowCount(); i++) {
EventDescriptorTemplate *eventDescriptorTemplate = ruleTemplate->eventDescriptorTemplates()->get(i);
bool haveThing = false;
for (int j = 0; j < things->rowCount(); j++) {
Device *thing = things->get(j);
if (thing->thingClass()->eventTypes()->findByName(eventDescriptorTemplate->eventName())) {
haveThing = true;
break;
}
}
if (!haveThing) {
qDebug() << "No thing to satisfy event" << eventDescriptorTemplate->eventName();
return false;
}
}
if (ruleTemplate->stateEvaluatorTemplate() && !thingsSatisfyStateEvaluatorTemplate(ruleTemplate->stateEvaluatorTemplate(), things)) {
qDebug() << "No thing to satisfy state evaluator template";
return false;
}
for (int i = 0; i < ruleTemplate->ruleActionTemplates()->rowCount(); i++) {
RuleActionTemplate *ruleActionTemplate = ruleTemplate->ruleActionTemplates()->get(i);
bool haveThing = false;
for (int j = 0; j < things->rowCount(); j++) {
Device *thing = things->get(j);
if (thing->thingClass()->actionTypes()->findByName(ruleActionTemplate->actionName())) {
haveThing = true;
break;
}
}
if (!haveThing) {
qDebug() << "No thing to satisfy action" << ruleActionTemplate->actionName();
return false;
}
}
for (int i = 0; i < ruleTemplate->ruleExitActionTemplates()->rowCount(); i++) {
RuleActionTemplate *ruleExitActionTemplate = ruleTemplate->ruleExitActionTemplates()->get(i);
bool haveThing = false;
for (int j = 0; j < things->rowCount(); j++) {
Device *thing = things->get(j);
if (thing->thingClass()->actionTypes()->findByName(ruleExitActionTemplate->actionName())) {
haveThing = true;
break;
}
}
if (!haveThing) {
qDebug() << "No thing to satisfy exit action" << ruleExitActionTemplate->actionName();
return false;
}
}
return true;
}
bool RuleTemplatesFilterModel::thingsSatisfyStateEvaluatorTemplate(StateEvaluatorTemplate *stateEvaluatorTemplate, DevicesProxy *things) const
{
if (stateEvaluatorTemplate->stateDescriptorTemplate()) {
bool haveThing = false;
for (int i = 0; i < things->rowCount(); i++) {
Device *thing = things->get(i);
if (thing->thingClass()->stateTypes()->findByName(stateEvaluatorTemplate->stateDescriptorTemplate()->stateName())) {
haveThing = true;
break;
}
}
if (!haveThing) {
return false;
}
}
for (int i = 0; i < stateEvaluatorTemplate->childEvaluatorTemplates()->rowCount(); i++) {
StateEvaluatorTemplate *childEvaluatorTemplate = stateEvaluatorTemplate->childEvaluatorTemplates()->get(i);
if (!thingsSatisfyStateEvaluatorTemplate(childEvaluatorTemplate, things)) {
return false;
}
}
return true;
}

View File

@ -38,6 +38,7 @@ class StateEvaluatorTemplate;
class TimeDescriptorTemplate;
class RepeatingOption;
class DevicesProxy;
class Device;
class RuleTemplates : public QAbstractListModel
{
@ -104,6 +105,10 @@ signals:
void countChanged();
private:
bool thingsSatisfyRuleTemplate(RuleTemplate *ruleTemplate, DevicesProxy *things) const;
bool thingsSatisfyStateEvaluatorTemplate(StateEvaluatorTemplate *stateEvaluatorTemplate, DevicesProxy *things) const;
private:
RuleTemplates* m_ruleTemplates = nullptr;
QStringList m_filterInterfaceNames;

View File

@ -30,10 +30,10 @@
#include "statedescriptortemplate.h"
StateDescriptorTemplate::StateDescriptorTemplate(const QString &interfaceName, const QString &interfaceState, int selectionId, StateDescriptorTemplate::SelectionMode selectionMode, StateDescriptorTemplate::ValueOperator valueOperator, const QVariant &value, QObject *parent):
StateDescriptorTemplate::StateDescriptorTemplate(const QString &interfaceName, const QString &stateName, int selectionId, StateDescriptorTemplate::SelectionMode selectionMode, StateDescriptorTemplate::ValueOperator valueOperator, const QVariant &value, QObject *parent):
QObject(parent),
m_interfaceName(interfaceName),
m_interfaceState(interfaceState),
m_stateName(stateName),
m_selectionId(selectionId),
m_selectionMode(selectionMode),
m_valueOperator(valueOperator),
@ -47,9 +47,9 @@ QString StateDescriptorTemplate::interfaceName() const
return m_interfaceName;
}
QString StateDescriptorTemplate::interfaceState() const
QString StateDescriptorTemplate::stateName() const
{
return m_interfaceState;
return m_stateName;
}
int StateDescriptorTemplate::selectionId() const

View File

@ -38,7 +38,7 @@ class StateDescriptorTemplate : public QObject
{
Q_OBJECT
Q_PROPERTY(QString interfaceName READ interfaceName CONSTANT)
Q_PROPERTY(QString interfaceState READ interfaceState CONSTANT)
Q_PROPERTY(QString stateName READ stateName CONSTANT)
Q_PROPERTY(int selectionId READ selectionId CONSTANT)
Q_PROPERTY(SelectionMode selectionMode READ selectionMode CONSTANT)
Q_PROPERTY(ValueOperator valueOperator READ valueOperator CONSTANT)
@ -61,10 +61,10 @@ public:
};
Q_ENUM(ValueOperator)
explicit StateDescriptorTemplate(const QString &interfaceName, const QString &interfaceState, int selectionId, SelectionMode selectionMode, ValueOperator valueOperator = ValueOperatorEquals, const QVariant &value = QVariant(), QObject *parent = nullptr);
explicit StateDescriptorTemplate(const QString &interfaceName, const QString &stateName, int selectionId, SelectionMode selectionMode, ValueOperator valueOperator = ValueOperatorEquals, const QVariant &value = QVariant(), QObject *parent = nullptr);
QString interfaceName() const;
QString interfaceState() const;
QString stateName() const;
int selectionId() const;
SelectionMode selectionMode() const;
ValueOperator valueOperator() const;
@ -72,7 +72,7 @@ public:
private:
QString m_interfaceName;
QString m_interfaceState;
QString m_stateName;
int m_selectionId = 0;
SelectionMode m_selectionMode = SelectionModeAny;
ValueOperator m_valueOperator = ValueOperatorEquals;

View File

@ -63,6 +63,48 @@
]
}
]
},
{
"description": "Automatic night mode",
"ruleNameTemplate": "Automatic night mode on %0",
"timeDescriptorTemplate": {
"calendarItemTemplates": [
{
"startTime": "22:00",
"duration": 600,
"repeatingOption": {
"repeatingMode": "RepeatingModeDaily"
},
"editable": true
}
]
},
"ruleActionTemplates": [
{
"interfaceName": "mediacontroller",
"interfaceAction": "nightMode",
"selectionId": 0,
"params": [
{
"name": "nightMode",
"value": true
}
]
}
],
"ruleExitActionTemplates": [
{
"interfaceName": "mediacontroller",
"interfaceAction": "nightMode",
"selectionId": 0,
"params": [
{
"name": "nightMode",
"value": false
}
]
}
]
}
]
}

View File

@ -454,6 +454,7 @@ ApplicationWindow {
return qsTr("smart meter");
case "media":
case "mediaplayer":
case "mediacontroller":
//: Select ...
return qsTr("media player");
case "moisturesensor":

View File

@ -63,7 +63,7 @@ Page {
// Fill in all EventDescriptors
for (var i = rule.eventDescriptors.count; i < ruleTemplate.eventDescriptorTemplates.count; i++) {
var eventDescriptorTemplate = ruleTemplate.eventDescriptorTemplates.get(i);
print("RuleFromTemplate: Filling eventDescriptor:", eventDescriptorTemplate.interfaceName, eventDescriptorTemplate.interfaceEvent, eventDescriptorTemplate.selectionId)
print("RuleFromTemplate: Filling eventDescriptor:", eventDescriptorTemplate.interfaceName, eventDescriptorTemplate.eventName, eventDescriptorTemplate.selectionId)
// If we already have a thing selected for this selectionIndex, use that
if (eventDescriptorTemplate.selectionId in selectedThings) {
var device = engine.deviceManager.devices.getDevice(selectedThings[eventDescriptorTemplate.selectionId]);
@ -82,7 +82,7 @@ Page {
// 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], requiredEventName: eventDescriptorTemplate.eventName});
page.thingSelected.connect(function(device) {
selectedThings[eventDescriptorTemplate.selectionId] = device.id;
selectedThingNames[eventDescriptorTemplate.selectionId] = device.name;
@ -152,13 +152,13 @@ Page {
for (var i = rule.actions.count; i < ruleTemplate.ruleActionTemplates.count; i++) {
var ruleActionTemplate = ruleTemplate.ruleActionTemplates.get(i);
print("RuleFromTemplate: Filling ruleAction:", ruleActionTemplate.interfaceName, ruleActionTemplate.interfaceAction, ruleActionTemplate.selectionId)
print("RuleFromTemplate: Filling ruleAction:", ruleActionTemplate.interfaceName, ruleActionTemplate.actionName, ruleActionTemplate.selectionId)
if (ruleActionTemplate.selectionMode === RuleActionTemplate.SelectionModeInterface) {
// TODO: Implement blacklist for interface based actions
var ruleAction = rule.actions.createNewRuleAction();
ruleAction.interfaceName = ruleActionTemplate.interfaceName;
ruleAction.interfaceAction = ruleActionTemplate.interfaceAction;
ruleAction.interfaceAction = ruleActionTemplate.actionName;
for (var j = 0; j < ruleActionTemplate.ruleActionParamTemplates.count; j++) {
var ruleActionParam = ruleActionTemplate.ruleActionParamTemplates.get(j)
ruleAction.ruleActionParams.setRuleActionParamByName(ruleActionParam.paramName, ruleActionParam.value)
@ -188,7 +188,7 @@ Page {
// Ok, we need to pick a thing
var multipleSelection = ruleActionTemplate.selectionMode === RuleActionTemplate.SelectionModeDevices;
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [ruleActionTemplate.interfaceName], multipleSelection: multipleSelection});
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [ruleActionTemplate.interfaceName], requiredActionName: ruleActionTemplate.actionName, multipleSelection: multipleSelection});
page.thingSelected.connect(function(device) {
selectedThings[ruleActionTemplate.selectionId] = device.id;
selectedThingNames[ruleActionTemplate.selectionId] = device.name;
@ -216,7 +216,7 @@ Page {
// TODO: Implement blacklist for interface based actions
var ruleExitAction = rule.exitActions.createNewRuleAction();
ruleExitAction.interfaceName = ruleExitActionTemplate.interfaceName;
ruleExitAction.interfaceAction = ruleExitActionTemplate.interfaceAction;
ruleExitAction.interfaceAction = ruleExitActionTemplate.actionName;
for (var j = 0; j < ruleExitActionTemplate.ruleActionParamTemplates.count; j++) {
var ruleActionParam = ruleExitActionTemplate.ruleActionParamTemplates.get(j)
ruleExitAction.ruleActionParams.setRuleActionParam(ruleActionParam.paramName, ruleActionParam.value)
@ -244,7 +244,7 @@ Page {
// Ok, we need to pick a thing
var multipleSelection = ruleActionTemplate.selectionMode === RuleActionTemplate.SelectionModeDevices;
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [ruleExitActionTemplate.interfaceName], multipleSelection: multipleSelection});
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [ruleExitActionTemplate.interfaceName], requiredActionName: ruleExitActionTemplate.actionName, multipleSelection: multipleSelection});
page.thingSelected.connect(function(device) {
selectedThings[ruleExitActionTemplate.selectionId] = device.id;
selectedThingNames[ruleExitActionTemplate.selectionId] = device.name;
@ -309,7 +309,7 @@ Page {
print("filling in state evaluator for selection mode:", stateEvaluatorTemplate.stateDescriptorTemplate.selectionMode)
if (stateEvaluatorTemplate.stateDescriptorTemplate.selectionMode === StateDescriptor.SelectionModeInterface) {
stateEvaluator.stateDescriptor.interfaceName = stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName;
stateEvaluator.stateDescriptor.interfaceState = stateEvaluatorTemplate.stateDescriptorTemplate.interfaceState;
stateEvaluator.stateDescriptor.interfaceState = stateEvaluatorTemplate.stateDescriptorTemplate.stateName;
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
stateEvaluator.stateDescriptor.value = stateEvaluatorTemplate.stateDescriptorTemplate.value;
selectedInterfaces[stateEvaluatorTemplate.stateDescriptorTemplate.selectionId] = stateEvaluator.stateDescriptor.interfaceName;
@ -323,7 +323,7 @@ Page {
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.stateTypeId = deviceClass.stateTypes.findByName(stateEvaluatorTemplate.stateDescriptorTemplate.stateName).id
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
stateEvaluator.stateDescriptor.value = stateEvaluatorTemplate.stateDescriptorTemplate.value;
fillRuleFromTemplate(rule, ruleTemplate);
@ -331,7 +331,7 @@ Page {
}
if (root.device && !deviceIsUsed(root.device.id) && 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.stateTypeId = root.deviceClass.stateTypes.findByName(stateEvaluatorTemplate.stateDescriptorTemplate.stateName).id
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
stateEvaluator.stateDescriptor.value = stateEvaluatorTemplate.stateDescriptorTemplate.value;
selectedThings[stateEvaluatorTemplate.stateDescriptorTemplate.selectionId] = root.device.id;
@ -341,11 +341,11 @@ Page {
}
print("opening SelectThingPage for shownInterfaces:")
print("..", stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName)
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName], allowSelectAny: stateEvaluatorTemplate.stateDescriptorTemplate.selectionMode === StateDescriptorTemplate.SelectionModeAny});
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {shownInterfaces: [stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName], requiredStateName: stateEvaluatorTemplate.stateDescriptorTemplate.stateName, allowSelectAny: stateEvaluatorTemplate.stateDescriptorTemplate.selectionMode === StateDescriptorTemplate.SelectionModeAny});
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.stateTypeId = deviceClass.stateTypes.findByName(stateEvaluatorTemplate.stateDescriptorTemplate.stateName).id;
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
stateEvaluator.stateDescriptor.value = stateEvaluatorTemplate.stateDescriptorTemplate.value;
selectedThings[stateEvaluatorTemplate.stateDescriptorTemplate.selectionId] = device.id;
@ -354,7 +354,7 @@ Page {
})
page.onAnySelected.connect(function() {
stateEvaluator.stateDescriptor.interfaceName = stateEvaluatorTemplate.stateDescriptorTemplate.interfaceName;
stateEvaluator.stateDescriptor.interfaceState = stateEvaluatorTemplate.stateDescriptorTemplate.interfaceState;
stateEvaluator.stateDescriptor.interfaceState = stateEvaluatorTemplate.stateDescriptorTemplate.stateName;
stateEvaluator.stateDescriptor.valueOperator = stateEvaluatorTemplate.stateDescriptorTemplate.valueOperator;
stateEvaluator.stateDescriptor.value = stateEvaluatorTemplate.stateDescriptorTemplate.value;
selectedInterfaces[stateEvaluatorTemplate.stateDescriptorTemplate.selectionId] = stateEvaluator.stateDescriptor.interfaceName;
@ -381,7 +381,7 @@ Page {
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
eventDescriptor.eventTypeId = deviceClass.eventTypes.findByName(eventDescriptorTemplate.eventName).id
var needsParams = false;
var eventType = deviceClass.eventTypes.getEventType(eventDescriptor.eventTypeId);
@ -423,9 +423,9 @@ Page {
var ruleAction = ruleActions.createNewRuleAction();
var deviceClass = engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
ruleAction.actionTypeId = deviceClass.actionTypes.findByName(ruleActionTemplate.interfaceAction).id
ruleAction.actionTypeId = deviceClass.actionTypes.findByName(ruleActionTemplate.actionName).id
ruleAction.deviceId = device.id;
print("Creating action", ruleActionTemplate.interfaceAction, "on device class", deviceClass.displayName)
print("Creating action", ruleActionTemplate.actionName, "on device class", deviceClass.displayName)
var actionType = deviceClass.actionTypes.getActionType(ruleAction.actionTypeId);
@ -441,7 +441,7 @@ Page {
for (var k = 0; k < ruleTemplate.eventDescriptorTemplates.count; k++) {
var tmp = ruleTemplate.eventDescriptorTemplates.get(k);
print("evaluating eventDescriptor", tmp.interfaceName)
if (tmp.interfaceName === ruleActionParamTemplate.eventInterface && tmp.interfaceEvent === ruleActionParamTemplate.eventName) {
if (tmp.interfaceName === ruleActionParamTemplate.eventInterface && tmp.eventName === ruleActionParamTemplate.eventName) {
eventDescriptorTemplate = tmp;
break;
}

View File

@ -45,6 +45,9 @@ Page {
property alias shownInterfaces: devicesProxy.shownInterfaces
property bool allowSelectAny: false
property bool multipleSelection: false
property alias requiredEventName: devicesProxy.requiredEventName
property alias requiredStateName: devicesProxy.requiredStateName
property alias requiredActionName: devicesProxy.requiredActionName
signal backPressed();
signal thingSelected(var device);