Expose Zigbee neighbor and routing tables to jsonrpc

This commit is contained in:
Michael Zanetti 2022-08-30 22:46:19 +02:00
parent 84163288b0
commit 1fc4c7f2d7
6 changed files with 136 additions and 3 deletions

View File

@ -47,6 +47,8 @@ ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) :
registerEnum<ZigbeeManager::ZigbeeNodeType>();
registerEnum<ZigbeeManager::ZigbeeNodeState>();
registerObject<ZigbeeAdapter, ZigbeeAdapters>();
registerEnum<ZigbeeNodeRelationship>();
registerEnum<ZigbeeNodeRouteStatus>();
// Network object describing a network instance
QVariantMap zigbeeNetworkDescription;
@ -66,6 +68,22 @@ ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) :
zigbeeNetworkDescription.insert("networkState", enumRef<ZigbeeManager::ZigbeeNetworkState>());
registerObject("ZigbeeNetwork", zigbeeNetworkDescription);
QVariantMap zigbeeNeighborTableRecordDescription;
zigbeeNeighborTableRecordDescription.insert("networkAddress", enumValueName(Uint));
zigbeeNeighborTableRecordDescription.insert("relationship", enumRef<ZigbeeNodeRelationship>());
zigbeeNeighborTableRecordDescription.insert("lqi", enumValueName(Uint));
zigbeeNeighborTableRecordDescription.insert("depth", enumValueName(Uint));
zigbeeNeighborTableRecordDescription.insert("permitJoining", enumValueName(Bool));
registerObject("ZigbeeNeighborTableRecord", zigbeeNeighborTableRecordDescription);
QVariantMap zigbeeRoutingTableRecordDescription;
zigbeeRoutingTableRecordDescription.insert("destinationAddress", enumValueName(Uint));
zigbeeRoutingTableRecordDescription.insert("nextHopAddress", enumValueName(Uint));
zigbeeRoutingTableRecordDescription.insert("status", enumRef<ZigbeeNodeRouteStatus>());
zigbeeRoutingTableRecordDescription.insert("manyToOne", enumValueName(Bool));
zigbeeRoutingTableRecordDescription.insert("memoryConstrained", enumValueName(Bool));
registerObject("ZigbeeRoutingTableRecord", zigbeeRoutingTableRecordDescription);
// Zigbee node description
QVariantMap zigbeeNodeDescription;
zigbeeNodeDescription.insert("networkUuid", enumValueName(Uuid));
@ -80,6 +98,8 @@ ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) :
zigbeeNodeDescription.insert("reachable", enumValueName(Bool));
zigbeeNodeDescription.insert("lqi", enumValueName(Uint));
zigbeeNodeDescription.insert("lastSeen", enumValueName(Uint));
zigbeeNodeDescription.insert("neighborTableRecords", QVariantList() << objectRef("ZigbeeNeighborTableRecord"));
zigbeeNodeDescription.insert("routingTableRecords", QVariantList() << objectRef("ZigbeeRoutingTableRecord"));
registerObject("ZigbeeNode", zigbeeNodeDescription);
QVariantMap params, returns;
@ -182,6 +202,12 @@ ZigbeeHandler::ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent) :
returns.insert("zigbeeError", enumRef<ZigbeeManager::ZigbeeError>());
registerMethod("SetPermitJoin", description, params, returns);
params.clear(); returns.clear();
description = "Refresh the neighbor table for all nodes. Note that calling this may cause a lot of traffic in the ZigBee network.";
params.insert("networkUuid", enumValueName(Uuid));
returns.insert("zigbeeError", enumRef<ZigbeeManager::ZigbeeError>());
registerMethod("RefreshNeighborTables", description, params, returns);
// GetNodes
params.clear(); returns.clear();
description = "Returns the list of ZigBee nodes from the network the given \'networkUuid\' in the system.";
@ -397,6 +423,12 @@ JsonReply *ZigbeeHandler::RemoveNode(const QVariantMap &params)
return createReply(returnMap);
}
JsonReply *ZigbeeHandler::RefreshNeighborTables(const QVariantMap &params)
{
ZigbeeManager::ZigbeeError error = m_zigbeeManager->refreshNeighborTables(params.value("networkUuid").toUuid());
return createReply({{"zigbeeError", enumValueName(error)}});
}
JsonReply *ZigbeeHandler::GetNetworks(const QVariantMap &params)
{
Q_UNUSED(params)
@ -497,6 +529,28 @@ QVariantMap ZigbeeHandler::packNode(ZigbeeNode *node)
nodeMap.insert("reachable", node->reachable());
nodeMap.insert("lqi", node->lqi());
nodeMap.insert("lastSeen", node->lastSeen().toMSecsSinceEpoch() / 1000);
QVariantList neighborTableRecords;
foreach (const ZigbeeDeviceProfile::NeighborTableListRecord &record, node->neighborTableRecords()) {
QVariantMap recordMap;
recordMap.insert("networkAddress", record.shortAddress);
recordMap.insert("depth", record.depth);
recordMap.insert("lqi", record.lqi);
recordMap.insert("relationship", enumValueName(static_cast<ZigbeeHandler::ZigbeeNodeRelationship>(record.relationship)));
recordMap.insert("permitJoining", record.permitJoining);
neighborTableRecords.append(recordMap);
}
nodeMap.insert("neighborTableRecords", neighborTableRecords);
QVariantList routingTableRecords;
foreach (const ZigbeeDeviceProfile::RoutingTableListRecord &record, node->routingTableRecords()) {
QVariantMap recordMap;
recordMap.insert("destinationAddress", record.destinationAddress);
recordMap.insert("nextHopAddress", record.nextHopAddress);
recordMap.insert("status", enumValueName(static_cast<ZigbeeHandler::ZigbeeNodeRouteStatus>(record.status)));
recordMap.insert("memoryConstrained", record.memoryConstrained);
recordMap.insert("manyToOne", record.manyToOne);
routingTableRecords.append(recordMap);
}
nodeMap.insert("routingTableRecords", routingTableRecords);
return nodeMap;
}

