This repository has been archived on 2026-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
powersync-app/nymea-app/ui/magic/NewThingMagicPage.qml
2018-07-11 23:10:30 +02:00

298 lines
17 KiB
QML

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