public void CommandReceived(ZigBeeCommand command) { // ZCL command received from remote node. Perform discovery if it is not yet known. if (command is ZclCommand zclCommand) { if (_networkManager.GetNode(zclCommand.SourceAddress.Address) == null) { // TODO: Protect against group address? ZigBeeEndpointAddress address = (ZigBeeEndpointAddress)zclCommand.SourceAddress; StartNodeDiscovery(address.Address); } return; } // Node has been announced. if (command is DeviceAnnounce) { DeviceAnnounce announce = (DeviceAnnounce)command; _logger.Debug("{IeeeAddress}: Device announce received. NWK={NetworkAddress}", announce.IeeeAddr, announce.NwkAddrOfInterest); AddNode(announce.IeeeAddr, announce.NwkAddrOfInterest); } }
/// <summary> /// Performs the top level node discovery. This discovers node level attributes such as the endpoints and /// descriptors. /// /// <param name="nodeNetworkAddress">the network address to start a discovery on</param> /// </summary> private void StartNodeDiscovery(ushort nodeNetworkAddress) { // Check if we need to do a rediscovery on this node first... lock (_discoveryStartTime) { if (_discoveryStartTime.ContainsKey(nodeNetworkAddress) && DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - _discoveryStartTime[nodeNetworkAddress] < _requeryPeriod) { Log.Information("{NetworkAddress}: NWK Discovery node discovery already in progress", nodeNetworkAddress); return; } _discoveryStartTime[nodeNetworkAddress] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); } Log.Debug("{NetworkAddress}: NWK Discovery scheduling node discovery", nodeNetworkAddress); // TODO: Return Task ? Task.Run(async() => { try { Log.Debug("{NetworkAddress}: NWK Discovery starting node discovery", nodeNetworkAddress); int retries = 0; bool success = true; do { if (Thread.CurrentThread.ThreadState == ThreadState.WaitSleepJoin) { break; } if (!success) { // We failed with the last request. Wait a bit then retry. await Task.Delay(_retryPeriod); } // If we don't know the node yet, then try to find the IEEE address // before requesting the associated nodes. if (_networkManager.GetNode(nodeNetworkAddress) == null) { success = await GetIeeeAddress(nodeNetworkAddress); continue; } success = await GetAssociatedNodes(nodeNetworkAddress); if (success) { break; } } while (retries++ < _retryCount); Log.Debug("{NetworkAddress}: NWK Discovery ending node discovery", nodeNetworkAddress); } catch (Exception e) { Log.Error("{NetworkAddress}: NWK Discovery error during node discovery: {Error}", nodeNetworkAddress, e); } }); }
static void Main(string[] args) { _nodes = new List <ZigBeeNode>(); // Configure Serilog Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() .CreateLogger(); try { TransportConfig transportOptions = new TransportConfig(); Console.Write("Please enter your COM Port: "); var port = Console.ReadLine(); ZigBeeSerialPort zigbeePort = new ZigBeeSerialPort(port); IZigBeeTransportTransmit dongle = new ZigBeeDongleTiCc2531(zigbeePort); ZigBeeNetworkManager networkManager = new ZigBeeNetworkManager(dongle); ZigBeeDiscoveryExtension discoveryExtension = new ZigBeeDiscoveryExtension(); discoveryExtension.setUpdatePeriod(60); networkManager.AddExtension(discoveryExtension); // Initialise the network networkManager.Initialize(); networkManager.AddCommandListener(new ConsoleCommandListener()); networkManager.AddNetworkNodeListener(new ConsoleNetworkNodeListener()); Log.Logger.Information("PAN ID: {PanId}", networkManager.ZigBeePanId); Log.Logger.Information("Extended PAN ID: {ExtendenPanId}", networkManager.ZigBeeExtendedPanId); Log.Logger.Information("Channel: {Channel}", networkManager.ZigbeeChannel); byte channel = 11; byte pan = 1; ExtendedPanId extendedPan = new ExtendedPanId(); ZigBeeKey nwkKey = ZigBeeKey.CreateRandom(); ZigBeeKey linkKey = new ZigBeeKey(new byte[] { 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39 }); Console.WriteLine("*** Resetting network"); Console.WriteLine(" * Channel = " + channel); Console.WriteLine(" * PAN ID = " + pan); Console.WriteLine(" * Extended PAN ID = " + extendedPan); Console.WriteLine(" * Link Key = " + linkKey); networkManager.SetZigBeeChannel((ZigBeeChannel)channel); networkManager.SetZigBeePanId(pan); networkManager.SetZigBeeExtendedPanId(extendedPan); networkManager.SetZigBeeNetworkKey(nwkKey); networkManager.SetZigBeeLinkKey(linkKey); transportOptions.AddOption(TransportConfigOption.TRUST_CENTRE_LINK_KEY, new ZigBeeKey(new byte[] { 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39 })); dongle.UpdateTransportConfig(transportOptions); networkManager.AddSupportedCluster(0x06); ZigBeeStatus startupSucceded = networkManager.Startup(false); if (startupSucceded == ZigBeeStatus.SUCCESS) { Log.Logger.Information("ZigBee console starting up ... [OK]"); } else { Log.Logger.Information("ZigBee console starting up ... [FAIL]"); return; } ZigBeeNode coord = networkManager.GetNode(0); coord.PermitJoin(true); Console.WriteLine("Joining enabled..."); string cmd = Console.ReadLine(); while (cmd != "exit") { if (cmd == "toggle") { Console.WriteLine("Destination Address: "); string nwkAddr = Console.ReadLine(); if (ushort.TryParse(nwkAddr, out ushort addr)) { var node = networkManager.GetNode(addr); if (node != null) { ZigBeeEndpoint ep = new ZigBeeEndpoint(node, 0); node.AddEndpoint(ep); ZclOnOffCluster onOff = new ZclOnOffCluster(node.GetEndpoint(0)); onOff.ToggleCommand(); } } } cmd = Console.ReadLine(); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
static async Task Main(string[] args) { // Configure Serilog Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() .CreateLogger(); bool showHelp = false; ZigBeeDongle zigBeeDongle = ZigBeeDongle.TiCc2531; OptionSet options = new OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "zbd|zigbeeDongle=", "the zigbee dongle to use. 0 = TiCc2531 | 1 = DigiXBee", (ZigBeeDongle zbd) => zigBeeDongle = zbd } }; try { IList <string> extraArgs = options.Parse(args); foreach (string extraArg in extraArgs) { Console.WriteLine($"Error: Unknown option: {extraArg}"); showHelp = true; } Console.Write("Enter COM Port: "); string port = Console.ReadLine(); ZigBeeSerialPort zigbeePort = new ZigBeeSerialPort(port); IZigBeeTransportTransmit dongle; switch (zigBeeDongle) { case ZigBeeDongle.TiCc2531: { dongle = new ZigBeeDongleTiCc2531(zigbeePort); } break; case ZigBeeDongle.DigiXbee: { dongle = new ZigBeeDongleXBee(zigbeePort); } break; default: { dongle = new ZigBeeDongleTiCc2531(zigbeePort); } break; } ZigBeeNetworkManager networkManager = new ZigBeeNetworkManager(dongle); JsonNetworkSerializer deviceSerializer = new JsonNetworkSerializer("devices.json"); //networkManager.NetworkStateSerializer = deviceSerializer; ZigBeeDiscoveryExtension discoveryExtension = new ZigBeeDiscoveryExtension(); discoveryExtension.SetUpdatePeriod(60); networkManager.AddExtension(discoveryExtension); // Initialise the network networkManager.Initialize(); /* Network (de)serialization */ //networkManager.AddCommandListener(new ZigBeeNetworkDiscoverer(networkManager)); //networkManager.AddCommandListener(new ZigBeeNodeServiceDiscoverer(networkManager)); networkManager.AddCommandListener(new ZigBeeTransaction(networkManager)); networkManager.AddCommandListener(new ConsoleCommandListener()); networkManager.AddNetworkNodeListener(new ConsoleNetworkNodeListener()); networkManager.AddSupportedCluster(ZclOnOffCluster.CLUSTER_ID); networkManager.AddSupportedCluster(ZclColorControlCluster.CLUSTER_ID); networkManager.AddSupportedCluster(ZclTouchlinkCluster.CLUSTER_ID); networkManager.AddExtension(new ZigBeeBasicServerExtension()); if (zigBeeDongle == ZigBeeDongle.TiCc2531) { ((ZigBeeDongleTiCc2531)dongle).SetLedMode(1, false); // green led ((ZigBeeDongleTiCc2531)dongle).SetLedMode(2, false); // red led } ZigBeeStatus startupSucceded = networkManager.Startup(false); if (startupSucceded == ZigBeeStatus.SUCCESS) { Log.Logger.Information("ZigBee console starting up ... [OK]"); } else { Log.Logger.Information("ZigBee console starting up ... [FAIL]"); Log.Logger.Information("Press any key to exit..."); Console.ReadKey(); return; } ZigBeeNode coord = networkManager.GetNode(0); Console.WriteLine("Joining enabled..."); string cmd = string.Empty; while (cmd != "exit") { Console.WriteLine(networkManager.Nodes.Count + " node(s)" + Environment.NewLine); if (cmd == "join") { coord.PermitJoin(true); } else if (cmd == "unjoin") { coord.PermitJoin(false); } else if (!string.IsNullOrEmpty(cmd)) { var tmp = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.DarkGreen; Console.Write("Destination Address: "); Console.ForegroundColor = tmp; string nwkAddr = Console.ReadLine(); if (ushort.TryParse(nwkAddr, out ushort addr)) { var node = networkManager.GetNode(addr); if (node != null) { ZigBeeEndpointAddress endpointAddress = null; var endpoint = node.Endpoints.Values.FirstOrDefault(); if (endpoint != null) { endpointAddress = endpoint.GetEndpointAddress(); } if (endpointAddress == null) { Console.WriteLine("No endpoint found"); continue; } try { if (cmd == "toggle") { await networkManager.Send(endpointAddress, new ToggleCommand()); } else if (cmd == "level") { Console.WriteLine("Level between 0 and 255: "); string level = Console.ReadLine(); Console.WriteLine("time between 0 and 65535: "); string time = Console.ReadLine(); var command = new MoveToLevelWithOnOffCommand() { Level = byte.Parse(level), TransitionTime = ushort.Parse(time) }; await networkManager.Send(endpointAddress, command); } else if (cmd == "move") { await networkManager.Send(endpointAddress, new MoveCommand() { MoveMode = 1, Rate = 100 }); } else if (cmd == "on") { await networkManager.Send(endpointAddress, new OnCommand()); } else if (cmd == "off") { await networkManager.Send(endpointAddress, new OffCommand()); } else if (cmd == "effect") { await networkManager.Send(endpointAddress, new OffCommand()); bool state = false; for (int i = 0; i < 10; i++) { if (state) { await networkManager.Send(endpointAddress, new OffCommand()); } else { await networkManager.Send(endpointAddress, new OnCommand()); } state = !state; await Task.Delay(1000); } } else if (cmd == "stress") { await networkManager.Send(endpointAddress, new OffCommand()); bool state = false; for (int i = 0; i < 100; i++) { if (state) { await networkManager.Send(endpointAddress, new OffCommand()); } else { await networkManager.Send(endpointAddress, new OnCommand()); } state = !state; await Task.Delay(1); } } else if (cmd == "desc") { NodeDescriptorRequest nodeDescriptorRequest = new NodeDescriptorRequest() { Destination = endpointAddress, NwkAddrOfInterest = addr }; networkManager.SendTransaction(nodeDescriptorRequest); } else if (cmd == "color") { Console.WriteLine("Red between 0 and 255: "); string r = Console.ReadLine(); Console.WriteLine("Green between 0 and 255: "); string g = Console.ReadLine(); Console.WriteLine("Blue between 0 and 255: "); string b = Console.ReadLine(); if (int.TryParse(r, out int _r) && int.TryParse(g, out int _g) && int.TryParse(b, out int _b)) { CieColor xyY = ColorConverter.RgbToCie(_r, _g, _b); MoveToColorCommand command = new MoveToColorCommand() { ColorX = xyY.X, ColorY = xyY.Y, TransitionTime = 10 }; await networkManager.Send(endpointAddress, command); } } else if (cmd == "hue") { Console.WriteLine("Red between 0 and 255: "); string hue = Console.ReadLine(); if (byte.TryParse(hue, out byte _hue)) { MoveToHueCommand command = new MoveToHueCommand() { Hue = _hue, Direction = 0, TransitionTime = 10 }; await networkManager.Send(endpointAddress, command); } } else if (cmd == "read") { var result = await((ZclElectricalMeasurementCluster)endpoint.GetInputCluster(ZclElectricalMeasurementCluster.CLUSTER_ID)).Read(ZclElectricalMeasurementCluster.ATTR_MEASUREMENTTYPE); if (result.IsSuccess()) { ReadAttributesResponse response = result.GetResponse <ReadAttributesResponse>(); if (response.Records.Count == 0) { Console.WriteLine("No records returned"); continue; } ZclStatus statusCode = response.Records[0].Status; if (statusCode == ZclStatus.SUCCESS) { Console.WriteLine("Cluster " + response + ", Attribute " + response.Records[0].AttributeIdentifier + ", type " + response.Records[0].AttributeDataType + ", value: " + response.Records[0].AttributeValue); } else { Console.WriteLine("Attribute value read error: " + statusCode); } } } } catch (Exception ex) { Log.Logger.Error(ex, "{Error}"); } } else { Console.WriteLine($"Node {addr} not found"); } } } var currentForeGroundColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.DarkGreen; Console.Write("cmd> "); Console.ForegroundColor = currentForeGroundColor; cmd = Console.ReadLine(); } } catch (OptionException e) { Console.WriteLine(e.Message); showHelp = true; } catch (Exception ex) { Console.WriteLine(ex.ToString()); } if (showHelp) { Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return; } }
static void Main(string[] args) { // Configure Serilog Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() .CreateLogger(); try { Console.Write("Enter COM Port: "); string port = Console.ReadLine(); ZigBeeSerialPort zigbeePort = new ZigBeeSerialPort(port); IZigBeeTransportTransmit dongle = new ZigBeeDongleTiCc2531(zigbeePort); ZigBeeNetworkManager networkManager = new ZigBeeNetworkManager(dongle); JsonNetworkSerializer deviceSerializer = new JsonNetworkSerializer("devices.json"); networkManager.NetworkStateSerializer = deviceSerializer; ZigBeeDiscoveryExtension discoveryExtension = new ZigBeeDiscoveryExtension(); discoveryExtension.SetUpdatePeriod(60); networkManager.AddExtension(discoveryExtension); // Initialise the network networkManager.Initialize(); networkManager.AddCommandListener(new ZigBeeNetworkDiscoverer(networkManager)); //networkManager.AddCommandListener(new ZigBeeNodeServiceDiscoverer(networkManager)); networkManager.AddCommandListener(new ZigBeeTransaction(networkManager)); networkManager.AddCommandListener(new ConsoleCommandListener()); networkManager.AddNetworkNodeListener(new ConsoleNetworkNodeListener()); networkManager.AddSupportedCluster(0x06); networkManager.AddSupportedCluster(0x08); networkManager.AddSupportedCluster(0x0300); ((ZigBeeDongleTiCc2531)dongle).SetLedMode(1, false); // green led ((ZigBeeDongleTiCc2531)dongle).SetLedMode(2, false); // red led ZigBeeStatus startupSucceded = networkManager.Startup(false); if (startupSucceded == ZigBeeStatus.SUCCESS) { Log.Logger.Information("ZigBee console starting up ... [OK]"); } else { Log.Logger.Information("ZigBee console starting up ... [FAIL]"); return; } ZigBeeNode coord = networkManager.GetNode(0); Console.WriteLine("Joining enabled..."); string cmd = Console.ReadLine(); while (cmd != "exit") { Console.WriteLine(networkManager.Nodes.Count + " node(s)"); if (cmd == "join") { coord.PermitJoin(true); } else if (cmd == "unjoin") { coord.PermitJoin(false); } else if (!string.IsNullOrEmpty(cmd)) { Console.WriteLine("Destination Address: "); string nwkAddr = Console.ReadLine(); if (ushort.TryParse(nwkAddr, out ushort addr)) { var node = networkManager.GetNode(addr); if (node != null) { ZigBeeEndpointAddress endpointAddress = null; var endpoint = node.Endpoints.Values.FirstOrDefault(); if (endpoint != null) { endpointAddress = endpoint.GetEndpointAddress(); } if (endpointAddress == null) { Console.WriteLine("No endpoint found"); continue; } try { if (cmd == "toggle") { networkManager.Send(endpointAddress, new ToggleCommand()).GetAwaiter().GetResult(); } else if (cmd == "level") { Console.WriteLine("Level between 0 and 255: "); string level = Console.ReadLine(); Console.WriteLine("time between 0 and 65535: "); string time = Console.ReadLine(); var command = new MoveToLevelWithOnOffCommand() { Level = byte.Parse(level), TransitionTime = ushort.Parse(time) }; networkManager.Send(endpointAddress, command).GetAwaiter().GetResult(); } else if (cmd == "move") { networkManager.Send(endpointAddress, new MoveCommand() { MoveMode = 1, Rate = 100 }).GetAwaiter().GetResult(); } else if (cmd == "on") { networkManager.Send(endpointAddress, new OnCommand()).GetAwaiter().GetResult(); } else if (cmd == "off") { networkManager.Send(endpointAddress, new OffCommand()).GetAwaiter().GetResult(); } else if (cmd == "effect") { networkManager.Send(endpointAddress, new OffCommand()).GetAwaiter().GetResult(); bool state = false; for (int i = 0; i < 10; i++) { if (state) { networkManager.Send(endpointAddress, new OffCommand()).GetAwaiter().GetResult(); } else { networkManager.Send(endpointAddress, new OnCommand()).GetAwaiter().GetResult(); } state = !state; System.Threading.Thread.Sleep(1000); } } else if (cmd == "desc") { NodeDescriptorRequest nodeDescriptorRequest = new NodeDescriptorRequest() { DestinationAddress = endpointAddress, NwkAddrOfInterest = addr }; networkManager.SendTransaction(nodeDescriptorRequest); } else if (cmd == "color") { Console.WriteLine("Red between 0 and 255: "); string r = Console.ReadLine(); Console.WriteLine("Green between 0 and 255: "); string g = Console.ReadLine(); Console.WriteLine("Blue between 0 and 255: "); string b = Console.ReadLine(); if (int.TryParse(r, out int _r) && int.TryParse(g, out int _g) && int.TryParse(b, out int _b)) { CieColor xyY = ColorConverter.RgbToCie(_r, _g, _b); MoveToColorCommand command = new MoveToColorCommand() { ColorX = xyY.X, ColorY = xyY.Y, TransitionTime = 10 }; networkManager.Send(endpointAddress, command).GetAwaiter().GetResult(); } } else if (cmd == "hue") { Console.WriteLine("Red between 0 and 255: "); string hue = Console.ReadLine(); if (byte.TryParse(hue, out byte _hue)) { MoveToHueCommand command = new MoveToHueCommand() { Hue = _hue, Direction = 0, TransitionTime = 10 }; networkManager.Send(endpointAddress, command).GetAwaiter().GetResult(); } } else if (cmd == "read") { //var value = ((ZclOnOffCluster)endpoint.GetInputCluster(6)).GetAttribute(ZclOnOffCluster.ATTR_ONOFF); var result = ((ZclColorControlCluster)endpoint.GetInputCluster(ZclColorControlCluster.CLUSTER_ID)).Read(ZclColorControlCluster.ATTR_CURRENTY).Result; if (result.IsSuccess()) { ReadAttributesResponse response = result.GetResponse <ReadAttributesResponse>(); if (response.Records.Count == 0) { Console.WriteLine("No records returned"); continue; } ZclStatus statusCode = response.Records[0].Status; if (statusCode == ZclStatus.SUCCESS) { Console.WriteLine("Cluster " + string.Format("%04X", response.ClusterId) + ", Attribute " + response.Records[0].AttributeIdentifier + ", type " + response.Records[0].AttributeDataType + ", value: " + response.Records[0].AttributeValue); } else { Console.WriteLine("Attribute value read error: " + statusCode); } } } } catch (Exception ex) { Log.Logger.Error(ex, "{Error}"); } } else { Console.WriteLine($"Node {addr} not found"); } } } cmd = Console.ReadLine(); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
static async Task Main(string[] args) { // Configure Serilog Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() .CreateLogger(); bool showHelp = false; ZigBeeDongle zigBeeDongle = ZigBeeDongle.TiCc2531; string port = ""; int baudrate = 115200; string flow = ""; FlowControl flowControl = FlowControl.FLOWCONTROL_OUT_NONE; bool resetNetwork = false; string store = "json"; string database = "devices"; string connection = ""; string collection = ""; OptionSet options = new OptionSet { { "h|help", "show this message and exit", h => showHelp = h != null }, { "zbd|zigbeeDongle=", "the zigbee dongle to use. 0 = TiCc2531 | 1 = DigiXBee | 2 = Conbee | 3 = Ember ", (ZigBeeDongle zbd) => zigBeeDongle = zbd }, { "p|port=", "the COM port to use", p => port = p }, { "b|baud=", $"the port baud rate to use. default is {baudrate}", b => int.TryParse(b, out baudrate) }, { "f|flow=", $"the flow control (none | hardware | software)", f => flow = f }, { "r|reset", $"Reset the Zigbee network", r => resetNetwork = r != null }, { "s|store=", $"The store for network state", s => store = s }, { "c|connection=", $"The mongoDb connection string", c => connection = c }, { "d|database=", $"The mongoDb database or json directory", d => database = d }, { "mc|mongoCollection=", $"The mongoDb collection", mc => collection = mc }, }; try { IList <string> extraArgs = options.Parse(args); foreach (string extraArg in extraArgs) { Console.WriteLine($"Error: Unknown option: {extraArg}"); showHelp = true; } if (showHelp) { ShowHelp(options); return; } if (string.IsNullOrEmpty(port)) { Console.Write("Enter COM Port: "); port = Console.ReadLine(); } if (string.IsNullOrEmpty(flow)) { // Default the flow control based on the dongle switch (zigBeeDongle) { case ZigBeeDongle.Ember: flowControl = FlowControl.FLOWCONTROL_OUT_XONOFF; break; default: flowControl = FlowControl.FLOWCONTROL_OUT_NONE; break; } } else { switch (flow) { case "software": flowControl = FlowControl.FLOWCONTROL_OUT_XONOFF; break; case "hardware": flowControl = FlowControl.FLOWCONTROL_OUT_RTSCTS; break; case "none": flowControl = FlowControl.FLOWCONTROL_OUT_NONE; break; default: Console.WriteLine($"Unknown flow control option used: {flow}"); break; } } ZigBeeSerialPort zigbeePort = new ZigBeeSerialPort(port, baudrate, flowControl); IZigBeeTransportTransmit dongle; switch (zigBeeDongle) { case ZigBeeDongle.TiCc2531: { dongle = new ZigBeeDongleTiCc2531(zigbeePort); } break; case ZigBeeDongle.DigiXbee: { dongle = new ZigBeeDongleXBee(zigbeePort); } break; case ZigBeeDongle.ConBee: { dongle = new ZigbeeDongleConBee(zigbeePort); } break; case ZigBeeDongle.Ember: { dongle = new ZigBeeDongleEzsp(zigbeePort); ((ZigBeeDongleEzsp)dongle).SetPollRate(0); } break; default: { dongle = new ZigBeeDongleTiCc2531(zigbeePort); } break; } ZigBeeNetworkManager networkManager = new ZigBeeNetworkManager(dongle); if (store == "json") { JsonNetworkDataStore dataStore = new JsonNetworkDataStore(database); networkManager.SetNetworkDataStore(dataStore); } else if (store == "mongo") { MongoDbDatabaseSettings settings = new MongoDbDatabaseSettings() { ConnectionString = connection, DatabaseName = database, NodesCollectionName = collection }; MongoDbDataStore mongoStore = new MongoDbDataStore(settings); networkManager.SetNetworkDataStore(mongoStore); } ZigBeeDiscoveryExtension discoveryExtension = new ZigBeeDiscoveryExtension(); discoveryExtension.SetUpdatePeriod(60); networkManager.AddExtension(discoveryExtension); // Initialise the network networkManager.Initialize(); /* Network (de)serialization */ //networkManager.AddCommandListener(new ZigBeeNetworkDiscoverer(networkManager)); //networkManager.AddCommandListener(new ZigBeeNodeServiceDiscoverer(networkManager)); networkManager.AddCommandListener(new ZigBeeTransaction(networkManager)); networkManager.AddCommandListener(new ConsoleCommandListener()); networkManager.AddNetworkNodeListener(new ConsoleNetworkNodeListener()); networkManager.AddSupportedCluster(ZclOnOffCluster.CLUSTER_ID); networkManager.AddSupportedCluster(ZclColorControlCluster.CLUSTER_ID); networkManager.AddExtension(new ZigBeeBasicServerExtension()); if (zigBeeDongle == ZigBeeDongle.TiCc2531) { ((ZigBeeDongleTiCc2531)dongle).SetLedMode(1, false); // green led ((ZigBeeDongleTiCc2531)dongle).SetLedMode(2, false); // red led } Console.WriteLine($"PAN ID = {networkManager.ZigBeePanId}"); Console.WriteLine($"Extended PAN ID = {networkManager.ZigBeeExtendedPanId}"); Console.WriteLine($"Channel = {networkManager.ZigbeeChannel}"); Console.WriteLine($"Network Key = {networkManager.ZigBeeNetworkKey}"); Console.WriteLine($"Link Key = {networkManager.ZigBeeLinkKey}"); if (resetNetwork) { //TODO: make the network parameters configurable ushort panId = 1; ExtendedPanId extendedPanId = new ExtendedPanId(); ZigBeeChannel channel = ZigBeeChannel.CHANNEL_11; ZigBeeKey networkKey = ZigBeeKey.CreateRandom(); ZigBeeKey linkKey = new ZigBeeKey(new byte[] { 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39 }); Console.WriteLine($"*** Resetting network"); Console.WriteLine($" * PAN ID = {panId}"); Console.WriteLine($" * Extended PAN ID = {extendedPanId}"); Console.WriteLine($" * Channel = {channel}"); Console.WriteLine($" * Network Key = {networkKey}"); Console.WriteLine($" * Link Key = {linkKey}"); networkManager.SetZigBeeChannel(channel); networkManager.SetZigBeePanId(panId); networkManager.SetZigBeeExtendedPanId(extendedPanId); networkManager.SetZigBeeNetworkKey(networkKey); networkManager.SetZigBeeLinkKey(linkKey); } ZigBeeStatus startupSucceded = networkManager.Startup(resetNetwork); if (startupSucceded == ZigBeeStatus.SUCCESS) { Log.Logger.Information("ZigBee console starting up ... [OK]"); } else { Log.Logger.Information("ZigBee console starting up ... [FAIL]"); Log.Logger.Information("Press any key to exit..."); Console.ReadKey(); return; } ZigBeeNode coord = networkManager.GetNode(0); Console.WriteLine("Joining enabled..."); string cmd = string.Empty; while (cmd != "exit") { if (cmd == "join") { coord.PermitJoin(true); } else if (cmd == "unjoin") { coord.PermitJoin(false); } else if (cmd == "endpoints") { var tmp = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.DarkGreen; Console.Write("Destination Address: "); Console.ForegroundColor = tmp; string nwkAddr = Console.ReadLine(); if (ushort.TryParse(nwkAddr, out ushort addr)) { var node = networkManager.Nodes.FirstOrDefault(n => n.NetworkAddress == addr); if (node != null) { Console.WriteLine(new string('-', 20)); foreach (var endpoint in node.GetEndpoints()) { Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("Input Cluster:" + Environment.NewLine); Console.ForegroundColor = tmp; foreach (var inputClusterId in endpoint.GetInputClusterIds()) { var cluster = endpoint.GetInputCluster(inputClusterId); var clusterName = cluster.GetClusterName(); Console.WriteLine($"{clusterName}"); } } Console.WriteLine(); foreach (var endpoint in node.GetEndpoints()) { Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("Output Cluster:" + Environment.NewLine); Console.ForegroundColor = tmp; foreach (var outputClusterIds in endpoint.GetOutputClusterIds()) { var cluster = endpoint.GetOutputCluster(outputClusterIds); var clusterName = cluster.GetClusterName(); Console.WriteLine($"{clusterName}"); } } Console.WriteLine(new string('-', 20)); } } } else if (cmd == "add") { var tmp = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.DarkGreen; Console.Write("Destination Address: "); Console.ForegroundColor = tmp; string nwkAddr = Console.ReadLine(); if (ushort.TryParse(nwkAddr, out ushort addr)) { Console.Write("IeeeAddress: "); Console.ForegroundColor = tmp; string ieeeAddr = Console.ReadLine(); networkManager.UpdateNode(new ZigBeeNode() { NetworkAddress = addr, IeeeAddress = new IeeeAddress(ieeeAddr) }); } } else if (!string.IsNullOrEmpty(cmd)) { var tmp = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.DarkGreen; Console.Write("Destination Address: "); Console.ForegroundColor = tmp; string nwkAddr = Console.ReadLine(); if (ushort.TryParse(nwkAddr, out ushort addr)) { var node = networkManager.GetNode(addr); if (node != null) { ZigBeeEndpointAddress endpointAddress = null; var endpoint = node.GetEndpoints().FirstOrDefault(); if (endpoint != null) { endpointAddress = endpoint.GetEndpointAddress(); } if (endpointAddress == null) { Console.WriteLine("No endpoint found"); continue; } try { if (cmd == "leave") { await networkManager.Leave(node.NetworkAddress, node.IeeeAddress); } else if (cmd == "toggle") { await networkManager.Send(endpointAddress, new ToggleCommand()); } else if (cmd == "level") { Console.WriteLine("Level between 0 and 255: "); string level = Console.ReadLine(); Console.WriteLine("time between 0 and 65535: "); string time = Console.ReadLine(); var command = new MoveToLevelWithOnOffCommand() { Level = byte.Parse(level), TransitionTime = ushort.Parse(time) }; await networkManager.Send(endpointAddress, command); } else if (cmd == "move") { await networkManager.Send(endpointAddress, new MoveCommand() { MoveMode = 1, Rate = 100 }); } else if (cmd == "on") { await networkManager.Send(endpointAddress, new OnCommand()); } else if (cmd == "off") { await networkManager.Send(endpointAddress, new OffCommand()); } else if (cmd == "effect") { await networkManager.Send(endpointAddress, new OffCommand()); bool state = false; for (int i = 0; i < 10; i++) { if (state) { await networkManager.Send(endpointAddress, new OffCommand()); } else { await networkManager.Send(endpointAddress, new OnCommand()); } state = !state; await Task.Delay(1000); } } else if (cmd == "stress") { await networkManager.Send(endpointAddress, new OffCommand()); bool state = false; for (int i = 0; i < 100; i++) { if (state) { await networkManager.Send(endpointAddress, new OffCommand()); } else { await networkManager.Send(endpointAddress, new OnCommand()); } state = !state; await Task.Delay(1); } } else if (cmd == "desc") { NodeDescriptorRequest nodeDescriptorRequest = new NodeDescriptorRequest() { DestinationAddress = endpointAddress, NwkAddrOfInterest = addr }; networkManager.SendTransaction(nodeDescriptorRequest); } else if (cmd == "color") { Console.WriteLine("Red between 0 and 255: "); string r = Console.ReadLine(); Console.WriteLine("Green between 0 and 255: "); string g = Console.ReadLine(); Console.WriteLine("Blue between 0 and 255: "); string b = Console.ReadLine(); if (int.TryParse(r, out int _r) && int.TryParse(g, out int _g) && int.TryParse(b, out int _b)) { CieColor xyY = ColorConverter.RgbToCie(_r, _g, _b); MoveToColorCommand command = new MoveToColorCommand() { ColorX = xyY.X, ColorY = xyY.Y, TransitionTime = 10 }; await networkManager.Send(endpointAddress, command); } } else if (cmd == "hue") { Console.WriteLine("Red between 0 and 255: "); string hue = Console.ReadLine(); if (byte.TryParse(hue, out byte _hue)) { MoveToHueCommand command = new MoveToHueCommand() { Hue = _hue, Direction = 0, TransitionTime = 10 }; await networkManager.Send(endpointAddress, command); } } else if (cmd == "read") { var cluster = endpoint.GetInputCluster(ZclBasicCluster.CLUSTER_ID); if (cluster != null) { string manufacturerName = (string)(await cluster.ReadAttributeValue(ZclBasicCluster.ATTR_MANUFACTURERNAME)); string model = (string)(await cluster.ReadAttributeValue(ZclBasicCluster.ATTR_MODELIDENTIFIER)); Console.WriteLine($"Manufacturer Name = {manufacturerName}"); Console.WriteLine($"Model identifier = {model}"); } } else if (cmd == "discover attributes") { foreach (int clusterId in endpoint.GetInputClusterIds()) { ZclCluster cluster = endpoint.GetInputCluster(clusterId); if (!await cluster.DiscoverAttributes(true)) { Console.WriteLine("Error while discovering attributes for cluster {0}", cluster.GetClusterName()); } } } else if (cmd == "update binding table") { ZigBeeStatus statusCode = await node.UpdateBindingTable(); if (statusCode != ZigBeeStatus.SUCCESS) { Console.WriteLine("Error while reading binding table: " + statusCode); } } } catch (Exception ex) { Log.Logger.Error(ex, "Error while executing cmd {Command}", cmd); } } else { Console.WriteLine($"Node {addr} not found"); } } } await Task.Delay(100); Console.WriteLine(Environment.NewLine + networkManager.Nodes.Count + " node(s)" + Environment.NewLine); for (int i = 0; i < networkManager.Nodes.Count; i++) { var node = networkManager.Nodes[i]; Console.WriteLine($"{i}. {node.LogicalType}: {node.NetworkAddress}"); } Console.WriteLine(); var currentForeGroundColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.DarkGreen; Console.Write("cmd> "); Console.ForegroundColor = currentForeGroundColor; cmd = Console.ReadLine(); } networkManager.Shutdown(); } catch (OptionException e) { Console.WriteLine(e.Message); ShowHelp(options); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } Console.ReadLine(); }