diff --git a/libnymea-app-core/ruletemplates/ruletemplates.cpp b/libnymea-app-core/ruletemplates/ruletemplates.cpp index 10a26e8b..6ec4fd20 100644 --- a/libnymea-app-core/ruletemplates/ruletemplates.cpp +++ b/libnymea-app-core/ruletemplates/ruletemplates.cpp @@ -21,10 +21,7 @@ RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent) RuleTemplate* t; EventDescriptorTemplate* evt; ParamDescriptor* evpt; - StateEvaluatorTemplate* set; RuleActionTemplate* rat; - RuleActionTemplate* reat; // exit - RuleActionParamTemplate* rapt; RuleActionParamTemplates* rapts; QDir ruleTemplatesDir(":/ruletemplates"); @@ -77,20 +74,7 @@ RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent) // StateEvaluatorTemplate if (ruleTemplate.contains("stateEvaluatorTemplate")) { - QVariantMap stateEvaluatorTemplate = ruleTemplate.value("stateEvaluatorTemplate").toMap(); - QVariantMap stateDescriptorTemplate = stateEvaluatorTemplate.value("stateDescriptorTemplate").toMap(); - QMetaEnum selectionModeEnum = QMetaEnum::fromType(); - QMetaEnum operatorEnum = QMetaEnum::fromType(); - set = new StateEvaluatorTemplate( - new StateDescriptorTemplate( - stateDescriptorTemplate.value("interfaceName").toString(), - stateDescriptorTemplate.value("interfaceState").toString(), - stateDescriptorTemplate.value("selectionId").toInt(), - static_cast(selectionModeEnum.keyToValue(stateDescriptorTemplate.value("selectionMode", "SelectionModeAny").toByteArray().data())), - static_cast(operatorEnum.keyToValue(stateDescriptorTemplate.value("operator").toByteArray().data())), - stateDescriptorTemplate.value("value"))); - t->setStateEvaluatorTemplate(set); - // TODO: Child evaluators not supported yet + t->setStateEvaluatorTemplate(loadStateEvaluatorTemplate(ruleTemplate.value("stateEvaluatorTemplate").toMap())); } // RuleActionTemplates @@ -190,6 +174,35 @@ RuleTemplate *RuleTemplates::get(int index) const return m_list.at(index); } +StateEvaluatorTemplate *RuleTemplates::loadStateEvaluatorTemplate(const QVariantMap &stateEvaluatorTemplate) const +{ + QVariantMap stateDescriptorTemplate = stateEvaluatorTemplate.value("stateDescriptorTemplate").toMap(); + QMetaEnum selectionModeEnum = QMetaEnum::fromType(); + QMetaEnum stateOperatorEnum = QMetaEnum::fromType(); + QMetaEnum valueOperatorEnum = QMetaEnum::fromType(); + StateEvaluatorTemplate::StateOperator stateOperator = StateEvaluatorTemplate::StateOperatorAnd; + if (stateEvaluatorTemplate.contains("stateOperatorTemplate")) { + stateOperator = static_cast(stateOperatorEnum.keyToValue(stateEvaluatorTemplate.value("stateOperatorTemplate").toByteArray().data())); + } + + StateEvaluatorTemplate *set = new StateEvaluatorTemplate( + new StateDescriptorTemplate( + stateDescriptorTemplate.value("interfaceName").toString(), + stateDescriptorTemplate.value("interfaceState").toString(), + stateDescriptorTemplate.value("selectionId").toInt(), + static_cast(selectionModeEnum.keyToValue(stateDescriptorTemplate.value("selectionMode", "SelectionModeAny").toByteArray().data())), + static_cast(valueOperatorEnum.keyToValue(stateDescriptorTemplate.value("operator").toByteArray().data())), + stateDescriptorTemplate.value("value")), + stateOperator + ); + foreach (const QVariant &childVariant, stateEvaluatorTemplate.value("childEvaluatorTemplates").toList()) { + QVariantMap childMap = childVariant.toMap(); + set->childEvaluatorTemplates()->addStateEvaluatorTemplate(loadStateEvaluatorTemplate(childMap.value("stateEvaluatorTemplate").toMap())); + } + + return set; +} + bool RuleTemplatesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { Q_UNUSED(source_parent) @@ -212,7 +225,7 @@ bool RuleTemplatesFilterModel::filterAcceptsRow(int source_row, const QModelInde } } if (!found) { - qDebug() << "Filtering out" << t->description() << "because required devices are not provided in filter proxy"; + qDebug() << "Filtering out" << t->description() << "because required no device in the provided filter proxy implements" << toBeFound; return false; } } diff --git a/libnymea-app-core/ruletemplates/ruletemplates.h b/libnymea-app-core/ruletemplates/ruletemplates.h index d327847d..a7777716 100644 --- a/libnymea-app-core/ruletemplates/ruletemplates.h +++ b/libnymea-app-core/ruletemplates/ruletemplates.h @@ -28,6 +28,9 @@ public: signals: void countChanged(); +private: + StateEvaluatorTemplate* loadStateEvaluatorTemplate(const QVariantMap &stateEvaluatorTemplate) const; + private: QList m_list; @@ -65,6 +68,8 @@ signals: void filterInterfaceNamesChanged(); void filterByDevicesChanged(); void countChanged(); + + private: RuleTemplates* m_ruleTemplates = nullptr; QStringList m_filterInterfaceNames; diff --git a/libnymea-common/types/stateevaluators.h b/libnymea-common/types/stateevaluators.h index 07c52e09..fbb15301 100644 --- a/libnymea-common/types/stateevaluators.h +++ b/libnymea-common/types/stateevaluators.h @@ -17,7 +17,7 @@ public: QVariant data(const QModelIndex &index, int role) const override; QHash roleNames() const override; - void addStateEvaluator(StateEvaluator* stateEvaluator); + Q_INVOKABLE void addStateEvaluator(StateEvaluator* stateEvaluator); Q_INVOKABLE StateEvaluator* get(int index) const; // Caller takes ownership, is responsible for deleting diff --git a/nymea-app/ruletemplates.qrc b/nymea-app/ruletemplates.qrc index 115382d3..e86cba88 100644 --- a/nymea-app/ruletemplates.qrc +++ b/nymea-app/ruletemplates.qrc @@ -6,7 +6,8 @@ ruletemplates/smartmetertemplates.json ruletemplates/presencesensortemplates.json ruletemplates/daylightsensor.json - ruletemplates/lighttemplates.json + ruletemplates/thermostattemplates.json + ruletemplates/mediatemplates.json ruletemplates/doorbellruletemplates.json diff --git a/nymea-app/ruletemplates/lighttemplates.json b/nymea-app/ruletemplates/lighttemplates.json deleted file mode 100644 index bfd870e4..00000000 --- a/nymea-app/ruletemplates/lighttemplates.json +++ /dev/null @@ -1,3 +0,0 @@ -{ -} - diff --git a/nymea-app/ruletemplates/mediatemplates.json b/nymea-app/ruletemplates/mediatemplates.json new file mode 100644 index 00000000..bd17f1cd --- /dev/null +++ b/nymea-app/ruletemplates/mediatemplates.json @@ -0,0 +1,69 @@ +{ + "templates": [ + { + "description": "Dim light while watching TV", + "ruleNameTemplate": "%0 dims %1 for movie time", + "stateEvaluatorTemplate": { + "stateDescriptorTemplate": { + "interfaceName": "mediaplayer", + "interfaceState": "playbackStatus", + "selectionId": 0, + "operator": "ValueOperatorEquals", + "value": "Playing" + }, + "stateOperatorTemplate": "StateOperatorAnd", + "childEvaluatorTemplates": [ + { + "stateEvaluatorTemplate": { + "stateDescriptorTemplate": { + "interfaceName": "mediaplayer", + "interfaceState": "playerType", + "selectionId": 0, + "operator": "ValueOperatorEquals", + "value": "video" + } + } + } + ] + }, + "ruleActionTemplates": [ + { + "interfaceName": "dimmablelight", + "interfaceAction": "power", + "selectionId": 1, + "params": [ + { + "name": "power", + "value": false + } + ] + } + ], + "ruleExitActionTemplates": [ + { + "interfaceName": "dimmablelight", + "interfaceAction": "power", + "selectionId": 1, + "params": [ + { + "name": "power", + "value": true + } + ] + }, + { + "interfaceName": "dimmablelight", + "interfaceAction": "brightness", + "selectionId": 1, + "params": [ + { + "name": "brightness", + "value": "50" + } + ] + } + ] + } + ] +} + diff --git a/nymea-app/ruletemplates/thermostattemplates.json b/nymea-app/ruletemplates/thermostattemplates.json new file mode 100644 index 00000000..252462d1 --- /dev/null +++ b/nymea-app/ruletemplates/thermostattemplates.json @@ -0,0 +1,38 @@ +{ + "templates": [ + { + "description": "Set temperature while I'm home", + "ruleNameTemplate": "Set temperature while I'm home", + "stateEvaluatorTemplate": { + "stateDescriptorTemplate": { + "interfaceName": "presencesensor", + "interfaceState": "isPresent", + "selectionId": 0, + "operator": "ValueOperatorEquals", + "value": true + } + }, + "ruleActionTemplates": [ + { + "interfaceName": "thermostat", + "interfaceAction": "targetTemperature", + "selectionId": 1 + } + ], + "ruleExitActionTemplates": [ + { + "interfaceName": "thermostat", + "interfaceAction": "targetTemperature", + "selectionId": 1, + "params": [ + { + "name": "targetTemperature", + "value": "16" + } + ] + } + ] + } + ] +} + diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index 1ee43b5d..7e03e682 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -277,6 +277,9 @@ ApplicationWindow { function interfaceToDisplayName(name) { switch (name) { case "light": + case "dimmablelight": + case "colorlight": + case "colortemperaturelight": return qsTr("light") case "button": return "button"; diff --git a/nymea-app/ui/magic/NewThingMagicPage.qml b/nymea-app/ui/magic/NewThingMagicPage.qml index eb9f5287..02fdbf41 100644 --- a/nymea-app/ui/magic/NewThingMagicPage.qml +++ b/nymea-app/ui/magic/NewThingMagicPage.qml @@ -265,10 +265,14 @@ Page { return true; } stateEvaluator.stateOperator = stateEvaluatorTemplate.stateOperator; + print("Added stateOperator", stateEvaluator.stateOperator) if (stateEvaluatorTemplate.childEvaluatorTemplates.count > stateEvaluator.childEvaluators.count) { + print("Adding more child evaluators. Have:", stateEvaluator.childEvaluators.count, "need:", stateEvaluatorTemplate.childEvaluatorTemplates.count) + print("getting", stateEvaluator.childEvaluators.count) + print("getting", stateEvaluatorTemplate.childEvaluatorTemplates.get(stateEvaluator.childEvaluators.count)) var childEvaluator = rule.createStateEvaluator(); - var more = fillStateEvaluatorFromTemplate(rule, ruleTemplate, childEvaluator, stateEvaluatorTemplate.childEvaluatorTemplates.get(stateEvaluator.childEvaluators.count)) stateEvaluator.childEvaluators.addStateEvaluator(childEvaluator); + var more = fillStateEvaluatorFromTemplate(rule, ruleTemplate, childEvaluator, stateEvaluatorTemplate.childEvaluatorTemplates.get(stateEvaluator.childEvaluators.count-1)) return more; } return false;