From a0169b179d53b71d464c306c4f0ba24e00ce582b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 9 Dec 2020 13:47:46 +0100 Subject: [PATCH] Add basic structure for zigbee nodes on jsonrpc api --- libnymea-core/jsonrpc/zigbeehandler.cpp | 122 ++++++++++++++++++++++++ libnymea-core/jsonrpc/zigbeehandler.h | 9 +- libnymea-core/zigbee/zigbeemanager.h | 20 +++- 3 files changed, 149 insertions(+), 2 deletions(-) diff --git a/libnymea-core/jsonrpc/zigbeehandler.cpp b/libnymea-core/jsonrpc/zigbeehandler.cpp index 66774f7e..85485a8c 100644 --- a/libnymea-core/jsonrpc/zigbeehandler.cpp +++ b/libnymea-core/jsonrpc/zigbeehandler.cpp @@ -44,6 +44,8 @@ ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) : qRegisterMetaType(); registerEnum(); registerEnum(); + registerEnum(); + registerEnum(); registerObject(); // Network object describing a network instance @@ -64,6 +66,22 @@ ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) : 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; @@ -163,6 +181,23 @@ ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) : 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); connect(m_zigbeeManager, &ZigbeeManager::availableAdapterAdded, this, [this](const ZigbeeAdapter &adapter){ QVariantMap params; @@ -278,6 +313,53 @@ JsonReply *ZigbeeHandler::SetPermitJoin(const QVariantMap ¶ms) 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) @@ -338,4 +420,44 @@ QVariantMap ZigbeeHandler::packNetwork(ZigbeeNetwork *network) 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; +} + } diff --git a/libnymea-core/jsonrpc/zigbeehandler.h b/libnymea-core/jsonrpc/zigbeehandler.h index 0494c8af..a94209b1 100644 --- a/libnymea-core/jsonrpc/zigbeehandler.h +++ b/libnymea-core/jsonrpc/zigbeehandler.h @@ -51,13 +51,18 @@ public: Q_INVOKABLE JsonReply *GetAvailableBackends(const QVariantMap ¶ms); Q_INVOKABLE JsonReply *GetAdapters(const QVariantMap ¶ms); + Q_INVOKABLE JsonReply *GetNetworks(const QVariantMap ¶ms); Q_INVOKABLE JsonReply *AddNetwork(const QVariantMap ¶ms); Q_INVOKABLE JsonReply *RemoveNetwork(const QVariantMap ¶ms); Q_INVOKABLE JsonReply *FactoryResetNetwork(const QVariantMap ¶ms); Q_INVOKABLE JsonReply *SetPermitJoin(const QVariantMap ¶ms); + Q_INVOKABLE JsonReply *GetNodes(const QVariantMap ¶ms); + Q_INVOKABLE JsonReply *RemoveNode(const QVariantMap ¶ms); + QVariantMap packNetwork(ZigbeeNetwork *network); + QVariantMap packNode(ZigbeeNode *node); private: ZigbeeManager *m_zigbeeManager = nullptr; @@ -68,7 +73,9 @@ signals: void NetworkAdded(const QVariantMap ¶ms); void NetworkRemoved(const QVariantMap ¶ms); void NetworkChanged(const QVariantMap ¶ms); - + void NodeAdded(const QVariantMap ¶ms); + void NodeRemoved(const QVariantMap ¶ms); + void NodeChanged(const QVariantMap ¶ms); }; } diff --git a/libnymea-core/zigbee/zigbeemanager.h b/libnymea-core/zigbee/zigbeemanager.h index 3e829043..66686494 100644 --- a/libnymea-core/zigbee/zigbeemanager.h +++ b/libnymea-core/zigbee/zigbeemanager.h @@ -60,10 +60,28 @@ public: ZigbeeErrorNetworkUuidNotFound, ZigbeeErrorDurationOutOfRange, ZigbeeErrorNetworkOffline, - ZigbeeErrorUnknownBackend + ZigbeeErrorUnknownBackend, + ZigbeeErrorNodeNotFound, + ZigbeeErrorForbidden }; Q_ENUM(ZigbeeError) + // Node information + enum ZigbeeNodeType { + ZigbeeNodeTypeCoordinator, + ZigbeeNodeTypeRouter, + ZigbeeNodeTypeEndDevice + }; + Q_ENUM(ZigbeeNodeType) + + enum ZigbeeNodeState { + ZigbeeNodeStateUninitialized, + ZigbeeNodeStateInitializing, + ZigbeeNodeStateInitialized, + ZigbeeNodeStateHandled + }; + Q_ENUM(ZigbeeNodeState) + explicit ZigbeeManager(QObject *parent = nullptr); bool available() const;