From 53a42661ada0115243dd99d922c8279f3c439ddf Mon Sep 17 00:00:00 2001 From: Gene Date: Tue, 14 Feb 2023 22:39:54 +0100 Subject: [PATCH] v1.2.14 - ZigBee: fix node add/discovery --- MIG.HomeAutomation/ZigBee.cs | 69 ++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/MIG.HomeAutomation/ZigBee.cs b/MIG.HomeAutomation/ZigBee.cs index 7e01666..c3ebeb1 100644 --- a/MIG.HomeAutomation/ZigBee.cs +++ b/MIG.HomeAutomation/ZigBee.cs @@ -107,10 +107,10 @@ const string EventPath_VersionReport private IZigBeeTransportTransmit transportTransmit; private string lastAddedNode; + private string lastRemovedNode; private bool initialized; private const string ZigBeeModulesDb = "zigbee_modules.xml"; - #endregion #region MIG Interface members @@ -187,11 +187,23 @@ public object InterfaceControl(MigInterfaceCommand request) var nodeToRemove = networkManager.GetNode(new IeeeAddress(nodeId)); if (nodeToRemove != null && nodeToRemove.NetworkAddress > 0) { - networkManager - .Leave(nodeToRemove.NetworkAddress, nodeToRemove.IeeeAddress, true) - .Wait(); - RemoveNode(nodeToRemove); - returnValue = new ResponseStatus(Status.Ok, $"Removed node {nodeToRemove.IeeeAddress}."); + lastRemovedNode = ""; + new Thread(()=> + { + networkManager + .Leave(nodeToRemove.NetworkAddress, nodeToRemove.IeeeAddress, true) + .Wait(); + if (String.IsNullOrEmpty(lastRemovedNode)) RemoveNode(nodeToRemove); + }).Start(); + for (int i = 0; i < NumberOfRemoveAttempts; i++) + { + if (!String.IsNullOrEmpty(lastRemovedNode)) + { + break; + } + Thread.Sleep(DelayBetweenAttempts); + } + returnValue = new ResponseStatus(Status.Ok, $"Removed node {lastRemovedNode}."); } else { @@ -301,7 +313,7 @@ public object InterfaceControl(MigInterfaceCommand request) raiseEvent = true; break; case Commands.NodeInfo_Get: - ReadClusterData(node); + QueryNodeData(node); break; default: returnValue = new ResponseStatus(Status.Error, "Command not understood."); @@ -318,8 +330,10 @@ public object InterfaceControl(MigInterfaceCommand request) public bool Connect() { initialized = false; - DeserializeModules(ZigBeeModulesDb, modules); Disconnect(); + // load cached modules + DeserializeModules(ZigBeeModulesDb, modules); + // initialize controller string portName = this.GetOption("Port").Value; if (String.IsNullOrEmpty(portName)) { @@ -432,27 +446,38 @@ public void AddNode(ZigBeeNode node) if (node.LogicalType == NodeDescriptor.LogicalType.ROUTER || node.LogicalType == NodeDescriptor.LogicalType.END_DEVICE) { string address = node.IeeeAddress.ToString(); - modules.RemoveAll((m) => m.Address == address); - modules.Add(new InterfaceModule() + var module = modules.Find((m) => m.Address == address); + if (module == null) { - Domain = "HomeAutomation.ZigBee", - Address = address, - CustomData = new ZigBeeNodeData() + module = new InterfaceModule() { - // TODO: get type from device node - Type = ModuleTypes.Generic - } - }); + Domain = "HomeAutomation.ZigBee", + Address = address, + CustomData = new ZigBeeNodeData() + { + // TODO: get type from device node + Type = ModuleTypes.Generic + } + }; + modules.Add(module); + } if (initialized) { ControllerEvent("Controller.Status", "Added node " + node.IeeeAddress); // get manufacturer name and model identifier - Task.Run(() => + new Thread(() => { - ReadClusterData(node).Wait(); + try + { + QueryNodeData(node).Wait(); + } + catch (Exception e) + { + //Console.WriteLine(e); + } OnInterfaceModulesChanged(this.GetDomain()); lastAddedNode = node.IeeeAddress.ToString(); - }); + }).Start(); } } } @@ -464,6 +489,7 @@ public void RemoveNode(ZigBeeNode node) { ControllerEvent("Controller.Status", "Removed node " + node.IeeeAddress); OnInterfaceModulesChanged(this.GetDomain()); + lastRemovedNode = node.IeeeAddress.ToString(); } } @@ -570,7 +596,6 @@ private void SoftReset() if (File.Exists(fileName)) { File.Delete(fileName); } - modules.Clear(); Connect(); } @@ -596,7 +621,7 @@ private async Task SetColorHsb(ZigBeeEndpointAddress endpointAddress, double h, await networkManager.Send(endpointAddress, cmd); } - private async Task ReadClusterData(ZigBeeNode node) + private async Task QueryNodeData(ZigBeeNode node) { var endpoint = node.GetEndpoints().FirstOrDefault(); // Get manufacturer / model