From 89d301d25a3546436c83ce14660831c98d3afc5b Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 2 Dec 2017 17:33:05 +0100 Subject: [PATCH] more work --- guh-control/models/rulesfiltermodel.cpp | 3 +- guh-control/rulemanager.cpp | 31 +++++++++ guh-control/rulemanager.h | 2 + guh-control/ui/magic/NewThingMagicPage.qml | 21 ++++++- guh-control/ui/magic/SelectActionPage.qml | 73 ++++++++++++++++++++++ libguh-common/libguh-common.pro | 10 ++- libguh-common/types/rule.cpp | 7 +++ libguh-common/types/rule.h | 4 ++ libguh-common/types/statedescriptor.cpp | 31 +++++++++ libguh-common/types/statedescriptor.h | 41 ++++++++++++ libguh-common/types/stateevaluator.cpp | 42 +++++++++++++ libguh-common/types/stateevaluator.h | 40 ++++++++++++ libguh-common/types/stateevaluators.cpp | 27 ++++++++ libguh-common/types/stateevaluators.h | 23 +++++++ 14 files changed, 351 insertions(+), 4 deletions(-) create mode 100644 libguh-common/types/statedescriptor.cpp create mode 100644 libguh-common/types/statedescriptor.h create mode 100644 libguh-common/types/stateevaluator.cpp create mode 100644 libguh-common/types/stateevaluator.h create mode 100644 libguh-common/types/stateevaluators.cpp create mode 100644 libguh-common/types/stateevaluators.h diff --git a/guh-control/models/rulesfiltermodel.cpp b/guh-control/models/rulesfiltermodel.cpp index 2c5d16db..c7ab5ff8 100644 --- a/guh-control/models/rulesfiltermodel.cpp +++ b/guh-control/models/rulesfiltermodel.cpp @@ -3,6 +3,7 @@ #include "types/rule.h" #include "types/eventdescriptors.h" #include "types/eventdescriptor.h" +#include "types/stateevaluator.h" #include @@ -58,7 +59,7 @@ bool RulesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &sourc break; } } - if (!found) { + if (!found && !rule->stateEvaluator()->containsDevice(m_filterEventDeviceId)) { return false; } } diff --git a/guh-control/rulemanager.cpp b/guh-control/rulemanager.cpp index adc027fc..5ee3c3e8 100644 --- a/guh-control/rulemanager.cpp +++ b/guh-control/rulemanager.cpp @@ -8,6 +8,8 @@ #include "types/ruleaction.h" #include "types/ruleactionparams.h" #include "types/ruleactionparam.h" +#include "types/stateevaluator.h" +#include "types/statedescriptor.h" RuleManager::RuleManager(JsonRpcClient* jsonClient, QObject *parent) : JsonHandler(parent), @@ -61,6 +63,9 @@ void RuleManager::handleRulesNotification(const QVariantMap ¶ms) rule->setName(name); rule->setEnabled(enabled); parseEventDescriptors(ruleMap.value("eventDescriptors").toList(), rule); + StateEvaluator* stateEvaluator = parseStateEvaluator(ruleMap.value("stateEvaluator").toMap()); + stateEvaluator->setParent(rule); + parseRuleActions(ruleMap.value("actions").toList(), rule); m_rules->insert(rule); } else if (params.value("notification").toString() == "Rules.RuleRemoved") { @@ -125,6 +130,32 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList, } } +StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluatorMap) +{ + StateEvaluator *stateEvaluator = new StateEvaluator(this); + if (stateEvaluatorMap.contains("stateDescriptor")) { + QVariantMap sdMap = stateEvaluatorMap.value("sateDescriptor").toMap(); + QString operatorString = sdMap.value("stateOperator").toString(); + StateDescriptor::ValueOperator op; + if (operatorString == "ValueOperatorEquals") { + op = StateDescriptor::ValueOperatorEquals; + } else if (operatorString == "ValueOperatorNotEquals") { + op = StateDescriptor::ValueOperatorNotEquals; + } else if (operatorString == "ValueOperatorLess") { + op = StateDescriptor::ValueOperatorLess; + } else if (operatorString == "ValueOperatorGreater") { + op = StateDescriptor::ValueOperatorGreater; + } else if (operatorString == "ValueOperatorLessOrEqual") { + op = StateDescriptor::ValueOperatorLessOrEqual; + } else if (operatorString == "ValueOperatorGreaterOrEqual") { + op = StateDescriptor::ValueOperatorGreaterOrEqual; + } + StateDescriptor *sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), op, sdMap.value("stateTypeId").toUuid(), sdMap.value("value"), stateEvaluator); +// stateEvaluator-> + + } +} + void RuleManager::parseRuleActions(const QVariantList &ruleActions, Rule *rule) { foreach (const QVariant &ruleActionVariant, ruleActions) { diff --git a/guh-control/rulemanager.h b/guh-control/rulemanager.h index cbf4a9ea..9e24e041 100644 --- a/guh-control/rulemanager.h +++ b/guh-control/rulemanager.h @@ -7,6 +7,7 @@ #include "jsonrpc/jsonhandler.h" class JsonRpcClient; +class StateEvaluator; class RuleManager : public JsonHandler { @@ -35,6 +36,7 @@ private slots: private: void parseEventDescriptors(const QVariantList &eventDescriptorList, Rule *rule); + StateEvaluator* parseStateEvaluator(const QVariantMap &stateEvaluatorMap); void parseRuleActions(const QVariantList &ruleActions, Rule *rule); private: diff --git a/guh-control/ui/magic/NewThingMagicPage.qml b/guh-control/ui/magic/NewThingMagicPage.qml index 3936a2e6..0848eb4a 100644 --- a/guh-control/ui/magic/NewThingMagicPage.qml +++ b/guh-control/ui/magic/NewThingMagicPage.qml @@ -19,6 +19,7 @@ Page { ListElement { interfaceName: "temperaturesensor"; text: "When it's freezing..."; identifier: "freeze"} ListElement { interfaceName: "battery"; text: "When the device runs out of battery..."; identifier: "lowBattery"} ListElement { interfaceName: "weather"; text: "When it starts raining..."; identifier: "rain" } + ListElement { interfaceName: "weather"; text: "When it's freezing..."; identifier: "freeze"} } ListModel { @@ -37,7 +38,25 @@ Page { function entrySelected(identifier) { switch (identifier) { case "freeze": - pageStack.push(Qt.resolvedUrl("SelectActionPage.qml"), {device: root.device }) + var page = pageStack.push(Qt.resolvedUrl("SelectActionPage.qml"), {device: root.device }) + page.complete.connect(function() { + print("have action:", page.actions.length) + var rule = {}; + rule["name"] = "Freeze in " + root.device.name + var stateEvaluator = {}; + var stateDescriptor = {}; + stateDescriptor["deviceId"] = root.device.id; + stateDescriptor["operator"] = "ValueOperatorLessOrEqual"; + stateDescriptor["stateTypeId"] = root.deviceClass.stateTypes.findByName("temperature").id; + stateDescriptor["value"] = 0; + stateEvaluator["stateDescriptor"] = stateDescriptor; + + rule["stateEvaluator"] = stateEvaluator; + rule["actions"] = page.actions; + Engine.ruleManager.addRule(rule); + pageStack.pop(root); + + }) } } diff --git a/guh-control/ui/magic/SelectActionPage.qml b/guh-control/ui/magic/SelectActionPage.qml index a4275e2d..684b8048 100644 --- a/guh-control/ui/magic/SelectActionPage.qml +++ b/guh-control/ui/magic/SelectActionPage.qml @@ -57,6 +57,8 @@ Page { case "manualAction": pageStack.push(selectDeviceComponent) break; + case "notify": + pageStack.push(notificationActionComponent) } } @@ -296,4 +298,75 @@ Page { } } } + + Component { + id: notificationActionComponent + Page { + header: GuhHeader { + text: "Send notification" + onBackPressed: pageStack.pop() + } + + ColumnLayout { + anchors.fill: parent + spacing: app.margins + Label { + Layout.fillWidth: true + text: "Notification text" + Layout.topMargin: app.margins + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + } + TextField { + id: notificationTextField + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + } + ThinDivider {} + Flickable { + Layout.fillHeight: true + Layout.fillWidth: true + interactive: contentHeight > height + clip: true + + Column { + width: parent.width + + Repeater { + id: notificationsRepeater + + model: DevicesProxy { + id: notificationsModel + devices: Engine.deviceManager.devices + filterInterface: "notifications" + } + delegate: CheckDelegate { + width: parent.width + text: model.name + checked: true + } + } + } + } + Button { + Layout.fillWidth: true + Layout.margins: app.margins + text: "OK" + onClicked: { + var action = {} + action["interface"] = "notifications"; + action["interfaceAction"] = "notify"; + action["ruleActionParams"] = []; + var ruleActionParam = {}; + ruleActionParam["paramName"] = "title"; + ruleActionParam["value"] = notificationTextField.text + action["ruleActionParams"].push(ruleActionParam) + root.actions.push(action) + root.complete() + } + } + } + } + } } diff --git a/libguh-common/libguh-common.pro b/libguh-common/libguh-common.pro index 60dbf1cd..4675623c 100644 --- a/libguh-common/libguh-common.pro +++ b/libguh-common/libguh-common.pro @@ -37,7 +37,10 @@ HEADERS += types/types.h \ types/ruleactions.h \ types/ruleactionparams.h \ types/ruleactionparam.h \ - types/logentry.h + types/logentry.h \ + types/stateevaluators.h \ + types/stateevaluator.h \ + types/statedescriptor.h SOURCES += types/vendor.cpp \ types/vendors.cpp \ @@ -66,7 +69,10 @@ SOURCES += types/vendor.cpp \ types/ruleactions.cpp \ types/ruleactionparams.cpp \ types/ruleactionparam.cpp \ - types/logentry.cpp + types/logentry.cpp \ + types/stateevaluators.cpp \ + types/stateevaluator.cpp \ + types/statedescriptor.cpp # install header file with relative subdirectory for(header, HEADERS) { diff --git a/libguh-common/types/rule.cpp b/libguh-common/types/rule.cpp index 8ccc9e5a..7a3e8243 100644 --- a/libguh-common/types/rule.cpp +++ b/libguh-common/types/rule.cpp @@ -2,11 +2,13 @@ #include "eventdescriptors.h" #include "ruleactions.h" +#include "stateevaluator.h" Rule::Rule(const QUuid &id, QObject *parent) : QObject(parent), m_id(id), m_eventDescriptors(new EventDescriptors(this)), + m_stateEvaluator(new StateEvaluator(this)), m_ruleActions(new RuleActions(this)) { @@ -48,6 +50,11 @@ EventDescriptors *Rule::eventDescriptors() const return m_eventDescriptors; } +StateEvaluator *Rule::stateEvaluator() const +{ + return m_stateEvaluator; +} + RuleActions *Rule::ruleActions() const { return m_ruleActions; diff --git a/libguh-common/types/rule.h b/libguh-common/types/rule.h index c1a6fefc..dae6d241 100644 --- a/libguh-common/types/rule.h +++ b/libguh-common/types/rule.h @@ -6,6 +6,7 @@ class EventDescriptors; class RuleActions; +class StateEvaluator; class Rule : public QObject { @@ -14,6 +15,7 @@ class Rule : public QObject Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) Q_PROPERTY(EventDescriptors* eventDescriptors READ eventDescriptors CONSTANT) + Q_PROPERTY(StateEvaluator* stateEvaluator READ stateEvaluator CONSTANT) Q_PROPERTY(RuleActions* ruleActions READ ruleActions CONSTANT) public: explicit Rule(const QUuid &id, QObject *parent = nullptr); @@ -27,6 +29,7 @@ public: void setEnabled(bool enabled); EventDescriptors* eventDescriptors() const; + StateEvaluator *stateEvaluator() const; RuleActions* ruleActions() const; signals: @@ -38,6 +41,7 @@ private: QString m_name; bool m_enabled = false; EventDescriptors *m_eventDescriptors = nullptr; + StateEvaluator *m_stateEvaluator = nullptr; RuleActions *m_ruleActions = nullptr; }; diff --git a/libguh-common/types/statedescriptor.cpp b/libguh-common/types/statedescriptor.cpp new file mode 100644 index 00000000..04557459 --- /dev/null +++ b/libguh-common/types/statedescriptor.cpp @@ -0,0 +1,31 @@ +#include "statedescriptor.h" + +StateDescriptor::StateDescriptor(const QUuid &deviceId, StateDescriptor::ValueOperator valueOperator, const QUuid &stateTypeId, const QVariant &value, QObject *parent): + QObject(parent), + m_deviceId(deviceId), + m_operator(valueOperator), + m_stateTypeId(stateTypeId), + m_value(value) +{ + +} + +QUuid StateDescriptor::deviceId() const +{ + return m_deviceId; +} + +StateDescriptor::ValueOperator StateDescriptor::valueOperator() const +{ + return m_operator; +} + +QUuid StateDescriptor::stateTypeId() const +{ + return m_stateTypeId; +} + +QVariant StateDescriptor::value() const +{ + return m_value; +} diff --git a/libguh-common/types/statedescriptor.h b/libguh-common/types/statedescriptor.h new file mode 100644 index 00000000..7cbb0963 --- /dev/null +++ b/libguh-common/types/statedescriptor.h @@ -0,0 +1,41 @@ +#ifndef STATEDESCRIPTOR_H +#define STATEDESCRIPTOR_H + +#include +#include +#include + +class StateDescriptor : public QObject +{ + Q_OBJECT + Q_PROPERTY(QUuid deviceId READ deviceId CONSTANT) + Q_PROPERTY(ValueOperator valueOperator READ valueOperator CONSTANT) + Q_PROPERTY(QUuid stateTypeId READ stateTypeId CONSTANT) + Q_PROPERTY(QVariant value READ value CONSTANT) + +public: + enum ValueOperator { + ValueOperatorEquals, + ValueOperatorNotEquals, + ValueOperatorLess, + ValueOperatorGreater, + ValueOperatorLessOrEqual, + ValueOperatorGreaterOrEqual + }; + Q_ENUM(ValueOperator) + + explicit StateDescriptor(const QUuid &deviceId, ValueOperator valueOperator, const QUuid &stateTypeId, const QVariant &value, QObject *parent = nullptr); + + QUuid deviceId() const; + ValueOperator valueOperator() const; + QUuid stateTypeId() const; + QVariant value() const; + +private: + QUuid m_deviceId; + ValueOperator m_operator = ValueOperatorEquals; + QUuid m_stateTypeId; + QVariant m_value; +}; + +#endif // STATEDESCRIPTOR_H diff --git a/libguh-common/types/stateevaluator.cpp b/libguh-common/types/stateevaluator.cpp new file mode 100644 index 00000000..2a891d9b --- /dev/null +++ b/libguh-common/types/stateevaluator.cpp @@ -0,0 +1,42 @@ +#include "stateevaluator.h" +#include "stateevaluators.h" +#include "statedescriptor.h" + +StateEvaluator::StateEvaluator(QObject *parent) : QObject(parent) +{ + m_childEvaluators = new StateEvaluators(this); +// m_stateDescriptor = new StateDescriptor(this); +} + +StateEvaluator::StateOperator StateEvaluator::stateOperator() const +{ + return m_operator; +} + +void StateEvaluator::setStateOperator(StateEvaluator::StateOperator stateOperator) +{ + m_operator = stateOperator; +} + +StateEvaluators *StateEvaluator::childEvaluators() const +{ + return m_childEvaluators; +} + +StateDescriptor *StateEvaluator::stateDescriptor() const +{ + return m_stateDescriptor; +} + +bool StateEvaluator::containsDevice(const QUuid &deviceId) const +{ + if (m_stateDescriptor->deviceId() == deviceId) { + return true; + } + for (int i = 0; i < m_childEvaluators->rowCount(); i++) { + if (m_childEvaluators->get(i)->containsDevice(deviceId)) { + return true; + } + } + return false; +} diff --git a/libguh-common/types/stateevaluator.h b/libguh-common/types/stateevaluator.h new file mode 100644 index 00000000..10880a5f --- /dev/null +++ b/libguh-common/types/stateevaluator.h @@ -0,0 +1,40 @@ +#ifndef STATEEVALUATOR_H +#define STATEEVALUATOR_H + +#include + +class StateEvaluators; +class StateDescriptor; + +class StateEvaluator : public QObject +{ + Q_OBJECT + Q_PROPERTY(StateOperator stateOperator READ stateOperator CONSTANT) + Q_PROPERTY(StateEvaluators* childEvaluators READ childEvaluators CONSTANT) + Q_PROPERTY(StateDescriptor* stateDescriptor READ stateDescriptor CONSTANT) + +public: + enum StateOperator { + StateOperatorAnd, + StateOperatorOr + }; + Q_ENUM(StateOperator) + explicit StateEvaluator(QObject *parent = nullptr); + + StateOperator stateOperator() const; + void setStateOperator(StateOperator stateOperator); + + StateEvaluators* childEvaluators() const; + + StateDescriptor* stateDescriptor() const; + + bool containsDevice(const QUuid &deviceId) const; + +private: + StateOperator m_operator = StateOperatorAnd; + StateEvaluators *m_childEvaluators = nullptr; + StateDescriptor *m_stateDescriptor = nullptr; + +}; + +#endif // STATEEVALUATOR_H diff --git a/libguh-common/types/stateevaluators.cpp b/libguh-common/types/stateevaluators.cpp new file mode 100644 index 00000000..d6608cab --- /dev/null +++ b/libguh-common/types/stateevaluators.cpp @@ -0,0 +1,27 @@ +#include "stateevaluators.h" + +StateEvaluators::StateEvaluators(QObject *parent) : QAbstractListModel(parent) +{ + +} + +int StateEvaluators::rowCount(const QModelIndex &parent) const +{ + return m_list.count(); +} + +QVariant StateEvaluators::data(const QModelIndex &index, int role) const +{ + return QVariant(); +} + +QHash StateEvaluators::roleNames() const +{ + QHash roles; + return roles; +} + +StateEvaluator *StateEvaluators::get(int index) const +{ + return m_list.at(index); +} diff --git a/libguh-common/types/stateevaluators.h b/libguh-common/types/stateevaluators.h new file mode 100644 index 00000000..d2e3094f --- /dev/null +++ b/libguh-common/types/stateevaluators.h @@ -0,0 +1,23 @@ +#ifndef STATEEVALUATORS_H +#define STATEEVALUATORS_H + +#include + +class StateEvaluator; + +class StateEvaluators : public QAbstractListModel +{ + Q_OBJECT +public: + explicit StateEvaluators(QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + + StateEvaluator* get(int index) const; +private: + QList m_list; +}; + +#endif // STATEEVALUATORS_H