/// <summary> /// Send an AT command to a node and wait for a response. /// </summary> /// <typeparam name="TResponseData">The expected response data type</typeparam> /// <param name="command">The command to send</param> /// <param name="address">The address of the node. If this is null the command will be sent to the local node.</param> /// <returns>The response data</returns> public async Task <TResponseData> ExecuteAtQueryAsync <TResponseData>(AtCommand command, NodeAddress address = null) where TResponseData : AtCommandResponseFrameData { AtCommandResponseFrameContent responseContent; if (address == null) { var atCommandFrame = new AtCommandFrameContent(command); AtCommandResponseFrame response = await ExecuteQueryAsync <AtCommandResponseFrame>(atCommandFrame, DefaultLocalQueryTimeout); responseContent = response.Content; } else { address.ShortAddress = address.LongAddress.IsBroadcast ? ShortAddress.Broadcast : ShortAddress.Disabled; var remoteCommand = new RemoteAtCommandFrameContent(address, command); RemoteAtCommandResponseFrame response = await ExecuteQueryAsync <RemoteAtCommandResponseFrame>(remoteCommand, DefaultRemoteQueryTimeout); responseContent = response.Content; } if (responseContent.Status != AtCommandStatus.Success) { throw new AtCommandException(responseContent.Status); } return(responseContent.Data as TResponseData); }
/// <summary> /// Start network discovery. The discovery of a node will result in a <see cref="NodeDiscovered" /> event. /// </summary> /// <param name="timeout">The amount of time to wait until discovery responses are ignored</param> /// <remarks>During network discovery nodes may be unresponsive</remarks> public async Task DiscoverNetworkAsync(TimeSpan timeout) { var atCommandFrame = new AtCommandFrameContent(new NetworkDiscoveryCommand()); await ExecuteMultiQueryAsync(atCommandFrame, new Action <AtCommandResponseFrame>( async frame => { var discoveryData = (NetworkDiscoveryResponseData)frame.Content.Data; if (NodeDiscovered != null && discoveryData?.LongAddress != null && !discoveryData.IsCoordinator) { var address = new NodeAddress(discoveryData.LongAddress, discoveryData.ShortAddress); // XBees have trouble recovering from discovery await Task.Delay(500); try { var node = await GetNodeAsync(address); var signalStrength = discoveryData.ReceivedSignalStrengthIndicator?.SignalStrength; NodeDiscovered?.Invoke(this, new NodeDiscoveredEventArgs(discoveryData.Name, signalStrength, node)); } catch (TimeoutException) { /* if we timeout getting the remote node info, no need to bubble up. * We just won't include the node in discovery */ } } }), timeout); }
/// <summary> /// Create a node. /// </summary> /// <param name="address">The address of the node or null for the controller node.</param> /// <param name="autodetectHardwareVersion">If true query node for hardware version. Otherwise assume controller version.</param> /// <returns>The specified node.</returns> public async Task <XBeeNode> GetNodeAsync(NodeAddress address = null, bool autodetectHardwareVersion = true) { await Initialize(); if (address == null) { return(Local); } HardwareVersion version; if (autodetectHardwareVersion) { if (!IsOpen) { throw new InvalidOperationException("Connection closed."); } version = await TaskExtensions.Retry(async() => await GetHardwareVersion(address), TimeSpan.FromSeconds(5), typeof(TimeoutException), typeof(AtCommandException)); } else { version = Local.HardwareVersion; } return(await Task.FromResult(CreateNode(version, address))); }
/// <summary> /// Send an AT command to a node and wait for a response. /// </summary> /// <typeparam name="TResponseData">The expected response data type</typeparam> /// <param name="command">The command to send</param> /// <param name="address">The address of the node. If this is null the command will be sent to the local node.</param> /// <param name="timeout"></param> /// <param name="queueLocal">Queue this command for deferred execution if issued to a local controller.</param> /// <returns>The response data</returns> internal async Task <TResponseData> ExecuteAtQueryAsync <TResponseData>(AtCommand command, NodeAddress address, TimeSpan timeout, bool queueLocal = false) where TResponseData : AtCommandResponseFrameData { AtCommandResponseFrameContent responseContent; if (address == null) { var atCommandFrame = queueLocal ? new AtQueuedCommandFrameContent(command) : new AtCommandFrameContent(command); var response = await ExecuteQueryAsync <AtCommandResponseFrame>(atCommandFrame, timeout); responseContent = response.Content; } else { address.ShortAddress = address.LongAddress.IsBroadcast ? ShortAddress.Broadcast : ShortAddress.Disabled; var remoteCommand = new RemoteAtCommandFrameContent(address, command); var response = await ExecuteQueryAsync <RemoteAtCommandResponseFrame>(remoteCommand, timeout); responseContent = response.Content; } if (responseContent.Status != AtCommandStatus.Success) { throw new AtCommandException(responseContent.Status); } return(responseContent.Data as TResponseData); }
internal SourcedSensorSampleReceivedEventArgs(NodeAddress address, OneWireSensor oneWireSensor, ushort sensorValueA, ushort sensorValueB, ushort sensorValueC, ushort sensorValueD, double temperatureCelcius) : base(oneWireSensor, sensorValueA, sensorValueB, sensorValueC, sensorValueD, temperatureCelcius) { Address = address; }
private XBeeNode CreateNode(HardwareVersion hardwareVersion, NodeAddress address = null) { switch (hardwareVersion) { case HardwareVersion.XBeeSeries1: return(new XBeeSeries1(this, HardwareVersion.XBeeSeries1, address)); case HardwareVersion.XBeeProSeries1: return(new XBeeSeries1(this, HardwareVersion.XBeeProSeries1, address)); case HardwareVersion.XBeeProS2: return(new XBeeSeries2(this, HardwareVersion.XBeeProS2, address)); case HardwareVersion.XBeeProS2B: return(new XBeeSeries2(this, HardwareVersion.XBeeProS2B, address)); case HardwareVersion.XBeePro900: return(new XBeePro900HP(this, HardwareVersion.XBeePro900, address)); case HardwareVersion.XBeePro900HP: return(new XBeePro900HP(this, HardwareVersion.XBeePro900HP, address)); default: throw new NotSupportedException($"{hardwareVersion} not supported."); } }
/// <summary> /// Send an AT command to a node and wait for a response. /// </summary> /// <typeparam name="TResponseData">The expected response data type</typeparam> /// <param name="command">The command to send</param> /// <param name="address">The address of the node. If this is null the command will be sent to the local node.</param> /// <param name="queueLocal">Queue this command for deferred execution if issued to a local controller.</param> /// <returns>The response data</returns> internal async Task <TResponseData> ExecuteAtQueryAsync <TResponseData>(AtCommand command, NodeAddress address = null, bool queueLocal = false) where TResponseData : AtCommandResponseFrameData { var timeout = address == null ? DefaultLocalQueryTimeout : DefaultRemoteQueryTimeout; return(await ExecuteAtQueryAsync <TResponseData>(command, address, timeout, queueLocal)); }
private async Task <HardwareVersion> GetHardwareVersion(NodeAddress address = null) { var version = await ExecuteAtQueryAsync <HardwareVersionResponseData>(new HardwareVersionCommand(), address, TimeSpan.FromSeconds(1)); return(version.HardwareVersion); }
/// <summary> /// Open a remote node. /// </summary> /// <param name="address">The address of the remote node</param> /// <returns>The remote node</returns> public async Task <XBeeNode> GetRemoteNodeAsync(NodeAddress address) { //TODO Get actual version for target device. For some reason this call keeps timing out during discovery. //TODO Consider doing deferred operation //HardwareVersionResponseData version = // await ExecuteAtQueryAsync<HardwareVersionResponseData>(new HardwareVersionCommand(), address); return(await Task.FromResult(CreateNode(HardwareVersion, address))); }
internal XBeeNode(XBeeController controller, HardwareVersion hardwareVersion, NodeAddress address = null) { Controller = controller; HardwareVersion = hardwareVersion; Address = address; Controller.SampleReceived += ControllerOnSampleReceived; Controller.DataReceived += ControllerOnDataReceived; }
internal XBeeNode(XBeeControllerBase controller, HardwareVersion hardwareVersion, ushort firmwareVersion, XBeeProtocol protocol, NodeAddress address = null) { Controller = controller; HardwareVersion = hardwareVersion; FirmwareVersion = firmwareVersion; Protocol = protocol; Address = address; Controller.DataReceived += ControllerOnDataReceived; Controller.SampleReceived += ControllerOnSampleReceived; Controller.SensorSampleReceived += ControllerOnSensorSampleReceived; }
/// <summary> /// Send an AT command to this node. /// </summary> /// <param name="command"></param> /// <param name="address"></param> /// <returns></returns> public async Task ExecuteAtCommand(AtCommand command, NodeAddress address = null) { if (address == null) { var atCommandFrame = new AtCommandFrameContent(command); await ExecuteAsync(atCommandFrame); } else { var remoteCommand = new RemoteAtCommandFrameContent(address, command); await ExecuteAsync(remoteCommand); } }
private void OnFrameReceived(object sender, FrameReceivedEventArgs e) { FrameContent content = e.FrameContent; if (content is ModemStatusFrame) { var modemStatusFrame = content as ModemStatusFrame; _modemResetTaskCompletionSource?.SetResult(modemStatusFrame.ModemStatus); } else if (content is CommandResponseFrameContent) { var commandResponse = content as CommandResponseFrameContent; byte frameId = commandResponse.FrameId; TaskCompletionSource <CommandResponseFrameContent> taskCompletionSource; if (ExecuteTaskCompletionSources.TryRemove(frameId, out taskCompletionSource)) { taskCompletionSource.SetResult(commandResponse); } else { Action <CommandResponseFrameContent> callback; if (ExecuteCallbacks.TryGetValue(frameId, out callback)) { callback(commandResponse); } } } else if (content is IRxIndicatorDataFrame) { var dataFrame = content as IRxIndicatorDataFrame; NodeAddress address = dataFrame.GetAddress(); _receivedDataSource.Push(new SourcedData(address, dataFrame.Data)); DataReceived?.Invoke(this, new SourcedDataReceivedEventArgs(address, dataFrame.Data)); } else if (content is IRxIndicatorSampleFrame) { var sampleFrame = content as IRxIndicatorSampleFrame; NodeAddress address = sampleFrame.GetAddress(); Sample sample = sampleFrame.GetSample(); _sampleSource.Push(new SourcedSample(address, sample)); SampleReceived?.Invoke(this, new SourcedSampleReceivedEventArgs(address, sample.DigitalSampleState, sample.AnalogSamples)); } }
public NodeIdentificationEventArgs(NodeAddress senderAddress, NodeAddress remoteAddress, ShortAddress parentAddress, string name, DeviceType deviceType, NodeIdentificationReason nodeIdentificationReason, ReceiveOptionsExt receiveOptions, ushort digiProfileId, ushort manufacturerId) { SenderAddress = senderAddress; RemoteAddress = remoteAddress; ParentAddress = parentAddress; Name = name; DeviceType = deviceType; NodeIdentificationReason = nodeIdentificationReason; ReceiveOptions = receiveOptions; DigiProfileId = digiProfileId; ManufacturerId = manufacturerId; }
/// <summary> /// Send an AT command to this node. /// </summary> /// <param name="command"></param> /// <param name="address"></param> /// <param name="queueLocal"></param> /// <returns></returns> internal async Task ExecuteAtCommand(AtCommand command, NodeAddress address = null, bool queueLocal = false) { if (address == null) { var atCommandFrame = queueLocal ? new AtQueuedCommandFrameContent(command) : new AtCommandFrameContent(command); await ExecuteAsync(atCommandFrame); } else { var remoteCommand = new RemoteAtCommandFrameContent(address, command); await ExecuteAsync(remoteCommand); } }
/// <summary> /// Start network discovery. The discovery of a node will result in a <see cref="NodeDiscovered"/> event. /// </summary> /// <param name="timeout">The amount of time to wait until discovery responses are ignored</param> /// <remarks>During network discovery nodes may be unresponsive</remarks> public async Task DiscoverNetwork(TimeSpan timeout) { var atCommandFrame = new AtCommandFrameContent(new NetworkDiscoveryCommand()); await ExecuteMultiQueryAsync(atCommandFrame, new Action <AtCommandResponseFrame>( async frame => { var discoveryData = (NetworkDiscoveryResponseData)frame.Content.Data; if (NodeDiscovered != null && discoveryData != null && !discoveryData.IsCoordinator) { var address = new NodeAddress(discoveryData.LongAddress, discoveryData.ShortAddress); /* For some reason it doesn't like answering us during ND */ // TODO find better approach for this XBeeNode node = null; for (int i = 0; i < 5; i++) { try { node = await GetRemoteNodeAsync(address); break; } catch (TimeoutException) { } catch (AtCommandException) { } } if (node == null) { throw new TimeoutException(); } var signalStrength = discoveryData.ReceivedSignalStrengthIndicator?.SignalStrength; NodeDiscovered(this, new NodeDiscoveredEventArgs(discoveryData.Name, signalStrength, node)); } }), timeout); }
private XBeeNode CreateNode(HardwareVersion hardwareVersion, NodeAddress address = null) { switch (hardwareVersion) { case Frames.AtCommands.HardwareVersion.XBeeSeries1: return(new XBeeSeries1(this, Frames.AtCommands.HardwareVersion.XBeeSeries1, address)); case Frames.AtCommands.HardwareVersion.XBeeProSeries1: return(new XBeeSeries1(this, Frames.AtCommands.HardwareVersion.XBeeProSeries1, address)); case Frames.AtCommands.HardwareVersion.ZNetZigBeeS2: return(new XBeeSeries2(this, Frames.AtCommands.HardwareVersion.ZNetZigBeeS2, address)); case Frames.AtCommands.HardwareVersion.XBeeProS2: return(new XBeeSeries2(this, Frames.AtCommands.HardwareVersion.XBeeProS2, address)); case Frames.AtCommands.HardwareVersion.XBeeProS2B: return(new XBeeSeries2(this, Frames.AtCommands.HardwareVersion.XBeeProS2B, address)); case Frames.AtCommands.HardwareVersion.XBee24C: return(new XBeeSeries2(this, Frames.AtCommands.HardwareVersion.XBee24C, address)); case Frames.AtCommands.HardwareVersion.XBeePro900: return(new XBeePro900HP(this, Frames.AtCommands.HardwareVersion.XBeePro900, address)); case Frames.AtCommands.HardwareVersion.XBeePro900HP: return(new XBeePro900HP(this, Frames.AtCommands.HardwareVersion.XBeePro900HP, address)); case Frames.AtCommands.HardwareVersion.XBeeProSX: return(new XBeePro900HP(this, Frames.AtCommands.HardwareVersion.XBeeProSX, address)); case Frames.AtCommands.HardwareVersion.XBeeCellular: return(new XBeeCellular(this, Frames.AtCommands.HardwareVersion.XBeeCellular, address)); default: throw new NotSupportedException($"{hardwareVersion} not supported."); } }
public bool Equals(NodeAddress other) { if (ReferenceEquals(null, other)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } if (LongAddress.IsDisabled || other.LongAddress.IsDisabled) { return(Equals(ShortAddress, other.ShortAddress)); } if (ShortAddress.IsDisabled || other.ShortAddress.IsDisabled) { return(Equals(LongAddress, other.LongAddress)); } return(Equals(LongAddress, other.LongAddress) && Equals(ShortAddress, other.ShortAddress)); }
public static XBeeNode CreateDevice(HardwareVersion hardwareVersion, ushort firmwareVersion, NodeAddress address, XBeeControllerBase controller) { var series = GetSeries(hardwareVersion); var protocol = GetProtocol(hardwareVersion, firmwareVersion); switch (series) { case DeviceSeries.Series1: return(new XBeeSeries1(controller, hardwareVersion, firmwareVersion, protocol, address)); case DeviceSeries.Series2: return(new XBeeSeries2(controller, hardwareVersion, firmwareVersion, protocol, address)); case DeviceSeries.Pro900: return(new XBeePro900HP(controller, hardwareVersion, firmwareVersion, protocol, address)); case DeviceSeries.Cellular: return(new XBeeCellular(controller, hardwareVersion, firmwareVersion, protocol, address)); default: throw new InvalidOperationException(); } }
internal SourcedSample(NodeAddress address, Sample sample) : base(address) { Sample = sample; }
public SourcedDataReceivedEventArgs(NodeAddress sourceAddress, byte[] data) : base(sourceAddress, data) { }
protected XBeeNodeBase(XBeeController controller, HardwareVersion hardwareVersion, NodeAddress address = null) { Controller = controller; HardwareVersion = hardwareVersion; Address = address; }
public SourcedSampleReceivedEventArgs(NodeAddress address, DigitalSampleState digitalSampleState, IEnumerable <AnalogSample> analogSamples) : base(digitalSampleState, analogSamples) { Address = address; }
internal SourcedSampleReceivedEventArgs(NodeAddress address, DigitalSampleChannels digitalChannels, DigitalSampleState digitalSampleState, AnalogSampleChannels analogChannels, IEnumerable <AnalogSample> analogSamples) : base(digitalChannels, digitalSampleState, analogChannels, analogSamples) { Address = address; }
internal SourcedSensorSample(NodeAddress address, SensorSample sensorSample) : base(address) { SensorSample = sensorSample; }
public async Task <XBeeNode> GetRemoteNodeAsync(NodeAddress address) { return(await GetNodeAsync(address)); }
/// <summary> /// Create a node. /// </summary> /// <param name="address">The address of the node or null for the controller node.</param> /// <param name="version">The hardware version to use for the specified node.</param> /// <returns>The specified node.</returns> public async Task <XBeeNode> GetNodeAsync(NodeAddress address, HardwareVersion version) { return(await Task.FromResult(CreateNode(version, address))); }
/// <summary> /// Execute an AT command on a node without waiting for a response. /// </summary> /// <param name="command">The AT command to execute</param> /// <param name="address">The address of the node. If this is null the command will be execute on the local node.</param> /// <returns></returns> public async Task ExecuteAtCommandAsync(AtCommand command, NodeAddress address = null) { await ExecuteAtQueryAsync <AtCommandResponseFrameData>(command, address); }
/// <summary> /// Execute an AT command on a node without waiting for a response. /// </summary> /// <param name="command">The AT command to execute</param> /// <param name="address">The address of the node. If this is null the command will be execute on the local node.</param> /// <param name="queueLocal">Queue this command for deferred execution if issued to a local controller.</param> /// <returns></returns> internal async Task ExecuteAtCommandAsync(AtCommand command, NodeAddress address = null, bool queueLocal = false) { await ExecuteAtQueryAsync <AtCommandResponseFrameData>(command, address, queueLocal); }
protected Sourced(NodeAddress address) { Address = address; }