First look at zigbee node api integration
This commit is contained in:
parent
47c41204ff
commit
6c37b3a750
@ -127,6 +127,8 @@
|
||||
#include "zigbee/zigbeeadaptersproxy.h"
|
||||
#include "zigbee/zigbeenetwork.h"
|
||||
#include "zigbee/zigbeenetworks.h"
|
||||
#include "zigbee/zigbeenodes.h"
|
||||
#include "zigbee/zigbeenodesproxy.h"
|
||||
#include "applogcontroller.h"
|
||||
#include "tagwatcher.h"
|
||||
#include "appdata.h"
|
||||
@ -314,6 +316,9 @@ void registerQmlTypes() {
|
||||
qmlRegisterType<ZigbeeAdaptersProxy>(uri, 1, 0, "ZigbeeAdaptersProxy");
|
||||
qmlRegisterUncreatableType<ZigbeeNetwork>(uri, 1, 0, "ZigbeeNetwork", "Get it from the ZigbeeManager");
|
||||
qmlRegisterUncreatableType<ZigbeeNetworks>(uri, 1, 0, "ZigbeeNetworks", "Get it from the ZigbeeManager");
|
||||
qmlRegisterUncreatableType<ZigbeeNode>(uri, 1, 0, "ZigbeeNode", "Get it from the ZigbeeNodes");
|
||||
qmlRegisterUncreatableType<ZigbeeNodes>(uri, 1, 0, "ZigbeeNodes", "Get it from the ZigbeeNetwork");
|
||||
qmlRegisterType<ZigbeeNodesProxy>(uri, 1, 0, "ZigbeeNodesProxy");
|
||||
|
||||
qmlRegisterType<ModbusRtuManager>(uri, 1, 0, "ModbusRtuManager");
|
||||
qmlRegisterUncreatableType<ModbusRtuMaster>(uri, 1, 0, "ModbusRtuMaster", "Get it from the ModbusRtuMasters");
|
||||
|
||||
@ -24,6 +24,8 @@ SOURCES += \
|
||||
$$PWD/models/scriptsproxymodel.cpp \
|
||||
$$PWD/tagwatcher.cpp \
|
||||
$$PWD/zigbee/zigbeenode.cpp \
|
||||
$$PWD/zigbee/zigbeenodes.cpp \
|
||||
$$PWD/zigbee/zigbeenodesproxy.cpp \
|
||||
$${PWD}/logging.cpp \
|
||||
$${PWD}/applogcontroller.cpp \
|
||||
$${PWD}/wifisetup/btwifisetup.cpp \
|
||||
@ -179,6 +181,8 @@ HEADERS += \
|
||||
$$PWD/models/scriptsproxymodel.h \
|
||||
$$PWD/tagwatcher.h \
|
||||
$$PWD/zigbee/zigbeenode.h \
|
||||
$$PWD/zigbee/zigbeenodes.h \
|
||||
$$PWD/zigbee/zigbeenodesproxy.h \
|
||||
$${PWD}/logging.h \
|
||||
$${PWD}/applogcontroller.h \
|
||||
$${PWD}/wifisetup/btwifisetup.h \
|
||||
|
||||
@ -36,9 +36,14 @@
|
||||
#include "zigbee/zigbeeadapters.h"
|
||||
#include "zigbee/zigbeenetwork.h"
|
||||
#include "zigbee/zigbeenetworks.h"
|
||||
#include "zigbee/zigbeenode.h"
|
||||
#include "zigbee/zigbeenodes.h"
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
#include "logging.h"
|
||||
NYMEA_LOGGING_CATEGORY(dcZigbee, "Zigbee")
|
||||
|
||||
ZigbeeManager::ZigbeeManager(QObject *parent) :
|
||||
JsonHandler(parent),
|
||||
m_adapters(new ZigbeeAdapters(this)),
|
||||
@ -100,7 +105,7 @@ int ZigbeeManager::addNetwork(const QString &serialPort, uint baudRate, const QS
|
||||
params.insert("baudRate", baudRate);
|
||||
params.insert("backend", backend);
|
||||
|
||||
qDebug() << "Add zigbee network" << params;
|
||||
qCDebug(dcZigbee()) << "Add zigbee network" << params;
|
||||
return m_engine->jsonRpcClient()->sendCommand("Zigbee.AddNetwork", params, this, "addNetworkResponse");
|
||||
}
|
||||
|
||||
@ -108,7 +113,7 @@ void ZigbeeManager::removeNetwork(const QUuid &networkUuid)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("networkUuid", networkUuid);
|
||||
qDebug() << "Remove zigbee network" << params;
|
||||
qCDebug(dcZigbee()) << "Remove zigbee network" << params;
|
||||
m_engine->jsonRpcClient()->sendCommand("Zigbee.RemoveNetwork", params, this, "removeNetworkResponse");
|
||||
}
|
||||
|
||||
@ -127,6 +132,21 @@ void ZigbeeManager::factoryResetNetwork(const QUuid &networkUuid)
|
||||
m_engine->jsonRpcClient()->sendCommand("Zigbee.FactoryResetNetwork", params, this, "factoryResetNetworkResponse");
|
||||
}
|
||||
|
||||
void ZigbeeManager::getNodes(const QUuid &networkUuid)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("networkUuid", networkUuid);
|
||||
m_engine->jsonRpcClient()->sendCommand("Zigbee.GetNodes", params, this, "getNodesResponse");
|
||||
}
|
||||
|
||||
int ZigbeeManager::removeNode(const QUuid &networkUuid, const QString &ieeeAddress)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("networkUuid", networkUuid);
|
||||
params.insert("ieeeAddress", ieeeAddress);
|
||||
return m_engine->jsonRpcClient()->sendCommand("Zigbee.RemoveNode", params, this, "removeNodeResponse");
|
||||
}
|
||||
|
||||
void ZigbeeManager::init()
|
||||
{
|
||||
m_adapters->clear();
|
||||
@ -142,7 +162,7 @@ void ZigbeeManager::init()
|
||||
|
||||
void ZigbeeManager::getAvailableBackendsResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Zigbee get available backends response" << commandId << params;
|
||||
qCDebug(dcZigbee()) << "Zigbee get available backends response" << commandId << params;
|
||||
m_availableBackends.clear();
|
||||
foreach (const QVariant &backendVariant, params.value("backends").toList()) {
|
||||
m_availableBackends << backendVariant.toString();
|
||||
@ -152,56 +172,73 @@ void ZigbeeManager::getAvailableBackendsResponse(int commandId, const QVariantMa
|
||||
|
||||
void ZigbeeManager::getAdaptersResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Zigbee get adapters response" << commandId << params;
|
||||
qCDebug(dcZigbee()) << "Zigbee get adapters response" << commandId << params;
|
||||
m_adapters->clear();
|
||||
foreach (const QVariant &adapterVariant, params.value("adapters").toList()) {
|
||||
QVariantMap adapterMap = adapterVariant.toMap();
|
||||
ZigbeeAdapter *adapter = unpackAdapter(adapterMap);
|
||||
qDebug() << "Zigbee adapter added" << adapter->description() << adapter->serialPort() << adapter->hardwareRecognized();
|
||||
qCDebug(dcZigbee()) << "Zigbee adapter added" << adapter->description() << adapter->serialPort() << adapter->hardwareRecognized();
|
||||
m_adapters->addAdapter(adapter);
|
||||
}
|
||||
|
||||
// ZigbeeAdapter *fakeAdapter = new ZigbeeAdapter();
|
||||
// fakeAdapter->setSerialPort("/dev/fake");
|
||||
// fakeAdapter->setBackend("Fake");
|
||||
// fakeAdapter->setBaudRate(9600);
|
||||
// fakeAdapter->setDescription("Fake adapter");
|
||||
// fakeAdapter->setHardwareRecognized(true);
|
||||
// fakeAdapter->setName("Fake");
|
||||
// m_adapters->addAdapter(fakeAdapter);
|
||||
}
|
||||
|
||||
void ZigbeeManager::getNetworksResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Zigbee get networks response" << commandId << params;
|
||||
qCDebug(dcZigbee()) << "Zigbee get networks response" << commandId << params;
|
||||
m_networks->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();
|
||||
qCDebug(dcZigbee()) << "Zigbee network added" << network->networkUuid().toString() << network->serialPort() << network->macAddress();
|
||||
m_networks->addNetwork(network);
|
||||
|
||||
// Get nodes from this network
|
||||
getNodes(network->networkUuid());
|
||||
}
|
||||
}
|
||||
|
||||
void ZigbeeManager::addNetworkResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Zigbee add network response" << commandId << params;
|
||||
qCDebug(dcZigbee()) << "Zigbee add network response" << commandId << params;
|
||||
emit addNetworkReply(commandId, params.value("zigbeeError").toString(), params.value("networkUuid").toUuid());
|
||||
}
|
||||
|
||||
void ZigbeeManager::removeNetworkResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Zigbee remove network response" << commandId << params;
|
||||
qCDebug(dcZigbee()) << "Zigbee remove network response" << commandId << params;
|
||||
}
|
||||
|
||||
void ZigbeeManager::setPermitJoinResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Zigbee set permit join network response" << commandId << params;
|
||||
qCDebug(dcZigbee()) << "Zigbee set permit join network response" << commandId << params;
|
||||
}
|
||||
|
||||
void ZigbeeManager::factoryResetNetworkResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Zigbee factory reset network response" << commandId << params;
|
||||
qCDebug(dcZigbee()) << "Zigbee factory reset network response" << commandId << params;
|
||||
}
|
||||
|
||||
void ZigbeeManager::getNodesResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qCDebug(dcZigbee()) << "Zigbee get nodes response" << commandId << params;
|
||||
|
||||
foreach (const QVariant &nodeVariant, params.value("zigbeeNodes").toList()) {
|
||||
QVariantMap nodeMap = nodeVariant.toMap();
|
||||
QUuid networkUuid = nodeMap.value("networkUuid").toUuid();
|
||||
ZigbeeNetwork *network = m_networks->getNetwork(networkUuid);
|
||||
if (!network) {
|
||||
qCWarning(dcZigbee()) << "Could not find network for node" << nodeMap;
|
||||
return;
|
||||
}
|
||||
|
||||
addOrUpdateNode(network, nodeMap);
|
||||
}
|
||||
}
|
||||
|
||||
void ZigbeeManager::removeNodeResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qCDebug(dcZigbee()) << "Zigbee remove node response" << commandId << params;
|
||||
emit removeNodeReply(commandId, params.value("zigbeeError").toString());
|
||||
}
|
||||
|
||||
void ZigbeeManager::notificationReceived(const QVariantMap ¬ification)
|
||||
@ -236,14 +273,54 @@ void ZigbeeManager::notificationReceived(const QVariantMap ¬ification)
|
||||
QUuid networkUuid = networkMap.value("networkUuid").toUuid();
|
||||
ZigbeeNetwork *network = m_networks->getNetwork(networkUuid);
|
||||
if (!network) {
|
||||
qWarning() << "Could not find network for changed notification";
|
||||
qCWarning(dcZigbee()) << "Could not find network for changed notification";
|
||||
return;
|
||||
}
|
||||
fillNetworkData(network, networkMap);
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Unhandled Zigbee notification" << notificationString << notification;
|
||||
if (notificationString == "Zigbee.NodeAdded") {
|
||||
QVariantMap nodeMap = notification.value("params").toMap().value("zigbeeNode").toMap();
|
||||
QUuid networkUuid = nodeMap.value("networkUuid").toUuid();
|
||||
ZigbeeNetwork *network = m_networks->getNetwork(networkUuid);
|
||||
if (!network) {
|
||||
qCWarning(dcZigbee()) << "Could not find network for node added notification" << nodeMap;
|
||||
return;
|
||||
}
|
||||
|
||||
addOrUpdateNode(network, nodeMap);
|
||||
return;
|
||||
}
|
||||
|
||||
if (notificationString == "Zigbee.NodeRemoved") {
|
||||
QVariantMap nodeMap = notification.value("params").toMap().value("zigbeeNode").toMap();
|
||||
QUuid networkUuid = nodeMap.value("networkUuid").toUuid();
|
||||
ZigbeeNetwork *network = m_networks->getNetwork(networkUuid);
|
||||
if (!network) {
|
||||
qCWarning(dcZigbee()) << "Could not find network for node removed notification" << nodeMap;
|
||||
return;
|
||||
}
|
||||
|
||||
QString ieeeAddress = nodeMap.value("ieeeAddress").toString();
|
||||
network->nodes()->removeNode(ieeeAddress);
|
||||
return;
|
||||
}
|
||||
|
||||
if (notificationString == "Zigbee.NodeChanged") {
|
||||
QVariantMap nodeMap = notification.value("params").toMap().value("zigbeeNode").toMap();
|
||||
QUuid networkUuid = nodeMap.value("networkUuid").toUuid();
|
||||
ZigbeeNetwork *network = m_networks->getNetwork(networkUuid);
|
||||
if (!network) {
|
||||
qCWarning(dcZigbee()) << "Could not find network for node changed notification" << nodeMap;
|
||||
return;
|
||||
}
|
||||
|
||||
addOrUpdateNode(network, nodeMap);
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbee()) << "Unhandled Zigbee notification" << notificationString << notification;
|
||||
}
|
||||
|
||||
ZigbeeAdapter *ZigbeeManager::unpackAdapter(const QVariantMap &adapterMap)
|
||||
@ -266,6 +343,15 @@ ZigbeeNetwork *ZigbeeManager::unpackNetwork(const QVariantMap &networkMap)
|
||||
return network;
|
||||
}
|
||||
|
||||
ZigbeeNode *ZigbeeManager::unpackNode(const QVariantMap &nodeMap)
|
||||
{
|
||||
QUuid networkUuid = nodeMap.value("networkUuid").toUuid();
|
||||
QString ieeeAddress = nodeMap.value("ieeeAddress").toString();
|
||||
ZigbeeNode *node = new ZigbeeNode(networkUuid, ieeeAddress, this);
|
||||
node->updateNodeProperties(nodeMap);
|
||||
return node;
|
||||
}
|
||||
|
||||
void ZigbeeManager::fillNetworkData(ZigbeeNetwork *network, const QVariantMap &networkMap)
|
||||
{
|
||||
network->setNetworkUuid(networkMap.value("networkUuid").toUuid());
|
||||
@ -283,3 +369,14 @@ void ZigbeeManager::fillNetworkData(ZigbeeNetwork *network, const QVariantMap &n
|
||||
network->setNetworkState(ZigbeeNetwork::stringToZigbeeNetworkState(networkMap.value("networkState").toString()));
|
||||
}
|
||||
|
||||
void ZigbeeManager::addOrUpdateNode(ZigbeeNetwork *network, const QVariantMap &nodeMap)
|
||||
{
|
||||
QString ieeeAddress = nodeMap.value("ieeeAddress").toString();
|
||||
ZigbeeNode *node = network->nodes()->getNode(ieeeAddress);
|
||||
if (node) {
|
||||
node->updateNodeProperties(nodeMap);
|
||||
} else {
|
||||
network->nodes()->addNode(unpackNode(nodeMap));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -35,11 +35,13 @@
|
||||
#include "zigbeeadapter.h"
|
||||
#include "jsonrpc/jsonhandler.h"
|
||||
|
||||
class Engine;
|
||||
class JsonRpcClient;
|
||||
class ZigbeeAdapters;
|
||||
class ZigbeeNetwork;
|
||||
class ZigbeeNetworks;
|
||||
class Engine;
|
||||
class ZigbeeNode;
|
||||
class ZigbeeNodes;
|
||||
|
||||
class ZigbeeManager : public JsonHandler
|
||||
{
|
||||
@ -63,15 +65,19 @@ public:
|
||||
ZigbeeAdapters *adapters() const;
|
||||
ZigbeeNetworks *networks() const;
|
||||
|
||||
// Network
|
||||
Q_INVOKABLE int addNetwork(const QString &serialPort, uint baudRate, const QString &backend);
|
||||
Q_INVOKABLE void removeNetwork(const QUuid &networkUuid);
|
||||
Q_INVOKABLE void setPermitJoin(const QUuid &networkUuid, uint duration = 120);
|
||||
Q_INVOKABLE void factoryResetNetwork(const QUuid &networkUuid);
|
||||
Q_INVOKABLE void getNodes(const QUuid &networkUuid);
|
||||
Q_INVOKABLE int removeNode(const QUuid &networkUuid, const QString &ieeeAddress);
|
||||
|
||||
signals:
|
||||
void engineChanged();
|
||||
void availableBackendsChanged();
|
||||
void addNetworkReply(int commandId, const QString &error, const QUuid &networkUuid);
|
||||
void removeNodeReply(int commandId, const QString &error);
|
||||
|
||||
private:
|
||||
void init();
|
||||
@ -85,6 +91,9 @@ private:
|
||||
Q_INVOKABLE void setPermitJoinResponse(int commandId, const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void factoryResetNetworkResponse(int commandId, const QVariantMap ¶ms);
|
||||
|
||||
Q_INVOKABLE void getNodesResponse(int commandId, const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void removeNodeResponse(int commandId, const QVariantMap ¶ms);
|
||||
|
||||
Q_INVOKABLE void notificationReceived(const QVariantMap ¬ification);
|
||||
|
||||
private:
|
||||
@ -95,8 +104,9 @@ private:
|
||||
|
||||
ZigbeeAdapter *unpackAdapter(const QVariantMap &adapterMap);
|
||||
ZigbeeNetwork *unpackNetwork(const QVariantMap &networkMap);
|
||||
ZigbeeNode *unpackNode(const QVariantMap &nodeMap);
|
||||
void fillNetworkData(ZigbeeNetwork *network, const QVariantMap &networkMap);
|
||||
|
||||
void addOrUpdateNode(ZigbeeNetwork *network, const QVariantMap &nodeMap);
|
||||
};
|
||||
|
||||
#endif // ZIGBEEMANAGER_H
|
||||
|
||||
@ -30,13 +30,14 @@
|
||||
|
||||
#include "zigbeenetwork.h"
|
||||
|
||||
ZigbeeNetwork::ZigbeeNetwork(QObject *parent) : QObject(parent)
|
||||
ZigbeeNetwork::ZigbeeNetwork(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_nodes(new ZigbeeNodes(this))
|
||||
{
|
||||
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();
|
||||
@ -44,6 +45,12 @@ ZigbeeNetwork::ZigbeeNetwork(QObject *parent) : QObject(parent)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
ZigbeeNodes *ZigbeeNetwork::nodes() const
|
||||
{
|
||||
return m_nodes;
|
||||
}
|
||||
|
||||
QUuid ZigbeeNetwork::networkUuid() const
|
||||
{
|
||||
return m_networkUuid;
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
#include "zigbeenodes.h"
|
||||
#include "zigbeeadapter.h"
|
||||
|
||||
class ZigbeeNetwork : public QObject
|
||||
@ -54,6 +55,7 @@ class ZigbeeNetwork : public QObject
|
||||
Q_PROPERTY(uint permitJoiningRemaining READ permitJoiningRemaining NOTIFY permitJoiningRemainingChanged)
|
||||
Q_PROPERTY(QString backend READ backend NOTIFY backendChanged)
|
||||
Q_PROPERTY(ZigbeeNetworkState networkState READ networkState NOTIFY networkStateChanged)
|
||||
Q_PROPERTY(ZigbeeNodes *nodes READ nodes CONSTANT)
|
||||
|
||||
// Internal properties
|
||||
|
||||
@ -69,6 +71,8 @@ public:
|
||||
|
||||
explicit ZigbeeNetwork(QObject *parent = nullptr);
|
||||
|
||||
ZigbeeNodes *nodes() const;
|
||||
|
||||
QUuid networkUuid() const;
|
||||
void setNetworkUuid(const QUuid &networkUuid);
|
||||
|
||||
@ -145,6 +149,8 @@ private:
|
||||
QString m_backend;
|
||||
ZigbeeNetworkState m_networkState;
|
||||
|
||||
ZigbeeNodes *m_nodes = nullptr;
|
||||
|
||||
QTimer *m_permitJoinTimer = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@ -92,7 +92,6 @@ QHash<int, QByteArray> ZigbeeNetworks::roleNames() const
|
||||
roles.insert(RoleBackend, "backend");
|
||||
roles.insert(RoleNetworkState, "networkState");
|
||||
return roles;
|
||||
|
||||
}
|
||||
|
||||
void ZigbeeNetworks::addNetwork(ZigbeeNetwork *network)
|
||||
|
||||
@ -1,8 +1,39 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "zigbeenode.h"
|
||||
|
||||
ZigbeeNode::ZigbeeNode(QUuid networkUuid, QObject *parent) :
|
||||
ZigbeeNode::ZigbeeNode(const QUuid &networkUuid, const QString &ieeeAddress, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_networkUuid(networkUuid)
|
||||
m_networkUuid(networkUuid),
|
||||
m_ieeeAddress(ieeeAddress)
|
||||
{
|
||||
|
||||
}
|
||||
@ -11,3 +42,187 @@ QUuid ZigbeeNode::networkUuid() const
|
||||
{
|
||||
return m_networkUuid;
|
||||
}
|
||||
|
||||
QString ZigbeeNode::ieeeAddress() const
|
||||
{
|
||||
return m_ieeeAddress;
|
||||
}
|
||||
|
||||
quint16 ZigbeeNode::networkAddress() const
|
||||
{
|
||||
return m_networkAddress;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setNetworkAddress(quint16 networkAddress)
|
||||
{
|
||||
if (m_networkAddress == networkAddress)
|
||||
return;
|
||||
|
||||
m_networkAddress = networkAddress;
|
||||
emit networkAddressChanged(m_networkAddress);
|
||||
}
|
||||
|
||||
ZigbeeNode::ZigbeeNodeType ZigbeeNode::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setType(ZigbeeNode::ZigbeeNodeType type)
|
||||
{
|
||||
if (m_type == type)
|
||||
return;
|
||||
|
||||
m_type = type;
|
||||
emit typeChanged(m_type);
|
||||
}
|
||||
|
||||
ZigbeeNode::ZigbeeNodeState ZigbeeNode::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setState(ZigbeeNode::ZigbeeNodeState state)
|
||||
{
|
||||
if (m_state == state)
|
||||
return;
|
||||
|
||||
m_state = state;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
|
||||
QString ZigbeeNode::manufacturer() const
|
||||
{
|
||||
return m_manufacturer;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setManufacturer(const QString &manufacturer)
|
||||
{
|
||||
if (m_manufacturer == manufacturer)
|
||||
return;
|
||||
|
||||
m_manufacturer = manufacturer;
|
||||
emit manufacturerChanged(m_manufacturer);
|
||||
}
|
||||
|
||||
QString ZigbeeNode::model() const
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setModel(const QString &model)
|
||||
{
|
||||
if (m_model == model)
|
||||
return;
|
||||
|
||||
m_model = model;
|
||||
emit modelChanged(m_model);
|
||||
}
|
||||
|
||||
QString ZigbeeNode::version() const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setVersion(const QString &version)
|
||||
{
|
||||
if (m_version == version)
|
||||
return;
|
||||
|
||||
m_version = version;
|
||||
emit versionChanged(m_version);
|
||||
}
|
||||
|
||||
bool ZigbeeNode::rxOnWhenIdle() const
|
||||
{
|
||||
return m_rxOnWhenIdle;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setRxOnWhenIdle(bool rxOnWhenIdle)
|
||||
{
|
||||
if (m_rxOnWhenIdle == rxOnWhenIdle)
|
||||
return;
|
||||
|
||||
m_rxOnWhenIdle = rxOnWhenIdle;
|
||||
emit rxOnWhenIdleChanged(m_rxOnWhenIdle);
|
||||
}
|
||||
|
||||
bool ZigbeeNode::reachable() const
|
||||
{
|
||||
return m_reachable;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setReachable(bool reachable)
|
||||
{
|
||||
if (m_reachable == reachable)
|
||||
return;
|
||||
|
||||
m_reachable = reachable;
|
||||
emit reachableChanged(m_reachable);
|
||||
}
|
||||
|
||||
uint ZigbeeNode::lqi() const
|
||||
{
|
||||
return m_lqi;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setLqi(uint lqi)
|
||||
{
|
||||
if (m_lqi == lqi)
|
||||
return;
|
||||
|
||||
m_lqi = lqi;
|
||||
emit lqiChanged(m_lqi);
|
||||
|
||||
}
|
||||
|
||||
QDateTime ZigbeeNode::lastSeen() const
|
||||
{
|
||||
return m_lastSeen;
|
||||
}
|
||||
|
||||
void ZigbeeNode::setLastSeen(const QDateTime &lastSeen)
|
||||
{
|
||||
if (m_lastSeen == lastSeen)
|
||||
return;
|
||||
|
||||
m_lastSeen = lastSeen;
|
||||
emit lastSeenChanged(m_lastSeen);
|
||||
}
|
||||
|
||||
ZigbeeNode::ZigbeeNodeState ZigbeeNode::stringToNodeState(const QString &nodeState)
|
||||
{
|
||||
if (nodeState == "ZigbeeNodeStateUninitialized") {
|
||||
return ZigbeeNodeStateUninitialized;
|
||||
} else if (nodeState == "ZigbeeNodeStateInitializing") {
|
||||
return ZigbeeNodeStateInitializing;
|
||||
} else if (nodeState == "ZigbeeNodeStateInitialized") {
|
||||
return ZigbeeNodeStateInitialized;
|
||||
} else {
|
||||
return ZigbeeNodeStateHandled;
|
||||
}
|
||||
}
|
||||
|
||||
ZigbeeNode::ZigbeeNodeType ZigbeeNode::stringToNodeType(const QString &nodeType)
|
||||
{
|
||||
if (nodeType == "ZigbeeNodeTypeCoordinator") {
|
||||
return ZigbeeNodeTypeCoordinator;
|
||||
} else if (nodeType == "ZigbeeNodeTypeRouter") {
|
||||
return ZigbeeNodeTypeRouter;
|
||||
} else {
|
||||
return ZigbeeNodeTypeEndDevice;
|
||||
}
|
||||
}
|
||||
|
||||
void ZigbeeNode::updateNodeProperties(const QVariantMap &nodeMap)
|
||||
{
|
||||
setNetworkAddress(nodeMap.value("networkAddress").toUInt());
|
||||
setType(ZigbeeNode::stringToNodeType(nodeMap.value("type").toString()));
|
||||
setState(ZigbeeNode::stringToNodeState(nodeMap.value("state").toString()));
|
||||
setManufacturer(nodeMap.value("manufacturer").toString());
|
||||
setModel(nodeMap.value("model").toString());
|
||||
setVersion(nodeMap.value("version").toString());
|
||||
setRxOnWhenIdle(nodeMap.value("receiverOnWhileIdle").toBool());
|
||||
setReachable(nodeMap.value("reachable").toBool());
|
||||
setLqi(nodeMap.value("lqi").toUInt());
|
||||
setLastSeen(QDateTime::fromMSecsSinceEpoch(nodeMap.value("lastSeen").toUInt() * 1000));
|
||||
}
|
||||
|
||||
@ -1,28 +1,138 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 ZIGBEENODE_H
|
||||
#define ZIGBEENODE_H
|
||||
|
||||
#include <QUuid>
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
#include <QVariantMap>
|
||||
|
||||
class ZigbeeNode : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid networkUuid READ networkUuid CONSTANT)
|
||||
|
||||
Q_PROPERTY(QString ieeeAddress READ ieeeAddress CONSTANT)
|
||||
Q_PROPERTY(quint16 networkAddress READ networkAddress WRITE setNetworkAddress NOTIFY networkAddressChanged)
|
||||
Q_PROPERTY(ZigbeeNodeType type READ type WRITE setType NOTIFY typeChanged)
|
||||
Q_PROPERTY(ZigbeeNodeState state READ state WRITE setState NOTIFY stateChanged)
|
||||
Q_PROPERTY(QString manufacturer READ manufacturer WRITE setManufacturer NOTIFY manufacturerChanged)
|
||||
Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged)
|
||||
Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged)
|
||||
Q_PROPERTY(bool rxOnWhenIdle READ rxOnWhenIdle WRITE setRxOnWhenIdle NOTIFY rxOnWhenIdleChanged)
|
||||
Q_PROPERTY(bool reachable READ reachable WRITE setReachable NOTIFY reachableChanged)
|
||||
Q_PROPERTY(uint lqi READ lqi WRITE setLqi NOTIFY lqiChanged)
|
||||
Q_PROPERTY(QDateTime lastSeen READ lastSeen WRITE setLastSeen NOTIFY lastSeenChanged)
|
||||
|
||||
public:
|
||||
explicit ZigbeeNode(QUuid networkUuid, QObject *parent = nullptr);
|
||||
enum ZigbeeNodeType {
|
||||
ZigbeeNodeTypeCoordinator,
|
||||
ZigbeeNodeTypeRouter,
|
||||
ZigbeeNodeTypeEndDevice
|
||||
};
|
||||
Q_ENUM(ZigbeeNodeType)
|
||||
|
||||
enum ZigbeeNodeState {
|
||||
ZigbeeNodeStateUninitialized,
|
||||
ZigbeeNodeStateInitializing,
|
||||
ZigbeeNodeStateInitialized,
|
||||
ZigbeeNodeStateHandled
|
||||
};
|
||||
Q_ENUM(ZigbeeNodeState)
|
||||
|
||||
explicit ZigbeeNode(const QUuid &networkUuid, const QString &ieeeAddress, QObject *parent = nullptr);
|
||||
|
||||
QUuid networkUuid() const;
|
||||
|
||||
QString ieeeAddress() const;
|
||||
void setIeeeAddress(const QString &ieeeAddress);
|
||||
|
||||
quint16 networkAddress() const;
|
||||
void setNetworkAddress(quint16 networkAddress);
|
||||
|
||||
ZigbeeNodeType type() const;
|
||||
void setType(ZigbeeNodeType type);
|
||||
|
||||
ZigbeeNodeState state() const;
|
||||
void setState(ZigbeeNodeState state);
|
||||
|
||||
QString manufacturer() const;
|
||||
void setManufacturer(const QString &manufacturer);
|
||||
|
||||
QString model() const;
|
||||
void setModel(const QString &model);
|
||||
|
||||
QString version() const;
|
||||
void setVersion(const QString &version);
|
||||
|
||||
bool rxOnWhenIdle() const;
|
||||
void setRxOnWhenIdle(bool rxOnWhenIdle);
|
||||
|
||||
bool reachable() const;
|
||||
void setReachable(bool reachable);
|
||||
|
||||
uint lqi() const;
|
||||
void setLqi(uint lqi);
|
||||
|
||||
QDateTime lastSeen() const;
|
||||
void setLastSeen(const QDateTime &lastSeen);
|
||||
|
||||
static ZigbeeNodeState stringToNodeState(const QString &nodeState);
|
||||
static ZigbeeNodeType stringToNodeType(const QString &nodeType);
|
||||
|
||||
void updateNodeProperties(const QVariantMap &nodeMap);
|
||||
|
||||
signals:
|
||||
void networkAddressChanged(quint16 networkAddress);
|
||||
void typeChanged(ZigbeeNodeType type);
|
||||
void stateChanged(ZigbeeNodeState state);
|
||||
void manufacturerChanged(const QString &manufacturer);
|
||||
void modelChanged(const QString &model);
|
||||
void versionChanged(const QString &version);
|
||||
void rxOnWhenIdleChanged(bool rxOnWhenIdle);
|
||||
void reachableChanged(bool reachable);
|
||||
void lqiChanged(uint lqi);
|
||||
void lastSeenChanged(const QDateTime &lastSeen);
|
||||
|
||||
private:
|
||||
QUuid m_networkUuid;
|
||||
QString m_ieeeAddress;
|
||||
quint16 m_networkAddress = 0;
|
||||
ZigbeeNodeType m_type = ZigbeeNodeTypeEndDevice;
|
||||
ZigbeeNodeState m_state = ZigbeeNodeStateUninitialized;
|
||||
QString m_manufacturer;
|
||||
QString m_model;
|
||||
QString m_version;
|
||||
bool m_rxOnWhenIdle = false;
|
||||
bool m_reachable = false;
|
||||
uint m_lqi = 0;
|
||||
QDateTime m_lastSeen;
|
||||
};
|
||||
|
||||
#endif // ZIGBEENODE_H
|
||||
|
||||
193
libnymea-app/zigbee/zigbeenodes.cpp
Normal file
193
libnymea-app/zigbee/zigbeenodes.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "zigbeenodes.h"
|
||||
|
||||
ZigbeeNodes::ZigbeeNodes(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int ZigbeeNodes::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_nodes.count();
|
||||
}
|
||||
|
||||
QVariant ZigbeeNodes::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
case RoleNetworkUuid:
|
||||
return m_nodes.at(index.row())->networkUuid();
|
||||
case RoleIeeeAddress:
|
||||
return m_nodes.at(index.row())->ieeeAddress();
|
||||
case RoleNetworkAddress:
|
||||
return m_nodes.at(index.row())->networkAddress();
|
||||
case RoleType:
|
||||
return m_nodes.at(index.row())->type();
|
||||
case RoleState:
|
||||
return m_nodes.at(index.row())->state();
|
||||
case RoleManufacturer:
|
||||
return m_nodes.at(index.row())->manufacturer();
|
||||
case RoleModel:
|
||||
return m_nodes.at(index.row())->model();
|
||||
case RoleVersion:
|
||||
return m_nodes.at(index.row())->version();
|
||||
case RoleRxOnWhenIdle:
|
||||
return m_nodes.at(index.row())->rxOnWhenIdle();
|
||||
case RoleReachable:
|
||||
return m_nodes.at(index.row())->reachable();
|
||||
case RoleLqi:
|
||||
return m_nodes.at(index.row())->lqi();
|
||||
case RoleLastSeen:
|
||||
return m_nodes.at(index.row())->lastSeen();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ZigbeeNodes::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles.insert(RoleNetworkUuid, "networkUuid");
|
||||
roles.insert(RoleIeeeAddress, "ieeeAddress");
|
||||
roles.insert(RoleNetworkAddress, "networkAddress");
|
||||
roles.insert(RoleType, "type");
|
||||
roles.insert(RoleState, "state");
|
||||
roles.insert(RoleManufacturer, "manufacturer");
|
||||
roles.insert(RoleModel, "model");
|
||||
roles.insert(RoleVersion, "version");
|
||||
roles.insert(RoleRxOnWhenIdle, "rxOnWhenIdle");
|
||||
roles.insert(RoleReachable, "reachable");
|
||||
roles.insert(RoleLqi, "lqi");
|
||||
roles.insert(RoleLastSeen, "lastSeen");
|
||||
return roles;
|
||||
}
|
||||
|
||||
void ZigbeeNodes::addNode(ZigbeeNode *node)
|
||||
{
|
||||
node->setParent(this);
|
||||
beginInsertRows(QModelIndex(), m_nodes.count(), m_nodes.count());
|
||||
m_nodes.append(node);
|
||||
|
||||
connect(node, &ZigbeeNode::networkAddressChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleNetworkAddress});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::typeChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleType});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::stateChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleState});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::manufacturerChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleManufacturer});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::modelChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleModel});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::versionChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleVersion});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::rxOnWhenIdleChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleRxOnWhenIdle});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::reachableChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleReachable});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::lqiChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleLqi});
|
||||
});
|
||||
|
||||
connect(node, &ZigbeeNode::lastSeenChanged, this, [this, node]() {
|
||||
QModelIndex idx = index(m_nodes.indexOf(node), 0);
|
||||
emit dataChanged(idx, idx, {RoleLastSeen});
|
||||
});
|
||||
|
||||
endInsertRows();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
void ZigbeeNodes::removeNode(const QString &ieeeAddress)
|
||||
{
|
||||
for (int i = 0; i < m_nodes.count(); i++) {
|
||||
if (m_nodes.at(i)->ieeeAddress() == ieeeAddress) {
|
||||
beginRemoveRows(QModelIndex(), i, i);
|
||||
m_nodes.takeAt(i)->deleteLater();
|
||||
endRemoveRows();
|
||||
emit countChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZigbeeNodes::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
qDeleteAll(m_nodes);
|
||||
m_nodes.clear();
|
||||
endResetModel();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
ZigbeeNode *ZigbeeNodes::get(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_nodes.count()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_nodes.at(index);
|
||||
}
|
||||
|
||||
ZigbeeNode *ZigbeeNodes::getNode(const QString &ieeeAddress) const
|
||||
{
|
||||
foreach (ZigbeeNode *node, m_nodes) {
|
||||
if (node->ieeeAddress() == ieeeAddress) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
84
libnymea-app/zigbee/zigbeenodes.h
Normal file
84
libnymea-app/zigbee/zigbeenodes.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 ZIGBEENODES_H
|
||||
#define ZIGBEENODES_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "zigbeenode.h"
|
||||
|
||||
class ZigbeeNodes : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
RoleNetworkUuid,
|
||||
RoleIeeeAddress,
|
||||
RoleNetworkAddress,
|
||||
RoleType,
|
||||
RoleState,
|
||||
RoleManufacturer,
|
||||
RoleModel,
|
||||
RoleVersion,
|
||||
RoleRxOnWhenIdle,
|
||||
RoleReachable,
|
||||
RoleLqi,
|
||||
RoleLastSeen
|
||||
};
|
||||
Q_ENUM(Roles)
|
||||
|
||||
explicit ZigbeeNodes(QObject *parent = nullptr);
|
||||
virtual ~ZigbeeNodes() override = default;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void addNode(ZigbeeNode *node);
|
||||
void removeNode(const QString &ieeeAddress);
|
||||
|
||||
void clear();
|
||||
|
||||
Q_INVOKABLE virtual ZigbeeNode *get(int index) const;
|
||||
Q_INVOKABLE ZigbeeNode *getNode(const QString &ieeeAddress) const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
protected:
|
||||
QList<ZigbeeNode *> m_nodes;
|
||||
|
||||
};
|
||||
|
||||
#endif // ZIGBEENODES_H
|
||||
76
libnymea-app/zigbee/zigbeenodesproxy.cpp
Normal file
76
libnymea-app/zigbee/zigbeenodesproxy.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "zigbeenodesproxy.h"
|
||||
#include "zigbeenode.h"
|
||||
#include "zigbeenodes.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
ZigbeeNodesProxy::ZigbeeNodesProxy(QObject *parent) :
|
||||
QSortFilterProxyModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ZigbeeNodes *ZigbeeNodesProxy::zigbeeNodes() const
|
||||
{
|
||||
return m_zigbeeNodes;
|
||||
}
|
||||
|
||||
void ZigbeeNodesProxy::setZigbeeNodes(ZigbeeNodes *zigbeeNodes)
|
||||
{
|
||||
if (m_zigbeeNodes == zigbeeNodes)
|
||||
return;
|
||||
|
||||
m_zigbeeNodes = zigbeeNodes;
|
||||
emit zigbeeNodesChanged(m_zigbeeNodes);
|
||||
|
||||
qWarning() << "Set nodes to proxy" << m_zigbeeNodes->rowCount();
|
||||
|
||||
connect(m_zigbeeNodes, &ZigbeeNodes::countChanged, this, [this](){
|
||||
emit countChanged();
|
||||
});
|
||||
|
||||
setSourceModel(m_zigbeeNodes);
|
||||
setSortRole(ZigbeeNodes::RoleNetworkAddress);
|
||||
sort(0, Qt::DescendingOrder);
|
||||
invalidateFilter();
|
||||
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
ZigbeeNode *ZigbeeNodesProxy::get(int index) const
|
||||
{
|
||||
if (index >= 0 && index < m_zigbeeNodes->rowCount()) {
|
||||
return m_zigbeeNodes->get(mapToSource(this->index(index, 0)).row());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
63
libnymea-app/zigbee/zigbeenodesproxy.h
Normal file
63
libnymea-app/zigbee/zigbeenodesproxy.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 ZIGBEENODESPROXY_H
|
||||
#define ZIGBEENODESPROXY_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class ZigbeeNode;
|
||||
class ZigbeeNodes;
|
||||
|
||||
class ZigbeeNodesProxy : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
Q_PROPERTY(ZigbeeNodes *zigbeeNodes READ zigbeeNodes WRITE setZigbeeNodes NOTIFY zigbeeNodesChanged)
|
||||
|
||||
public:
|
||||
explicit ZigbeeNodesProxy(QObject *parent = nullptr);
|
||||
|
||||
ZigbeeNodes *zigbeeNodes() const;
|
||||
void setZigbeeNodes(ZigbeeNodes *zigbeeNodes);
|
||||
|
||||
Q_INVOKABLE ZigbeeNode *get(int index) const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
void zigbeeNodesChanged(ZigbeeNodes *zigbeeNodes);
|
||||
|
||||
private:
|
||||
ZigbeeNodes *m_zigbeeNodes = nullptr;
|
||||
|
||||
};
|
||||
|
||||
#endif // ZIGBEENODESPROXY_H
|
||||
@ -262,5 +262,6 @@
|
||||
<file>ui/images/modbus.svg</file>
|
||||
<file>ui/images/setupwizard/wired-connection.svg</file>
|
||||
<file>ui/images/setupwizard/wireless-connection.svg</file>
|
||||
<file>ui/images/system-suspend.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -219,7 +219,7 @@
|
||||
<file>ui/components/ThingInfoPane.qml</file>
|
||||
<file>ui/system/ZigbeeSettingsPage.qml</file>
|
||||
<file>ui/system/ZigbeeAddNetworkPage.qml</file>
|
||||
<file>ui/system/ZigbeeNetworkPage.qml</file>
|
||||
<file>ui/system/ZigbeeNetworkSettingsPage.qml</file>
|
||||
<file>ui/MainMenu.qml</file>
|
||||
<file>ui/components/NymeaItemDelegate.qml</file>
|
||||
<file>ui/components/NymeaSwipeDelegate.qml</file>
|
||||
@ -251,5 +251,6 @@
|
||||
<file>ui/system/ModbusRtuReconfigureMasterPage.qml</file>
|
||||
<file>ui/connection/NewConnectionWizard.qml</file>
|
||||
<file>ui/components/WizardPageBase.qml</file>
|
||||
<file>ui/system/ZigbeeNetworkPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
19
nymea-app/ui/images/system-suspend.svg
Normal file
19
nymea-app/ui/images/system-suspend.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg4874" width="96" height="96" version="1.1" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata id="metadata4879">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g id="layer1" transform="translate(67.857 -78.505)">
|
||||
<rect id="rect4782" transform="rotate(90)" x="78.505" y="-28.143" width="96" height="96" style="color:#000000;fill:none"/>
|
||||
<path id="path4145" transform="translate(-67.857 78.505)" d="m48.018 11.98c-16.282 0.0038-30.558 10.962-34.775 26.693-4.2175 15.731 2.6648 32.354 16.764 40.494 14.099 8.14 31.934 5.7877 43.449-5.7305 6.9212-6.9231 10.526-16.131 10.539-25.438h-3.9902c-0.00963 8.2694-3.2168 16.448-9.377 22.609-10.249 10.252-26.074 12.338-38.621 5.0938-12.547-7.244-18.652-21.992-14.898-35.994 3.7539-14.002 16.42-23.725 30.91-23.729v-4z" style="color-rendering:auto;color:#000000;fill:#808080;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:none;font-variant-numeric:normal;font-variant-position:normal;image-rendering:auto;isolation:auto;mix-blend-mode:normal;shape-padding:0;shape-rendering:auto;solid-color:#000000;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
|
||||
<path id="path4271" d="m21.942 103.82c-0.51329 0.53896-1.1934 1.2961-2.0403 2.2713-0.82127 0.97525-1.7067 2.066-2.6563 3.2722-0.94959 1.1806-1.912 2.4253-2.8873 3.7342-0.94959 1.2832-1.8094 2.5151-2.5793 3.6957h10.394v3.8882h-16.015v-2.8873c0.56462-1.0266 1.2704-2.143 2.1173-3.3492 0.84693-1.2062 1.7195-2.4125 2.6178-3.6187 0.89826-1.2319 1.7837-2.3996 2.6563-3.5032 0.89826-1.1036 1.6939-2.066 2.3868-2.8873h-9.7507v-3.8882h15.756z" style="fill:#808080"/>
|
||||
<path id="path4273" d="m-0.67371 104.09c-0.82494 0.89993-1.8249 2.0748-2.9998 3.5247-1.1749 1.4249-2.3873 2.9873-3.6372 4.6872-1.2499 1.6749-2.4873 3.4122-3.7122 5.2121-1.1999 1.7749-2.2623 3.4622-3.1873 5.0621h14.313v4.0122h-20.012v-2.9623c0.49996-0.92493 1.0749-1.9249 1.7249-2.9998 0.67495-1.0999 1.3874-2.2248 2.1373-3.3748s1.5249-2.3123 2.3248-3.4872c0.82494-1.1749 1.6374-2.2998 2.4373-3.3748 0.79994-1.0999 1.5749-2.1373 2.3248-3.1123 0.77494-0.99993 1.4999-1.8874 2.1748-2.6623h-13.069v-4.0122h19.181z" style="fill:#808080"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@ -1,6 +1,6 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
@ -42,120 +42,347 @@ SettingsPageBase {
|
||||
property ZigbeeNetwork network: null
|
||||
|
||||
header: NymeaHeader {
|
||||
text: qsTr("ZigBee network settings")
|
||||
text: qsTr("ZigBee network")
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "/ui/images/configure.svg"
|
||||
text: qsTr("Network settings")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkSettingsPage.qml"), { zigbeeManager: zigbeeManager, network: network })
|
||||
}
|
||||
}
|
||||
|
||||
busy: d.pendingCommandId != -1
|
||||
QtObject {
|
||||
id: d
|
||||
property int pendingCommandId: -1
|
||||
function removeNode(networkUuid, ieeeAddress) {
|
||||
d.pendingCommandId = root.zigbeeManager.removeNode(networkUuid, ieeeAddress)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.zigbeeManager
|
||||
onRemoveNodeReply: {
|
||||
if (commandId == d.pendingCommandId) {
|
||||
d.pendingCommandId = -1
|
||||
var props = {};
|
||||
switch (error) {
|
||||
case "ZigbeeErrorNoError":
|
||||
return;
|
||||
case "ZigbeeErrorAdapterNotAvailable":
|
||||
props.text = qsTr("The selected adapter is not available or the selected serial port configration is incorrect.");
|
||||
break;
|
||||
case "ZigbeeErrorAdapterAlreadyInUse":
|
||||
props.text = qsTr("The selected adapter is already in use.");
|
||||
break;
|
||||
default:
|
||||
props.errorCode = error;
|
||||
}
|
||||
var comp = Qt.createComponent("../components/ErrorDialog.qml")
|
||||
var popup = comp.createObject(app, props)
|
||||
popup.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Network information")
|
||||
text: qsTr("Network")
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Network state")
|
||||
subText: {
|
||||
switch (root.network.networkState) {
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOnline:
|
||||
return qsTr("The network is online")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOffline:
|
||||
return qsTr("The network is offline")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateStarting:
|
||||
return qsTr("The network is starting...")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateUpdating:
|
||||
return qsTr("The controller is currently installing an update")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateError:
|
||||
return qsTr("The network is in an error state.")
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
|
||||
Label {
|
||||
//Layout.fillWidth: true
|
||||
text: {
|
||||
switch (network.networkState) {
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOnline:
|
||||
return qsTr("Online")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOffline:
|
||||
return qsTr("Offline")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateStarting:
|
||||
return qsTr("Starting")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateUpdating:
|
||||
return qsTr("Updating")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateError:
|
||||
return qsTr("Error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
progressive: false
|
||||
Led {
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
state: {
|
||||
switch (network.networkState) {
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOnline:
|
||||
return "on"
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOffline:
|
||||
return "off"
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateStarting:
|
||||
return "orange"
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateUpdating:
|
||||
return "orange"
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateError:
|
||||
return "red"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Channel")
|
||||
subText: root.network.channel
|
||||
progressive: false
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
text: qsTr("Channel") + ": " + network.channel
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Network PAN ID")
|
||||
subText: root.network.panId
|
||||
progressive: false
|
||||
}
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Hardware information")
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("MAC address:")
|
||||
subText: root.network.macAddress
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Serial port")
|
||||
subText: root.network.serialPort
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Baud rate")
|
||||
subText: root.network.baudRate
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Controller backend")
|
||||
subText: root.network.backend
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Controller firmware version")
|
||||
subText: root.network.firmwareVersion
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Manage network")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
Button {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
text: qsTr("Remove network")
|
||||
onClicked: {
|
||||
root.zigbeeManager.removeNetwork(root.network.networkUuid)
|
||||
pageStack.pop()
|
||||
text: qsTr("Permit new devices:")
|
||||
}
|
||||
Label {
|
||||
text: network.permitJoiningEnabled ? qsTr("Open for %0 s").arg(network.permitJoiningRemaining) : qsTr("Closed")
|
||||
}
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
name: network.permitJoiningEnabled ? "/ui/images/lock-open.svg" : "/ui/images/lock-closed.svg"
|
||||
visible: !network.permitJoiningEnabled
|
||||
}
|
||||
Canvas {
|
||||
id: canvas
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
rotation: -90
|
||||
visible: network.permitJoiningEnabled
|
||||
|
||||
property real progress: network.permitJoiningRemaining / network.permitJoiningDuration
|
||||
onProgressChanged: {
|
||||
canvas.requestPaint()
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.save();
|
||||
ctx.reset();
|
||||
var data = [1 - progress, progress];
|
||||
var myTotal = 0;
|
||||
|
||||
for(var e = 0; e < data.length; e++) {
|
||||
myTotal += data[e];
|
||||
}
|
||||
|
||||
ctx.fillStyle = Style.accentColor
|
||||
ctx.strokeStyle = Style.accentColor
|
||||
ctx.lineWidth = 1;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(canvas.width/2,canvas.height/2);
|
||||
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2,0,(Math.PI*2*((1-progress)/myTotal)),false);
|
||||
ctx.lineTo(canvas.width/2,canvas.height/2);
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
ctx.beginPath();
|
||||
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2 - 1,0,Math.PI*2,false);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
|
||||
text: network.permitJoiningEnabled ? qsTr("Extend open duration") : qsTr("Open for new devices")
|
||||
enabled: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline
|
||||
onClicked: zigbeeManager.setPermitJoin(network.networkUuid)
|
||||
}
|
||||
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Zigbee nodes")
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: zigbeeNodeRepeater
|
||||
model: ZigbeeNodesProxy {
|
||||
id: zigbeeNodesProxy
|
||||
zigbeeNodes: root.network.nodes
|
||||
}
|
||||
|
||||
delegate: BigTile {
|
||||
|
||||
property ZigbeeNode node: root.network.nodes.get(index)
|
||||
|
||||
Layout.fillWidth: true
|
||||
interactive: false
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: app.margins
|
||||
|
||||
Loader {
|
||||
id: nodeTypeLoader
|
||||
Layout.fillWidth: true
|
||||
sourceComponent: node.type === ZigbeeNode.ZigbeeNodeTypeCoordinator ? coordinatorComponent : deviceComponent
|
||||
}
|
||||
|
||||
Component {
|
||||
id: coordinatorComponent
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
Led {
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
state: {
|
||||
switch (network.networkState) {
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOnline:
|
||||
return "on"
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOffline:
|
||||
return "off"
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateStarting:
|
||||
return "orange"
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateUpdating:
|
||||
return "orange"
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateError:
|
||||
return "red"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Coordinator")
|
||||
}
|
||||
}
|
||||
|
||||
Label { text: network.backend }
|
||||
Label {
|
||||
visible: node.version !== ""
|
||||
text: qsTr("Version") + ": " + network.firmwareVersion
|
||||
}
|
||||
Label {
|
||||
text: qsTr("IEEE address") + ": " + node.ieeeAddress
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Network address") + ": 0x" + (node.networkAddress + Math.pow(16, 4)).toString(16).slice(-4).toUpperCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: deviceComponent
|
||||
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
Led {
|
||||
id: reachableLed
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
state: node.reachable ? "on" : "red"
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: node
|
||||
onLastSeenChanged: {
|
||||
communicationIndicatorLed.state = "on"
|
||||
communicationIndicatorLedTimer.start()
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: communicationIndicatorLedTimer
|
||||
interval: 200
|
||||
repeat: false
|
||||
onTriggered: communicationIndicatorLed.state = "off"
|
||||
}
|
||||
|
||||
Led {
|
||||
id: communicationIndicatorLed
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
state: "off"
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
running: visible
|
||||
visible: node.state !== ZigbeeNode.ZigbeeNodeStateInitialized
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: node.type === ZigbeeNode.ZigbeeNodeTypeRouter ? qsTr("Router") : qsTr("End device")
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: iconLoader
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
active: !node.rxOnWhenIdle
|
||||
sourceComponent: sleepyDeviceComponent
|
||||
}
|
||||
|
||||
Component {
|
||||
id: sleepyDeviceComponent
|
||||
ColorIcon {
|
||||
name: "/ui/images/system-suspend.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: node.manufacturer + " - " + node.model
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: node.version !== ""
|
||||
text: qsTr("Version") + ": " + node.version
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("IEEE address") + ": " + node.ieeeAddress
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Network address") + ": 0x" + (node.networkAddress + Math.pow(16, 4)).toString(16).slice(-4).toUpperCase();
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Signal strength") + ": " + Math.round(node.lqi * 100.0 / 255.0) + "%"
|
||||
}
|
||||
|
||||
Button {
|
||||
id: removeNodeButton
|
||||
text: qsTr("Remove node")
|
||||
onClicked: d.removeNode(network.networkUuid, node.ieeeAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
text: qsTr("Factory reset controller")
|
||||
onClicked: {
|
||||
root.zigbeeManager.factoryResetNetwork(root.network.networkUuid)
|
||||
}
|
||||
}
|
||||
|
||||
// NymeaSwipeDelegate {
|
||||
// Layout.fillWidth: true
|
||||
// iconName: "../images/zigbee.svg"
|
||||
// text: node.manufacturer + " - " + node.model + " - " + node.version
|
||||
// subText: node.ieeeAddress + " " + node.networkAddress
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
161
nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml
Normal file
161
nymea-app/ui/system/ZigbeeNetworkSettingsPage.qml
Normal file
@ -0,0 +1,161 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 ZigbeeManager zigbeeManager: null
|
||||
property ZigbeeNetwork network: null
|
||||
|
||||
header: NymeaHeader {
|
||||
text: qsTr("ZigBee network settings")
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Network information")
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Network state")
|
||||
subText: {
|
||||
switch (root.network.networkState) {
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOnline:
|
||||
return qsTr("The network is online")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateOffline:
|
||||
return qsTr("The network is offline")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateStarting:
|
||||
return qsTr("The network is starting...")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateUpdating:
|
||||
return qsTr("The controller is currently installing an update")
|
||||
case ZigbeeNetwork.ZigbeeNetworkStateError:
|
||||
return qsTr("The network is in an error state.")
|
||||
}
|
||||
}
|
||||
|
||||
progressive: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Channel")
|
||||
subText: root.network ? root.network.channel : ""
|
||||
progressive: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Network PAN ID")
|
||||
subText: root.network ? root.network.panId : ""
|
||||
progressive: false
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Hardware information")
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("MAC address:")
|
||||
subText: root.network ? root.network.macAddress : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Serial port")
|
||||
subText: root.network ? root.network.serialPort : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Baud rate")
|
||||
subText: root.network ? root.network.baudRate : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Controller backend")
|
||||
subText: root.network ? root.network.backend : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Controller firmware version")
|
||||
subText: root.network ? root.network.firmwareVersion : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Manage network")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
text: qsTr("Remove network")
|
||||
onClicked: {
|
||||
root.zigbeeManager.removeNetwork(root.network.networkUuid)
|
||||
pageStack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
text: qsTr("Factory reset controller")
|
||||
onClicked: {
|
||||
root.zigbeeManager.factoryResetNetwork(root.network.networkUuid)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,8 +81,11 @@ SettingsPageBase {
|
||||
Layout.fillWidth: true
|
||||
interactive: false
|
||||
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkPage.qml"), { zigbeeManager: zigbeeManager, network: zigbeeManager.networks.get(index) })
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: app.margins
|
||||
|
||||
RowLayout {
|
||||
ColorIcon {
|
||||
name: "/ui/images/zigbee/" + model.backend + ".svg"
|
||||
@ -95,14 +98,8 @@ SettingsPageBase {
|
||||
text: model.backend
|
||||
font.pixelSize: app.largeFont
|
||||
}
|
||||
|
||||
ProgressButton {
|
||||
size: Style.iconSize
|
||||
imageSource: "/ui/images/configure.svg"
|
||||
longpressEnabled: false
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkPage.qml"), { zigbeeManager: zigbeeManager, network: zigbeeManager.networks.get(index) })
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
@ -148,65 +145,21 @@ SettingsPageBase {
|
||||
RowLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Permit new devices:")
|
||||
text: qsTr("MAC address:")
|
||||
}
|
||||
Label {
|
||||
text: model.permitJoiningEnabled ? qsTr("Open for %0 s").arg(model.permitJoiningRemaining) : qsTr("Closed")
|
||||
}
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
name: model.permitJoiningEnabled ? "/ui/images/lock-open.svg" : "/ui/images/lock-closed.svg"
|
||||
visible: !model.permitJoiningEnabled
|
||||
}
|
||||
Canvas {
|
||||
id: canvas
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
rotation: -90
|
||||
visible: model.permitJoiningEnabled
|
||||
|
||||
property real progress: model.permitJoiningRemaining / model.permitJoiningDuration
|
||||
onProgressChanged: {
|
||||
canvas.requestPaint()
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.save();
|
||||
ctx.reset();
|
||||
var data = [1 - progress, progress];
|
||||
var myTotal = 0;
|
||||
|
||||
for(var e = 0; e < data.length; e++) {
|
||||
myTotal += data[e];
|
||||
}
|
||||
|
||||
ctx.fillStyle = Style.accentColor
|
||||
ctx.strokeStyle = Style.accentColor
|
||||
ctx.lineWidth = 1;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(canvas.width/2,canvas.height/2);
|
||||
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2,0,(Math.PI*2*((1-progress)/myTotal)),false);
|
||||
ctx.lineTo(canvas.width/2,canvas.height/2);
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
ctx.beginPath();
|
||||
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2 - 1,0,Math.PI*2,false);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
text: model.macAddress
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: model.permitJoiningEnabled ? qsTr("Extend open duration") : qsTr("Open for new devices")
|
||||
enabled: model.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline
|
||||
onClicked: zigbeeManager.setPermitJoin(model.networkUuid)
|
||||
RowLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Firmware version:")
|
||||
}
|
||||
Label {
|
||||
text: model.firmwareVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user