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/zigbeeadaptersproxy.h"
|
||||||
#include "zigbee/zigbeenetwork.h"
|
#include "zigbee/zigbeenetwork.h"
|
||||||
#include "zigbee/zigbeenetworks.h"
|
#include "zigbee/zigbeenetworks.h"
|
||||||
|
#include "zigbee/zigbeenodes.h"
|
||||||
|
#include "zigbee/zigbeenodesproxy.h"
|
||||||
#include "applogcontroller.h"
|
#include "applogcontroller.h"
|
||||||
#include "tagwatcher.h"
|
#include "tagwatcher.h"
|
||||||
#include "appdata.h"
|
#include "appdata.h"
|
||||||
@ -314,6 +316,9 @@ void registerQmlTypes() {
|
|||||||
qmlRegisterType<ZigbeeAdaptersProxy>(uri, 1, 0, "ZigbeeAdaptersProxy");
|
qmlRegisterType<ZigbeeAdaptersProxy>(uri, 1, 0, "ZigbeeAdaptersProxy");
|
||||||
qmlRegisterUncreatableType<ZigbeeNetwork>(uri, 1, 0, "ZigbeeNetwork", "Get it from the ZigbeeManager");
|
qmlRegisterUncreatableType<ZigbeeNetwork>(uri, 1, 0, "ZigbeeNetwork", "Get it from the ZigbeeManager");
|
||||||
qmlRegisterUncreatableType<ZigbeeNetworks>(uri, 1, 0, "ZigbeeNetworks", "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");
|
qmlRegisterType<ModbusRtuManager>(uri, 1, 0, "ModbusRtuManager");
|
||||||
qmlRegisterUncreatableType<ModbusRtuMaster>(uri, 1, 0, "ModbusRtuMaster", "Get it from the ModbusRtuMasters");
|
qmlRegisterUncreatableType<ModbusRtuMaster>(uri, 1, 0, "ModbusRtuMaster", "Get it from the ModbusRtuMasters");
|
||||||
|
|||||||
@ -24,6 +24,8 @@ SOURCES += \
|
|||||||
$$PWD/models/scriptsproxymodel.cpp \
|
$$PWD/models/scriptsproxymodel.cpp \
|
||||||
$$PWD/tagwatcher.cpp \
|
$$PWD/tagwatcher.cpp \
|
||||||
$$PWD/zigbee/zigbeenode.cpp \
|
$$PWD/zigbee/zigbeenode.cpp \
|
||||||
|
$$PWD/zigbee/zigbeenodes.cpp \
|
||||||
|
$$PWD/zigbee/zigbeenodesproxy.cpp \
|
||||||
$${PWD}/logging.cpp \
|
$${PWD}/logging.cpp \
|
||||||
$${PWD}/applogcontroller.cpp \
|
$${PWD}/applogcontroller.cpp \
|
||||||
$${PWD}/wifisetup/btwifisetup.cpp \
|
$${PWD}/wifisetup/btwifisetup.cpp \
|
||||||
@ -179,6 +181,8 @@ HEADERS += \
|
|||||||
$$PWD/models/scriptsproxymodel.h \
|
$$PWD/models/scriptsproxymodel.h \
|
||||||
$$PWD/tagwatcher.h \
|
$$PWD/tagwatcher.h \
|
||||||
$$PWD/zigbee/zigbeenode.h \
|
$$PWD/zigbee/zigbeenode.h \
|
||||||
|
$$PWD/zigbee/zigbeenodes.h \
|
||||||
|
$$PWD/zigbee/zigbeenodesproxy.h \
|
||||||
$${PWD}/logging.h \
|
$${PWD}/logging.h \
|
||||||
$${PWD}/applogcontroller.h \
|
$${PWD}/applogcontroller.h \
|
||||||
$${PWD}/wifisetup/btwifisetup.h \
|
$${PWD}/wifisetup/btwifisetup.h \
|
||||||
|
|||||||
@ -36,9 +36,14 @@
|
|||||||
#include "zigbee/zigbeeadapters.h"
|
#include "zigbee/zigbeeadapters.h"
|
||||||
#include "zigbee/zigbeenetwork.h"
|
#include "zigbee/zigbeenetwork.h"
|
||||||
#include "zigbee/zigbeenetworks.h"
|
#include "zigbee/zigbeenetworks.h"
|
||||||
|
#include "zigbee/zigbeenode.h"
|
||||||
|
#include "zigbee/zigbeenodes.h"
|
||||||
|
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
|
||||||
|
#include "logging.h"
|
||||||
|
NYMEA_LOGGING_CATEGORY(dcZigbee, "Zigbee")
|
||||||
|
|
||||||
ZigbeeManager::ZigbeeManager(QObject *parent) :
|
ZigbeeManager::ZigbeeManager(QObject *parent) :
|
||||||
JsonHandler(parent),
|
JsonHandler(parent),
|
||||||
m_adapters(new ZigbeeAdapters(this)),
|
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("baudRate", baudRate);
|
||||||
params.insert("backend", backend);
|
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");
|
return m_engine->jsonRpcClient()->sendCommand("Zigbee.AddNetwork", params, this, "addNetworkResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +113,7 @@ void ZigbeeManager::removeNetwork(const QUuid &networkUuid)
|
|||||||
{
|
{
|
||||||
QVariantMap params;
|
QVariantMap params;
|
||||||
params.insert("networkUuid", networkUuid);
|
params.insert("networkUuid", networkUuid);
|
||||||
qDebug() << "Remove zigbee network" << params;
|
qCDebug(dcZigbee()) << "Remove zigbee network" << params;
|
||||||
m_engine->jsonRpcClient()->sendCommand("Zigbee.RemoveNetwork", params, this, "removeNetworkResponse");
|
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");
|
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()
|
void ZigbeeManager::init()
|
||||||
{
|
{
|
||||||
m_adapters->clear();
|
m_adapters->clear();
|
||||||
@ -142,7 +162,7 @@ void ZigbeeManager::init()
|
|||||||
|
|
||||||
void ZigbeeManager::getAvailableBackendsResponse(int commandId, const QVariantMap ¶ms)
|
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();
|
m_availableBackends.clear();
|
||||||
foreach (const QVariant &backendVariant, params.value("backends").toList()) {
|
foreach (const QVariant &backendVariant, params.value("backends").toList()) {
|
||||||
m_availableBackends << backendVariant.toString();
|
m_availableBackends << backendVariant.toString();
|
||||||
@ -152,56 +172,73 @@ void ZigbeeManager::getAvailableBackendsResponse(int commandId, const QVariantMa
|
|||||||
|
|
||||||
void ZigbeeManager::getAdaptersResponse(int commandId, const QVariantMap ¶ms)
|
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();
|
m_adapters->clear();
|
||||||
foreach (const QVariant &adapterVariant, params.value("adapters").toList()) {
|
foreach (const QVariant &adapterVariant, params.value("adapters").toList()) {
|
||||||
QVariantMap adapterMap = adapterVariant.toMap();
|
QVariantMap adapterMap = adapterVariant.toMap();
|
||||||
ZigbeeAdapter *adapter = unpackAdapter(adapterMap);
|
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);
|
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)
|
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();
|
m_networks->clear();
|
||||||
foreach (const QVariant &networkVariant, params.value("zigbeeNetworks").toList()) {
|
foreach (const QVariant &networkVariant, params.value("zigbeeNetworks").toList()) {
|
||||||
QVariantMap networkMap = networkVariant.toMap();
|
QVariantMap networkMap = networkVariant.toMap();
|
||||||
ZigbeeNetwork *network = unpackNetwork(networkMap);
|
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);
|
m_networks->addNetwork(network);
|
||||||
|
|
||||||
|
// Get nodes from this network
|
||||||
|
getNodes(network->networkUuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeManager::addNetworkResponse(int commandId, const QVariantMap ¶ms)
|
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());
|
emit addNetworkReply(commandId, params.value("zigbeeError").toString(), params.value("networkUuid").toUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeManager::removeNetworkResponse(int commandId, const QVariantMap ¶ms)
|
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)
|
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)
|
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)
|
void ZigbeeManager::notificationReceived(const QVariantMap ¬ification)
|
||||||
@ -236,14 +273,54 @@ void ZigbeeManager::notificationReceived(const QVariantMap ¬ification)
|
|||||||
QUuid networkUuid = networkMap.value("networkUuid").toUuid();
|
QUuid networkUuid = networkMap.value("networkUuid").toUuid();
|
||||||
ZigbeeNetwork *network = m_networks->getNetwork(networkUuid);
|
ZigbeeNetwork *network = m_networks->getNetwork(networkUuid);
|
||||||
if (!network) {
|
if (!network) {
|
||||||
qWarning() << "Could not find network for changed notification";
|
qCWarning(dcZigbee()) << "Could not find network for changed notification";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fillNetworkData(network, networkMap);
|
fillNetworkData(network, networkMap);
|
||||||
return;
|
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)
|
ZigbeeAdapter *ZigbeeManager::unpackAdapter(const QVariantMap &adapterMap)
|
||||||
@ -266,6 +343,15 @@ ZigbeeNetwork *ZigbeeManager::unpackNetwork(const QVariantMap &networkMap)
|
|||||||
return network;
|
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)
|
void ZigbeeManager::fillNetworkData(ZigbeeNetwork *network, const QVariantMap &networkMap)
|
||||||
{
|
{
|
||||||
network->setNetworkUuid(networkMap.value("networkUuid").toUuid());
|
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()));
|
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 "zigbeeadapter.h"
|
||||||
#include "jsonrpc/jsonhandler.h"
|
#include "jsonrpc/jsonhandler.h"
|
||||||
|
|
||||||
|
class Engine;
|
||||||
class JsonRpcClient;
|
class JsonRpcClient;
|
||||||
class ZigbeeAdapters;
|
class ZigbeeAdapters;
|
||||||
class ZigbeeNetwork;
|
class ZigbeeNetwork;
|
||||||
class ZigbeeNetworks;
|
class ZigbeeNetworks;
|
||||||
class Engine;
|
class ZigbeeNode;
|
||||||
|
class ZigbeeNodes;
|
||||||
|
|
||||||
class ZigbeeManager : public JsonHandler
|
class ZigbeeManager : public JsonHandler
|
||||||
{
|
{
|
||||||
@ -63,15 +65,19 @@ public:
|
|||||||
ZigbeeAdapters *adapters() const;
|
ZigbeeAdapters *adapters() const;
|
||||||
ZigbeeNetworks *networks() const;
|
ZigbeeNetworks *networks() const;
|
||||||
|
|
||||||
|
// Network
|
||||||
Q_INVOKABLE int addNetwork(const QString &serialPort, uint baudRate, const QString &backend);
|
Q_INVOKABLE int addNetwork(const QString &serialPort, uint baudRate, const QString &backend);
|
||||||
Q_INVOKABLE void removeNetwork(const QUuid &networkUuid);
|
Q_INVOKABLE void removeNetwork(const QUuid &networkUuid);
|
||||||
Q_INVOKABLE void setPermitJoin(const QUuid &networkUuid, uint duration = 120);
|
Q_INVOKABLE void setPermitJoin(const QUuid &networkUuid, uint duration = 120);
|
||||||
Q_INVOKABLE void factoryResetNetwork(const QUuid &networkUuid);
|
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:
|
signals:
|
||||||
void engineChanged();
|
void engineChanged();
|
||||||
void availableBackendsChanged();
|
void availableBackendsChanged();
|
||||||
void addNetworkReply(int commandId, const QString &error, const QUuid &networkUuid);
|
void addNetworkReply(int commandId, const QString &error, const QUuid &networkUuid);
|
||||||
|
void removeNodeReply(int commandId, const QString &error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
@ -85,6 +91,9 @@ private:
|
|||||||
Q_INVOKABLE void setPermitJoinResponse(int commandId, const QVariantMap ¶ms);
|
Q_INVOKABLE void setPermitJoinResponse(int commandId, const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE void factoryResetNetworkResponse(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);
|
Q_INVOKABLE void notificationReceived(const QVariantMap ¬ification);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -95,8 +104,9 @@ private:
|
|||||||
|
|
||||||
ZigbeeAdapter *unpackAdapter(const QVariantMap &adapterMap);
|
ZigbeeAdapter *unpackAdapter(const QVariantMap &adapterMap);
|
||||||
ZigbeeNetwork *unpackNetwork(const QVariantMap &networkMap);
|
ZigbeeNetwork *unpackNetwork(const QVariantMap &networkMap);
|
||||||
|
ZigbeeNode *unpackNode(const QVariantMap &nodeMap);
|
||||||
void fillNetworkData(ZigbeeNetwork *network, const QVariantMap &networkMap);
|
void fillNetworkData(ZigbeeNetwork *network, const QVariantMap &networkMap);
|
||||||
|
void addOrUpdateNode(ZigbeeNetwork *network, const QVariantMap &nodeMap);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ZIGBEEMANAGER_H
|
#endif // ZIGBEEMANAGER_H
|
||||||
|
|||||||
@ -30,13 +30,14 @@
|
|||||||
|
|
||||||
#include "zigbeenetwork.h"
|
#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 = new QTimer(this);
|
||||||
m_permitJoinTimer->setInterval(1000);
|
m_permitJoinTimer->setInterval(1000);
|
||||||
m_permitJoinTimer->setSingleShot(true);
|
m_permitJoinTimer->setSingleShot(true);
|
||||||
connect(m_permitJoinTimer, &QTimer::timeout, this, [this](){
|
connect(m_permitJoinTimer, &QTimer::timeout, this, [this](){
|
||||||
|
|
||||||
setPermitJoiningRemaining(m_permitJoiningRemaining - 1);
|
setPermitJoiningRemaining(m_permitJoiningRemaining - 1);
|
||||||
if (m_permitJoiningRemaining <= 0) {
|
if (m_permitJoiningRemaining <= 0) {
|
||||||
m_permitJoinTimer->stop();
|
m_permitJoinTimer->stop();
|
||||||
@ -44,6 +45,12 @@ ZigbeeNetwork::ZigbeeNetwork(QObject *parent) : QObject(parent)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZigbeeNodes *ZigbeeNetwork::nodes() const
|
||||||
|
{
|
||||||
|
return m_nodes;
|
||||||
|
}
|
||||||
|
|
||||||
QUuid ZigbeeNetwork::networkUuid() const
|
QUuid ZigbeeNetwork::networkUuid() const
|
||||||
{
|
{
|
||||||
return m_networkUuid;
|
return m_networkUuid;
|
||||||
|
|||||||
@ -35,6 +35,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "zigbeenodes.h"
|
||||||
#include "zigbeeadapter.h"
|
#include "zigbeeadapter.h"
|
||||||
|
|
||||||
class ZigbeeNetwork : public QObject
|
class ZigbeeNetwork : public QObject
|
||||||
@ -54,6 +55,7 @@ class ZigbeeNetwork : public QObject
|
|||||||
Q_PROPERTY(uint permitJoiningRemaining READ permitJoiningRemaining NOTIFY permitJoiningRemainingChanged)
|
Q_PROPERTY(uint permitJoiningRemaining READ permitJoiningRemaining NOTIFY permitJoiningRemainingChanged)
|
||||||
Q_PROPERTY(QString backend READ backend NOTIFY backendChanged)
|
Q_PROPERTY(QString backend READ backend NOTIFY backendChanged)
|
||||||
Q_PROPERTY(ZigbeeNetworkState networkState READ networkState NOTIFY networkStateChanged)
|
Q_PROPERTY(ZigbeeNetworkState networkState READ networkState NOTIFY networkStateChanged)
|
||||||
|
Q_PROPERTY(ZigbeeNodes *nodes READ nodes CONSTANT)
|
||||||
|
|
||||||
// Internal properties
|
// Internal properties
|
||||||
|
|
||||||
@ -69,6 +71,8 @@ public:
|
|||||||
|
|
||||||
explicit ZigbeeNetwork(QObject *parent = nullptr);
|
explicit ZigbeeNetwork(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
ZigbeeNodes *nodes() const;
|
||||||
|
|
||||||
QUuid networkUuid() const;
|
QUuid networkUuid() const;
|
||||||
void setNetworkUuid(const QUuid &networkUuid);
|
void setNetworkUuid(const QUuid &networkUuid);
|
||||||
|
|
||||||
@ -145,6 +149,8 @@ private:
|
|||||||
QString m_backend;
|
QString m_backend;
|
||||||
ZigbeeNetworkState m_networkState;
|
ZigbeeNetworkState m_networkState;
|
||||||
|
|
||||||
|
ZigbeeNodes *m_nodes = nullptr;
|
||||||
|
|
||||||
QTimer *m_permitJoinTimer = nullptr;
|
QTimer *m_permitJoinTimer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -92,7 +92,6 @@ QHash<int, QByteArray> ZigbeeNetworks::roleNames() const
|
|||||||
roles.insert(RoleBackend, "backend");
|
roles.insert(RoleBackend, "backend");
|
||||||
roles.insert(RoleNetworkState, "networkState");
|
roles.insert(RoleNetworkState, "networkState");
|
||||||
return roles;
|
return roles;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworks::addNetwork(ZigbeeNetwork *network)
|
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"
|
#include "zigbeenode.h"
|
||||||
|
|
||||||
ZigbeeNode::ZigbeeNode(QUuid networkUuid, QObject *parent) :
|
ZigbeeNode::ZigbeeNode(const QUuid &networkUuid, const QString &ieeeAddress, QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_networkUuid(networkUuid)
|
m_networkUuid(networkUuid),
|
||||||
|
m_ieeeAddress(ieeeAddress)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -11,3 +42,187 @@ QUuid ZigbeeNode::networkUuid() const
|
|||||||
{
|
{
|
||||||
return m_networkUuid;
|
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
|
#ifndef ZIGBEENODE_H
|
||||||
#define ZIGBEENODE_H
|
#define ZIGBEENODE_H
|
||||||
|
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QVariantMap>
|
||||||
|
|
||||||
class ZigbeeNode : public QObject
|
class ZigbeeNode : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QUuid networkUuid READ networkUuid CONSTANT)
|
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:
|
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;
|
QUuid networkUuid() const;
|
||||||
|
|
||||||
QString ieeeAddress() 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:
|
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:
|
private:
|
||||||
QUuid m_networkUuid;
|
QUuid m_networkUuid;
|
||||||
QString m_ieeeAddress;
|
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
|
#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/modbus.svg</file>
|
||||||
<file>ui/images/setupwizard/wired-connection.svg</file>
|
<file>ui/images/setupwizard/wired-connection.svg</file>
|
||||||
<file>ui/images/setupwizard/wireless-connection.svg</file>
|
<file>ui/images/setupwizard/wireless-connection.svg</file>
|
||||||
|
<file>ui/images/system-suspend.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -219,7 +219,7 @@
|
|||||||
<file>ui/components/ThingInfoPane.qml</file>
|
<file>ui/components/ThingInfoPane.qml</file>
|
||||||
<file>ui/system/ZigbeeSettingsPage.qml</file>
|
<file>ui/system/ZigbeeSettingsPage.qml</file>
|
||||||
<file>ui/system/ZigbeeAddNetworkPage.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/MainMenu.qml</file>
|
||||||
<file>ui/components/NymeaItemDelegate.qml</file>
|
<file>ui/components/NymeaItemDelegate.qml</file>
|
||||||
<file>ui/components/NymeaSwipeDelegate.qml</file>
|
<file>ui/components/NymeaSwipeDelegate.qml</file>
|
||||||
@ -251,5 +251,6 @@
|
|||||||
<file>ui/system/ModbusRtuReconfigureMasterPage.qml</file>
|
<file>ui/system/ModbusRtuReconfigureMasterPage.qml</file>
|
||||||
<file>ui/connection/NewConnectionWizard.qml</file>
|
<file>ui/connection/NewConnectionWizard.qml</file>
|
||||||
<file>ui/components/WizardPageBase.qml</file>
|
<file>ui/components/WizardPageBase.qml</file>
|
||||||
|
<file>ui/system/ZigbeeNetworkPage.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</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
|
* Contact: contact@nymea.io
|
||||||
*
|
*
|
||||||
* This file is part of nymea.
|
* This file is part of nymea.
|
||||||
@ -42,120 +42,347 @@ SettingsPageBase {
|
|||||||
property ZigbeeNetwork network: null
|
property ZigbeeNetwork network: null
|
||||||
|
|
||||||
header: NymeaHeader {
|
header: NymeaHeader {
|
||||||
text: qsTr("ZigBee network settings")
|
text: qsTr("ZigBee network")
|
||||||
backButtonVisible: true
|
backButtonVisible: true
|
||||||
onBackPressed: pageStack.pop()
|
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 {
|
SettingsPageSectionHeader {
|
||||||
text: qsTr("Network information")
|
text: qsTr("Network")
|
||||||
}
|
}
|
||||||
|
|
||||||
NymeaSwipeDelegate {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("Network state")
|
Layout.leftMargin: app.margins
|
||||||
subText: {
|
Layout.rightMargin: app.margins
|
||||||
switch (root.network.networkState) {
|
|
||||||
case ZigbeeNetwork.ZigbeeNetworkStateOnline:
|
Label {
|
||||||
return qsTr("The network is online")
|
//Layout.fillWidth: true
|
||||||
case ZigbeeNetwork.ZigbeeNetworkStateOffline:
|
text: {
|
||||||
return qsTr("The network is offline")
|
switch (network.networkState) {
|
||||||
case ZigbeeNetwork.ZigbeeNetworkStateStarting:
|
case ZigbeeNetwork.ZigbeeNetworkStateOnline:
|
||||||
return qsTr("The network is starting...")
|
return qsTr("Online")
|
||||||
case ZigbeeNetwork.ZigbeeNetworkStateUpdating:
|
case ZigbeeNetwork.ZigbeeNetworkStateOffline:
|
||||||
return qsTr("The controller is currently installing an update")
|
return qsTr("Offline")
|
||||||
case ZigbeeNetwork.ZigbeeNetworkStateError:
|
case ZigbeeNetwork.ZigbeeNetworkStateStarting:
|
||||||
return qsTr("The network is in an error state.")
|
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
|
Layout.fillWidth: true
|
||||||
text: qsTr("Channel")
|
Layout.leftMargin: app.margins
|
||||||
subText: root.network.channel
|
Layout.rightMargin: app.margins
|
||||||
progressive: false
|
text: qsTr("Channel") + ": " + network.channel
|
||||||
}
|
}
|
||||||
|
|
||||||
NymeaSwipeDelegate {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("Network PAN ID")
|
Layout.leftMargin: app.margins
|
||||||
subText: root.network.panId
|
Layout.rightMargin: app.margins
|
||||||
progressive: false
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsPageSectionHeader {
|
Label {
|
||||||
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 {
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: app.margins
|
text: qsTr("Permit new devices:")
|
||||||
Layout.rightMargin: app.margins
|
}
|
||||||
text: qsTr("Remove network")
|
Label {
|
||||||
onClicked: {
|
text: network.permitJoiningEnabled ? qsTr("Open for %0 s").arg(network.permitJoiningRemaining) : qsTr("Closed")
|
||||||
root.zigbeeManager.removeNetwork(root.network.networkUuid)
|
}
|
||||||
pageStack.pop()
|
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
|
// NymeaSwipeDelegate {
|
||||||
Layout.leftMargin: app.margins
|
// Layout.fillWidth: true
|
||||||
Layout.rightMargin: app.margins
|
// iconName: "../images/zigbee.svg"
|
||||||
text: qsTr("Factory reset controller")
|
// text: node.manufacturer + " - " + node.model + " - " + node.version
|
||||||
onClicked: {
|
// subText: node.ieeeAddress + " " + node.networkAddress
|
||||||
root.zigbeeManager.factoryResetNetwork(root.network.networkUuid)
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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
|
Layout.fillWidth: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
|
onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkPage.qml"), { zigbeeManager: zigbeeManager, network: zigbeeManager.networks.get(index) })
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
spacing: app.margins
|
spacing: app.margins
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
ColorIcon {
|
ColorIcon {
|
||||||
name: "/ui/images/zigbee/" + model.backend + ".svg"
|
name: "/ui/images/zigbee/" + model.backend + ".svg"
|
||||||
@ -95,14 +98,8 @@ SettingsPageBase {
|
|||||||
text: model.backend
|
text: model.backend
|
||||||
font.pixelSize: app.largeFont
|
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 {
|
RowLayout {
|
||||||
Label {
|
Label {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@ -148,65 +145,21 @@ SettingsPageBase {
|
|||||||
RowLayout {
|
RowLayout {
|
||||||
Label {
|
Label {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("Permit new devices:")
|
text: qsTr("MAC address:")
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
text: model.permitJoiningEnabled ? qsTr("Open for %0 s").arg(model.permitJoiningRemaining) : qsTr("Closed")
|
text: model.macAddress
|
||||||
}
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Label {
|
||||||
text: model.permitJoiningEnabled ? qsTr("Extend open duration") : qsTr("Open for new devices")
|
Layout.fillWidth: true
|
||||||
enabled: model.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline
|
text: qsTr("Firmware version:")
|
||||||
onClicked: zigbeeManager.setPermitJoin(model.networkUuid)
|
}
|
||||||
|
Label {
|
||||||
|
text: model.firmwareVersion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user