diff --git a/QtZeroConf b/QtZeroConf index cbf4f2bf..39efbe28 160000 --- a/QtZeroConf +++ b/QtZeroConf @@ -1 +1 @@ -Subproject commit cbf4f2bf7b926b9a874af013efbf0f6dde3155e9 +Subproject commit 39efbe2879d93bd483ee1f14fc94281a03b49935 diff --git a/libnymea-app/libnymea-app-core.h b/libnymea-app/libnymea-app-core.h index a6d6987f..89539b1c 100644 --- a/libnymea-app/libnymea-app-core.h +++ b/libnymea-app/libnymea-app-core.h @@ -124,6 +124,8 @@ #include "zigbee/zigbeeadapter.h" #include "zigbee/zigbeeadapters.h" #include "zigbee/zigbeeadaptersproxy.h" +#include "zigbee/zigbeenetwork.h" +#include "zigbee/zigbeenetworks.h" #include @@ -304,6 +306,8 @@ void registerQmlTypes() { qmlRegisterUncreatableType(uri, 1, 0, "ZigbeeAdapter", "Get it from the ZigbeeAdapters"); qmlRegisterUncreatableType(uri, 1, 0, "ZigbeeAdapters", "Get it from ZigbeeManager"); qmlRegisterType(uri, 1, 0, "ZigbeeAdaptersProxy"); + qmlRegisterUncreatableType(uri, 1, 0, "ZigbeeNetwork", "Get it from the ZigbeeManager"); + qmlRegisterUncreatableType(uri, 1, 0, "ZigbeeNetworks", "Get it from the ZigbeeManager"); qmlRegisterType(uri, 1, 0, "NetworkManager"); qmlRegisterUncreatableType(uri, 1, 0, "NetworkDevices", "Get it from NetworkManager"); diff --git a/libnymea-app/libnymea-app.pro b/libnymea-app/libnymea-app.pro index e47a1e6d..b0cdc5b9 100644 --- a/libnymea-app/libnymea-app.pro +++ b/libnymea-app/libnymea-app.pro @@ -164,6 +164,8 @@ SOURCES += \ zigbee/zigbeeadaptersproxy.cpp \ zigbee/zigbeemanager.cpp \ zigbee/zigbeeadapter.cpp \ + zigbee/zigbeenetwork.cpp \ + zigbee/zigbeenetworks.cpp @@ -308,6 +310,8 @@ HEADERS += \ zigbee/zigbeeadaptersproxy.h \ zigbee/zigbeemanager.h \ zigbee/zigbeeadapter.h \ + zigbee/zigbeenetwork.h \ + zigbee/zigbeenetworks.h ubports: { DEFINES += UBPORTS diff --git a/libnymea-app/zigbee/zigbeeadapter.cpp b/libnymea-app/zigbee/zigbeeadapter.cpp index 3f13415e..e4e65730 100644 --- a/libnymea-app/zigbee/zigbeeadapter.cpp +++ b/libnymea-app/zigbee/zigbeeadapter.cpp @@ -123,3 +123,15 @@ ZigbeeAdapter::ZigbeeBackendType ZigbeeAdapter::stringToZigbeeBackendType(const } } +QDebug operator<<(QDebug debug, const ZigbeeAdapter &adapter) +{ + debug.nospace() << "ZigbeeAdapter(" << adapter.name() << " - " << adapter.description(); + debug.nospace() << ", " << adapter.systemLocation(); + if (adapter.hardwareRecognized()) { + debug.nospace() << " Hardware recognized: " << adapter.backendType(); + debug.nospace() << ", " << adapter.baudRate(); + } + + debug.nospace() << ")"; + return debug.space(); +} diff --git a/libnymea-app/zigbee/zigbeeadapter.h b/libnymea-app/zigbee/zigbeeadapter.h index 22375061..d3faeda0 100644 --- a/libnymea-app/zigbee/zigbeeadapter.h +++ b/libnymea-app/zigbee/zigbeeadapter.h @@ -31,6 +31,7 @@ #ifndef ZIGBEEADAPTER_H #define ZIGBEEADAPTER_H +#include #include class ZigbeeAdapter : public QObject @@ -91,4 +92,6 @@ signals: void baudRateChanged(); }; +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 ae422bad..9584f266 100644 --- a/libnymea-app/zigbee/zigbeeadapters.cpp +++ b/libnymea-app/zigbee/zigbeeadapters.cpp @@ -77,7 +77,6 @@ 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}); @@ -107,8 +106,6 @@ void ZigbeeAdapters::addAdapter(ZigbeeAdapter *adapter) QModelIndex idx = index(m_adapters.indexOf(adapter), 0); emit dataChanged(idx, idx, {RoleBaudRate}); }); - - endInsertRows(); emit countChanged(); } diff --git a/libnymea-app/zigbee/zigbeeadaptersproxy.cpp b/libnymea-app/zigbee/zigbeeadaptersproxy.cpp index 6a45c755..63e04cab 100644 --- a/libnymea-app/zigbee/zigbeeadaptersproxy.cpp +++ b/libnymea-app/zigbee/zigbeeadaptersproxy.cpp @@ -45,13 +45,16 @@ ZigbeeAdapters *ZigbeeAdaptersProxy::adapters() const void ZigbeeAdaptersProxy::setAdapters(ZigbeeAdapters *adapters) { m_adapters = adapters; - emit adaptersChanged(); + connect(m_adapters, &ZigbeeAdapters::countChanged, this, [this](){ + invalidateFilter(); + emit countChanged(); + }); setSourceModel(m_adapters); - connect(m_adapters, &ZigbeeAdapters::countChanged, this, &ZigbeeAdaptersProxy::countChanged); setSortRole(ZigbeeAdapters::RoleSystemLocation); sort(0, Qt::DescendingOrder); invalidateFilter(); + emit countChanged(); } ZigbeeAdaptersProxy::HardwareFilter ZigbeeAdaptersProxy::hardwareFilter() const @@ -64,6 +67,7 @@ void ZigbeeAdaptersProxy::setHardwareFilter(ZigbeeAdaptersProxy::HardwareFilter m_hardwareFilter = hardwareFilter; emit hardwareFilterChanged(m_hardwareFilter); invalidateFilter(); + emit countChanged(); } ZigbeeAdapter *ZigbeeAdaptersProxy::get(int index) const @@ -76,18 +80,11 @@ bool ZigbeeAdaptersProxy::filterAcceptsRow(int source_row, const QModelIndex &so Q_UNUSED(source_parent) ZigbeeAdapter *adapter = m_adapters->get(source_row); - if (m_hardwareFilter == HardwareFilterRecognized) { - if (adapter->hardwareRecognized() == false) { - return true; - } + return adapter->hardwareRecognized(); + } else if (m_hardwareFilter == HardwareFilterUnrecognized) { + return !adapter->hardwareRecognized(); } - if (m_hardwareFilter == HardwareFilterUnrecognized) { - if (adapter->hardwareRecognized() == true) { - return true; - } - } - - return false; + return true; } diff --git a/libnymea-app/zigbee/zigbeemanager.cpp b/libnymea-app/zigbee/zigbeemanager.cpp index 152376b5..04764b73 100644 --- a/libnymea-app/zigbee/zigbeemanager.cpp +++ b/libnymea-app/zigbee/zigbeemanager.cpp @@ -31,12 +31,16 @@ #include "zigbeemanager.h" #include "jsonrpc/jsonrpcclient.h" +#include "zigbee/zigbeeadapter.h" #include "zigbee/zigbeeadapters.h" +#include "zigbee/zigbeenetwork.h" +#include "zigbee/zigbeenetworks.h" ZigbeeManager::ZigbeeManager(JsonRpcClient *client, QObject *parent) : JsonHandler(parent), m_client(client), - m_adapters(new ZigbeeAdapters(this)) + m_adapters(new ZigbeeAdapters(this)), + m_networks(new ZigbeeNetworks(this)) { client->registerNotificationHandler(this, "notificationReceived"); } @@ -56,30 +60,43 @@ ZigbeeAdapters *ZigbeeManager::adapters() const return m_adapters; } +ZigbeeNetworks *ZigbeeManager::networks() const +{ + return m_networks; +} + void ZigbeeManager::init() { qDebug() << "Zigbee init..."; m_adapters->clear(); m_client->sendCommand("Zigbee.GetAdapters", this, "getAdaptersResponse"); + m_client->sendCommand("Zigbee.GetNetworks", this, "getNetworksResponse"); } -void ZigbeeManager::getAdaptersResponse(const QVariantMap ¶ms) +void ZigbeeManager::getAdaptersResponse(int commandId, const QVariantMap ¶ms) { - qDebug() << "Get adapters response" << params; + qDebug() << "Zigbee get adapters response" << commandId << params; m_adapters->clear(); - foreach (const QVariant &adapterVariant, params.value("params").toMap().value("adapters").toList()) { + foreach (const QVariant &adapterVariant, params.value("adapters").toList()) { QVariantMap adapterMap = adapterVariant.toMap(); - 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->setBackendType(ZigbeeAdapter::stringToZigbeeBackendType(adapterMap.value("backendType").toString())); - adapter->setBaudRate(adapterMap.value("baudRate").toUInt()); + ZigbeeAdapter *adapter = unpackAdapter(adapterMap); qDebug() << "Zigbee adapter added" << adapter->description() << adapter->systemLocation(); m_adapters->addAdapter(adapter); } } +void ZigbeeManager::getNetworksResponse(int commandId, const QVariantMap ¶ms) +{ + qDebug() << "Zigbee get networks response" << commandId << params; + m_adapters->clear(); + foreach (const QVariant &networkVariant, params.value("zigbeeNetworks").toList()) { + QVariantMap networkMap = networkVariant.toMap(); + ZigbeeNetwork *network = unpackNetwork(networkMap); + qDebug() << "Zigbee network added" << network->networkUuid().toString() << network->serialPort() << network->macAddress(); + m_networks->addNetwork(network); + } +} + void ZigbeeManager::notificationReceived(const QVariantMap ¬ification) { QString notificationString = notification.value("notification").toString(); @@ -95,6 +112,30 @@ void ZigbeeManager::notificationReceived(const QVariantMap ¬ification) return; } + if (notificationString == "Zigbee.NetworkAdded") { + QVariantMap networkMap = notification.value("params").toMap().value("zigbeeNetwork").toMap(); + m_networks->addNetwork(unpackNetwork(networkMap)); + return; + } + + if (notificationString == "Zigbee.NetworkRemoved") { + QUuid networkUuid = notification.value("params").toMap().value("zigbeeNetwork").toUuid(); + m_networks->removeNetwork(networkUuid); + return; + } + + if (notificationString == "Zigbee.NetworkChanged") { + QVariantMap networkMap = notification.value("params").toMap().value("zigbeeNetwork").toMap(); + QUuid networkUuid = networkMap.value("networkUuid").toUuid(); + ZigbeeNetwork *network = m_networks->getNetwork(networkUuid); + if (!network) { + qWarning() << "Could not find network for changed notification"; + return; + } + fillNetworkData(network, networkMap); + return; + } + qDebug() << "Unhandled Zigbee notification" << notificationString << notification; } @@ -104,8 +145,33 @@ ZigbeeAdapter *ZigbeeManager::unpackAdapter(const QVariantMap &adapterMap) adapter->setName(adapterMap.value("name").toString()); adapter->setDescription(adapterMap.value("description").toString()); adapter->setSystemLocation(adapterMap.value("systemLocation").toString()); + adapter->setHardwareRecognized(adapterMap.value("hardwareRecognized").toBool()); adapter->setBackendType(ZigbeeAdapter::stringToZigbeeBackendType(adapterMap.value("backendType").toString())); adapter->setBaudRate(adapterMap.value("baudRate").toUInt()); return adapter; } +ZigbeeNetwork *ZigbeeManager::unpackNetwork(const QVariantMap &networkMap) +{ + ZigbeeNetwork *network = new ZigbeeNetwork(m_networks); + fillNetworkData(network, networkMap); + return network; +} + +void ZigbeeManager::fillNetworkData(ZigbeeNetwork *network, const QVariantMap &networkMap) +{ + network->setNetworkUuid(networkMap.value("networkUuid").toUuid()); + network->setSerialPort(networkMap.value("serialPort").toString()); + network->setBaudRate(networkMap.value("baudRate").toUInt()); + network->setMacAddress(networkMap.value("macAddress").toString()); + network->setFirmwareVersion(networkMap.value("firmwareVersion").toString()); + network->setPanId(networkMap.value("panId").toUInt()); + network->setChannel(networkMap.value("channel").toUInt()); + network->setChannelMask(networkMap.value("channelMask").toUInt()); + network->setPermitJoiningEnabled(networkMap.value("permitJoiningEnabled").toBool()); + network->setPermitJoiningDuration(networkMap.value("permitJoiningDuration").toUInt()); + network->setPermitJoiningRemaining(networkMap.value("permitJoiningRemaining").toUInt()); + network->setBackendType(ZigbeeAdapter::stringToZigbeeBackendType(networkMap.value("backendType").toString())); + network->setNetworkState(ZigbeeNetwork::stringToZigbeeNetworkState(networkMap.value("networkState").toString())); +} + diff --git a/libnymea-app/zigbee/zigbeemanager.h b/libnymea-app/zigbee/zigbeemanager.h index 56f99a8d..057c388f 100644 --- a/libnymea-app/zigbee/zigbeemanager.h +++ b/libnymea-app/zigbee/zigbeemanager.h @@ -37,11 +37,14 @@ class JsonRpcClient; class ZigbeeAdapter; class ZigbeeAdapters; +class ZigbeeNetwork; +class ZigbeeNetworks; class ZigbeeManager : public JsonHandler { Q_OBJECT Q_PROPERTY(ZigbeeAdapters *adapters READ adapters CONSTANT) + Q_PROPERTY(ZigbeeNetworks *networks READ networks CONSTANT) public: explicit ZigbeeManager(JsonRpcClient* client, QObject *parent = nullptr); @@ -50,22 +53,26 @@ public: QString nameSpace() const override; ZigbeeAdapters *adapters() const; + ZigbeeNetworks *networks() const; void init(); signals: private: - Q_INVOKABLE void getAdaptersResponse(const QVariantMap ¶ms); + Q_INVOKABLE void getAdaptersResponse(int commandId, const QVariantMap ¶ms); + Q_INVOKABLE void getNetworksResponse(int commandId, const QVariantMap ¶ms); Q_INVOKABLE void notificationReceived(const QVariantMap ¬ification); private: JsonRpcClient* m_client = nullptr; ZigbeeAdapters *m_adapters = nullptr; + ZigbeeNetworks *m_networks = nullptr; ZigbeeAdapter *unpackAdapter(const QVariantMap &adapterMap); - + ZigbeeNetwork *unpackNetwork(const QVariantMap &networkMap); + void fillNetworkData(ZigbeeNetwork *network, const QVariantMap &networkMap); }; diff --git a/libnymea-app/zigbee/zigbeenetwork.cpp b/libnymea-app/zigbee/zigbeenetwork.cpp new file mode 100644 index 00000000..7eaa61a4 --- /dev/null +++ b/libnymea-app/zigbee/zigbeenetwork.cpp @@ -0,0 +1,237 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "zigbeenetwork.h" + +ZigbeeNetwork::ZigbeeNetwork(QObject *parent) : QObject(parent) +{ + +} + +QUuid ZigbeeNetwork::networkUuid() const +{ + return m_networkUuid; +} + +void ZigbeeNetwork::setNetworkUuid(const QUuid &networkUuid) +{ + if (m_networkUuid == networkUuid) + return; + + m_networkUuid = networkUuid; + emit networkUuidChanged(); +} + +QString ZigbeeNetwork::serialPort() const +{ + return m_serialPort; +} + +void ZigbeeNetwork::setSerialPort(const QString &serialPort) +{ + if (m_serialPort == serialPort) + return; + + m_serialPort = serialPort; + emit serialPortChanged(); +} + +uint ZigbeeNetwork::baudRate() const +{ + return m_baudRate; +} + +void ZigbeeNetwork::setBaudRate(uint baudRate) +{ + if (m_baudRate == baudRate) + return; + + m_baudRate = baudRate; + emit baudRateChanged(); +} + +QString ZigbeeNetwork::macAddress() const +{ + return m_macAddress; +} + +void ZigbeeNetwork::setMacAddress(const QString &macAddress) +{ + if (m_macAddress == macAddress) + return; + + m_macAddress = macAddress; + emit macAddressChanged(); +} + +QString ZigbeeNetwork::firmwareVersion() const +{ + return m_firmwareVersion; +} + +void ZigbeeNetwork::setFirmwareVersion(const QString &firmwareVersion) +{ + if (m_firmwareVersion == firmwareVersion) + return; + + m_firmwareVersion = firmwareVersion; + emit firmwareVersionChanged(); +} + +uint ZigbeeNetwork::panId() const +{ + return m_panId; +} + +void ZigbeeNetwork::setPanId(uint panId) +{ + if (m_panId == panId) + return; + + m_panId = panId; + emit panIdChanged(); +} + +uint ZigbeeNetwork::channel() const +{ + return m_channel; +} + +void ZigbeeNetwork::setChannel(uint channel) +{ + if (m_channel == channel) + return; + + m_channel = channel; + emit channelChanged(); +} + +uint ZigbeeNetwork::channelMask() const +{ + return m_channelMask; +} + +void ZigbeeNetwork::setChannelMask(uint channelMask) +{ + if (m_channelMask == channelMask) + return; + + m_channelMask = channelMask; + emit channelMaskChanged(); +} + +bool ZigbeeNetwork::permitJoiningEnabled() const +{ + return m_permitJoiningEnabled; +} + +void ZigbeeNetwork::setPermitJoiningEnabled(bool permitJoiningEnabled) +{ + if (m_permitJoiningEnabled == permitJoiningEnabled) + return; + + m_permitJoiningEnabled = permitJoiningEnabled; + emit permitJoiningEnabledChanged(); +} + +uint ZigbeeNetwork::permitJoiningDuration() const +{ + return m_permitJoiningDuration; +} + +void ZigbeeNetwork::setPermitJoiningDuration(uint permitJoiningDuration) +{ + if (m_permitJoiningDuration == permitJoiningDuration) + return; + + m_permitJoiningDuration = permitJoiningDuration; + emit permitJoiningDurationChanged(); +} + +uint ZigbeeNetwork::permitJoiningRemaining() const +{ + return m_permitJoiningRemaining; +} + +void ZigbeeNetwork::setPermitJoiningRemaining(uint permitJoiningRemaining) +{ + if (m_permitJoiningRemaining == permitJoiningRemaining) + return; + + m_permitJoiningRemaining = permitJoiningRemaining; + emit permitJoiningRemainingChanged(); +} + +ZigbeeAdapter::ZigbeeBackendType ZigbeeNetwork::backendType() const +{ + return m_backendType; +} + +void ZigbeeNetwork::setBackendType(ZigbeeAdapter::ZigbeeBackendType backendType) +{ + if (m_backendType == backendType) + return; + + m_backendType = backendType; + emit backendTypeChanged(); +} + +ZigbeeNetwork::ZigbeeNetworkState ZigbeeNetwork::networkState() const +{ + return m_networkState; +} + +void ZigbeeNetwork::setNetworkState(ZigbeeNetwork::ZigbeeNetworkState networkState) +{ + if (m_networkState == networkState) + return; + + m_networkState = networkState; + emit networkStateChanged(); +} + +ZigbeeNetwork::ZigbeeNetworkState ZigbeeNetwork::stringToZigbeeNetworkState(const QString &networkStateString) +{ + if (networkStateString == "ZigbeeNetworkStateOffline") { + return ZigbeeNetworkStateOffline; + } else if (networkStateString == "ZigbeeNetworkStateStarting") { + return ZigbeeNetworkStateStarting; + } else if (networkStateString == "ZigbeeNetworkStateUpdating") { + return ZigbeeNetworkStateUpdating; + } else if (networkStateString == "ZigbeeNetworkStateOnline") { + return ZigbeeNetworkStateOnline; + } else if (networkStateString == "ZigbeeNetworkStateError") { + return ZigbeeNetworkStateError; + } else { + return ZigbeeNetworkStateError; + } +} + + diff --git a/libnymea-app/zigbee/zigbeenetwork.h b/libnymea-app/zigbee/zigbeenetwork.h new file mode 100644 index 00000000..805e1bbd --- /dev/null +++ b/libnymea-app/zigbee/zigbeenetwork.h @@ -0,0 +1,141 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef ZIGBEENETWORK_H +#define ZIGBEENETWORK_H + +#include +#include + +#include "zigbeeadapter.h" + +class ZigbeeNetwork : public QObject +{ + Q_OBJECT + Q_PROPERTY(QUuid networkUuid READ networkUuid NOTIFY networkUuidChanged) + Q_PROPERTY(QString serialPort READ serialPort NOTIFY serialPortChanged) + Q_PROPERTY(uint baudRate READ baudRate NOTIFY baudRateChanged) + Q_PROPERTY(QString macAddress READ macAddress NOTIFY macAddressChanged) + Q_PROPERTY(QString firmwareVersion READ firmwareVersion NOTIFY firmwareVersionChanged) + Q_PROPERTY(uint panId READ panId NOTIFY panIdChanged) + Q_PROPERTY(uint channel READ channel NOTIFY channelChanged) + Q_PROPERTY(uint channelMask READ channelMask NOTIFY channelMaskChanged) + Q_PROPERTY(bool permitJoiningEnabled READ permitJoiningEnabled NOTIFY permitJoiningEnabledChanged) + Q_PROPERTY(uint permitJoiningDuration READ permitJoiningDuration NOTIFY permitJoiningDurationChanged) + Q_PROPERTY(uint permitJoiningRemaining READ permitJoiningRemaining NOTIFY permitJoiningRemainingChanged) + Q_PROPERTY(ZigbeeAdapter::ZigbeeBackendType backendType READ backendType NOTIFY backendTypeChanged) + Q_PROPERTY(ZigbeeNetworkState networkState READ networkState NOTIFY networkStateChanged) + +public: + + enum ZigbeeNetworkState { + ZigbeeNetworkStateOffline, + ZigbeeNetworkStateStarting, + ZigbeeNetworkStateUpdating, + ZigbeeNetworkStateOnline, + ZigbeeNetworkStateError + }; + Q_ENUM(ZigbeeNetworkState) + + explicit ZigbeeNetwork(QObject *parent = nullptr); + + QUuid networkUuid() const; + void setNetworkUuid(const QUuid &networkUuid); + + QString serialPort() const; + void setSerialPort(const QString &serialPort); + + uint baudRate() const; + void setBaudRate(uint baudRate); + + QString macAddress() const; + void setMacAddress(const QString &macAddress); + + QString firmwareVersion() const; + void setFirmwareVersion(const QString &firmwareVersion); + + uint panId() const; + void setPanId(uint panId); + + uint channel() const; + void setChannel(uint channel); + + uint channelMask() const; + void setChannelMask(uint channelMask); + + bool permitJoiningEnabled() const; + void setPermitJoiningEnabled(bool permitJoiningEnabled); + + uint permitJoiningDuration() const; + void setPermitJoiningDuration(uint permitJoiningDuration); + + uint permitJoiningRemaining() const; + void setPermitJoiningRemaining(uint permitJoiningRemaining); + + ZigbeeAdapter::ZigbeeBackendType backendType() const; + void setBackendType(ZigbeeAdapter::ZigbeeBackendType backendType); + + ZigbeeNetworkState networkState() const; + void setNetworkState(ZigbeeNetworkState networkState); + + static ZigbeeNetworkState stringToZigbeeNetworkState(const QString &networkStateString); + +signals: + void networkUuidChanged(); + void serialPortChanged(); + void baudRateChanged(); + void macAddressChanged(); + void firmwareVersionChanged(); + void panIdChanged(); + void channelChanged(); + void channelMaskChanged(); + void permitJoiningEnabledChanged(); + void permitJoiningDurationChanged(); + void permitJoiningRemainingChanged(); + void backendTypeChanged(); + void networkStateChanged(); + +private: + QUuid m_networkUuid; + QString m_serialPort; + uint m_baudRate; + QString m_macAddress; + QString m_firmwareVersion; + uint m_panId; + uint m_channel; + uint m_channelMask; + bool m_permitJoiningEnabled; + uint m_permitJoiningDuration; + uint m_permitJoiningRemaining; + ZigbeeAdapter::ZigbeeBackendType m_backendType; + ZigbeeNetworkState m_networkState; +}; + +#endif // ZIGBEENETWORK_H diff --git a/libnymea-app/zigbee/zigbeenetworks.cpp b/libnymea-app/zigbee/zigbeenetworks.cpp new file mode 100644 index 00000000..41a3ec62 --- /dev/null +++ b/libnymea-app/zigbee/zigbeenetworks.cpp @@ -0,0 +1,211 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "zigbeenetworks.h" + +ZigbeeNetworks::ZigbeeNetworks(QObject *parent) : QAbstractListModel(parent) +{ + +} + +int ZigbeeNetworks::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_networks.count(); +} + +QVariant ZigbeeNetworks::data(const QModelIndex &index, int role) const +{ + switch (role) { + case RoleUuid: + return m_networks.at(index.row())->networkUuid(); + case RoleSerialPort: + return m_networks.at(index.row())->serialPort(); + case RoleBaudRate: + return m_networks.at(index.row())->baudRate(); + case RoleMacAddress: + return m_networks.at(index.row())->macAddress(); + case RoleFirmwareVersion: + return m_networks.at(index.row())->firmwareVersion(); + case RolePanId: + return m_networks.at(index.row())->panId(); + case RoleChannel: + return m_networks.at(index.row())->channel(); + case RoleChannelMask: + return m_networks.at(index.row())->channelMask(); + case RolePermitJoiningEnabled: + return m_networks.at(index.row())->permitJoiningEnabled(); + case RolePermitJoiningDuration: + return m_networks.at(index.row())->permitJoiningDuration(); + case RolePermitJoiningRemaining: + return m_networks.at(index.row())->permitJoiningRemaining(); + case RoleBackendType: + return m_networks.at(index.row())->backendType(); + case RoleNetworkState: + return m_networks.at(index.row())->networkState(); + } + + return QVariant(); +} + +QHash ZigbeeNetworks::roleNames() const +{ + QHash roles; + roles.insert(RoleUuid, "networkUuid"); + roles.insert(RoleSerialPort, "serialPort"); + roles.insert(RoleBaudRate, "baudRate"); + roles.insert(RoleMacAddress, "macAddress"); + roles.insert(RoleFirmwareVersion, "firmwareVersion"); + roles.insert(RolePanId, "panId"); + roles.insert(RoleChannel, "channel"); + roles.insert(RoleChannelMask, "channelMask"); + roles.insert(RolePermitJoiningEnabled, "permitJoiningEnabled"); + roles.insert(RolePermitJoiningDuration, "permitJoiningDuration"); + roles.insert(RolePermitJoiningRemaining, "permitJoiningRemaining"); + roles.insert(RoleBackendType, "backendType"); + roles.insert(RoleNetworkState, "networkState"); + return roles; + +} + +void ZigbeeNetworks::addNetwork(ZigbeeNetwork *network) +{ + network->setParent(this); + beginInsertRows(QModelIndex(), m_networks.count(), m_networks.count()); + m_networks.append(network); + connect(network, &ZigbeeNetwork::networkUuidChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleUuid}); + }); + + connect(network, &ZigbeeNetwork::serialPortChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleSerialPort}); + }); + + connect(network, &ZigbeeNetwork::baudRateChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleBaudRate}); + }); + + connect(network, &ZigbeeNetwork::macAddressChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleMacAddress}); + }); + + connect(network, &ZigbeeNetwork::firmwareVersionChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleFirmwareVersion}); + }); + + connect(network, &ZigbeeNetwork::panIdChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RolePanId}); + }); + + connect(network, &ZigbeeNetwork::channelChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleChannel}); + }); + + connect(network, &ZigbeeNetwork::channelMaskChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleChannelMask}); + }); + + connect(network, &ZigbeeNetwork::permitJoiningEnabledChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RolePermitJoiningEnabled}); + }); + + connect(network, &ZigbeeNetwork::permitJoiningDurationChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RolePermitJoiningDuration}); + }); + + connect(network, &ZigbeeNetwork::permitJoiningRemainingChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RolePermitJoiningRemaining}); + }); + + connect(network, &ZigbeeNetwork::backendTypeChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleBackendType}); + }); + + connect(network, &ZigbeeNetwork::networkStateChanged, this, [this, network]() { + QModelIndex idx = index(m_networks.indexOf(network), 0); + emit dataChanged(idx, idx, {RoleNetworkState}); + }); + + endInsertRows(); + emit countChanged(); + +} + +void ZigbeeNetworks::removeNetwork(const QUuid &networkUuid) +{ + for (int i = 0; i < m_networks.count(); i++) { + if (m_networks.at(i)->networkUuid() == networkUuid) { + beginRemoveRows(QModelIndex(), i, i); + m_networks.takeAt(i)->deleteLater(); + endRemoveRows(); + return; + } + } +} + +void ZigbeeNetworks::clear() +{ + beginResetModel(); + qDeleteAll(m_networks); + m_networks.clear(); + endResetModel(); + emit countChanged(); +} + +ZigbeeNetwork *ZigbeeNetworks::get(int index) const +{ + if (index < 0 || index > m_networks.count() - 1) { + return nullptr; + } + return m_networks.at(index); +} + +ZigbeeNetwork *ZigbeeNetworks::getNetwork(const QUuid &networkUuid) const +{ + foreach (ZigbeeNetwork *network, m_networks) { + if (network->networkUuid() == networkUuid) { + return network; + } + } + + return nullptr; +} diff --git a/libnymea-app/zigbee/zigbeenetworks.h b/libnymea-app/zigbee/zigbeenetworks.h new file mode 100644 index 00000000..3a6376ff --- /dev/null +++ b/libnymea-app/zigbee/zigbeenetworks.h @@ -0,0 +1,85 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef ZIGBEENETWORKS_H +#define ZIGBEENETWORKS_H + +#include +#include + +#include "zigbeenetwork.h" + +class ZigbeeNetworks : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) + +public: + enum Roles { + RoleUuid, + RoleSerialPort, + RoleBaudRate, + RoleMacAddress, + RoleFirmwareVersion, + RolePanId, + RoleChannel, + RoleChannelMask, + RolePermitJoiningEnabled, + RolePermitJoiningDuration, + RolePermitJoiningRemaining, + RoleBackendType, + RoleNetworkState + }; + Q_ENUM(Roles) + + explicit ZigbeeNetworks(QObject *parent = nullptr); + virtual ~ZigbeeNetworks() override = default; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + + void addNetwork(ZigbeeNetwork *network); + void removeNetwork(const QUuid &networkUuid); + + void clear(); + + Q_INVOKABLE virtual ZigbeeNetwork *get(int index) const; + Q_INVOKABLE ZigbeeNetwork *getNetwork(const QUuid &networkUuid) const; + +signals: + void countChanged(); + +protected: + QList m_networks; + +}; + +#endif // ZIGBEENETWORKS_H diff --git a/nymea-app/ui/system/ZigbeeNetworkAddPage.qml b/nymea-app/ui/system/ZigbeeNetworkAddPage.qml index a3fe13ca..2085e846 100644 --- a/nymea-app/ui/system/ZigbeeNetworkAddPage.qml +++ b/nymea-app/ui/system/ZigbeeNetworkAddPage.qml @@ -51,7 +51,7 @@ SettingsPageBase { delegate: NymeaListItemDelegate { Layout.fillWidth: true - property var adapter: engine.zigbeeManager.adapters.get(index) +// 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}) @@ -70,7 +70,7 @@ SettingsPageBase { delegate: NymeaListItemDelegate { Layout.fillWidth: true - property var adapter: engine.zigbeeManager.adapters.get(index) +// 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}) diff --git a/nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml b/nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml index 2b83ad9c..35821600 100644 --- a/nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml +++ b/nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml @@ -61,6 +61,22 @@ SettingsPageBase { } + Repeater { + model: engine.zigbeeManager.networks + + + delegate: NymeaListItemDelegate { + Layout.fillWidth: true + // property var adapter: engine.zigbeeManager.adapters.get(index) + iconName: "../images/zigbee.svg" + text: model.macAddress + " - " + model.serialPort + subText: model.firmwareVersion + + //onClicked: pageStack.push(Qt.resolvedUrl("PluginParamsPage.qml"), {plugin: plugin}) + } + } + + NymeaListItemDelegate { Layout.fillWidth: true