diff --git a/libnymea-app/zigbee/zigbeeadapter.cpp b/libnymea-app/zigbee/zigbeeadapter.cpp index e4e65730..8e3a591f 100644 --- a/libnymea-app/zigbee/zigbeeadapter.cpp +++ b/libnymea-app/zigbee/zigbeeadapter.cpp @@ -57,15 +57,26 @@ void ZigbeeAdapter::setDescription(const QString &description) emit descriptionChanged(); } -QString ZigbeeAdapter::systemLocation() const +QString ZigbeeAdapter::serialPort() const { - return m_systemLocation; + return m_serialPort; } -void ZigbeeAdapter::setSystemLocation(const QString &systemLocation) +void ZigbeeAdapter::setSerialPort(const QString &serialPort) { - m_systemLocation = systemLocation; - emit systemLocationChanged(); + m_serialPort = serialPort; + emit serialPortChanged(); +} + +QString ZigbeeAdapter::serialNumber() const +{ + return m_serialNumber; +} + +void ZigbeeAdapter::setSerialNumber(const QString &serialNumber) +{ + m_serialNumber = serialNumber; + emit serialNumberChanged(); } bool ZigbeeAdapter::hardwareRecognized() const @@ -103,7 +114,7 @@ void ZigbeeAdapter::setBaudRate(qint32 baudRate) bool ZigbeeAdapter::operator==(const ZigbeeAdapter &other) const { - return m_systemLocation == other.systemLocation() + return m_serialPort == other.serialPort() && m_name == other.name() && m_description == other.description() && m_hardwareRecognized == other.hardwareRecognized() @@ -123,10 +134,22 @@ ZigbeeAdapter::ZigbeeBackendType ZigbeeAdapter::stringToZigbeeBackendType(const } } +QString ZigbeeAdapter::getBackendName(ZigbeeAdapter::ZigbeeBackendType backendType) +{ + switch (backendType) { + case ZigbeeAdapter::ZigbeeBackendTypeDeconz: + return "deCONZ"; + case ZigbeeAdapter::ZigbeeBackendTypeNxp: + return "Nxp"; + default: + return tr("Unknown"); + } +} + QDebug operator<<(QDebug debug, const ZigbeeAdapter &adapter) { debug.nospace() << "ZigbeeAdapter(" << adapter.name() << " - " << adapter.description(); - debug.nospace() << ", " << adapter.systemLocation(); + debug.nospace() << ", " << adapter.serialPort(); if (adapter.hardwareRecognized()) { debug.nospace() << " Hardware recognized: " << adapter.backendType(); debug.nospace() << ", " << adapter.baudRate(); diff --git a/libnymea-app/zigbee/zigbeeadapter.h b/libnymea-app/zigbee/zigbeeadapter.h index d3faeda0..434fdfa3 100644 --- a/libnymea-app/zigbee/zigbeeadapter.h +++ b/libnymea-app/zigbee/zigbeeadapter.h @@ -39,7 +39,8 @@ class ZigbeeAdapter : public QObject Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) - Q_PROPERTY(QString systemLocation READ systemLocation WRITE setSystemLocation NOTIFY systemLocationChanged) + Q_PROPERTY(QString serialPort READ serialPort WRITE setSerialPort NOTIFY serialPortChanged) + Q_PROPERTY(QString serialNumber READ serialNumber WRITE setSerialNumber NOTIFY serialNumberChanged) Q_PROPERTY(bool hardwareRecognized READ hardwareRecognized WRITE setHardwareRecognized NOTIFY hardwareRecognizedChanged) Q_PROPERTY(ZigbeeAdapter::ZigbeeBackendType backendType READ backendType WRITE setBackendType NOTIFY backendTypeChanged) Q_PROPERTY(qint32 baudRate READ baudRate WRITE setBaudRate NOTIFY baudRateChanged) @@ -59,8 +60,11 @@ public: QString description() const; void setDescription(const QString &description); - QString systemLocation() const; - void setSystemLocation(const QString &systemLocation); + QString serialPort() const; + void setSerialPort(const QString &serialPort); + + QString serialNumber() const; + void setSerialNumber(const QString &serialNumber); bool hardwareRecognized() const; void setHardwareRecognized(bool hardwareRecognized); @@ -75,10 +79,13 @@ public: static ZigbeeAdapter::ZigbeeBackendType stringToZigbeeBackendType(const QString &backendTypeString); + Q_INVOKABLE static QString getBackendName(ZigbeeAdapter::ZigbeeBackendType backendType); + private: QString m_name; QString m_description; - QString m_systemLocation; + QString m_serialPort; + QString m_serialNumber; bool m_hardwareRecognized = false; ZigbeeAdapter::ZigbeeBackendType m_backendType = ZigbeeAdapter::ZigbeeBackendTypeDeconz; qint32 m_baudRate = 38400; @@ -86,12 +93,15 @@ private: signals: void nameChanged(); void descriptionChanged(); - void systemLocationChanged(); + void serialPortChanged(); + void serialNumberChanged(); void hardwareRecognizedChanged(); void backendTypeChanged(); void baudRateChanged(); }; +Q_DECLARE_METATYPE(ZigbeeAdapter::ZigbeeBackendType) + QDebug operator<<(QDebug debug, const ZigbeeAdapter &adapter); #endif // ZIGBEEADAPTER_H diff --git a/libnymea-app/zigbee/zigbeeadapters.cpp b/libnymea-app/zigbee/zigbeeadapters.cpp index 9584f266..190628dc 100644 --- a/libnymea-app/zigbee/zigbeeadapters.cpp +++ b/libnymea-app/zigbee/zigbeeadapters.cpp @@ -48,8 +48,8 @@ QVariant ZigbeeAdapters::data(const QModelIndex &index, int role) const return m_adapters.at(index.row())->name(); case RoleDescription: return m_adapters.at(index.row())->description(); - case RoleSystemLocation: - return m_adapters.at(index.row())->systemLocation(); + case RoleSerialPort: + return m_adapters.at(index.row())->serialPort(); case RoleHardwareRecognized: return m_adapters.at(index.row())->hardwareRecognized(); case RoleBackendType: @@ -65,7 +65,7 @@ QHash ZigbeeAdapters::roleNames() const QHash roles; roles.insert(RoleName, "name"); roles.insert(RoleDescription, "description"); - roles.insert(RoleSystemLocation, "systemLocation"); + roles.insert(RoleSerialPort, "serialPort"); roles.insert(RoleHardwareRecognized, "hardwareRecognized"); roles.insert(RoleBackendType, "backendType"); roles.insert(RoleBaudRate, "baudRate"); @@ -75,8 +75,10 @@ QHash ZigbeeAdapters::roleNames() const void ZigbeeAdapters::addAdapter(ZigbeeAdapter *adapter) { adapter->setParent(this); + beginInsertRows(QModelIndex(), m_adapters.count(), m_adapters.count()); m_adapters.append(adapter); + connect(adapter, &ZigbeeAdapter::nameChanged, this, [this, adapter]() { QModelIndex idx = index(m_adapters.indexOf(adapter), 0); emit dataChanged(idx, idx, {RoleName}); @@ -87,9 +89,9 @@ void ZigbeeAdapters::addAdapter(ZigbeeAdapter *adapter) emit dataChanged(idx, idx, {RoleDescription}); }); - connect(adapter, &ZigbeeAdapter::systemLocationChanged, this, [this, adapter]() { + connect(adapter, &ZigbeeAdapter::serialPortChanged, this, [this, adapter]() { QModelIndex idx = index(m_adapters.indexOf(adapter), 0); - emit dataChanged(idx, idx, {RoleSystemLocation}); + emit dataChanged(idx, idx, {RoleSerialPort}); }); connect(adapter, &ZigbeeAdapter::hardwareRecognizedChanged, this, [this, adapter]() { @@ -106,14 +108,16 @@ void ZigbeeAdapters::addAdapter(ZigbeeAdapter *adapter) QModelIndex idx = index(m_adapters.indexOf(adapter), 0); emit dataChanged(idx, idx, {RoleBaudRate}); }); + endInsertRows(); + emit countChanged(); } -void ZigbeeAdapters::removeAdapter(const QString &systemLocation) +void ZigbeeAdapters::removeAdapter(const QString &serialPort) { for (int i = 0; i < m_adapters.count(); i++) { - if (m_adapters.at(i)->systemLocation() == systemLocation) { + if (m_adapters.at(i)->serialPort() == serialPort) { beginRemoveRows(QModelIndex(), i, i); m_adapters.takeAt(i)->deleteLater(); endRemoveRows(); @@ -136,5 +140,6 @@ ZigbeeAdapter *ZigbeeAdapters::get(int index) const if (index < 0 || index > m_adapters.count() - 1) { return nullptr; } + return m_adapters.at(index); } diff --git a/libnymea-app/zigbee/zigbeeadapters.h b/libnymea-app/zigbee/zigbeeadapters.h index 7a0f4b5c..e4cf2433 100644 --- a/libnymea-app/zigbee/zigbeeadapters.h +++ b/libnymea-app/zigbee/zigbeeadapters.h @@ -45,7 +45,7 @@ public: enum Roles { RoleName, RoleDescription, - RoleSystemLocation, + RoleSerialPort, RoleHardwareRecognized, RoleBackendType, RoleBaudRate @@ -60,7 +60,7 @@ public: QHash roleNames() const override; void addAdapter(ZigbeeAdapter *adapter); - void removeAdapter(const QString &systemLocation); + void removeAdapter(const QString &serialPort); void clear(); diff --git a/libnymea-app/zigbee/zigbeeadaptersproxy.cpp b/libnymea-app/zigbee/zigbeeadaptersproxy.cpp index 63e04cab..9b365c30 100644 --- a/libnymea-app/zigbee/zigbeeadaptersproxy.cpp +++ b/libnymea-app/zigbee/zigbeeadaptersproxy.cpp @@ -51,7 +51,7 @@ void ZigbeeAdaptersProxy::setAdapters(ZigbeeAdapters *adapters) }); setSourceModel(m_adapters); - setSortRole(ZigbeeAdapters::RoleSystemLocation); + setSortRole(ZigbeeAdapters::RoleSerialPort); sort(0, Qt::DescendingOrder); invalidateFilter(); emit countChanged(); @@ -66,6 +66,7 @@ void ZigbeeAdaptersProxy::setHardwareFilter(ZigbeeAdaptersProxy::HardwareFilter { m_hardwareFilter = hardwareFilter; emit hardwareFilterChanged(m_hardwareFilter); + invalidateFilter(); emit countChanged(); } @@ -80,6 +81,9 @@ bool ZigbeeAdaptersProxy::filterAcceptsRow(int source_row, const QModelIndex &so Q_UNUSED(source_parent) ZigbeeAdapter *adapter = m_adapters->get(source_row); + if (!adapter) + return false; + if (m_hardwareFilter == HardwareFilterRecognized) { return adapter->hardwareRecognized(); } else if (m_hardwareFilter == HardwareFilterUnrecognized) { diff --git a/libnymea-app/zigbee/zigbeemanager.cpp b/libnymea-app/zigbee/zigbeemanager.cpp index 04764b73..fb54aa80 100644 --- a/libnymea-app/zigbee/zigbeemanager.cpp +++ b/libnymea-app/zigbee/zigbeemanager.cpp @@ -36,12 +36,16 @@ #include "zigbee/zigbeenetwork.h" #include "zigbee/zigbeenetworks.h" +#include + ZigbeeManager::ZigbeeManager(JsonRpcClient *client, QObject *parent) : JsonHandler(parent), m_client(client), m_adapters(new ZigbeeAdapters(this)), m_networks(new ZigbeeNetworks(this)) { + qRegisterMetaType(); + client->registerNotificationHandler(this, "notificationReceived"); } @@ -65,10 +69,31 @@ ZigbeeNetworks *ZigbeeManager::networks() const return m_networks; } +void ZigbeeManager::addNetwork(const QString &serialPort, uint baudRate, ZigbeeAdapter::ZigbeeBackendType backendType) +{ + QVariantMap params; + params.insert("serialPort", serialPort); + params.insert("baudRate", baudRate); + QMetaEnum metaEnum = QMetaEnum::fromType(); + params.insert("backendType", metaEnum.valueToKey(backendType)); + + qDebug() << "Add zigbee network" << params; + m_client->sendCommand("Zigbee.AddNetwork", params, this, "addNetworkResponse"); +} + +void ZigbeeManager::removeNetwork(const QUuid &networkUuid) +{ + QVariantMap params; + params.insert("networkUuid", networkUuid); + qDebug() << "Remove zigbee network" << params; + m_client->sendCommand("Zigbee.RemoveNetwork", params, this, "removeNetworkResponse"); +} + void ZigbeeManager::init() { - qDebug() << "Zigbee init..."; + // FIXME: load only when used m_adapters->clear(); + m_networks->clear(); m_client->sendCommand("Zigbee.GetAdapters", this, "getAdaptersResponse"); m_client->sendCommand("Zigbee.GetNetworks", this, "getNetworksResponse"); } @@ -80,7 +105,7 @@ void ZigbeeManager::getAdaptersResponse(int commandId, const QVariantMap ¶ms foreach (const QVariant &adapterVariant, params.value("adapters").toList()) { QVariantMap adapterMap = adapterVariant.toMap(); ZigbeeAdapter *adapter = unpackAdapter(adapterMap); - qDebug() << "Zigbee adapter added" << adapter->description() << adapter->systemLocation(); + qDebug() << "Zigbee adapter added" << adapter->description() << adapter->serialPort() << adapter->hardwareRecognized(); m_adapters->addAdapter(adapter); } } @@ -88,7 +113,7 @@ void ZigbeeManager::getAdaptersResponse(int commandId, const QVariantMap ¶ms void ZigbeeManager::getNetworksResponse(int commandId, const QVariantMap ¶ms) { qDebug() << "Zigbee get networks response" << commandId << params; - m_adapters->clear(); + m_networks->clear(); foreach (const QVariant &networkVariant, params.value("zigbeeNetworks").toList()) { QVariantMap networkMap = networkVariant.toMap(); ZigbeeNetwork *network = unpackNetwork(networkMap); @@ -97,6 +122,16 @@ void ZigbeeManager::getNetworksResponse(int commandId, const QVariantMap ¶ms } } +void ZigbeeManager::addNetworkResponse(int commandId, const QVariantMap ¶ms) +{ + qDebug() << "Zigbee add network response" << commandId << params; +} + +void ZigbeeManager::removeNetworkResponse(int commandId, const QVariantMap ¶ms) +{ + qDebug() << "Zigbee remove network response" << commandId << params; +} + void ZigbeeManager::notificationReceived(const QVariantMap ¬ification) { QString notificationString = notification.value("notification").toString(); @@ -108,7 +143,7 @@ void ZigbeeManager::notificationReceived(const QVariantMap ¬ification) if (notificationString == "Zigbee.AdapterRemoved") { QVariantMap adapterMap = notification.value("params").toMap().value("adapter").toMap(); - m_adapters->removeAdapter(adapterMap.value("systemLocation").toString()); + m_adapters->removeAdapter(adapterMap.value("serialPort").toString()); return; } @@ -119,7 +154,7 @@ void ZigbeeManager::notificationReceived(const QVariantMap ¬ification) } if (notificationString == "Zigbee.NetworkRemoved") { - QUuid networkUuid = notification.value("params").toMap().value("zigbeeNetwork").toUuid(); + QUuid networkUuid = notification.value("params").toMap().value("networkUuid").toUuid(); m_networks->removeNetwork(networkUuid); return; } @@ -144,7 +179,8 @@ ZigbeeAdapter *ZigbeeManager::unpackAdapter(const QVariantMap &adapterMap) ZigbeeAdapter *adapter = new ZigbeeAdapter(m_adapters); adapter->setName(adapterMap.value("name").toString()); adapter->setDescription(adapterMap.value("description").toString()); - adapter->setSystemLocation(adapterMap.value("systemLocation").toString()); + adapter->setSerialPort(adapterMap.value("serialPort").toString()); + adapter->setSerialNumber(adapterMap.value("serialNumber").toString()); adapter->setHardwareRecognized(adapterMap.value("hardwareRecognized").toBool()); adapter->setBackendType(ZigbeeAdapter::stringToZigbeeBackendType(adapterMap.value("backendType").toString())); adapter->setBaudRate(adapterMap.value("baudRate").toUInt()); diff --git a/libnymea-app/zigbee/zigbeemanager.h b/libnymea-app/zigbee/zigbeemanager.h index 057c388f..091fb047 100644 --- a/libnymea-app/zigbee/zigbeemanager.h +++ b/libnymea-app/zigbee/zigbeemanager.h @@ -32,10 +32,10 @@ #define ZIGBEEMANAGER_H #include +#include "zigbeeadapter.h" #include "jsonrpc/jsonhandler.h" class JsonRpcClient; -class ZigbeeAdapter; class ZigbeeAdapters; class ZigbeeNetwork; class ZigbeeNetworks; @@ -55,6 +55,9 @@ public: ZigbeeAdapters *adapters() const; ZigbeeNetworks *networks() const; + Q_INVOKABLE void addNetwork(const QString &serialPort, uint baudRate, ZigbeeAdapter::ZigbeeBackendType backendType); + Q_INVOKABLE void removeNetwork(const QUuid &networkUuid); + void init(); signals: @@ -63,6 +66,10 @@ private: Q_INVOKABLE void getAdaptersResponse(int commandId, const QVariantMap ¶ms); Q_INVOKABLE void getNetworksResponse(int commandId, const QVariantMap ¶ms); + Q_INVOKABLE void addNetworkResponse(int commandId, const QVariantMap ¶ms); + Q_INVOKABLE void removeNetworkResponse(int commandId, const QVariantMap ¶ms); + + Q_INVOKABLE void notificationReceived(const QVariantMap ¬ification); private: diff --git a/libnymea-app/zigbee/zigbeenetwork.cpp b/libnymea-app/zigbee/zigbeenetwork.cpp index 7eaa61a4..4458c0e1 100644 --- a/libnymea-app/zigbee/zigbeenetwork.cpp +++ b/libnymea-app/zigbee/zigbeenetwork.cpp @@ -32,7 +32,16 @@ ZigbeeNetwork::ZigbeeNetwork(QObject *parent) : QObject(parent) { + m_permitJoinTimer = new QTimer(this); + m_permitJoinTimer->setInterval(1000); + m_permitJoinTimer->setSingleShot(true); + connect(m_permitJoinTimer, &QTimer::timeout, this, [this](){ + setPermitJoiningRemaining(m_permitJoiningRemaining - 1); + if (m_permitJoiningRemaining <= 0) { + m_permitJoinTimer->stop(); + } + }); } QUuid ZigbeeNetwork::networkUuid() const @@ -186,7 +195,14 @@ void ZigbeeNetwork::setPermitJoiningRemaining(uint permitJoiningRemaining) return; m_permitJoiningRemaining = permitJoiningRemaining; - emit permitJoiningRemainingChanged(); + emit permitJoiningRemainingChanged(); + + if (m_permitJoinTimer->isActive()) + m_permitJoinTimer->stop(); + + if (m_permitJoiningRemaining != 0) { + m_permitJoinTimer->start(); + } } ZigbeeAdapter::ZigbeeBackendType ZigbeeNetwork::backendType() const diff --git a/libnymea-app/zigbee/zigbeenetwork.h b/libnymea-app/zigbee/zigbeenetwork.h index 805e1bbd..7df52102 100644 --- a/libnymea-app/zigbee/zigbeenetwork.h +++ b/libnymea-app/zigbee/zigbeenetwork.h @@ -33,6 +33,7 @@ #include #include +#include #include "zigbeeadapter.h" @@ -53,8 +54,9 @@ class ZigbeeNetwork : public QObject Q_PROPERTY(ZigbeeAdapter::ZigbeeBackendType backendType READ backendType NOTIFY backendTypeChanged) Q_PROPERTY(ZigbeeNetworkState networkState READ networkState NOTIFY networkStateChanged) -public: + // Internal properties +public: enum ZigbeeNetworkState { ZigbeeNetworkStateOffline, ZigbeeNetworkStateStarting, @@ -136,6 +138,8 @@ private: uint m_permitJoiningRemaining; ZigbeeAdapter::ZigbeeBackendType m_backendType; ZigbeeNetworkState m_networkState; + + QTimer *m_permitJoinTimer = nullptr; }; #endif // ZIGBEENETWORK_H diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc index 87ea25d0..c81ba76a 100644 --- a/nymea-app/resources.qrc +++ b/nymea-app/resources.qrc @@ -227,5 +227,7 @@ ui/components/ThingInfoPane.qml ui/system/ZigbeeNetworkSettingsPage.qml ui/system/ZigbeeNetworkAddPage.qml + ui/system/ZigbeeNetworkPage.qml + ui/system/ZigbeeNetworkInfoPage.qml diff --git a/nymea-app/ui/system/ZigbeeNetworkAddPage.qml b/nymea-app/ui/system/ZigbeeNetworkAddPage.qml index 2085e846..58dd883b 100644 --- a/nymea-app/ui/system/ZigbeeNetworkAddPage.qml +++ b/nymea-app/ui/system/ZigbeeNetworkAddPage.qml @@ -39,11 +39,14 @@ SettingsPageBase { id: root title: qsTr("Add a new Zigbee network") + + SettingsPageSectionHeader { text: qsTr("Zigbee adapters") } Repeater { + id: recognizedRepeater model: ZigbeeAdaptersProxy { adapters: engine.zigbeeManager.adapters hardwareFilter: ZigbeeAdaptersProxy.HardwareFilterRecognized @@ -51,18 +54,20 @@ SettingsPageBase { delegate: NymeaListItemDelegate { Layout.fillWidth: true -// property var adapter: engine.zigbeeManager.adapters.get(index) - iconName: "../images/stock_link.svg" - text: model.description + " - " + model.systemLocation - //onClicked: pageStack.push(Qt.resolvedUrl("PluginParamsPage.qml"), {plugin: plugin}) + property ZigbeeAdapter adapter: engine.zigbeeManager.adapters.get(index) + iconName: "../images/add.svg" + text: model.description + " - " + model.serialPort + onClicked: engine.zigbeeManager.addNetwork(adapter.serialPort, adapter.baudRate, adapter.backendType) } } SettingsPageSectionHeader { text: qsTr("Unrecognized Zigbee adapters") + visible: unrecognizedRepeater.count !== 0 } Repeater { + id: unrecognizedRepeater model: ZigbeeAdaptersProxy { adapters: engine.zigbeeManager.adapters hardwareFilter: ZigbeeAdaptersProxy.HardwareFilterUnrecognized @@ -71,8 +76,9 @@ SettingsPageBase { delegate: NymeaListItemDelegate { Layout.fillWidth: true // property var adapter: engine.zigbeeManager.adapters.get(index) - iconName: "../images/stock_link.svg" - text: model.description + " - " + model.systemLocation + iconName: "../images/add.svg" + text: model.description + " - " + model.serialPort + // TODO: show backend and baudrate popup before adding //onClicked: pageStack.push(Qt.resolvedUrl("PluginParamsPage.qml"), {plugin: plugin}) } } diff --git a/nymea-app/ui/system/ZigbeeNetworkInfoPage.qml b/nymea-app/ui/system/ZigbeeNetworkInfoPage.qml new file mode 100644 index 00000000..e3a002f9 --- /dev/null +++ b/nymea-app/ui/system/ZigbeeNetworkInfoPage.qml @@ -0,0 +1,122 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU General Public License as published by the Free Software +* Foundation, GNU version 3. This project is distributed in the hope that it +* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +* Public License for more details. +* +* You should have received a copy of the GNU General Public License along with +* this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +import QtQuick 2.8 +import QtQuick.Controls 2.2 +import QtQuick.Controls.Material 2.1 +import QtQuick.Layouts 1.3 +import "../components" +import Nymea 1.0 + +SettingsPageBase { + id: root + + property ZigbeeNetwork network: null + + header: NymeaHeader { + text: qsTr("Network settings") + backButtonVisible: true + onBackPressed: pageStack.pop() + } + + SettingsPageSectionHeader { + text: qsTr("Hardware information") + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: qsTr("MAC address:") + subText: root.network.macAddress + progressive: false + prominentSubText: false + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: qsTr("Serial port") + subText: root.network.serialPort + progressive: false + prominentSubText: false + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: qsTr("Baud rate") + subText: root.network.baudRate + progressive: false + prominentSubText: false + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: qsTr("Controller backend") + subText: ZigbeeAdapter.getBackendName(root.network.backendType) + progressive: false + prominentSubText: false + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: qsTr("Controller firmware version") + subText: root.network.firmwareVersion + progressive: false + prominentSubText: false + } + + SettingsPageSectionHeader { + text: qsTr("Manage network") + } + + ColumnLayout { + anchors { left: parent.left; right: parent.right } + + Button { + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + text: qsTr("Remove network") + onClicked: { + engine.zigbeeManager.removeNetwork(root.network.networkUuid) + pageStack.pop() + pageStack.pop() + } + } + + Button { + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + text: qsTr("Factory reset controller") + onClicked: print("Reset clicked") + } + } + + +} diff --git a/nymea-app/ui/system/ZigbeeNetworkPage.qml b/nymea-app/ui/system/ZigbeeNetworkPage.qml new file mode 100644 index 00000000..6fd630cc --- /dev/null +++ b/nymea-app/ui/system/ZigbeeNetworkPage.qml @@ -0,0 +1,115 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU General Public License as published by the Free Software +* Foundation, GNU version 3. This project is distributed in the hope that it +* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +* Public License for more details. +* +* You should have received a copy of the GNU General Public License along with +* this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +import QtQuick 2.8 +import QtQuick.Controls 2.2 +import QtQuick.Controls.Material 2.1 +import QtQuick.Layouts 1.3 +import "../components" +import Nymea 1.0 + +SettingsPageBase { + id: root + + property ZigbeeNetwork network: null + + header: NymeaHeader { + text: qsTr("Network") + " " + root.network.macAddress + backButtonVisible: true + onBackPressed: pageStack.pop() + + HeaderButton { + text: qsTr("Settings") + imageSource: "../images/settings.svg" + onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkInfoPage.qml"), { network: root.network }) + } + } + + SettingsPageSectionHeader { + text: qsTr("Network information") + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: qsTr("Network state") + subText: root.network.networkState + progressive: false + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: qsTr("Channel") + subText: root.network.channel + progressive: false + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: qsTr("Network PAN ID") + subText: root.network.panId + progressive: false + } + + SettingsPageSectionHeader { + text: qsTr("Adding zigbee devices") + } + + NymeaListItemDelegate { + Layout.fillWidth: true + text: root.network.permitJoiningEnabled ? qsTr("The network is open") : qsTr("The network is closed") + subText: root.network.permitJoiningEnabled ? qsTr("Devices can join this network") : qsTr("Devices are not allowed to join this network") + progressive: false + prominentSubText: false + } + + ColumnLayout { + anchors { left: parent.left; right: parent.right } + + ProgressBar { + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + visible: root.network.permitJoiningEnabled + from: root.network.permitJoiningDuration + to: 0 + value: root.network.permitJoiningRemaining + } + + Button { + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + enabled: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline + text: root.network.permitJoiningEnabled ? qsTr("Extend network open duration") : qsTr("Open network for new Zigbee devices") + onClicked: print("Permit join clicked") + } + } + +} diff --git a/nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml b/nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml index 35821600..c1f64411 100644 --- a/nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml +++ b/nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml @@ -42,13 +42,14 @@ SettingsPageBase { backButtonVisible: true onBackPressed: pageStack.pop() - HeaderButton { - text: qsTr("Settings") - imageSource: "../images/settings.svg" - onClicked: { - //pageStack.push() - } - } + // TODO: create a settings page where zigbee networking can be enabled/disabled in general + // HeaderButton { + // text: qsTr("Settings") + // imageSource: "../images/settings.svg" + // onClicked: { + // //pageStack.push() + // } + // } } ColumnLayout { @@ -60,24 +61,18 @@ SettingsPageBase { text: qsTr("Zigbee networks") } - Repeater { model: engine.zigbeeManager.networks - - delegate: NymeaListItemDelegate { Layout.fillWidth: true - // property var adapter: engine.zigbeeManager.adapters.get(index) + property var network: engine.zigbeeManager.networks.get(index) iconName: "../images/zigbee.svg" - text: model.macAddress + " - " + model.serialPort - subText: model.firmwareVersion - - //onClicked: pageStack.push(Qt.resolvedUrl("PluginParamsPage.qml"), {plugin: plugin}) + text: model.macAddress + subText: model.serialPort + " - " + model.firmwareVersion + onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkPage.qml"), { network: network }) } } - - NymeaListItemDelegate { Layout.fillWidth: true text: qsTr("Add Zigbee network")