more work on rules
parent
27b8946ff5
commit
0592ee6133
|
|
@ -85,7 +85,7 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
|
|||
{
|
||||
QString notification = data.value("notification").toString();
|
||||
if (notification == "Devices.StateChanged") {
|
||||
qDebug() << "Device state changed" << data.value("params");
|
||||
// qDebug() << "Device state changed" << data.value("params");
|
||||
Device *dev = m_devices->getDevice(data.value("params").toMap().value("deviceId").toUuid());
|
||||
if (!dev) {
|
||||
qWarning() << "Device state change notification received for an unknown device";
|
||||
|
|
|
|||
|
|
@ -120,4 +120,6 @@ DISTFILES += \
|
|||
|
||||
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
|
||||
|
||||
target.path = /usr/bin
|
||||
INSTALLS += target
|
||||
|
||||
|
|
|
|||
|
|
@ -254,10 +254,11 @@ void JsonRpcClient::dataReceived(const QByteArray &data)
|
|||
JsonHandler *handler = m_notificationHandlers.value(nameSpace).first;
|
||||
|
||||
if (!handler) {
|
||||
qWarning() << "JsonRpc: handler not implemented:" << nameSpace;
|
||||
// qWarning() << "JsonRpc: handler not implemented:" << nameSpace;
|
||||
return;
|
||||
}
|
||||
|
||||
// qDebug() << "Incoming notification:" << jsonDoc.toJson();
|
||||
QMetaObject::invokeMethod(handler, m_notificationHandlers.value(nameSpace).second.toLatin1().data(), Q_ARG(QVariantMap, dataMap));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@
|
|||
#include "deviceclasses.h"
|
||||
#include "types/params.h"
|
||||
#include "types/paramtypes.h"
|
||||
#include "types/rule.h"
|
||||
#include "types/ruleaction.h"
|
||||
#include "types/ruleactions.h"
|
||||
#include "types/eventdescriptor.h"
|
||||
#include "types/eventdescriptors.h"
|
||||
#include "types/ruleactionparam.h"
|
||||
#include "types/ruleactionparams.h"
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
|
|
@ -165,7 +172,7 @@ EventType *JsonTypes::unpackEventType(const QVariantMap &eventTypeMap, QObject *
|
|||
ActionType *JsonTypes::unpackActionType(const QVariantMap &actionTypeMap, QObject *parent)
|
||||
{
|
||||
ActionType *actionType = new ActionType(parent);
|
||||
actionType->setId(actionTypeMap.value("id").toUuid());
|
||||
actionType->setId(actionTypeMap.value("id").toString());
|
||||
actionType->setName(actionTypeMap.value("name").toString());
|
||||
actionType->setDisplayName(actionTypeMap.value("displayName").toString());
|
||||
actionType->setIndex(actionTypeMap.value("index").toInt());
|
||||
|
|
@ -207,6 +214,58 @@ Device *JsonTypes::unpackDevice(const QVariantMap &deviceMap, QObject *parent)
|
|||
return device;
|
||||
}
|
||||
|
||||
QVariantMap JsonTypes::packRule(Rule *rule)
|
||||
{
|
||||
QVariantMap ret;
|
||||
ret.insert("ruleId", rule->id());
|
||||
ret.insert("name", rule->name());
|
||||
ret.insert("enabled", true);
|
||||
|
||||
if (rule->ruleActions()->rowCount() > 0) {
|
||||
QVariantList actions;
|
||||
for (int i = 0; i < rule->ruleActions()->rowCount(); i++) {
|
||||
QVariantMap ruleAction;
|
||||
ruleAction.insert("actionTypeId", rule->ruleActions()->get(i)->actionTypeId());
|
||||
ruleAction.insert("deviceId", rule->ruleActions()->get(i)->deviceId());
|
||||
if (rule->ruleActions()->get(i)->ruleActionParams()->rowCount() > 0) {
|
||||
QVariantList ruleActionParams;
|
||||
for (int j = 0; j < rule->ruleActions()->get(i)->ruleActionParams()->rowCount(); j++) {
|
||||
QVariantMap ruleActionParam;
|
||||
ruleActionParam.insert("paramTypeId", rule->ruleActions()->get(i)->ruleActionParams()->get(j)->paramTypeId());
|
||||
ruleActionParam.insert("value", rule->ruleActions()->get(i)->ruleActionParams()->get(j)->value());
|
||||
ruleActionParams.append(ruleActionParam);
|
||||
}
|
||||
ruleAction.insert("ruleActionParams", ruleActionParams);
|
||||
}
|
||||
actions.append(ruleAction);
|
||||
}
|
||||
ret.insert("actions", actions);
|
||||
}
|
||||
|
||||
if (rule->eventDescriptors()->rowCount() > 0) {
|
||||
QVariantList eventDescriptors;
|
||||
for (int i = 0; i < rule->eventDescriptors()->rowCount(); i++) {
|
||||
QVariantMap eventDescriptor;
|
||||
eventDescriptor.insert("eventTypeId", rule->eventDescriptors()->get(i)->eventTypeId());
|
||||
eventDescriptor.insert("deviceId", rule->eventDescriptors()->get(i)->deviceId());
|
||||
if (rule->eventDescriptors()->get(i)->paramDescriptors()->rowCount() > 0) {
|
||||
QVariantList paramDescriptors;
|
||||
for (int j = 0; j < rule->eventDescriptors()->get(i)->paramDescriptors()->rowCount(); j++) {
|
||||
QVariantMap paramDescriptor;
|
||||
paramDescriptor.insert("paramTypeId", rule->eventDescriptors()->get(i)->paramDescriptors()->get(j)->id());
|
||||
paramDescriptor.insert("value", rule->eventDescriptors()->get(i)->paramDescriptors()->get(j)->value());
|
||||
paramDescriptors.append(paramDescriptor);
|
||||
}
|
||||
eventDescriptor.insert("paramDescriptors", paramDescriptors);
|
||||
}
|
||||
eventDescriptors.append(eventDescriptor);
|
||||
}
|
||||
ret.insert("eventDescriptors", eventDescriptors);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DeviceClass::SetupMethod JsonTypes::stringToSetupMethod(const QString &setupMethodString)
|
||||
{
|
||||
if (setupMethodString == "SetupMethodJustAdd") {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "types/actiontype.h"
|
||||
|
||||
class Vendor;
|
||||
class Rule;
|
||||
|
||||
class JsonTypes : public QObject
|
||||
{
|
||||
|
|
@ -54,6 +55,7 @@ public:
|
|||
static ActionType *unpackActionType(const QVariantMap &actionTypeMap, QObject *parent);
|
||||
static Device *unpackDevice(const QVariantMap &deviceMap, QObject *parent);
|
||||
|
||||
static QVariantMap packRule(Rule* rule);
|
||||
private:
|
||||
static DeviceClass::SetupMethod stringToSetupMethod(const QString &setupMethodString);
|
||||
static QList<DeviceClass::BasicTag> stringListToBasicTags(const QStringList &basicTagsStringList);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QGuiApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QtQml/QQmlContext>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication application(argc, argv);
|
||||
QGuiApplication application(argc, argv);
|
||||
application.setApplicationName("guh-control");
|
||||
application.setOrganizationName("guh");
|
||||
|
||||
|
|
|
|||
|
|
@ -112,5 +112,8 @@
|
|||
<file>ui/magic/ComposeEventDescriptorPage.qml</file>
|
||||
<file>ui/images/view-expand.svg</file>
|
||||
<file>ui/images/view-collapse.svg</file>
|
||||
<file>ui/magic/SelectRuleActionPage.qml</file>
|
||||
<file>ui/magic/SelectRuleActionParamsPage.qml</file>
|
||||
<file>ui/images/tick.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "rulemanager.h"
|
||||
|
||||
#include "jsonrpc/jsonrpcclient.h"
|
||||
#include "jsonrpc/jsontypes.h"
|
||||
#include "types/rule.h"
|
||||
#include "types/eventdescriptor.h"
|
||||
#include "types/eventdescriptors.h"
|
||||
|
|
@ -49,6 +50,12 @@ void RuleManager::addRule(const QVariantMap params)
|
|||
m_jsonClient->sendCommand("Rules.AddRule", params, this, "addRuleReply");
|
||||
}
|
||||
|
||||
void RuleManager::addRule(Rule *rule)
|
||||
{
|
||||
QVariantMap params = JsonTypes::packRule(rule);
|
||||
m_jsonClient->sendCommand("Rules.AddRule", params, this, "addRuleReply");
|
||||
}
|
||||
|
||||
void RuleManager::removeRule(const QUuid &ruleId)
|
||||
{
|
||||
QVariantMap params;
|
||||
|
|
@ -56,6 +63,13 @@ void RuleManager::removeRule(const QUuid &ruleId)
|
|||
m_jsonClient->sendCommand("Rules.RemoveRule", params, this, "removeRuleReply");
|
||||
}
|
||||
|
||||
void RuleManager::editRule(Rule *rule)
|
||||
{
|
||||
QVariantMap params = JsonTypes::packRule(rule);
|
||||
m_jsonClient->sendCommand("Rules.EditRule", params, this, "editRuleReply");
|
||||
|
||||
}
|
||||
|
||||
void RuleManager::handleRulesNotification(const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "rules notification received" << params;
|
||||
|
|
@ -124,6 +138,11 @@ void RuleManager::removeRuleReply(const QVariantMap ¶ms)
|
|||
qDebug() << "Have remove rule reply" << params;
|
||||
}
|
||||
|
||||
void RuleManager::editRuleReply(const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Edit rule reply:" << params;
|
||||
}
|
||||
|
||||
void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList, Rule *rule)
|
||||
{
|
||||
foreach (const QVariant &eventDescriptorVariant, eventDescriptorList) {
|
||||
|
|
@ -156,9 +175,10 @@ StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluat
|
|||
op = StateDescriptor::ValueOperatorGreaterOrEqual;
|
||||
}
|
||||
StateDescriptor *sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), op, sdMap.value("stateTypeId").toUuid(), sdMap.value("value"), stateEvaluator);
|
||||
// stateEvaluator->
|
||||
stateEvaluator->setStateDescriptor(sd);
|
||||
|
||||
}
|
||||
return stateEvaluator;
|
||||
}
|
||||
|
||||
void RuleManager::parseRuleActions(const QVariantList &ruleActions, Rule *rule)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ public:
|
|||
Q_INVOKABLE Rule* createNewRule();
|
||||
|
||||
Q_INVOKABLE void addRule(const QVariantMap params);
|
||||
Q_INVOKABLE void addRule(Rule *rule);
|
||||
Q_INVOKABLE void removeRule(const QUuid &ruleId);
|
||||
Q_INVOKABLE void editRule(Rule *rule);
|
||||
|
||||
private slots:
|
||||
void handleRulesNotification(const QVariantMap ¶ms);
|
||||
|
|
@ -35,6 +37,7 @@ private slots:
|
|||
void getRuleDetailsReply(const QVariantMap ¶ms);
|
||||
void addRuleReply(const QVariantMap ¶ms);
|
||||
void removeRuleReply(const QVariantMap ¶ms);
|
||||
void editRuleReply(const QVariantMap ¶ms);
|
||||
|
||||
private:
|
||||
void parseEventDescriptors(const QVariantList &eventDescriptorList, Rule *rule);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,12 @@ Page {
|
|||
|
||||
HeaderButton {
|
||||
imageSource: Qt.resolvedUrl("images/add.svg")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("magic/NewRulePage.qml"), {rule: Engine.ruleManager.createNewRule() })
|
||||
onClicked: {
|
||||
var newRulePage = pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: Engine.ruleManager.createNewRule() });
|
||||
newRulePage.onAccept.connect(function() {
|
||||
Engine.ruleManager.addRule(newRulePage.rule);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -19,15 +24,37 @@ Page {
|
|||
anchors.fill: parent
|
||||
|
||||
model: Engine.ruleManager.rules
|
||||
delegate: ItemDelegate {
|
||||
delegate: SwipeDelegate {
|
||||
width: parent.width
|
||||
Label {
|
||||
text: model.name
|
||||
}
|
||||
text: model.name
|
||||
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: Engine.ruleManager.rules.get(index) })
|
||||
var editRulePage = pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: Engine.ruleManager.rules.get(index) })
|
||||
editRulePage.onAccept.connect(function() {
|
||||
Engine.ruleManager.editRule(editRulePage.rule);
|
||||
})
|
||||
}
|
||||
|
||||
// swipe.right: ColorIcon {
|
||||
// name: "delete.svg"
|
||||
// color: "red"
|
||||
// }
|
||||
|
||||
swipe.right: Label {
|
||||
id: deleteLabel
|
||||
text: qsTr("Delete")
|
||||
color: "white"
|
||||
verticalAlignment: Label.AlignVCenter
|
||||
padding: 12
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
|
||||
SwipeDelegate.onClicked: Engine.ruleManager.removeRule(model.id)
|
||||
|
||||
background: Rectangle {
|
||||
color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg4874" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="96" viewBox="0 0 96 96.000001" width="96" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata id="metadata4879">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g id="layer1" transform="translate(67.857 -78.505)">
|
||||
<rect id="rect4782" style="color:#000000;fill:none" transform="rotate(90)" height="96" width="96" y="-28.143" x="78.505"/>
|
||||
<path id="path4041-9" style="fill:#808080" d="m21.228 99.016-46.196 41.447-26.606-23.802-4.2834 4.8422 30.878 32.49 49.122-51.691z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 936 B |
|
|
@ -1,36 +1,167 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.1
|
||||
import "../components"
|
||||
import QtQuick.Layouts 1.2
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
|
||||
property var rule: null
|
||||
|
||||
signal accept();
|
||||
|
||||
function addEventDescriptor() {
|
||||
var eventDescriptor = root.rule.eventDescriptors.createNewEventDescriptor();
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.onBackPressed.connect(function() { pageStack.pop(); });
|
||||
page.onThingSelected.connect(function(device) {
|
||||
eventDescriptor.deviceId = device.id;
|
||||
selectEventDescriptorData(eventDescriptor)
|
||||
})
|
||||
page.onInterfaceSelected.connect(function(interfaceName) {
|
||||
eventDescriptor.interfaceName = interfaceName;
|
||||
selectEventDescriptorData(eventDescriptor)
|
||||
})
|
||||
}
|
||||
|
||||
function selectEventDescriptorData(eventDescriptor) {
|
||||
var eventPage = pageStack.push(Qt.resolvedUrl("SelectEventPage.qml"), {text: "Select event", eventDescriptor: eventDescriptor});
|
||||
eventPage.onBackPressed.connect(function() {pageStack.pop()})
|
||||
eventPage.onDone.connect(function() {
|
||||
root.rule.eventDescriptors.addEventDescriptor(eventPage.eventDescriptor);
|
||||
pageStack.pop(root)
|
||||
})
|
||||
}
|
||||
|
||||
function addRuleAction() {
|
||||
var ruleAction = root.rule.ruleActions.createNewRuleAction();
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.onBackPressed.connect(function() { pageStack.pop() })
|
||||
page.onThingSelected.connect(function(device) {
|
||||
ruleAction.deviceId = device.id;
|
||||
selectRuleActionData(ruleAction)
|
||||
})
|
||||
page.onInterfaceSelected.connect(function(interfaceName) {
|
||||
ruleAction.interfaceName = interfaceName;
|
||||
selectRuleActionData(ruleAction)
|
||||
})
|
||||
}
|
||||
function selectRuleActionData(ruleAction) {
|
||||
var ruleActionPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionPage.qml"), {text: "Select action", ruleAction: ruleAction });
|
||||
ruleActionPage.onBackPressed.connect(function() {
|
||||
ruleAction.destroy();
|
||||
pageStack.pop(root);
|
||||
})
|
||||
ruleActionPage.onDone.connect(function() {
|
||||
root.rule.ruleActions.addRuleAction(ruleAction)
|
||||
pageStack.pop(root);
|
||||
})
|
||||
}
|
||||
|
||||
header: GuhHeader {
|
||||
text: "Add some magic"
|
||||
text: "New rule"
|
||||
onBackPressed: pageStack.pop()
|
||||
HeaderButton {
|
||||
imageSource: "../images/tick.svg"
|
||||
onClicked: {
|
||||
root.accept()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
Label {
|
||||
text: "When"
|
||||
text: "Rule name"
|
||||
}
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
text: root.rule.name
|
||||
onTextChanged: {
|
||||
root.rule.name = text;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
RadioButton {
|
||||
id: whenButton
|
||||
text: "When"
|
||||
checked: true
|
||||
}
|
||||
RadioButton {
|
||||
id: whileButton
|
||||
text: "While"
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
visible: eventsRepeater.count == 0
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: "Add an event which should trigger the execution of the rule"
|
||||
}
|
||||
Button {
|
||||
text: "+"
|
||||
onClicked: root.addEventDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: rule.eventDescriptors
|
||||
ItemDelegate {
|
||||
property var device: Engine.deviceManager.devices.getDevice(model.deviceId)
|
||||
id: eventsRepeater
|
||||
model: root.rule.eventDescriptors
|
||||
delegate: ItemDelegate {
|
||||
id: eventDelegate
|
||||
property var device: Engine.deviceManager.devices.getDevice(root.rule.eventDescriptors.get(index).deviceId)
|
||||
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(model.eventTypeId) : null
|
||||
property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(root.rule.eventDescriptors.get(index).eventTypeId) : null
|
||||
contentItem: ColumnLayout {
|
||||
Label {
|
||||
text: device ? device.name : "Unknown device"
|
||||
text: eventDelegate.device ? eventDelegate.device.name : "Unknown device" + root.rule.eventDescriptors.get(index).deviceId
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
text: eventType ? eventType.name : "Unknown event"
|
||||
text: eventDelegate.eventType ? eventDelegate.eventType.displayName : "Unknown event" + root.rule.eventDescriptors.get(index).eventTypeId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "do the following:" + root.rule.ruleActions.count
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
visible: actionsRepeater.count == 0
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: "Add action which should be executed when the rule is triggered"
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
Button {
|
||||
text: "+"
|
||||
onClicked: root.addRuleAction();
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: actionsRepeater
|
||||
model: root.rule.ruleActions
|
||||
delegate: ItemDelegate {
|
||||
id: actionDelegate
|
||||
property var device: Engine.deviceManager.devices.getDevice(root.rule.ruleActions.get(index).deviceId)
|
||||
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
property var actionType: deviceClass ? deviceClass.actionTypes.getActionType(root.rule.ruleActions.get(index).actionTypeId) : null
|
||||
contentItem: ColumnLayout {
|
||||
Label {
|
||||
text: actionDelegate.device.name
|
||||
}
|
||||
Label {
|
||||
text: actionDelegate.actionType.displayName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
import QtQuick 2.4
|
||||
import QtQuick.Controls 2.1
|
||||
import "../components"
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
property alias text: header.text
|
||||
|
||||
// a ruleAction object needs to be set and prefilled with either deviceId or interfaceName
|
||||
property var ruleAction: null
|
||||
|
||||
readonly property var device: ruleAction && ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
|
||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
|
||||
signal backPressed();
|
||||
signal done();
|
||||
|
||||
onRuleActionChanged: buildInterface()
|
||||
Component.onCompleted: buildInterface()
|
||||
|
||||
header: GuhHeader {
|
||||
id: header
|
||||
onBackPressed: root.backPressed();
|
||||
|
||||
property bool interfacesMode: true
|
||||
onInterfacesModeChanged: root.buildInterface()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: header.interfacesMode ? "../images/view-expand.svg" : "../images/view-collapse.svg"
|
||||
onClicked: header.interfacesMode = !header.interfacesMode
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: actionTemplateModel
|
||||
ListElement { interfaceName: "light"; text: "Switch light"; identifier: "switchLight"}
|
||||
ListElement { interfaceName: "dimmablelight"; text: "Dim light"; identifier: "dimLight"}
|
||||
ListElement { interfaceName: "colorlight"; text: "Set light color"; identifier: "colorLight" }
|
||||
ListElement { interfaceName: "mediacontroller"; text: "Pause playback"; identifier: "pausePlayback" }
|
||||
ListElement { interfaceName: "mediacontroller"; text: "Resume playback"; identifier: "resumePlayback" }
|
||||
ListElement { interfaceName: "extendedvolumecontroller"; text: "Set volume"; identifier: "setVolume" }
|
||||
ListElement { interfaceName: "extendedvolumecontroller"; text: "Mute"; identifier: "mute" }
|
||||
ListElement { interfaceName: "extendedvolumecontroller"; text: "Unmute"; identifier: "unmute" }
|
||||
ListElement { interfaceName: "notifications"; text: "Notify me"; identifier: "notify" }
|
||||
}
|
||||
|
||||
function buildInterface() {
|
||||
actualModel.clear()
|
||||
|
||||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
print("device supports interfaces", deviceClass.interfaces)
|
||||
for (var i = 0; i < actionTemplateModel.count; i++) {
|
||||
print("action is for interface", actionTemplateModel.get(i).interfaceName)
|
||||
if (deviceClass.interfaces.indexOf(actionTemplateModel.get(i).interfaceName) >= 0) {
|
||||
actualModel.append(actionTemplateModel.get(i))
|
||||
}
|
||||
}
|
||||
} else if (root.ruleAction.interfaceName !== "") {
|
||||
for (var i = 0; i < actionTemplateModel.count; i++) {
|
||||
if (actionTemplateModel.get(i).interfaceName === root.ruleAction.interfaceName) {
|
||||
actualModel.append(actionTemplateModel.get(i))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn("You need to set device or interfaceName");
|
||||
}
|
||||
} else {
|
||||
if (root.device) {
|
||||
print("fdsfasdfdsafdas", deviceClass.actionTypes.count)
|
||||
for (var i = 0; i < deviceClass.actionTypes.count; i++) {
|
||||
print("bla", deviceClass.actionTypes.get(i).name, deviceClass.actionTypes.get(i).displayName, deviceClass.actionTypes.get(i).id)
|
||||
actualModel.append({text: deviceClass.actionTypes.get(i).displayName, actionTypeId: deviceClass.actionTypes.get(i).id})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: actualModel
|
||||
ListElement { text: ""; actionTypeId: "" }
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
model: actualModel
|
||||
|
||||
delegate: ItemDelegate {
|
||||
text: model.text
|
||||
onClicked: {
|
||||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
print("selected:", model.identifier)
|
||||
switch (model.identfier) {
|
||||
case "switchLight":
|
||||
root.done();
|
||||
break;
|
||||
default:
|
||||
console.warn("FIXME: Unhandled interface action");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (root.device) {
|
||||
var actionType = root.deviceClass.actionTypes.getActionType(model.actionTypeId);
|
||||
console.log("ActionType", actionType.id, "selected. Has", actionType.paramTypes.count, "params");
|
||||
root.ruleAction.actionTypeId = actionType.id;
|
||||
if (actionType.paramTypes.count > 0) {
|
||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionParamsPage.qml"), {ruleAction: root.ruleAction})
|
||||
paramsPage.onCompleted.connect(function() {
|
||||
pageStack.pop();
|
||||
root.done();
|
||||
})
|
||||
} else {
|
||||
root.done();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import "../components"
|
||||
import "../paramdelegates"
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
// Needs to be set and filled in with deviceId and actionTypeId
|
||||
property var ruleAction
|
||||
|
||||
readonly property var device: ruleAction && ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
|
||||
readonly property var actionType: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId).actionTypes.getActionType(ruleAction.actionTypeId) : null
|
||||
|
||||
signal backPressed();
|
||||
signal completed();
|
||||
|
||||
header: GuhHeader {
|
||||
text: "params"
|
||||
onBackPressed: root.backPressed();
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
Repeater {
|
||||
id: delegateRepeater
|
||||
model: root.actionType.paramTypes
|
||||
delegate: ParamDelegate {
|
||||
paramType: root.actionType.paramTypes.get(index)
|
||||
value: paramType.defaultValue
|
||||
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Button {
|
||||
text: "OK"
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
onClicked: {
|
||||
var params = [];
|
||||
for (var i = 0; i < delegateRepeater.count; i++) {
|
||||
var paramDelegate = delegateRepeater.itemAt(i);
|
||||
root.ruleAction.ruleActionParams.setRuleActionParam(paramDelegate.paramType.id, paramDelegate.value)
|
||||
}
|
||||
root.completed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ Loader {
|
|||
var comp;
|
||||
switch (loader.paramType.type) {
|
||||
case "bool":
|
||||
case "Bool":
|
||||
comp = "Bool";
|
||||
break;
|
||||
case "String":
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ ActionType::ActionType(QObject *parent) :
|
|||
{
|
||||
}
|
||||
|
||||
QUuid ActionType::id() const
|
||||
QString ActionType::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void ActionType::setId(const QUuid &id)
|
||||
void ActionType::setId(const QString &id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
class ActionType : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid id READ id CONSTANT)
|
||||
Q_PROPERTY(QString id READ id CONSTANT)
|
||||
Q_PROPERTY(QString name READ name CONSTANT)
|
||||
Q_PROPERTY(QString displayName READ displayName CONSTANT)
|
||||
Q_PROPERTY(int index READ index CONSTANT)
|
||||
|
|
@ -40,8 +40,8 @@ class ActionType : public QObject
|
|||
public:
|
||||
explicit ActionType(QObject *parent = 0);
|
||||
|
||||
QUuid id() const;
|
||||
void setId(const QUuid &id);
|
||||
QString id() const;
|
||||
void setId(const QString &id);
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
|
@ -56,7 +56,7 @@ public:
|
|||
void setParamTypes(ParamTypes *paramTypes);
|
||||
|
||||
private:
|
||||
QUuid m_id;
|
||||
QString m_id;
|
||||
QString m_name;
|
||||
QString m_displayName;
|
||||
int m_index;
|
||||
|
|
|
|||
|
|
@ -33,17 +33,12 @@ QList<ActionType *> ActionTypes::actionTypes()
|
|||
return m_actionTypes;
|
||||
}
|
||||
|
||||
int ActionTypes::count() const
|
||||
{
|
||||
return m_actionTypes.count();
|
||||
}
|
||||
|
||||
ActionType *ActionTypes::get(int index) const
|
||||
{
|
||||
return m_actionTypes.at(index);
|
||||
}
|
||||
|
||||
ActionType *ActionTypes::getActionType(const QUuid &actionTypeId) const
|
||||
ActionType *ActionTypes::getActionType(const QString &actionTypeId) const
|
||||
{
|
||||
foreach (ActionType *actionType, m_actionTypes) {
|
||||
if (actionType->id() == actionTypeId) {
|
||||
|
|
@ -68,7 +63,7 @@ QVariant ActionTypes::data(const QModelIndex &index, int role) const
|
|||
if (role == NameRole) {
|
||||
return actionType->name();
|
||||
} else if (role == IdRole) {
|
||||
return actionType->id().toString();
|
||||
return actionType->id();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
|
@ -79,6 +74,7 @@ void ActionTypes::addActionType(ActionType *actionType)
|
|||
//qDebug() << "ActionTypes: loaded actionType" << actionType->name();
|
||||
m_actionTypes.append(actionType);
|
||||
endInsertRows();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
ActionType *ActionTypes::findByName(const QString &name) const
|
||||
|
|
@ -96,6 +92,7 @@ void ActionTypes::clearModel()
|
|||
beginResetModel();
|
||||
m_actionTypes.clear();
|
||||
endResetModel();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ActionTypes::roleNames() const
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
class ActionTypes : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
public:
|
||||
enum ActionTypeRole {
|
||||
NameRole = Qt::DisplayRole,
|
||||
|
|
@ -42,9 +42,8 @@ public:
|
|||
|
||||
QList<ActionType *> actionTypes();
|
||||
|
||||
Q_INVOKABLE int count() const;
|
||||
Q_INVOKABLE ActionType *get(int index) const;
|
||||
Q_INVOKABLE ActionType *getActionType(const QUuid &actionTypeId) const;
|
||||
Q_INVOKABLE ActionType *getActionType(const QString &actionTypeId) const;
|
||||
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
|
|
@ -55,6 +54,9 @@ public:
|
|||
|
||||
void clearModel();
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ void DeviceClass::setActionTypes(ActionTypes *actionTypes)
|
|||
emit actionTypesChanged();
|
||||
}
|
||||
|
||||
bool DeviceClass::hasActionType(const QUuid &actionTypeId)
|
||||
bool DeviceClass::hasActionType(const QString &actionTypeId)
|
||||
{
|
||||
foreach (ActionType *actionType, m_actionTypes->actionTypes()) {
|
||||
if (actionType->id() == actionTypeId) {
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ public:
|
|||
ActionTypes *actionTypes() const;
|
||||
void setActionTypes(ActionTypes *actionTypes);
|
||||
|
||||
Q_INVOKABLE bool hasActionType(const QUuid &actionTypeId);
|
||||
Q_INVOKABLE bool hasActionType(const QString &actionTypeId);
|
||||
|
||||
static QString basicTagToString(BasicTag basicTag);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ QVariant ParamDescriptors::data(const QModelIndex &index, int role) const
|
|||
return QVariant();
|
||||
}
|
||||
|
||||
ParamDescriptor *ParamDescriptors::get(int index) const
|
||||
{
|
||||
return m_list.at(index);
|
||||
}
|
||||
|
||||
ParamDescriptor *ParamDescriptors::createNewParamDescriptor() const
|
||||
{
|
||||
return new ParamDescriptor();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ public:
|
|||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
ParamDescriptor* get(int index) const;
|
||||
|
||||
ParamDescriptor* createNewParamDescriptor() const;
|
||||
void addParamDescriptor(ParamDescriptor* paramDescriptor);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class Rule : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid id READ id CONSTANT)
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
|
||||
Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
|
||||
Q_PROPERTY(EventDescriptors* eventDescriptors READ eventDescriptors CONSTANT)
|
||||
Q_PROPERTY(StateEvaluator* stateEvaluator READ stateEvaluator CONSTANT)
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ class RuleActionParams;
|
|||
class RuleAction : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid deviceId READ deviceId NOTIFY deviceIdChanged)
|
||||
Q_PROPERTY(QUuid actionTypeId READ actionTypeId NOTIFY actionTypeIdChanged)
|
||||
Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
|
||||
Q_PROPERTY(QUuid actionTypeId READ actionTypeId WRITE setActionTypeId NOTIFY actionTypeIdChanged)
|
||||
Q_PROPERTY(RuleActionParams* ruleActionParams READ ruleActionParams CONSTANT)
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -26,6 +26,22 @@ void RuleActionParams::addRuleActionParam(RuleActionParam *ruleActionParam)
|
|||
endInsertRows();
|
||||
}
|
||||
|
||||
void RuleActionParams::setRuleActionParam(const QString ¶mTypeId, const QVariant &value)
|
||||
{
|
||||
foreach (RuleActionParam *rap, m_list) {
|
||||
if (rap->paramTypeId() == paramTypeId) {
|
||||
rap->setValue(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Still here? Need to add it
|
||||
RuleActionParam *rap = new RuleActionParam(this);
|
||||
rap->setParamTypeId(paramTypeId);
|
||||
rap->setValue(value);
|
||||
addRuleActionParam(rap);
|
||||
}
|
||||
|
||||
RuleActionParam *RuleActionParams::get(int index) const
|
||||
{
|
||||
return m_list.at(index);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public:
|
|||
|
||||
void addRuleActionParam(RuleActionParam* ruleActionParam);
|
||||
|
||||
Q_INVOKABLE void setRuleActionParam(const QString ¶mTypeId, const QVariant &value);
|
||||
Q_INVOKABLE RuleActionParam* get(int index) const;
|
||||
|
||||
signals:
|
||||
|
|
|
|||
|
|
@ -28,3 +28,8 @@ RuleAction *RuleActions::get(int index) const
|
|||
{
|
||||
return m_list.at(index);
|
||||
}
|
||||
|
||||
RuleAction *RuleActions::createNewRuleAction() const
|
||||
{
|
||||
return new RuleAction();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ public:
|
|||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
void addRuleAction(RuleAction* ruleAction);
|
||||
Q_INVOKABLE void addRuleAction(RuleAction* ruleAction);
|
||||
|
||||
Q_INVOKABLE RuleAction* get(int index) const;
|
||||
Q_INVOKABLE RuleAction* createNewRuleAction() const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ QVariant Rules::data(const QModelIndex &index, int role) const
|
|||
switch (role) {
|
||||
case RoleName:
|
||||
return m_list.at(index.row())->name();
|
||||
case RoleId:
|
||||
return m_list.at(index.row())->id();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
|
@ -31,6 +33,7 @@ QHash<int, QByteArray> Rules::roleNames() const
|
|||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles.insert(RoleName, "name");
|
||||
roles.insert(RoleId, "id");
|
||||
return roles;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ class Rules : public QAbstractListModel
|
|||
Q_OBJECT
|
||||
public:
|
||||
enum Roles {
|
||||
RoleName
|
||||
RoleName,
|
||||
RoleId
|
||||
};
|
||||
explicit Rules(QObject *parent = nullptr);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue