diff --git a/libnymea-core/jsonrpc/zigbeehandler.cpp b/libnymea-core/jsonrpc/zigbeehandler.cpp
index eab8bb7c..24e7d5bc 100644
--- a/libnymea-core/jsonrpc/zigbeehandler.cpp
+++ b/libnymea-core/jsonrpc/zigbeehandler.cpp
@@ -1,530 +1,530 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-*
-* 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 Lesser General Public License Usage
-* Alternatively, this project may be redistributed and/or modified under the
-* terms of the GNU Lesser General Public License as published by the Free
-* Software Foundation; 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
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with this project. If not, see .
-*
-* For any further details and any questions please contact us under
-* contact@nymea.io or see our FAQ/Licensing Information on
-* https://nymea.io/license/faq
-*
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-#include "zigbeehandler.h"
-#include "zigbee/zigbeemanager.h"
-#include "zigbee/zigbeeadapters.h"
-#include "loggingcategories.h"
-
-#include
-
-namespace nymeaserver {
-
-ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) :
- JsonHandler(parent),
- m_zigbeeManager(zigbeeManager)
-{
- qRegisterMetaType();
- registerEnum();
- registerEnum();
- registerEnum();
- registerEnum();
- registerObject();
-
- // Network object describing a network instance
- QVariantMap zigbeeNetworkDescription;
- zigbeeNetworkDescription.insert("networkUuid", enumValueName(Uuid));
- zigbeeNetworkDescription.insert("enabled", enumValueName(Bool));
- zigbeeNetworkDescription.insert("serialPort", enumValueName(String));
- zigbeeNetworkDescription.insert("baudRate", enumValueName(Uint));
- zigbeeNetworkDescription.insert("macAddress", enumValueName(String));
- zigbeeNetworkDescription.insert("firmwareVersion", enumValueName(String));
- zigbeeNetworkDescription.insert("panId", enumValueName(Uint));
- zigbeeNetworkDescription.insert("channel", enumValueName(Uint));
- zigbeeNetworkDescription.insert("channelMask", enumValueName(Uint));
- zigbeeNetworkDescription.insert("permitJoiningEnabled", enumValueName(Bool));
- zigbeeNetworkDescription.insert("permitJoiningDuration", enumValueName(Uint));
- zigbeeNetworkDescription.insert("permitJoiningRemaining", enumValueName(Uint));
- zigbeeNetworkDescription.insert("backend", enumValueName(String));
- zigbeeNetworkDescription.insert("networkState", enumRef());
- registerObject("ZigbeeNetwork", zigbeeNetworkDescription);
-
- // Zigbee node description
- QVariantMap zigbeeNodeDescription;
- zigbeeNodeDescription.insert("networkUuid", enumValueName(Uuid));
- zigbeeNodeDescription.insert("ieeeAddress", enumValueName(String));
- zigbeeNodeDescription.insert("networkAddress", enumValueName(Uint));
- zigbeeNodeDescription.insert("type", enumRef());
- zigbeeNodeDescription.insert("state", enumRef());
- zigbeeNodeDescription.insert("manufacturer", enumValueName(String));
- zigbeeNodeDescription.insert("model", enumValueName(String));
- zigbeeNodeDescription.insert("version", enumValueName(String));
- zigbeeNodeDescription.insert("receiverOnWhileIdle", enumValueName(Bool));
- zigbeeNodeDescription.insert("reachable", enumValueName(Bool));
- zigbeeNodeDescription.insert("lqi", enumValueName(Uint));
- zigbeeNodeDescription.insert("lastSeen", enumValueName(Uint));
- registerObject("ZigbeeNode", zigbeeNodeDescription);
-
- QVariantMap params, returns;
- QString description;
-
- // GetAvailableBackends
- params.clear(); returns.clear();
- description = "Get the list of available ZigBee backends.";
- returns.insert("backends", QVariantList() << enumValueName(String));
- registerMethod("GetAvailableBackends", description, params, returns);
-
- // GetAdapters
- params.clear(); returns.clear();
- description = "Get the list of available ZigBee adapters and serial ports in order to set up the ZigBee network "
- "on the desired interface. The \'serialPort\' property can be used as unique identifier for an adapter. "
- "If an adapter hardware has been recognized as a well known ZigBee adapter, "
- "the \'hardwareRecognized\' property will be true and the \'baudRate\' and \'backend\' "
- "configurations can be used as they where given, otherwise the user might set the backend "
- "and baud rate manually. The available backends can be fetched using the GetAvailableBackends method.";
- returns.insert("adapters", objectRef());
- registerMethod("GetAdapters", description, params, returns);
-
- // AdapterAdded notification
- params.clear();
- description = "Emitted whenever a new ZigBee adapter or serial port has been detected in the system.";
- params.insert("adapter", objectRef());
- registerNotification("AdapterAdded", description, params);
-
- // AdapterRemoved notification
- params.clear();
- description = "Emitted whenever a ZigBee adapter or serial port has been removed from the system (i.e. unplugged).";
- params.insert("adapter", objectRef());
- registerNotification("AdapterRemoved", description, params);
-
- // GetNetworks
- params.clear(); returns.clear();
- description = "Returns the list of configured ZigBee networks in the system.";
- returns.insert("zigbeeNetworks", QVariantList() << objectRef("ZigbeeNetwork"));
- registerMethod("GetNetworks", description, params, returns);
-
- // AddNetwork
- params.clear(); returns.clear();
- description = "Create a new ZigBee network for the given \'serialPort\', \'baudRate\' and \'backend\'. "
- "The serial ports can be fetched from the available adapters. See \'GetAdapters\' for more information. "
- "The available backends can be fetched using the \'GetAvailableBackends\' method.";
- params.insert("serialPort", enumValueName(String));
- params.insert("baudRate", enumValueName(Uint));
- params.insert("backend", enumValueName(String));
- params.insert("o:channelMask", enumValueName(Uint));
- returns.insert("zigbeeError", enumRef());
- returns.insert("o:networkUuid", enumValueName(Uuid));
- registerMethod("AddNetwork", description, params, returns);
-
- // RemoveNetwork
- params.clear(); returns.clear();
- description = "Remove the ZigBee network with the given network uuid.";
- params.insert("networkUuid", enumValueName(Uuid));
- returns.insert("zigbeeError", enumRef());
- registerMethod("RemoveNetwork", description, params, returns);
-
- // NetworkAdded notification
- params.clear();
- description = "Emitted whenever a new ZigBee network has been added.";
- params.insert("zigbeeNetwork", objectRef("ZigbeeNetwork"));
- registerNotification("NetworkAdded", description, params);
-
- // NetworkRemoved notification
- params.clear();
- description = "Emitted whenever a new ZigBee network has been removed.";
- params.insert("networkUuid", enumValueName(Uuid));
- registerNotification("NetworkRemoved", description, params);
-
- // NetworkChanged notification
- params.clear();
- description = "Emitted whenever a new ZigBee network has changed.";
- params.insert("zigbeeNetwork", objectRef("ZigbeeNetwork"));
- registerNotification("NetworkChanged", description, params);
-
- // FactoryResetNetwork
- params.clear(); returns.clear();
- description = "Factory reset the network with the given \'networkUuid\'. The network does not have "
- "to be online for this procedure, and all associated nodes and things will be removed permanently.";
- params.insert("networkUuid", enumValueName(Uuid));
- returns.insert("zigbeeError", enumRef());
- registerMethod("FactoryResetNetwork", description, params, returns);
-
- // SetPermitJoin
- params.clear(); returns.clear();
- description = "Allow or deny nodes to join the network with the given \'networkUuid\' for a specific \'duration\' in seconds. "
- "The duration value has to be between 0 and 255 seconds. The \'permitJoinDuration\' property of ZigBee network "
- "object indicates how long permit has been enabled and the \'permitJoiningRemaining\' indicates the rest of the time. "
- "Those values can be used to show a countdown or progressbar. This method can be recalled for resetting the timeout. "
- "If the duration is set to 0 seconds, joining will be disabled immediatly for the entire network. "
- "The \'shortAddress\' is optional and defaults to the broadcast address 0xfffc for all routers in the network. "
- "If the short address matches the address of a router node in the network, only that specific router will "
- "be able to allow new nodes to join the network. A new node will join to the router with the best link quality index (LQI).";
- params.insert("networkUuid", enumValueName(Uuid));
- params.insert("duration", enumValueName(Uint));
- params.insert("o:shortAddress", enumValueName(Uint));
- returns.insert("zigbeeError", enumRef());
- registerMethod("SetPermitJoin", description, params, returns);
-
- // GetNodes
- params.clear(); returns.clear();
- description = "Returns the list of ZigBee nodes from the network the given \'networkUuid\' in the system.";
- params.insert("networkUuid", enumValueName(Uuid));
- returns.insert("zigbeeError", enumRef());
- returns.insert("o:zigbeeNodes", QVariantList() << objectRef("ZigbeeNode"));
- registerMethod("GetNodes", description, params, returns);
-
- // RemoveNode
- params.clear(); returns.clear();
- description = "Remove a ZigBee node with the given \'ieeeAddress\' from the network with the given \'networkUuid\'. "
- "If there is a thing configured for this node, also the thing will be removed from the system. "
- "The coordinator node cannot be removed.";
- params.insert("networkUuid", enumValueName(Uuid));
- params.insert("ieeeAddress", enumValueName(String));
- returns.insert("zigbeeError", enumRef());
- registerMethod("RemoveNode", description, params, returns);
-
- // NodeAdded
- params.clear();
- description = "Emitted whenever a new ZigBee node has joined the network with the given \'networkUuid\'.";
- params.insert("networkUuid", enumValueName(Uuid));
- params.insert("zigbeeNode", objectRef("ZigbeeNode"));
- registerNotification("NodeAdded", description, params);
-
- // NodeRemoved
- params.clear();
- description = "Emitted whenever a ZigBee node has removed from the network with the given \'networkUuid\'.";
- params.insert("networkUuid", enumValueName(Uuid));
- params.insert("zigbeeNode", objectRef("ZigbeeNode"));
- registerNotification("NodeRemoved", description, params);
-
- // NodeChanged
- params.clear();
- description = "Emitted whenever a ZigBee node has changed.";
- params.insert("networkUuid", enumValueName(Uuid));
- params.insert("zigbeeNode", objectRef("ZigbeeNode"));
- registerNotification("NodeChanged", description, params);
-
- connect(m_zigbeeManager, &ZigbeeManager::availableAdapterAdded, this, [this](const ZigbeeAdapter &adapter){
- QVariantMap params;
- params.insert("adapter", pack(adapter));
- emit AdapterAdded(params);
- });
-
- connect(m_zigbeeManager, &ZigbeeManager::availableAdapterRemoved, this, [this](const ZigbeeAdapter &adapter){
- QVariantMap params;
- params.insert("adapter", pack(adapter));
- emit AdapterRemoved(params);
- });
-
- connect(m_zigbeeManager, &ZigbeeManager::zigbeeNetworkAdded, this, [this](ZigbeeNetwork *network){
- QVariantMap params;
- params.insert("zigbeeNetwork", packNetwork(network));
- emit NetworkAdded(params);
- });
-
- connect(m_zigbeeManager, &ZigbeeManager::zigbeeNetworkChanged, this, [this](ZigbeeNetwork *network){
- QVariantMap params;
- params.insert("zigbeeNetwork", packNetwork(network));
- emit NetworkChanged(params);
- });
-
- connect(m_zigbeeManager, &ZigbeeManager::zigbeeNetworkRemoved, this, [this](const QUuid &networkUuid){
- QVariantMap params;
- params.insert("networkUuid", networkUuid);
- emit NetworkRemoved(params);
- });
-
- connect(m_zigbeeManager, &ZigbeeManager::nodeJoined, this, &ZigbeeHandler::onNodeJoined);
- connect(m_zigbeeManager, &ZigbeeManager::nodeAdded, this, &ZigbeeHandler::onNodeAdded);
- connect(m_zigbeeManager, &ZigbeeManager::nodeChanged, this, &ZigbeeHandler::onNodeChanged);
- connect(m_zigbeeManager, &ZigbeeManager::nodeRemoved, this, &ZigbeeHandler::onNodeRemoved);
-
-}
-
-QString ZigbeeHandler::name() const
-{
- return "Zigbee";
-}
-
-JsonReply *ZigbeeHandler::GetAvailableBackends(const QVariantMap ¶ms)
-{
- Q_UNUSED(params)
-
- QVariantMap returnMap;
- QVariantList backendsList;
- foreach (const QString &backendName, ZigbeeAdapter::backendNames().values()) {
- backendsList << backendName;
- }
- returnMap.insert("backends", backendsList);
- return createReply(returnMap);
-}
-
-JsonReply *ZigbeeHandler::GetAdapters(const QVariantMap ¶ms)
-{
- Q_UNUSED(params)
-
- QVariantMap returnMap;
- QVariantList adapterList;
- foreach (const ZigbeeAdapter &adapter, m_zigbeeManager->availableAdapters()) {
- adapterList << pack(adapter);
- }
- returnMap.insert("adapters", adapterList);
- return createReply(returnMap);
-}
-
-JsonReply *ZigbeeHandler::AddNetwork(const QVariantMap ¶ms)
-{
- QVariantMap returnMap;
-
- QString serialPort = params.value("serialPort").toString();
- uint baudRate = params.value("baudRate").toUInt();
- QString backendString = params.value("backend").toString();
- if (!ZigbeeAdapter::backendNames().values().contains(backendString)) {
- returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorUnknownBackend));
- return createReply(returnMap);
- }
-
- ZigbeeChannelMask channelMask = ZigbeeChannelMask::ChannelConfigurationAllChannels;
- if (params.contains("channelMask")) {
- channelMask = params.value("channelMask").toUInt() & ZigbeeChannelMask::ChannelConfigurationAllChannels;
- if (channelMask == ZigbeeChannelMask::ChannelConfigurationNoChannel) {
- returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorInvalidChannel));
- return createReply(returnMap);
- }
- }
-
- QPair result = m_zigbeeManager->createZigbeeNetwork(serialPort, baudRate, ZigbeeAdapter::backendNames().key(backendString), channelMask);
- if (result.first == ZigbeeManager::ZigbeeErrorNoError) {
- returnMap.insert("networkUuid", result.second);
- }
- returnMap.insert("zigbeeError", enumValueName(result.first));
- return createReply(returnMap);
-}
-
-JsonReply *ZigbeeHandler::RemoveNetwork(const QVariantMap ¶ms)
-{
- QUuid networkUuid = params.value("networkUuid").toUuid();
- ZigbeeManager::ZigbeeError error = m_zigbeeManager->removeZigbeeNetwork(networkUuid);
- QVariantMap returnMap;
- returnMap.insert("zigbeeError", enumValueName(error));
- return createReply(returnMap);
-}
-
-JsonReply *ZigbeeHandler::FactoryResetNetwork(const QVariantMap ¶ms)
-{
- QUuid networkUuid = params.value("networkUuid").toUuid();
- ZigbeeManager::ZigbeeError error = m_zigbeeManager->factoryResetNetwork(networkUuid);
- QVariantMap returnMap;
- returnMap.insert("zigbeeError", enumValueName(error));
- return createReply(returnMap);
-}
-
-JsonReply *ZigbeeHandler::SetPermitJoin(const QVariantMap ¶ms)
-{
- QUuid networkUuid = params.value("networkUuid").toUuid();
- uint duration = params.value("duration").toUInt();
- quint16 shortAddress = static_cast(Zigbee::BroadcastAddressAllRouters);
- if (params.contains("shortAddress")) {
- shortAddress = static_cast(params.value("shortAddress").toUInt());
- }
- ZigbeeManager::ZigbeeError error = m_zigbeeManager->setZigbeeNetworkPermitJoin(networkUuid, shortAddress, duration);
- QVariantMap returnMap;
- returnMap.insert("zigbeeError", enumValueName(error));
- return createReply(returnMap);
-}
-
-JsonReply *ZigbeeHandler::GetNodes(const QVariantMap ¶ms)
-{
- QVariantMap returnMap;
- QUuid networkUuid = params.value("networkUuid").toUuid();
- ZigbeeNetwork *network = m_zigbeeManager->zigbeeNetworks().value(networkUuid);
- if (!network) {
- returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNetworkUuidNotFound));
- return createReply(returnMap);
- }
-
- QVariantList nodeList;
- foreach (ZigbeeNode *node, network->nodes()) {
- nodeList << packNode(node);
- }
-
- returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNoError));
- returnMap.insert("zigbeeNodes", nodeList);
- return createReply(returnMap);
-}
-
-JsonReply *ZigbeeHandler::RemoveNode(const QVariantMap ¶ms)
-{
- QVariantMap returnMap;
- QUuid networkUuid = params.value("networkUuid").toUuid();
- ZigbeeAddress nodeAddress(params.value("ieeeAddress").toString());
- ZigbeeNetwork *network = m_zigbeeManager->zigbeeNetworks().value(networkUuid);
- if (!network) {
- returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNetworkUuidNotFound));
- return createReply(returnMap);
- }
-
- if (!network->hasNode(nodeAddress)) {
- returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNodeNotFound));
- return createReply(returnMap);
- }
-
- ZigbeeNode *node = network->getZigbeeNode(nodeAddress);
- if (node->shortAddress() == 0x0000) {
- returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorForbidden));
- return createReply(returnMap);
- }
-
- network->removeZigbeeNode(nodeAddress);
- returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNoError));
- return createReply(returnMap);
-}
-
-JsonReply *ZigbeeHandler::GetNetworks(const QVariantMap ¶ms)
-{
- Q_UNUSED(params)
-
- QVariantMap returnMap;
- QVariantList networkList;
- foreach (ZigbeeNetwork *network, m_zigbeeManager->zigbeeNetworks().values()) {
- networkList.append(packNetwork(network));
- }
- returnMap.insert("zigbeeNetworks", networkList);
- return createReply(returnMap);
-}
-
-QVariantMap ZigbeeHandler::packNetwork(ZigbeeNetwork *network)
-{
- QVariantMap networkMap;
- networkMap.insert("networkUuid", network->networkUuid());
- networkMap.insert("enabled", true); // FIXME: set actual value once supported
- networkMap.insert("serialPort", network->serialPortName());
- networkMap.insert("baudRate", network->serialBaudrate());
- networkMap.insert("macAddress", network->macAddress().toString());
- networkMap.insert("firmwareVersion", network->firmwareVersion());
- networkMap.insert("panId", network->panId());
- networkMap.insert("channel", network->channel());
- networkMap.insert("channelMask", network->channelMask().toUInt32());
- networkMap.insert("permitJoiningEnabled", network->permitJoiningEnabled());
- networkMap.insert("permitJoiningDuration", network->permitJoiningDuration());
- networkMap.insert("permitJoiningRemaining", network->permitJoiningRemaining());
-
- switch (network->backendType()) {
- case Zigbee::ZigbeeBackendTypeDeconz:
- networkMap.insert("backend", ZigbeeAdapter::backendNames().value(ZigbeeAdapter::ZigbeeBackendTypeDeconz));
- break;
- case Zigbee::ZigbeeBackendTypeNxp:
- networkMap.insert("backend", ZigbeeAdapter::backendNames().value(ZigbeeAdapter::ZigbeeBackendTypeNxp));
- break;
- }
-
- switch (network->state()) {
- case ZigbeeNetwork::StateOffline:
- case ZigbeeNetwork::StateStopping:
- networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateOffline));
- break;
- case ZigbeeNetwork::StateStarting:
- networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateStarting));
- break;
- case ZigbeeNetwork::StateRunning:
- networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateOnline));
- break;
- case ZigbeeNetwork::StateUpdating:
- networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateUpdating));
- break;
- case ZigbeeNetwork::StateUninitialized:
- networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateError));
- break;
- }
-
- return networkMap;
-}
-
-QVariantMap ZigbeeHandler::packNode(ZigbeeNode *node)
-{
- QVariantMap nodeMap;
- nodeMap.insert("networkUuid", node->networkUuid());
- nodeMap.insert("ieeeAddress", node->extendedAddress().toString());
- nodeMap.insert("networkAddress", node->shortAddress());
- switch (node->nodeDescriptor().nodeType) {
- case ZigbeeDeviceProfile::NodeTypeCoordinator:
- nodeMap.insert("type", enumValueName(ZigbeeManager::ZigbeeNodeTypeCoordinator));
- break;
- case ZigbeeDeviceProfile::NodeTypeRouter:
- nodeMap.insert("type", enumValueName(ZigbeeManager::ZigbeeNodeTypeRouter));
- break;
- default:
- nodeMap.insert("type", enumValueName(ZigbeeManager::ZigbeeNodeTypeEndDevice));
- break;
- }
-
- switch (node->state()) {
- case ZigbeeNode::StateUninitialized:
- nodeMap.insert("state", enumValueName(ZigbeeManager::ZigbeeNodeStateUninitialized));
- break;
- case ZigbeeNode::StateInitializing:
- nodeMap.insert("state", enumValueName(ZigbeeManager::ZigbeeNodeStateInitializing));
- break;
- case ZigbeeNode::StateInitialized:
- nodeMap.insert("state", enumValueName(ZigbeeManager::ZigbeeNodeStateInitialized));
- break;
- }
-
- nodeMap.insert("manufacturer", node->manufacturerName());
- nodeMap.insert("model", node->modelName());
- nodeMap.insert("version", node->version());
- nodeMap.insert("receiverOnWhileIdle", node->macCapabilities().receiverOnWhenIdle);
- nodeMap.insert("reachable", node->reachable());
- nodeMap.insert("lqi", node->lqi());
- nodeMap.insert("lastSeen", node->lastSeen().toMSecsSinceEpoch() / 1000);
- return nodeMap;
-}
-
-void ZigbeeHandler::onNodeJoined(const QUuid &networkUuid, ZigbeeNode *node)
-{
- QVariantMap params;
- params.insert("networkUuid", networkUuid);
- params.insert("zigbeeNode", packNode(node));
- emit NodeAdded(params);
-}
-
-void ZigbeeHandler::onNodeAdded(const QUuid &networkUuid, ZigbeeNode *node)
-{
- // Note: we emit the node changed signal here, since the node has been added internally after initialization.
- onNodeChanged(networkUuid, node);
-}
-
-void ZigbeeHandler::onNodeChanged(const QUuid &networkUuid, ZigbeeNode *node)
-{
- QVariantMap params;
- params.insert("networkUuid", networkUuid);
- params.insert("zigbeeNode", packNode(node));
- emit NodeChanged(params);
-}
-
-void ZigbeeHandler::onNodeRemoved(const QUuid &networkUuid, ZigbeeNode *node)
-{
- QVariantMap params;
- params.insert("networkUuid", networkUuid);
- params.insert("zigbeeNode", packNode(node));
- emit NodeRemoved(params);
-}
-
-}
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* 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 Lesser General Public License Usage
+* Alternatively, this project may be redistributed and/or modified under the
+* terms of the GNU Lesser General Public License as published by the Free
+* Software Foundation; 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this project. If not, see .
+*
+* For any further details and any questions please contact us under
+* contact@nymea.io or see our FAQ/Licensing Information on
+* https://nymea.io/license/faq
+*
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "zigbeehandler.h"
+#include "zigbee/zigbeemanager.h"
+#include "zigbee/zigbeeadapters.h"
+#include "loggingcategories.h"
+
+#include
+
+namespace nymeaserver {
+
+ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) :
+ JsonHandler(parent),
+ m_zigbeeManager(zigbeeManager)
+{
+ qRegisterMetaType();
+ registerEnum();
+ registerEnum();
+ registerEnum();
+ registerEnum();
+ registerObject();
+
+ // Network object describing a network instance
+ QVariantMap zigbeeNetworkDescription;
+ zigbeeNetworkDescription.insert("networkUuid", enumValueName(Uuid));
+ zigbeeNetworkDescription.insert("enabled", enumValueName(Bool));
+ zigbeeNetworkDescription.insert("serialPort", enumValueName(String));
+ zigbeeNetworkDescription.insert("baudRate", enumValueName(Uint));
+ zigbeeNetworkDescription.insert("macAddress", enumValueName(String));
+ zigbeeNetworkDescription.insert("firmwareVersion", enumValueName(String));
+ zigbeeNetworkDescription.insert("panId", enumValueName(Uint));
+ zigbeeNetworkDescription.insert("channel", enumValueName(Uint));
+ zigbeeNetworkDescription.insert("channelMask", enumValueName(Uint));
+ zigbeeNetworkDescription.insert("permitJoiningEnabled", enumValueName(Bool));
+ zigbeeNetworkDescription.insert("permitJoiningDuration", enumValueName(Uint));
+ zigbeeNetworkDescription.insert("permitJoiningRemaining", enumValueName(Uint));
+ zigbeeNetworkDescription.insert("backend", enumValueName(String));
+ zigbeeNetworkDescription.insert("networkState", enumRef());
+ registerObject("ZigbeeNetwork", zigbeeNetworkDescription);
+
+ // Zigbee node description
+ QVariantMap zigbeeNodeDescription;
+ zigbeeNodeDescription.insert("networkUuid", enumValueName(Uuid));
+ zigbeeNodeDescription.insert("ieeeAddress", enumValueName(String));
+ zigbeeNodeDescription.insert("networkAddress", enumValueName(Uint));
+ zigbeeNodeDescription.insert("type", enumRef());
+ zigbeeNodeDescription.insert("state", enumRef());
+ zigbeeNodeDescription.insert("manufacturer", enumValueName(String));
+ zigbeeNodeDescription.insert("model", enumValueName(String));
+ zigbeeNodeDescription.insert("version", enumValueName(String));
+ zigbeeNodeDescription.insert("receiverOnWhileIdle", enumValueName(Bool));
+ zigbeeNodeDescription.insert("reachable", enumValueName(Bool));
+ zigbeeNodeDescription.insert("lqi", enumValueName(Uint));
+ zigbeeNodeDescription.insert("lastSeen", enumValueName(Uint));
+ registerObject("ZigbeeNode", zigbeeNodeDescription);
+
+ QVariantMap params, returns;
+ QString description;
+
+ // GetAvailableBackends
+ params.clear(); returns.clear();
+ description = "Get the list of available ZigBee backends.";
+ returns.insert("backends", QVariantList() << enumValueName(String));
+ registerMethod("GetAvailableBackends", description, params, returns);
+
+ // GetAdapters
+ params.clear(); returns.clear();
+ description = "Get the list of available ZigBee adapters and serial ports in order to set up the ZigBee network "
+ "on the desired interface. The \'serialPort\' property can be used as unique identifier for an adapter. "
+ "If an adapter hardware has been recognized as a well known ZigBee adapter, "
+ "the \'hardwareRecognized\' property will be true and the \'baudRate\' and \'backend\' "
+ "configurations can be used as they where given, otherwise the user might set the backend "
+ "and baud rate manually. The available backends can be fetched using the GetAvailableBackends method.";
+ returns.insert("adapters", objectRef());
+ registerMethod("GetAdapters", description, params, returns);
+
+ // AdapterAdded notification
+ params.clear();
+ description = "Emitted whenever a new ZigBee adapter or serial port has been detected in the system.";
+ params.insert("adapter", objectRef());
+ registerNotification("AdapterAdded", description, params);
+
+ // AdapterRemoved notification
+ params.clear();
+ description = "Emitted whenever a ZigBee adapter or serial port has been removed from the system (i.e. unplugged).";
+ params.insert("adapter", objectRef());
+ registerNotification("AdapterRemoved", description, params);
+
+ // GetNetworks
+ params.clear(); returns.clear();
+ description = "Returns the list of configured ZigBee networks in the system.";
+ returns.insert("zigbeeNetworks", QVariantList() << objectRef("ZigbeeNetwork"));
+ registerMethod("GetNetworks", description, params, returns);
+
+ // AddNetwork
+ params.clear(); returns.clear();
+ description = "Create a new ZigBee network for the given \'serialPort\', \'baudRate\' and \'backend\'. "
+ "The serial ports can be fetched from the available adapters. See \'GetAdapters\' for more information. "
+ "The available backends can be fetched using the \'GetAvailableBackends\' method.";
+ params.insert("serialPort", enumValueName(String));
+ params.insert("baudRate", enumValueName(Uint));
+ params.insert("backend", enumValueName(String));
+ params.insert("o:channelMask", enumValueName(Uint));
+ returns.insert("zigbeeError", enumRef());
+ returns.insert("o:networkUuid", enumValueName(Uuid));
+ registerMethod("AddNetwork", description, params, returns);
+
+ // RemoveNetwork
+ params.clear(); returns.clear();
+ description = "Remove the ZigBee network with the given network uuid.";
+ params.insert("networkUuid", enumValueName(Uuid));
+ returns.insert("zigbeeError", enumRef());
+ registerMethod("RemoveNetwork", description, params, returns);
+
+ // NetworkAdded notification
+ params.clear();
+ description = "Emitted whenever a new ZigBee network has been added.";
+ params.insert("zigbeeNetwork", objectRef("ZigbeeNetwork"));
+ registerNotification("NetworkAdded", description, params);
+
+ // NetworkRemoved notification
+ params.clear();
+ description = "Emitted whenever a new ZigBee network has been removed.";
+ params.insert("networkUuid", enumValueName(Uuid));
+ registerNotification("NetworkRemoved", description, params);
+
+ // NetworkChanged notification
+ params.clear();
+ description = "Emitted whenever a new ZigBee network has changed.";
+ params.insert("zigbeeNetwork", objectRef("ZigbeeNetwork"));
+ registerNotification("NetworkChanged", description, params);
+
+ // FactoryResetNetwork
+ params.clear(); returns.clear();
+ description = "Factory reset the network with the given \'networkUuid\'. The network does not have "
+ "to be online for this procedure, and all associated nodes and things will be removed permanently.";
+ params.insert("networkUuid", enumValueName(Uuid));
+ returns.insert("zigbeeError", enumRef());
+ registerMethod("FactoryResetNetwork", description, params, returns);
+
+ // SetPermitJoin
+ params.clear(); returns.clear();
+ description = "Allow or deny nodes to join the network with the given \'networkUuid\' for a specific \'duration\' in seconds. "
+ "The duration value has to be between 0 and 255 seconds. The \'permitJoinDuration\' property of ZigBee network "
+ "object indicates how long permit has been enabled and the \'permitJoiningRemaining\' indicates the rest of the time. "
+ "Those values can be used to show a countdown or progressbar. This method can be recalled for resetting the timeout. "
+ "If the duration is set to 0 seconds, joining will be disabled immediatly for the entire network. "
+ "The \'shortAddress\' is optional and defaults to the broadcast address 0xfffc for all routers in the network. "
+ "If the short address matches the address of a router node in the network, only that specific router will "
+ "be able to allow new nodes to join the network. A new node will join to the router with the best link quality index (LQI).";
+ params.insert("networkUuid", enumValueName(Uuid));
+ params.insert("duration", enumValueName(Uint));
+ params.insert("o:shortAddress", enumValueName(Uint));
+ returns.insert("zigbeeError", enumRef());
+ registerMethod("SetPermitJoin", description, params, returns);
+
+ // GetNodes
+ params.clear(); returns.clear();
+ description = "Returns the list of ZigBee nodes from the network the given \'networkUuid\' in the system.";
+ params.insert("networkUuid", enumValueName(Uuid));
+ returns.insert("zigbeeError", enumRef());
+ returns.insert("o:zigbeeNodes", QVariantList() << objectRef("ZigbeeNode"));
+ registerMethod("GetNodes", description, params, returns);
+
+ // RemoveNode
+ params.clear(); returns.clear();
+ description = "Remove a ZigBee node with the given \'ieeeAddress\' from the network with the given \'networkUuid\'. "
+ "If there is a thing configured for this node, also the thing will be removed from the system. "
+ "The coordinator node cannot be removed.";
+ params.insert("networkUuid", enumValueName(Uuid));
+ params.insert("ieeeAddress", enumValueName(String));
+ returns.insert("zigbeeError", enumRef());
+ registerMethod("RemoveNode", description, params, returns);
+
+ // NodeAdded
+ params.clear();
+ description = "Emitted whenever a new ZigBee node has joined the network with the given \'networkUuid\'.";
+ params.insert("networkUuid", enumValueName(Uuid));
+ params.insert("zigbeeNode", objectRef("ZigbeeNode"));
+ registerNotification("NodeAdded", description, params);
+
+ // NodeRemoved
+ params.clear();
+ description = "Emitted whenever a ZigBee node has removed from the network with the given \'networkUuid\'.";
+ params.insert("networkUuid", enumValueName(Uuid));
+ params.insert("zigbeeNode", objectRef("ZigbeeNode"));
+ registerNotification("NodeRemoved", description, params);
+
+ // NodeChanged
+ params.clear();
+ description = "Emitted whenever a ZigBee node has changed.";
+ params.insert("networkUuid", enumValueName(Uuid));
+ params.insert("zigbeeNode", objectRef("ZigbeeNode"));
+ registerNotification("NodeChanged", description, params);
+
+ connect(m_zigbeeManager, &ZigbeeManager::availableAdapterAdded, this, [this](const ZigbeeAdapter &adapter){
+ QVariantMap params;
+ params.insert("adapter", pack(adapter));
+ emit AdapterAdded(params);
+ });
+
+ connect(m_zigbeeManager, &ZigbeeManager::availableAdapterRemoved, this, [this](const ZigbeeAdapter &adapter){
+ QVariantMap params;
+ params.insert("adapter", pack(adapter));
+ emit AdapterRemoved(params);
+ });
+
+ connect(m_zigbeeManager, &ZigbeeManager::zigbeeNetworkAdded, this, [this](ZigbeeNetwork *network){
+ QVariantMap params;
+ params.insert("zigbeeNetwork", packNetwork(network));
+ emit NetworkAdded(params);
+ });
+
+ connect(m_zigbeeManager, &ZigbeeManager::zigbeeNetworkChanged, this, [this](ZigbeeNetwork *network){
+ QVariantMap params;
+ params.insert("zigbeeNetwork", packNetwork(network));
+ emit NetworkChanged(params);
+ });
+
+ connect(m_zigbeeManager, &ZigbeeManager::zigbeeNetworkRemoved, this, [this](const QUuid &networkUuid){
+ QVariantMap params;
+ params.insert("networkUuid", networkUuid);
+ emit NetworkRemoved(params);
+ });
+
+ connect(m_zigbeeManager, &ZigbeeManager::nodeJoined, this, &ZigbeeHandler::onNodeJoined);
+ connect(m_zigbeeManager, &ZigbeeManager::nodeAdded, this, &ZigbeeHandler::onNodeAdded);
+ connect(m_zigbeeManager, &ZigbeeManager::nodeChanged, this, &ZigbeeHandler::onNodeChanged);
+ connect(m_zigbeeManager, &ZigbeeManager::nodeRemoved, this, &ZigbeeHandler::onNodeRemoved);
+
+}
+
+QString ZigbeeHandler::name() const
+{
+ return "Zigbee";
+}
+
+JsonReply *ZigbeeHandler::GetAvailableBackends(const QVariantMap ¶ms)
+{
+ Q_UNUSED(params)
+
+ QVariantMap returnMap;
+ QVariantList backendsList;
+ foreach (const QString &backendName, ZigbeeAdapter::backendNames().values()) {
+ backendsList << backendName;
+ }
+ returnMap.insert("backends", backendsList);
+ return createReply(returnMap);
+}
+
+JsonReply *ZigbeeHandler::GetAdapters(const QVariantMap ¶ms)
+{
+ Q_UNUSED(params)
+
+ QVariantMap returnMap;
+ QVariantList adapterList;
+ foreach (const ZigbeeAdapter &adapter, m_zigbeeManager->availableAdapters()) {
+ adapterList << pack(adapter);
+ }
+ returnMap.insert("adapters", adapterList);
+ return createReply(returnMap);
+}
+
+JsonReply *ZigbeeHandler::AddNetwork(const QVariantMap ¶ms)
+{
+ QVariantMap returnMap;
+
+ QString serialPort = params.value("serialPort").toString();
+ uint baudRate = params.value("baudRate").toUInt();
+ QString backendString = params.value("backend").toString();
+ if (!ZigbeeAdapter::backendNames().values().contains(backendString)) {
+ returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorUnknownBackend));
+ return createReply(returnMap);
+ }
+
+ ZigbeeChannelMask channelMask = ZigbeeChannelMask::ChannelConfigurationAllChannels;
+ if (params.contains("channelMask")) {
+ channelMask = params.value("channelMask").toUInt() & ZigbeeChannelMask::ChannelConfigurationAllChannels;
+ if (channelMask == ZigbeeChannelMask::ChannelConfigurationNoChannel) {
+ returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorInvalidChannel));
+ return createReply(returnMap);
+ }
+ }
+
+ QPair result = m_zigbeeManager->createZigbeeNetwork(serialPort, baudRate, ZigbeeAdapter::backendNames().key(backendString), channelMask);
+ if (result.first == ZigbeeManager::ZigbeeErrorNoError) {
+ returnMap.insert("networkUuid", result.second);
+ }
+ returnMap.insert("zigbeeError", enumValueName(result.first));
+ return createReply(returnMap);
+}
+
+JsonReply *ZigbeeHandler::RemoveNetwork(const QVariantMap ¶ms)
+{
+ QUuid networkUuid = params.value("networkUuid").toUuid();
+ ZigbeeManager::ZigbeeError error = m_zigbeeManager->removeZigbeeNetwork(networkUuid);
+ QVariantMap returnMap;
+ returnMap.insert("zigbeeError", enumValueName(error));
+ return createReply(returnMap);
+}
+
+JsonReply *ZigbeeHandler::FactoryResetNetwork(const QVariantMap ¶ms)
+{
+ QUuid networkUuid = params.value("networkUuid").toUuid();
+ ZigbeeManager::ZigbeeError error = m_zigbeeManager->factoryResetNetwork(networkUuid);
+ QVariantMap returnMap;
+ returnMap.insert("zigbeeError", enumValueName(error));
+ return createReply(returnMap);
+}
+
+JsonReply *ZigbeeHandler::SetPermitJoin(const QVariantMap ¶ms)
+{
+ QUuid networkUuid = params.value("networkUuid").toUuid();
+ uint duration = params.value("duration").toUInt();
+ quint16 shortAddress = static_cast(Zigbee::BroadcastAddressAllRouters);
+ if (params.contains("shortAddress")) {
+ shortAddress = static_cast(params.value("shortAddress").toUInt());
+ }
+ ZigbeeManager::ZigbeeError error = m_zigbeeManager->setZigbeeNetworkPermitJoin(networkUuid, shortAddress, duration);
+ QVariantMap returnMap;
+ returnMap.insert("zigbeeError", enumValueName(error));
+ return createReply(returnMap);
+}
+
+JsonReply *ZigbeeHandler::GetNodes(const QVariantMap ¶ms)
+{
+ QVariantMap returnMap;
+ QUuid networkUuid = params.value("networkUuid").toUuid();
+ ZigbeeNetwork *network = m_zigbeeManager->zigbeeNetworks().value(networkUuid);
+ if (!network) {
+ returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNetworkUuidNotFound));
+ return createReply(returnMap);
+ }
+
+ QVariantList nodeList;
+ foreach (ZigbeeNode *node, network->nodes()) {
+ nodeList << packNode(node);
+ }
+
+ returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNoError));
+ returnMap.insert("zigbeeNodes", nodeList);
+ return createReply(returnMap);
+}
+
+JsonReply *ZigbeeHandler::RemoveNode(const QVariantMap ¶ms)
+{
+ QVariantMap returnMap;
+ QUuid networkUuid = params.value("networkUuid").toUuid();
+ ZigbeeAddress nodeAddress(params.value("ieeeAddress").toString());
+ ZigbeeNetwork *network = m_zigbeeManager->zigbeeNetworks().value(networkUuid);
+ if (!network) {
+ returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNetworkUuidNotFound));
+ return createReply(returnMap);
+ }
+
+ if (!network->hasNode(nodeAddress)) {
+ returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNodeNotFound));
+ return createReply(returnMap);
+ }
+
+ ZigbeeNode *node = network->getZigbeeNode(nodeAddress);
+ if (node->shortAddress() == 0x0000) {
+ returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorForbidden));
+ return createReply(returnMap);
+ }
+
+ network->removeZigbeeNode(nodeAddress);
+ returnMap.insert("zigbeeError", enumValueName(ZigbeeManager::ZigbeeErrorNoError));
+ return createReply(returnMap);
+}
+
+JsonReply *ZigbeeHandler::GetNetworks(const QVariantMap ¶ms)
+{
+ Q_UNUSED(params)
+
+ QVariantMap returnMap;
+ QVariantList networkList;
+ foreach (ZigbeeNetwork *network, m_zigbeeManager->zigbeeNetworks().values()) {
+ networkList.append(packNetwork(network));
+ }
+ returnMap.insert("zigbeeNetworks", networkList);
+ return createReply(returnMap);
+}
+
+QVariantMap ZigbeeHandler::packNetwork(ZigbeeNetwork *network)
+{
+ QVariantMap networkMap;
+ networkMap.insert("networkUuid", network->networkUuid());
+ networkMap.insert("enabled", true); // FIXME: set actual value once supported
+ networkMap.insert("serialPort", network->serialPortName());
+ networkMap.insert("baudRate", network->serialBaudrate());
+ networkMap.insert("macAddress", network->macAddress().toString());
+ networkMap.insert("firmwareVersion", network->firmwareVersion());
+ networkMap.insert("panId", network->panId());
+ networkMap.insert("channel", network->channel());
+ networkMap.insert("channelMask", network->channelMask().toUInt32());
+ networkMap.insert("permitJoiningEnabled", network->permitJoiningEnabled());
+ networkMap.insert("permitJoiningDuration", network->permitJoiningDuration());
+ networkMap.insert("permitJoiningRemaining", network->permitJoiningRemaining());
+
+ switch (network->backendType()) {
+ case Zigbee::ZigbeeBackendTypeDeconz:
+ networkMap.insert("backend", ZigbeeAdapter::backendNames().value(ZigbeeAdapter::ZigbeeBackendTypeDeconz));
+ break;
+ case Zigbee::ZigbeeBackendTypeNxp:
+ networkMap.insert("backend", ZigbeeAdapter::backendNames().value(ZigbeeAdapter::ZigbeeBackendTypeNxp));
+ break;
+ }
+
+ switch (network->state()) {
+ case ZigbeeNetwork::StateOffline:
+ case ZigbeeNetwork::StateStopping:
+ networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateOffline));
+ break;
+ case ZigbeeNetwork::StateStarting:
+ networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateStarting));
+ break;
+ case ZigbeeNetwork::StateRunning:
+ networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateOnline));
+ break;
+ case ZigbeeNetwork::StateUpdating:
+ networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateUpdating));
+ break;
+ case ZigbeeNetwork::StateUninitialized:
+ networkMap.insert("networkState", enumValueName(ZigbeeManager::ZigbeeNetworkStateError));
+ break;
+ }
+
+ return networkMap;
+}
+
+QVariantMap ZigbeeHandler::packNode(ZigbeeNode *node)
+{
+ QVariantMap nodeMap;
+ nodeMap.insert("networkUuid", node->networkUuid());
+ nodeMap.insert("ieeeAddress", node->extendedAddress().toString());
+ nodeMap.insert("networkAddress", node->shortAddress());
+ switch (node->nodeDescriptor().nodeType) {
+ case ZigbeeDeviceProfile::NodeTypeCoordinator:
+ nodeMap.insert("type", enumValueName(ZigbeeManager::ZigbeeNodeTypeCoordinator));
+ break;
+ case ZigbeeDeviceProfile::NodeTypeRouter:
+ nodeMap.insert("type", enumValueName(ZigbeeManager::ZigbeeNodeTypeRouter));
+ break;
+ default:
+ nodeMap.insert("type", enumValueName(ZigbeeManager::ZigbeeNodeTypeEndDevice));
+ break;
+ }
+
+ switch (node->state()) {
+ case ZigbeeNode::StateUninitialized:
+ nodeMap.insert("state", enumValueName(ZigbeeManager::ZigbeeNodeStateUninitialized));
+ break;
+ case ZigbeeNode::StateInitializing:
+ nodeMap.insert("state", enumValueName(ZigbeeManager::ZigbeeNodeStateInitializing));
+ break;
+ case ZigbeeNode::StateInitialized:
+ nodeMap.insert("state", enumValueName(ZigbeeManager::ZigbeeNodeStateInitialized));
+ break;
+ }
+
+ nodeMap.insert("manufacturer", node->manufacturerName());
+ nodeMap.insert("model", node->modelName());
+ nodeMap.insert("version", node->version());
+ nodeMap.insert("receiverOnWhileIdle", node->macCapabilities().receiverOnWhenIdle);
+ nodeMap.insert("reachable", node->reachable());
+ nodeMap.insert("lqi", node->lqi());
+ nodeMap.insert("lastSeen", node->lastSeen().toMSecsSinceEpoch() / 1000);
+ return nodeMap;
+}
+
+void ZigbeeHandler::onNodeJoined(const QUuid &networkUuid, ZigbeeNode *node)
+{
+ QVariantMap params;
+ params.insert("networkUuid", networkUuid);
+ params.insert("zigbeeNode", packNode(node));
+ emit NodeAdded(params);
+}
+
+void ZigbeeHandler::onNodeAdded(const QUuid &networkUuid, ZigbeeNode *node)
+{
+ // Note: we emit the node changed signal here, since the node has been added internally after initialization.
+ onNodeChanged(networkUuid, node);
+}
+
+void ZigbeeHandler::onNodeChanged(const QUuid &networkUuid, ZigbeeNode *node)
+{
+ QVariantMap params;
+ params.insert("networkUuid", networkUuid);
+ params.insert("zigbeeNode", packNode(node));
+ emit NodeChanged(params);
+}
+
+void ZigbeeHandler::onNodeRemoved(const QUuid &networkUuid, ZigbeeNode *node)
+{
+ QVariantMap params;
+ params.insert("networkUuid", networkUuid);
+ params.insert("zigbeeNode", packNode(node));
+ emit NodeRemoved(params);
+}
+
+}