View File

@ -45,6 +45,24 @@ class ZigbeeHandler : public JsonHandler
{
Q_OBJECT
public:
enum ZigbeeNodeRelationship {
ZigbeeNodeRelationshipParent,
ZigbeeNodeRelationshipChild,
ZigbeeNodeRelationshipSibling,
ZigbeeNodeRelationshipNone,
ZigbeeNodeRelationshipPreviousChild
};
Q_ENUM(ZigbeeNodeRelationship)
enum ZigbeeNodeRouteStatus {
ZigbeeNodeRouteStatusActive,
ZigbeeNodeRouteStatusDiscoveryUnderway,
ZigbeeNodeRouteStatusDiscoveryFailed,
ZigbeeNodeRouteStatusInactive,
ZigbeeNodeRouteStatusValidationUnderway
};
Q_ENUM(ZigbeeNodeRouteStatus)
explicit ZigbeeHandler(ZigbeeManager *zigbeeManager, QObject *parent = nullptr);
QString name() const override;
@ -61,6 +79,8 @@ public:
Q_INVOKABLE JsonReply *GetNodes(const QVariantMap &params);
Q_INVOKABLE JsonReply *RemoveNode(const QVariantMap &params);
Q_INVOKABLE JsonReply *RefreshNeighborTables(const QVariantMap &params);
QVariantMap packNetwork(ZigbeeNetwork *network);
QVariantMap packNode(ZigbeeNode *node);

View File

@ -237,7 +237,7 @@ ZigbeeManager::ZigbeeError ZigbeeManager::setZigbeeNetworkPermitJoin(const QUuid
ZigbeeManager::ZigbeeError ZigbeeManager::factoryResetNetwork(const QUuid &networkUuid)
{
if (!m_zigbeeNetworks.keys().contains(networkUuid)) {
if (!m_zigbeeNetworks.contains(networkUuid)) {
qCWarning(dcZigbee()) << "Could not factory reset network with uuid" << networkUuid.toString() << "because there is no network with this uuid.";
return ZigbeeManager::ZigbeeErrorNetworkUuidNotFound;
}
@ -248,6 +248,16 @@ ZigbeeManager::ZigbeeError ZigbeeManager::factoryResetNetwork(const QUuid &netwo
return ZigbeeManager::ZigbeeErrorNoError;
}
ZigbeeManager::ZigbeeError ZigbeeManager::refreshNeighborTables(const QUuid &networkUuid)
{
if (!m_zigbeeNetworks.contains(networkUuid)) {
qCWarning(dcZigbee()) << "No network with uuid" << networkUuid.toString();
return ZigbeeManager::ZigbeeErrorNetworkUuidNotFound;
}
m_zigbeeNetworks.value(networkUuid)->refreshNeighborTable();
return ZigbeeManager::ZigbeeErrorNoError;
}
void ZigbeeManager::saveNetwork(ZigbeeNetwork *network)
{
NymeaSettings settings(NymeaSettings::SettingsRoleZigbee);
@ -690,6 +700,10 @@ void ZigbeeManager::setupNodeSignals(ZigbeeNode *node)
connect(node, &ZigbeeNode::reachableChanged, this, [=](){
emit nodeChanged(node->networkUuid(), node);
});
connect(node, &ZigbeeNode::neighborTableRecordsChanged, this, [=](){
emit nodeChanged(node->networkUuid(), node);
});
}

View File

@ -95,6 +95,7 @@ public:
ZigbeeError removeZigbeeNetwork(const QUuid &networkUuid);
ZigbeeError setZigbeeNetworkPermitJoin(const QUuid &networkUuid, quint16 shortAddress = Zigbee::BroadcastAddressAllRouters, uint duration = 120);
ZigbeeError factoryResetNetwork(const QUuid &networkUuid);
ZigbeeError refreshNeighborTables(const QUuid &networkUuid);
private:
ZigbeeAdapters m_adapters;

View File

@ -5,7 +5,7 @@ NYMEA_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"
# define protocol versions
JSON_PROTOCOL_VERSION_MAJOR=6
JSON_PROTOCOL_VERSION_MINOR=1
JSON_PROTOCOL_VERSION_MINOR=2
JSON_PROTOCOL_VERSION="$${JSON_PROTOCOL_VERSION_MAJOR}.$${JSON_PROTOCOL_VERSION_MINOR}"
LIBNYMEA_API_VERSION_MAJOR=7
LIBNYMEA_API_VERSION_MINOR=3

View File

@ -1,4 +1,4 @@
6.1
6.2
{
"enums": {
"BasicType": [
@ -509,6 +509,20 @@
"ZigbeeNetworkStateOnline",
"ZigbeeNetworkStateError"
],
"ZigbeeNodeRelationship": [
"ZigbeeNodeRelationshipParent",
"ZigbeeNodeRelationshipChild",
"ZigbeeNodeRelationshipSibling",
"ZigbeeNodeRelationshipNone",
"ZigbeeNodeRelationshipPreviousChild"
],
"ZigbeeNodeRouteStatus": [
"ZigbeeNodeRouteStatusActive",
"ZigbeeNodeRouteStatusDiscoveryUnderway",
"ZigbeeNodeRouteStatusDiscoveryFailed",
"ZigbeeNodeRouteStatusInactive",
"ZigbeeNodeRouteStatusValidationUnderway"
],
"ZigbeeNodeState": [
"ZigbeeNodeStateUninitialized",
"ZigbeeNodeStateInitializing",
@ -2198,6 +2212,16 @@
"zigbeeError": "$ref:ZigbeeError"
}
},
"Zigbee.RefreshNeighborTables": {
"description": "Refresh the neighbor table for all nodes. Note that calling this may cause a lot of traffic in the ZigBee network.",
"params": {
"networkUuid": "Uuid"
},
"permissionScope": "PermissionScopeAdmin",
"returns": {
"zigbeeError": "$ref:ZigbeeError"
}
},
"Zigbee.RemoveNetwork": {
"description": "Remove the ZigBee network with the given network uuid.",
"params": {
@ -3252,6 +3276,13 @@
"ZigbeeAdapters": [
"$ref:ZigbeeAdapter"
],
"ZigbeeNeighborTableRecord": {
"depth": "Uint",
"lqi": "Uint",
"networkAddress": "Uint",
"permitJoining": "Bool",
"relationship": "$ref:ZigbeeNodeRelationship"
},
"ZigbeeNetwork": {
"backend": "String",
"baudRate": "Uint",
@ -3274,13 +3305,26 @@
"lqi": "Uint",
"manufacturer": "String",
"model": "String",
"neighborTableRecords": [
"$ref:ZigbeeNeighborTableRecord"
],
"networkAddress": "Uint",
"networkUuid": "Uuid",
"reachable": "Bool",
"receiverOnWhileIdle": "Bool",
"routingTableRecords": [
"$ref:ZigbeeRoutingTableRecord"
],
"state": "$ref:ZigbeeNodeState",
"type": "$ref:ZigbeeNodeType",
"version": "String"
},
"ZigbeeRoutingTableRecord": {
"destinationAddress": "Uint",
"manyToOne": "Bool",
"memoryConstrained": "Bool",
"nextHopAddress": "Uint",
"status": "$ref:ZigbeeNodeRouteStatus"
}
}
}