From 6e0291c7e2859c4d8af80a6fb7b218eccce07664 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 4 Oct 2018 14:11:15 +0200 Subject: [PATCH] fingerprint reader rule templates --- libnymea-app-core/devicemanager.cpp | 4 +- libnymea-app-core/jsonrpc/jsonrpcclient.cpp | 2 +- libnymea-app-core/libnymea-app-core.h | 3 + libnymea-app-core/libnymea-app-core.pro | 6 +- .../ruletemplates/ruleactionparamtemplate.cpp | 51 ++++++++++ .../ruletemplates/ruleactionparamtemplate.h | 70 +++++++++++++ .../ruletemplates/ruleactiontemplate.cpp | 12 +-- .../ruletemplates/ruleactiontemplate.h | 12 +-- .../ruletemplates/ruletemplates.cpp | 38 +++++-- libnymea-common/types/param.h | 2 +- libnymea-common/types/ruleactionparam.h | 2 +- nymea-app/nymea-app.pro | 3 +- nymea-app/resources.qrc | 1 + nymea-app/ruletemplates.qrc | 1 + .../ruletemplates/accesscontroltemplates.json | 99 +++++++++++++++++++ nymea-app/ui/Nymea.qml | 2 + .../FingerprintReaderDevicePage.qml | 47 ++++++--- nymea-app/ui/images/fingerprint.svg | 67 +++++++++++++ nymea-app/ui/magic/NewThingMagicPage.qml | 36 ++++++- 19 files changed, 412 insertions(+), 46 deletions(-) create mode 100644 libnymea-app-core/ruletemplates/ruleactionparamtemplate.cpp create mode 100644 libnymea-app-core/ruletemplates/ruleactionparamtemplate.h create mode 100644 nymea-app/ruletemplates/accesscontroltemplates.json create mode 100644 nymea-app/ui/images/fingerprint.svg diff --git a/libnymea-app-core/devicemanager.cpp b/libnymea-app-core/devicemanager.cpp index b9222cb3..18b66f13 100644 --- a/libnymea-app-core/devicemanager.cpp +++ b/libnymea-app-core/devicemanager.cpp @@ -155,7 +155,7 @@ void DeviceManager::getVendorsResponse(const QVariantMap ¶ms) void DeviceManager::getSupportedDevicesResponse(const QVariantMap ¶ms) { - qDebug() << "DeviceClass received:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson(QJsonDocument::Indented)); +// qDebug() << "DeviceClass received:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson(QJsonDocument::Indented)); if (params.value("params").toMap().keys().contains("deviceClasses")) { QVariantList deviceClassList = params.value("params").toMap().value("deviceClasses").toList(); foreach (QVariant deviceClassVariant, deviceClassList) { @@ -168,7 +168,7 @@ void DeviceManager::getSupportedDevicesResponse(const QVariantMap ¶ms) void DeviceManager::getPluginsResponse(const QVariantMap ¶ms) { - qDebug() << "received plugins"; +// qDebug() << "received plugins"; if (params.value("params").toMap().keys().contains("plugins")) { QVariantList pluginList = params.value("params").toMap().value("plugins").toList(); foreach (QVariant pluginVariant, pluginList) { diff --git a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp index 31a293d8..ef2b07a7 100644 --- a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp @@ -303,7 +303,7 @@ void JsonRpcClient::sendRequest(const QVariantMap &request) { QVariantMap newRequest = request; newRequest.insert("token", m_token); -// qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson()); + qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson()); m_connection->sendData(QJsonDocument::fromVariant(newRequest).toJson(QJsonDocument::Compact) + "\n"); } diff --git a/libnymea-app-core/libnymea-app-core.h b/libnymea-app-core/libnymea-app-core.h index 4038784f..6e27fd5c 100644 --- a/libnymea-app-core/libnymea-app-core.h +++ b/libnymea-app-core/libnymea-app-core.h @@ -49,6 +49,7 @@ #include "ruletemplates/stateevaluatortemplate.h" #include "ruletemplates/statedescriptortemplate.h" #include "ruletemplates/ruleactiontemplate.h" +#include "ruletemplates/ruleactionparamtemplate.h" #include "connection/awsclient.h" #include @@ -181,6 +182,8 @@ void registerQmlTypes() { qmlRegisterUncreatableType(uri, 1, 0, "StateDescriptorTemplate", "Get it from StateEvaluatorTemplate"); qmlRegisterUncreatableType(uri, 1, 0, "RuleActionTemplates", "Get it from RuleTemplate"); qmlRegisterUncreatableType(uri, 1, 0, "RuleActionTemplate", "Get it from RuleActionTemplates"); + qmlRegisterUncreatableType(uri, 1, 0, "RuleActionParamTemplates", "Get it from RuleActionTemplate"); + qmlRegisterUncreatableType(uri, 1, 0, "RuleActionParamTemplate", "Get it from RuleActionParamTemplates"); } #endif // LIBNYMEAAPPCORE_H diff --git a/libnymea-app-core/libnymea-app-core.pro b/libnymea-app-core/libnymea-app-core.pro index 22d40baa..451e2091 100644 --- a/libnymea-app-core/libnymea-app-core.pro +++ b/libnymea-app-core/libnymea-app-core.pro @@ -77,7 +77,8 @@ SOURCES += \ ruletemplates/statedescriptortemplate.cpp \ discovery/bluetoothservicediscovery.cpp \ connection/cloudtransport.cpp \ - connection/sigv4utils.cpp + connection/sigv4utils.cpp \ + ruletemplates/ruleactionparamtemplate.cpp HEADERS += \ engine.h \ @@ -134,7 +135,8 @@ HEADERS += \ ruletemplates/stateevaluatortemplate.h \ ruletemplates/statedescriptortemplate.h \ discovery/bluetoothservicediscovery.h \ - connection/cloudtransport.h + connection/cloudtransport.h \ + ruletemplates/ruleactionparamtemplate.h unix { target.path = /usr/lib diff --git a/libnymea-app-core/ruletemplates/ruleactionparamtemplate.cpp b/libnymea-app-core/ruletemplates/ruleactionparamtemplate.cpp new file mode 100644 index 00000000..1012e74b --- /dev/null +++ b/libnymea-app-core/ruletemplates/ruleactionparamtemplate.cpp @@ -0,0 +1,51 @@ +#include "ruleactionparamtemplate.h" + +RuleActionParamTemplate::RuleActionParamTemplate(const QString ¶mName, const QVariant &value, QObject *parent): + RuleActionParam(paramName, value, parent) +{ + +} + +RuleActionParamTemplate::RuleActionParamTemplate(const QString ¶mName, const QString &eventInterface, const QString &eventName, const QString &eventParamName, QObject *parent): + RuleActionParam(parent), + m_eventInterface(eventInterface), + m_eventName(eventName), + m_eventParamName(eventParamName) +{ + setParamName(paramName); +} + +RuleActionParamTemplate::RuleActionParamTemplate(QObject *parent) : RuleActionParam(parent) +{ + +} + +QString RuleActionParamTemplate::eventInterface() const +{ + return m_eventInterface; +} + +void RuleActionParamTemplate::setEventInterface(const QString &eventInterface) +{ + m_eventInterface = eventInterface; +} + +QString RuleActionParamTemplate::eventName() const +{ + return m_eventName; +} + +void RuleActionParamTemplate::setEventName(const QString &eventName) +{ + m_eventName = eventName; +} + +QString RuleActionParamTemplate::eventParamName() const +{ + return m_eventParamName; +} + +void RuleActionParamTemplate::setEventParamName(const QString &eventParamName) +{ + m_eventParamName = eventParamName; +} diff --git a/libnymea-app-core/ruletemplates/ruleactionparamtemplate.h b/libnymea-app-core/ruletemplates/ruleactionparamtemplate.h new file mode 100644 index 00000000..1b47d2e5 --- /dev/null +++ b/libnymea-app-core/ruletemplates/ruleactionparamtemplate.h @@ -0,0 +1,70 @@ +#ifndef RULEACTIONPARAMTEMPLATE_H +#define RULEACTIONPARAMTEMPLATE_H + +#include "types/ruleactionparam.h" + +#include +#include + +class RuleActionParamTemplate : public RuleActionParam +{ + Q_OBJECT + Q_PROPERTY(QString eventInterface READ eventInterface CONSTANT) + Q_PROPERTY(QString eventName READ eventName CONSTANT) + Q_PROPERTY(QString eventParamName READ eventParamName CONSTANT) +public: + explicit RuleActionParamTemplate(const QString ¶mName, const QVariant &value, QObject *parent = nullptr); + explicit RuleActionParamTemplate(const QString ¶mName, const QString &eventInterface, const QString &eventName, const QString &eventParamName, QObject *parent = nullptr); + explicit RuleActionParamTemplate(QObject *parent = nullptr); + + QString eventInterface() const; + void setEventInterface(const QString &eventInterface); + + QString eventName() const; + void setEventName(const QString &eventName); + + QString eventParamName() const; + void setEventParamName(const QString &eventParamName); + +private: + QString m_eventInterface; + QString m_eventName; + QString m_eventParamName; +}; + + +class RuleActionParamTemplate; + +class RuleActionParamTemplates : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) +public: + explicit RuleActionParamTemplates(QObject *parent = nullptr): QAbstractListModel(parent) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return m_list.count(); } + QVariant data(const QModelIndex &index, int role) const override { Q_UNUSED(index) Q_UNUSED(role) return QVariant(); } + + void addRuleActionParamTemplate(RuleActionParamTemplate *ruleActionParamTemplate) { + ruleActionParamTemplate->setParent(this); + beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + m_list.append(ruleActionParamTemplate); + endInsertRows(); + emit countChanged(); + } + + Q_INVOKABLE RuleActionParamTemplate* get(int index) const { + if (index < 0 || index >= m_list.count()) { + return nullptr; + } + return m_list.at(index); + } + +signals: + void countChanged(); + +private: + QList m_list; +}; + +#endif // RULEACTIONPARAMTEMPLATE_H diff --git a/libnymea-app-core/ruletemplates/ruleactiontemplate.cpp b/libnymea-app-core/ruletemplates/ruleactiontemplate.cpp index 3686c8b1..14444232 100644 --- a/libnymea-app-core/ruletemplates/ruleactiontemplate.cpp +++ b/libnymea-app-core/ruletemplates/ruleactiontemplate.cpp @@ -1,15 +1,15 @@ #include "ruleactiontemplate.h" +#include "ruleactionparamtemplate.h" - -RuleActionTemplate::RuleActionTemplate(const QString &interfaceName, const QString &interfaceAction, int selectionId, RuleActionTemplate::SelectionMode selectionMode, RuleActionParams *params, QObject *parent): +RuleActionTemplate::RuleActionTemplate(const QString &interfaceName, const QString &interfaceAction, int selectionId, RuleActionTemplate::SelectionMode selectionMode, RuleActionParamTemplates *params, QObject *parent): QObject(parent), m_interfaceName(interfaceName), m_interfaceAction(interfaceAction), m_selectionId(selectionId), m_selectionMode(selectionMode), - m_ruleActionParams(params ? params : new RuleActionParams()) + m_ruleActionParamTemplates(params ? params : new RuleActionParamTemplates()) { - m_ruleActionParams->setParent(this); + m_ruleActionParamTemplates->setParent(this); } QString RuleActionTemplate::interfaceName() const @@ -32,7 +32,7 @@ RuleActionTemplate::SelectionMode RuleActionTemplate::selectionMode() const return m_selectionMode; } -RuleActionParams *RuleActionTemplate::ruleActionParams() const +RuleActionParamTemplates *RuleActionTemplate::ruleActionParamTemplates() const { - return m_ruleActionParams; + return m_ruleActionParamTemplates; } diff --git a/libnymea-app-core/ruletemplates/ruleactiontemplate.h b/libnymea-app-core/ruletemplates/ruleactiontemplate.h index 726f0454..22881dc6 100644 --- a/libnymea-app-core/ruletemplates/ruleactiontemplate.h +++ b/libnymea-app-core/ruletemplates/ruleactiontemplate.h @@ -1,10 +1,10 @@ #ifndef RULEACTIONTEMPLATE_H #define RULEACTIONTEMPLATE_H -#include "types/ruleactionparams.h" - #include +class RuleActionParamTemplates; + class RuleActionTemplate : public QObject { Q_OBJECT @@ -12,7 +12,7 @@ class RuleActionTemplate : public QObject Q_PROPERTY(QString interfaceAction READ interfaceAction CONSTANT) Q_PROPERTY(int selectionId READ selectionId CONSTANT) Q_PROPERTY(SelectionMode selectionMode READ selectionMode CONSTANT) - Q_PROPERTY(RuleActionParams* ruleActionParams READ ruleActionParams CONSTANT) + Q_PROPERTY(RuleActionParamTemplates* ruleActionParamTemplates READ ruleActionParamTemplates CONSTANT) public: enum SelectionMode { @@ -22,20 +22,20 @@ public: }; Q_ENUM(SelectionMode) - explicit RuleActionTemplate(const QString &interfaceName, const QString &interfaceAction, int selectionId, SelectionMode selectionMode = SelectionModeAny, RuleActionParams *params = nullptr, QObject *parent = nullptr); + explicit RuleActionTemplate(const QString &interfaceName, const QString &interfaceAction, int selectionId, SelectionMode selectionMode = SelectionModeAny, RuleActionParamTemplates *params = nullptr, QObject *parent = nullptr); QString interfaceName() const; QString interfaceAction() const; int selectionId() const; SelectionMode selectionMode() const; - RuleActionParams* ruleActionParams() const; + RuleActionParamTemplates* ruleActionParamTemplates() const; private: QString m_interfaceName; QString m_interfaceAction; int m_selectionId = 0; SelectionMode m_selectionMode = SelectionModeAny; - RuleActionParams* m_ruleActionParams = nullptr; + RuleActionParamTemplates* m_ruleActionParamTemplates = nullptr; }; #include diff --git a/libnymea-app-core/ruletemplates/ruletemplates.cpp b/libnymea-app-core/ruletemplates/ruletemplates.cpp index 4f0d61f3..41e2d549 100644 --- a/libnymea-app-core/ruletemplates/ruletemplates.cpp +++ b/libnymea-app-core/ruletemplates/ruletemplates.cpp @@ -4,6 +4,7 @@ #include "eventdescriptortemplate.h" #include "ruleactiontemplate.h" #include "stateevaluatortemplate.h" +#include "ruleactionparamtemplate.h" #include "types/ruleactionparam.h" #include "types/ruleactionparams.h" @@ -22,7 +23,8 @@ RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent) StateEvaluatorTemplate* set; RuleActionTemplate* rat; RuleActionTemplate* reat; // exit - RuleActionParams* raps; + RuleActionParamTemplate* rapt; + RuleActionParamTemplates* rapts; QDir ruleTemplatesDir(":/ruletemplates"); @@ -87,10 +89,21 @@ RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent) // RuleActionTemplates foreach (const QVariant &ruleActionVariant, ruleTemplate.value("ruleActionTemplates").toList()) { QVariantMap ruleActionTemplate = ruleActionVariant.toMap(); - raps = new RuleActionParams(); + rapts = new RuleActionParamTemplates(); foreach (const QVariant &ruleActionParamVariant, ruleActionTemplate.value("params").toList()) { QVariantMap ruleActionParamTemplate = ruleActionParamVariant.toMap(); - raps->addRuleActionParam(new RuleActionParam(ruleActionParamTemplate.value("name").toString(), ruleActionParamTemplate.value("value"))); + QString paramName = ruleActionParamTemplate.value("name").toString(); + if (ruleActionParamTemplate.contains("value")) { + QVariant paramValue = ruleActionParamTemplate.value("value"); + rapts->addRuleActionParamTemplate(new RuleActionParamTemplate(paramName, paramValue)); + } else if (ruleActionParamTemplate.contains("eventInterface") && ruleActionParamTemplate.contains("eventName") && ruleActionParamTemplate.contains("eventParamName")) { + QString eventInterface = ruleActionParamTemplate.value("eventInterface").toString(); + QString eventName = ruleActionParamTemplate.value("eventName").toString(); + QString eventParamName = ruleActionParamTemplate.value("eventParamName").toString(); + rapts->addRuleActionParamTemplate(new RuleActionParamTemplate(paramName, eventInterface, eventName, eventParamName)); + } else { + qWarning() << "Invalid rule action param name on rule template:" << paramName; + } } QMetaEnum selectionModeEnum = QMetaEnum::fromType(); rat = new RuleActionTemplate( @@ -98,17 +111,28 @@ RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent) ruleActionTemplate.value("interfaceAction").toString(), ruleActionTemplate.value("selectionId").toInt(), static_cast(selectionModeEnum.keyToValue(ruleActionTemplate.value("selectionMode", "SelectionModeDevice").toByteArray().data())), - raps); + rapts); t->ruleActionTemplates()->addRuleActionTemplate(rat); } // RuleExitActionTemplates foreach (const QVariant &ruleActionVariant, ruleTemplate.value("ruleExitActionTemplates").toList()) { QVariantMap ruleActionTemplate = ruleActionVariant.toMap(); - raps = new RuleActionParams(); + rapts = new RuleActionParamTemplates(); foreach (const QVariant &ruleActionParamVariant, ruleActionTemplate.value("params").toList()) { QVariantMap ruleActionParamTemplate = ruleActionParamVariant.toMap(); - raps->addRuleActionParam(new RuleActionParam(ruleActionParamTemplate.value("name").toString(), ruleActionParamTemplate.value("value"))); + QString paramName = ruleActionParamTemplate.value("name").toString(); + if (ruleActionParamTemplate.contains("value")) { + QVariant paramValue = ruleActionParamTemplate.value("value"); + rapts->addRuleActionParamTemplate(new RuleActionParamTemplate(paramName, paramValue)); + } else if (ruleActionParamTemplate.contains("eventInterface") && ruleActionParamTemplate.contains("eventName") && ruleActionParamTemplate.contains("eventParamName")) { + QString eventInterface = ruleActionParamTemplate.value("eventInterface").toString(); + QString eventName = ruleActionParamTemplate.value("eventName").toString(); + QString eventParamName = ruleActionParamTemplate.value("eventParamName").toString(); + rapts->addRuleActionParamTemplate(new RuleActionParamTemplate(paramName, eventInterface, eventName, eventParamName)); + } else { + qWarning() << "Invalid rule exit action param name on rule template:" << paramName; + } } QMetaEnum selectionModeEnum = QMetaEnum::fromType(); rat = new RuleActionTemplate( @@ -116,7 +140,7 @@ RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent) ruleActionTemplate.value("interfaceAction").toString(), ruleActionTemplate.value("selectionId").toInt(), static_cast(selectionModeEnum.keyToValue(ruleActionTemplate.value("selectionMode", "SelectionModeDevice").toByteArray().data())), - raps); + rapts); t->ruleExitActionTemplates()->addRuleActionTemplate(rat); } diff --git a/libnymea-common/types/param.h b/libnymea-common/types/param.h index 149c98a8..7682e346 100644 --- a/libnymea-common/types/param.h +++ b/libnymea-common/types/param.h @@ -47,7 +47,7 @@ signals: void paramTypeIdChanged(); void valueChanged(); -private: +protected: QString m_paramTypeId; QVariant m_value; }; diff --git a/libnymea-common/types/ruleactionparam.h b/libnymea-common/types/ruleactionparam.h index 0684f594..e25ee6ea 100644 --- a/libnymea-common/types/ruleactionparam.h +++ b/libnymea-common/types/ruleactionparam.h @@ -32,7 +32,7 @@ signals: void eventTypeIdChanged(); void eventParamTypeIdChanged(); -private: +protected: QString m_paramName; QString m_eventTypeId; QString m_eventParamTypeId; diff --git a/nymea-app/nymea-app.pro b/nymea-app/nymea-app.pro index 18d6e32d..2a393964 100644 --- a/nymea-app/nymea-app.pro +++ b/nymea-app/nymea-app.pro @@ -124,4 +124,5 @@ DISTFILES += \ ui/devicepages/NotificationsDevicePage.qml \ ruletemplates/buttontemplates.json \ ruletemplates/notificationtemplates.json \ - ui/devicepages/LightDevicePage.qml + ui/devicepages/LightDevicePage.qml \ + ruletemplates/accesscontroltemplates.json diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc index 9ebcc1b3..4bd2b005 100644 --- a/nymea-app/resources.qrc +++ b/nymea-app/resources.qrc @@ -263,5 +263,6 @@ ui/components/FingerprintVisual.qml ui/images/fingerprint/fingerprint_boxes.json ui/images/fingerprint/fingerprint_segmented.png + ui/images/fingerprint.svg diff --git a/nymea-app/ruletemplates.qrc b/nymea-app/ruletemplates.qrc index ad6c56d1..ee47f538 100644 --- a/nymea-app/ruletemplates.qrc +++ b/nymea-app/ruletemplates.qrc @@ -2,5 +2,6 @@ ruletemplates/buttontemplates.json ruletemplates/notificationtemplates.json + ruletemplates/accesscontroltemplates.json diff --git a/nymea-app/ruletemplates/accesscontroltemplates.json b/nymea-app/ruletemplates/accesscontroltemplates.json new file mode 100644 index 00000000..715891ac --- /dev/null +++ b/nymea-app/ruletemplates/accesscontroltemplates.json @@ -0,0 +1,99 @@ +{ + "templates": [ + { + "interfaceName": "accesscontrol", + "description": "Alert me on denied access attempts", + "ruleNameTemplate": "Denied access attempt on %0", + "eventDescriptorTemplates": [ + { + "interfaceName": "accesscontrol", + "interfaceEvent": "accessDenied", + "selectionId": 0 + } + ], + "ruleActionTemplates": [ + { + "interfaceName": "notifications", + "interfaceAction": "notify", + "selectionId": 1, + "params": [ + { + "name": "title", + "value": "Denied access attempt!" + }, + { + "name": "body", + "value": "Someone tried to enter %0." + } + ] + } + ] + }, + { + "interfaceName": "accesscontrol", + "description": "Notify my about access", + "ruleNameTemplate": "Access granted on %0", + "eventDescriptorTemplates": [ + { + "interfaceName": "accesscontrol", + "interfaceEvent": "accessGranted", + "selectionId": 0 + } + ], + "ruleActionTemplates": [ + { + "interfaceName": "notifications", + "interfaceAction": "notify", + "selectionId": 1, + "params": [ + { + "name": "title", + "value": "User access" + }, + { + "name": "body", + "value": "Someone entered %0." + } + ] + } + ] + }, + { + "interfaceName": "useraccesscontrol", + "description": "Notify my about user access", + "ruleNameTemplate": "Access granted to user on %0", + "eventDescriptorTemplates": [ + { + "interfaceName": "useraccesscontrol", + "interfaceEvent": "accessGranted", + "selectionId": 0, + "params": [ + { + "name": "userId" + } + ] + } + ], + "ruleActionTemplates": [ + { + "interfaceName": "notifications", + "interfaceAction": "notify", + "selectionId": 1, + "params": [ + { + "name": "title", + "value": "User access" + }, + { + "name": "body", + "eventInterface": "useraccesscontrol", + "eventName": "accessGranted", + "eventParamName": "userId" + } + ] + } + ] + } + ] +} + diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index 3ae2e51d..dc0ca3d5 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -171,6 +171,8 @@ ApplicationWindow { return Qt.resolvedUrl("images/select-none.svg") case "simpleclosable": return Qt.resolvedUrl("images/sort-listitem.svg") + case "fingerprintreader": + return Qt.resolvedUrl("images/fingerprint.svg") case "accesscontrol": return Qt.resolvedUrl("images/network-secure.svg"); default: diff --git a/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml b/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml index f5f97ec2..57acd5b0 100644 --- a/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml +++ b/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml @@ -43,15 +43,17 @@ DevicePageBase { delegate: MeaListItemDelegate { width: parent.width - iconName: model.typeId === root.accessGrantedEventType.id ? "../images/tick.svg" : "../images/dialog-error-symbolic.svg" - iconColor: model.typeId === root.accessGrantedEventType.id ? "green" : "red" - text: model.typeId === root.accessGrantedEventType.id ? qsTr("Access granted for user %1").arg(model.value) : qsTr("Access denied") + iconName: accessGranted ? "../images/tick.svg" : "../images/dialog-error-symbolic.svg" + iconColor: accessGranted ? "green" : "red" + text: accessGranted ? qsTr("Access granted for user %1").arg(model.value) : qsTr("Access denied") subText: Qt.formatDateTime(model.timestamp) progressive: false + property bool accessGranted: model.typeId === root.accessGrantedEventType.id + onClicked: { var parts = model.value.trim().split(', ') - var popup = detailsPopup.createObject(root, {timestamp: model.timestamp, notificationTitle: parts[1], notificationBody: parts[0]}); + var popup = detailsPopup.createObject(root, {timestamp: model.timestamp, accessGranted: accessGranted, user: parts[0], finger: parts[1]}); popup.open(); } } @@ -94,6 +96,10 @@ DevicePageBase { progressive: false iconName: "../images/account.svg" canDelete: true + onClicked: { + pageStack.push(addUserComponent, {user: modelData}) + } + onDeleteClicked: { var actionType = root.deviceClass.actionTypes.findByName("removeUser") var params = [] @@ -107,12 +113,13 @@ DevicePageBase { ColumnLayout { anchors.centerIn: parent - width: 200 spacing: app.margins * 2 visible: parent.count === 0 + width: parent.width - app.margins * 2 Item { - Layout.fillWidth: true + Layout.preferredWidth: 100 Layout.preferredHeight: width + Layout.alignment: Qt.AlignHCenter FingerprintVisual { id: fingerprintVisual anchors.centerIn: parent @@ -123,7 +130,7 @@ DevicePageBase { Button { text: qsTr("Add a fingerprint") onClicked: pageStack.push(addUserComponent) - Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter } } } @@ -140,6 +147,8 @@ DevicePageBase { onBackPressed: pageStack.pop() } + property string user: "" + property bool error: false Connections { @@ -159,6 +168,7 @@ DevicePageBase { Layout.topMargin: app.margins * 2 Layout.preferredHeight: 200 Layout.alignment: Qt.AlignTop + interactive: false Item { width: addUserSwipeView.width height: addUserSwipeView.height @@ -174,6 +184,8 @@ DevicePageBase { TextField { id: userIdTextField Layout.fillWidth: true + placeholderText: addUserPage.user + enabled: addUserPage.user.length === 0 } Label { Layout.fillWidth: true @@ -305,12 +317,13 @@ DevicePageBase { MeaDialog { id: detailsDialog property string timestamp - property string notificationTitle - property string notificationBody - title: qsTr("Notification details") + property bool accessGranted + property string user + property string finger + title: qsTr("Access request details") Label { Layout.fillWidth: true - text: qsTr("Date sent") + text: qsTr("Date/Time") font.bold: true } @@ -321,26 +334,30 @@ DevicePageBase { Label { Layout.topMargin: app.margins Layout.fillWidth: true - text: qsTr("Title") + text: detailsDialog.accessGranted ? qsTr("User") : qsTr("Access denied") font.bold: true } Label { Layout.fillWidth: true - text: detailsDialog.notificationTitle + text: detailsDialog.user wrapMode: Text.WordWrap + visible: detailsDialog.accessGranted } + Label { Layout.topMargin: app.margins Layout.fillWidth: true - text: qsTr("Text") + text: qsTr("Fingerprint") font.bold: true + visible: detailsDialog.accessGranted } Label { Layout.fillWidth: true - text: detailsDialog.notificationBody + text: detailsDialog.finger wrapMode: Text.WordWrap + visible: detailsDialog.accessGranted } } } diff --git a/nymea-app/ui/images/fingerprint.svg b/nymea-app/ui/images/fingerprint.svg new file mode 100644 index 00000000..bdca9c92 --- /dev/null +++ b/nymea-app/ui/images/fingerprint.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/nymea-app/ui/magic/NewThingMagicPage.qml b/nymea-app/ui/magic/NewThingMagicPage.qml index 7c2395fa..fc5b237a 100644 --- a/nymea-app/ui/magic/NewThingMagicPage.qml +++ b/nymea-app/ui/magic/NewThingMagicPage.qml @@ -279,11 +279,39 @@ Page { var deviceClass = engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId); ruleAction.deviceId = device.id; ruleAction.actionTypeId = deviceClass.actionTypes.findByName(ruleActionTemplate.interfaceAction).id - for (var j = 0; j < ruleActionTemplate.ruleActionParams.count; j++) { - var ruleActionParam = ruleActionTemplate.ruleActionParams.get(j) + for (var j = 0; j < ruleActionTemplate.ruleActionParamTemplates.count; j++) { + var ruleActionParamTemplate = ruleActionTemplate.ruleActionParamTemplates.get(j) var actionType = deviceClass.actionTypes.getActionType(ruleAction.actionTypeId); - var paramType = actionType.paramTypes.findByName(ruleActionParam.paramName); - ruleAction.ruleActionParams.setRuleActionParam(paramType.id, ruleActionParam.value) + var paramType = actionType.paramTypes.findByName(ruleActionParamTemplate.paramName); + if (ruleActionParamTemplate.value !== undefined) { + ruleAction.ruleActionParams.setRuleActionParam(paramType.id, ruleActionParamTemplate.value) + } else if (ruleActionParamTemplate.eventInterface && ruleActionParamTemplate.eventName && ruleActionParamTemplate.eventParamName) { + print("should create rule action param from interface", ruleActionParamTemplate.eventInterface, ruleActionParamTemplate.eventName, ruleActionParamTemplate.eventParamName) + // find matching eventDescriptor + var eventDescriptorTemplate = null; + 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) { + eventDescriptorTemplate = tmp; + break; + } + } + if (eventDescriptorTemplate === null) { + console.warn("Unable to find an event matching the criteria:", ruleActionParamTemplate.eventInterface, ruleActionParamTemplate.eventName, ruleActionParamTemplate.eventParamName) + break + } + print("selected device:", selectedThings, eventDescriptorTemplate.selectionId) + var eventDevice = engine.deviceManager.devices.getDevice(selectedThings[eventDescriptorTemplate.selectionId]) + var eventDeviceClass = engine.deviceManager.deviceClasses.getDeviceClass(eventDevice.deviceClassId); + var eventType = eventDeviceClass.eventTypes.findByName(ruleActionParamTemplate.eventName); + var eventParamType = eventType.paramTypes.findByName(ruleActionParamTemplate.eventParamName); + + ruleAction.ruleActionParams.setRuleActionParamEvent(paramType.id, eventType.id, eventParamType.id) + } else { + console.warn("Invalid RuleActionParamTemplate. Has neither value nor event spec") + } + } ruleActions.addRuleAction(ruleAction); fillRuleFromTemplate(rule, ruleTemplate, selectedThings);