From 2b8107ddaffd08ed4c388b652ff92400e0cecebd Mon Sep 17 00:00:00 2001 From: Patrick Ritchie Date: Tue, 28 Nov 2023 01:16:45 -0500 Subject: [PATCH] Updated ShdrAdapter to inherit from MTConnectAdapter base class --- .../Adapters/ShdrAdapter - Copy.cs | 2559 ----------------- .../Adapters/ShdrAdapter.cs | 63 + .../Adapters/ShdrIntervalAdapter.cs | 68 +- .../Adapters/ShdrIntervalQueueAdapter.cs | 70 +- .../Adapters/ShdrQueueAdapter.cs | 299 +- .../MTConnect.NET-SHDR.csproj | 11 - 6 files changed, 75 insertions(+), 2995 deletions(-) delete mode 100644 libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter - Copy.cs diff --git a/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter - Copy.cs b/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter - Copy.cs deleted file mode 100644 index 9659d9f1..00000000 --- a/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter - Copy.cs +++ /dev/null @@ -1,2559 +0,0 @@ -// Copyright (c) 2023 TrakHound Inc., All Rights Reserved. -// TrakHound Inc. licenses this file to you under the MIT license. - -using MTConnect.Configurations; -using MTConnect.Input; -using MTConnect.Shdr; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace MTConnect.Adapters -{ - /// - /// An Adapter class for communicating with an MTConnect Agent using the SHDR protocol. - /// Supports multiple concurrent Agent connections. - /// Uses a queue to collect changes to Observations and sends the most recent changes at the specified interval. - /// - public class ShdrAdapter - { - private readonly object _lock = new object(); - private readonly AgentClientConnectionListener _connectionListener; - private readonly Dictionary _clients = new Dictionary(); - - private readonly Dictionary _currentDataItems = new Dictionary(); - private readonly Dictionary _lastDataItems = new Dictionary(); - - private readonly Dictionary _currentMessages = new Dictionary(); - private readonly Dictionary _lastMessages = new Dictionary(); - - private readonly Dictionary _currentConditions = new Dictionary(); - private readonly Dictionary _lastConditions = new Dictionary(); - - private readonly Dictionary _currentTimeSeries = new Dictionary(); - private readonly Dictionary _lastTimeSeries = new Dictionary(); - - private readonly Dictionary _currentDataSets = new Dictionary(); - private readonly Dictionary _lastDataSets = new Dictionary(); - - private readonly Dictionary _currentTables = new Dictionary(); - private readonly Dictionary _lastTables = new Dictionary(); - - private readonly Dictionary _currentAssets = new Dictionary(); - private readonly Dictionary _lastAssets = new Dictionary(); - - private readonly Dictionary _devices = new Dictionary(); - - - private CancellationTokenSource _stop; - protected CancellationTokenSource StopToken => _stop; - - - /// - /// Get a unique identifier for the Adapter - /// - public string Id { get; } - - /// - /// The Name or UUID of the Device to create a connection for - /// - public string DeviceKey { get; } - - /// - /// The TCP Port used for communication - /// - public int Port { get; } - - /// - /// The heartbeat used to maintain a connection between the Adapter and the Agent - /// - public int Heartbeat { get; } - - /// - /// The amount of time (in milliseconds) to allow for a connection attempt to the Agent - /// - public int Timeout { get; set; } - - /// - /// Use multiline Assets - /// - public bool MultilineAssets { get; set; } - - /// - /// Use multiline Devices - /// - public bool MultilineDevices { get; set; } - - /// - /// Determines whether to filter out duplicate data - /// - public bool FilterDuplicates { get; set; } - - /// - /// Determines whether to output Timestamps for each SHDR line - /// - public bool OutputTimestamps { get; set; } - - - /// - /// Raised when a new Agent connection is established. Includes the AgentClient ID as an argument. - /// - public event EventHandler AgentConnected; - - /// - /// Raised when an existing Agent connection is disconnected. Includes the AgentClient ID as an argument. - /// - public event EventHandler AgentDisconnected; - - /// - /// Raised when an error occurs during an existing Agent connection. Includes the AgentClient ID as an argument. - /// - public event EventHandler AgentConnectionError; - - - /// - /// Raised when a Ping request message is received from an Agent. Includes the AgentClient ID as an argument. - /// - public event EventHandler PingReceived; - - /// - /// Raised when a Pong response message is sent to an Agent. Includes the AgentClient ID as an argument. - /// - public event EventHandler PongSent; - - /// - /// Raised when a new line is sent to the Agent. Includes the AgentClient ID and the Line sent as an argument. - /// - public event EventHandler LineSent; - - /// - /// Raised when new data is sent to the Agent. Includes the AgentClient ID and the Line sent as an argument. - /// - public event EventHandler DataSent; - - /// - /// Raised when an error occurs when sending a new line to the Agent. Includes the AgentClient ID and the Error message as an argument. - /// - public event EventHandler SendError; - - - public ShdrAdapter(int port = 7878, int heartbeat = 10000) - { - FilterDuplicates = true; - OutputTimestamps = true; - Port = port; - Heartbeat = heartbeat; - Timeout = 5000; - - _connectionListener = new AgentClientConnectionListener(Port, heartbeat); - _connectionListener.ClientConnected += ClientConnected; - _connectionListener.ClientDisconnected += ClientDisconnected; - _connectionListener.ClientPingReceived += ClientPingReceived; - _connectionListener.ClientPongSent += ClientPongSent; - } - - public ShdrAdapter(string deviceKey, int port = 7878, int heartbeat = 10000) - { - FilterDuplicates = true; - OutputTimestamps = true; - DeviceKey = deviceKey; - Port = port; - Heartbeat = heartbeat; - Timeout = 5000; - - _connectionListener = new AgentClientConnectionListener(Port, heartbeat); - _connectionListener.ClientConnected += ClientConnected; - _connectionListener.ClientDisconnected += ClientDisconnected; - _connectionListener.ClientPingReceived += ClientPingReceived; - _connectionListener.ClientPongSent += ClientPongSent; - } - - public ShdrAdapter(ShdrAdapterClientConfiguration configuration) - { - FilterDuplicates = true; - OutputTimestamps = true; - - if (configuration != null) - { - DeviceKey = configuration.DeviceKey; - Port = configuration.Port; - Heartbeat = configuration.Heartbeat; - Timeout = 5000; - - _connectionListener = new AgentClientConnectionListener(Port, Heartbeat); - _connectionListener.ClientConnected += ClientConnected; - _connectionListener.ClientDisconnected += ClientDisconnected; - _connectionListener.ClientPingReceived += ClientPingReceived; - _connectionListener.ClientPongSent += ClientPongSent; - } - } - - - /// - /// Starts the Adapter to begins listening for Agent connections as well as starts the Queue for collecting and sending data to the Agent(s). - /// - public void Start() - { - _stop = new CancellationTokenSource(); - - // Start Agent Connection Listener - _connectionListener.Start(_stop.Token); - - // Call Overridable Method - OnStart(); - } - - /// - /// Stops the adapter which also stops listening for Agent connections, disconnects any existing Agent connections, and stops the Queue for sending data to the Agent(s). - /// - public void Stop() - { - if (_stop != null) _stop.Cancel(); - _connectionListener.Stop(); - - // Call Overridable Method - OnStop(); - } - - - protected virtual void OnStart() { } - - protected virtual void OnStop() { } - - - /// - /// Set all items to Unavailable - /// - public void SetUnavailable(long timestamp = 0) - { - SetDataItemsUnavailable(timestamp); - SetMessagesUnavailable(timestamp); - SetConditionsUnavailable(timestamp); - SetTimeSeriesUnavailable(timestamp); - SetDataSetsUnavailable(timestamp); - SetTablesUnavailable(timestamp); - } - - - #region "Event Handlers" - - private void ClientConnected(string clientId, TcpClient client) - { - AddAgentClient(clientId, client); - AgentConnected?.Invoke(this, clientId); - - SendLast(UnixDateTime.Now); - } - - private void ClientDisconnected(string clientId) - { - RemoveAgentClient(clientId); - AgentDisconnected?.Invoke(this, clientId); - } - - private void ClientPingReceived(string clientId) - { - PingReceived?.Invoke(this, clientId); - } - - private void ClientPongSent(string clientId) - { - PongSent?.Invoke(this, clientId); - } - - #endregion - - #region "Clients" - - private void AddAgentClient(string clientId, TcpClient tcpClient) - { - if (!string.IsNullOrEmpty(clientId) && tcpClient != null) - { - lock (_lock) - { - _clients.Remove(clientId); - _clients.Add(clientId, new AgentClient(clientId, tcpClient)); - } - } - } - - private AgentClient GetAgentClient(string clientId) - { - if (!string.IsNullOrEmpty(clientId)) - { - lock (_lock) - { - if (_clients.TryGetValue(clientId, out AgentClient agentClient)) - { - return agentClient; - } - } - } - - return null; - } - - private IEnumerable GetAgentClients() - { - lock (_lock) - { - return _clients.Values; - } - } - - private void RemoveAgentClient(string clientId) - { - if (!string.IsNullOrEmpty(clientId)) - { - lock (_lock) - { - _clients.Remove(clientId); - } - } - } - - #endregion - - #region "Send" - - /// - /// Sends all Items that have changed since last sent to the Agent - /// - public void SendChanged() - { - WriteChangedDataItems(); - WriteChangedMessages(); - WriteChangedConditions(); - WriteChangedTimeSeries(); - WriteChangedDataSets(); - WriteChangedTables(); - WriteChangedAssets(); - - // Call Overridable Method - OnChangedSent(); - } - - /// - /// Sends all of the last sent Items, Assets, and Devices to the Agent. This can be used upon reconnection to the Agent - /// - public void SendLast(long timestamp = 0) - { - WriteLastDataItems(timestamp); - WriteLastMessages(timestamp); - WriteLastConditions(timestamp); - WriteLastTimeSeries(timestamp); - WriteLastDataSets(timestamp); - WriteLastTables(timestamp); - WriteAllAssets(); - WriteAllDevices(); - - // Call Overridable Method - OnLastSent(); - } - - - protected virtual void OnChangedSent() { } - - protected virtual void OnLastSent() { } - - #endregion - - #region "Write" - - protected bool WriteLine(string line) - { - if (!string.IsNullOrEmpty(line)) - { - try - { - // Write Line to each client in stored client list - var clients = GetAgentClients(); - if (!clients.IsNullOrEmpty()) - { - var success = true; - - foreach (var client in clients) - { - if (!WriteLineToClient(client, line)) success = false; - } - - return success; - } - } - catch { } - } - - return false; - } - - private bool WriteLine(string clientId, string line) - { - if (!string.IsNullOrEmpty(line)) - { - var client = GetAgentClient(clientId); - if (client != null) - { - return WriteLineToClient(client, line); - } - } - - return false; - } - - private async Task WriteLineAsync(string line) - { - if (!string.IsNullOrEmpty(line)) - { - // Write Line to each client in stored client list - var clients = GetAgentClients(); - if (!clients.IsNullOrEmpty()) - { - foreach (var client in clients) - { - await WriteLineToClientAsync(client, line); - } - - return true; - } - } - - return false; - } - - private async Task WriteLineAsync(string clientId, string line) - { - if (!string.IsNullOrEmpty(line)) - { - var client = GetAgentClient(clientId); - if (client != null) - { - return await WriteLineToClientAsync(client, line); - } - } - - return false; - } - - - private bool WriteLineToClient(AgentClient client, string line) - { - if (client != null && !string.IsNullOrEmpty(line)) - { - var lines = SplitLines(line); - if (!lines.IsNullOrEmpty()) - { - foreach (var singleLine in lines) - { - try - { - // Convert string to ASCII bytes and add line terminator - var bytes = Encoding.ASCII.GetBytes(singleLine + "\n"); - - // Get the TcpClient Stream - var stream = client.TcpClient.GetStream(); - stream.ReadTimeout = Timeout; - stream.WriteTimeout = Timeout; - - // Write the line (in bytes) to the Stream - stream.Write(bytes, 0, bytes.Length); - - LineSent?.Invoke(this, new AdapterEventArgs(client.Id, singleLine)); - } - catch (Exception ex) - { - SendError?.Invoke(this, new AdapterEventArgs(client.Id, ex.Message)); - return false; - } - } - - return true; - } - } - - return false; - } - - private async Task WriteLineToClientAsync(AgentClient client, string line) - { - if (client != null) - { - try - { - // Convert string to ASCII bytes and add line terminator - var bytes = Encoding.ASCII.GetBytes(line + "\n"); - - // Get the TcpClient Stream - var stream = client.TcpClient.GetStream(); - stream.ReadTimeout = Timeout; - stream.WriteTimeout = Timeout; - - // Write the line (in bytes) to the Stream - await stream.WriteAsync(bytes, 0, bytes.Length); - - LineSent?.Invoke(this, new AdapterEventArgs(client.Id, line)); - - return true; - } - catch (Exception ex) - { - SendError?.Invoke(this, new AdapterEventArgs(client.Id, ex.Message)); - } - } - - return false; - } - - - // Split Lines by \r\n - // Can't use string.Split(string, StringSplitOptions.TrimEntries since - // it isn't fully compatible with all of the target runtimes - private static IEnumerable SplitLines(string line) - { - if (!string.IsNullOrEmpty(line)) - { - var lines = new List(); - char cr = '\r'; - char lf = '\n'; - char prev = '$'; - var s = 0; - var e = 0; - string l; - - while (e < line.Length - 1) - { - // Look for \r\n - if (line[e] == lf && prev == cr) - { - // Add trimmed line to return list - l = line.Substring(s, (e - s) + 1).Trim('\r').Trim('\n'); - if (!string.IsNullOrEmpty(l)) - { - if (l.Length > 1 || (l.Length == 1 && l[0] != cr)) - { - lines.Add(l); - } - } - s = e; - } - - prev = line[e]; - e++; - } - - // Get Last Line - l = line.Substring(s, (e - s) + 1).Trim('\n'); - if (!string.IsNullOrEmpty(l)) - { - if (l.Length > 1 || (l.Length == 1 && l[0] != cr)) - { - lines.Add(l); - } - } - - return lines; - } - - return null; - } - - #endregion - - - #region "DataItems" - - protected virtual void OnDataItemAdd(ShdrDataItem dataItem) { } - - - public void AddDataItem(string dataItemId, object value) - { - AddDataItem(dataItemId, value, UnixDateTime.Now); - } - - public void AddDataItem(string dataItemId, object value, DateTime timestamp) - { - AddDataItem(dataItemId, value, timestamp.ToUnixTime()); - } - - public void AddDataItem(string dataItemId, object value, long timestamp) - { - AddDataItem(new ShdrDataItem(dataItemId, value, timestamp)); - } - - public void AddDataItem(IObservationInput observation) - { - AddDataItem(new ShdrDataItem(observation)); - } - - public void AddDataItem(ShdrDataItem dataItem) - { - if (dataItem != null) - { - var newDataItem = new ShdrDataItem(dataItem); - - // Set the DeviceKey - newDataItem.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (newDataItem.Timestamp <= 0) newDataItem.Timestamp = UnixDateTime.Now; - - // Get the Current Observation (if exists) - ShdrDataItem currentDataItem; - lock (_lock) _currentDataItems.TryGetValue(newDataItem.DataItemKey, out currentDataItem); - - // Check to see if new Observation is the same as the Current - var add = true; - if (currentDataItem != null && FilterDuplicates) - { - add = !ObjectExtensions.ByteArraysEqual(newDataItem.ChangeId, currentDataItem.ChangeId); - } - - if (add) - { - // Add to Current - lock (_lock) - { - _currentDataItems.Remove(newDataItem.DataItemKey); - _currentDataItems.Add(newDataItem.DataItemKey, newDataItem); - } - - // Call Overridable Method - OnDataItemAdd(newDataItem); - } - } - } - - public void AddDataItems(IEnumerable dataItems) - { - if (!dataItems.IsNullOrEmpty()) - { - foreach (var dataItem in dataItems) - { - AddDataItem(dataItem); - } - } - } - - - public bool SendDataItem(string dataItemId, object value) - { - return SendDataItem(dataItemId, value, UnixDateTime.Now); - } - - public bool SendDataItem(string dataItemId, object value, DateTime timestamp) - { - return SendDataItem(dataItemId, value, timestamp.ToUnixTime()); - } - - public bool SendDataItem(string dataItemId, object value, long timestamp) - { - return SendDataItem(new ShdrDataItem(dataItemId, value, timestamp)); - } - - public bool SendDataItem(IObservationInput observation) - { - return SendDataItem(new ShdrDataItem(observation)); - } - - public bool SendDataItem(ShdrDataItem dataItem) - { - if (dataItem != null) - { - var newDataItem = new ShdrDataItem(dataItem); - - // Set the DeviceKey - newDataItem.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (newDataItem.Timestamp <= 0) newDataItem.Timestamp = UnixDateTime.Now; - //if (!OutputTimestamps) newDataItem.Timestamp = 0; - //else /*if (newDataItem.Timestamp <= 0) newDataItem.Timestamp = UnixDateTime.Now;*/ - - // Remove from Current - lock (_lock) _currentDataItems.Remove(newDataItem.DataItemKey); - - // Call Overridable Method - OnDataItemAdd(newDataItem); - - // Create SHDR string to send - var sendItem = new ShdrDataItem(newDataItem); - if (!OutputTimestamps) sendItem.Timestamp = 0; - var shdrLine = sendItem.ToString(); - - var success = WriteLine(shdrLine); - //if (success) - //{ - // Update Last Sent DataItems - UpdateLastDataItems(new List { newDataItem }); - //} - - return success; - } - - return false; - } - - public bool SendDataItems(IEnumerable dataItems) - { - var success = true; - - if (!dataItems.IsNullOrEmpty()) - { - foreach (var dataItem in dataItems) - { - if (!SendDataItem(dataItem)) success = false; - } - - return success; - } - - return false; - } - - - protected void UpdateLastDataItems(IEnumerable dataItems) - { - if (!dataItems.IsNullOrEmpty()) - { - // Find the most recent Observation for each DataItemKey - var dataItemKeys = dataItems.Select(o => o.DataItemKey).Distinct(); - foreach (var dataItemKey in dataItemKeys) - { - var keyDataItems = dataItems.Where(o => o.DataItemKey == dataItemKey); - var mostRecent = keyDataItems.OrderByDescending(o => o.Timestamp).FirstOrDefault(); - if (mostRecent != null) - { - var lastDataItem = new ShdrDataItem(mostRecent); - - lock (_lock) - { - _lastDataItems.Remove(lastDataItem.DataItemKey); - _lastDataItems.Add(lastDataItem.DataItemKey, lastDataItem); - } - } - } - } - } - - - protected bool WriteChangedDataItems() - { - // Get a list of all Current DataItems - List dataItems; - lock (_lock) - { - // Get List of DataItems that need to be Updated - dataItems = new List(); - var items = _currentDataItems.Values; - foreach (var item in items) - { - if (!item.IsSent) - { - item.IsSent = true; - - var sendItem = new ShdrDataItem(item); - if (!OutputTimestamps) sendItem.Timestamp = 0; - dataItems.Add(sendItem); - } - } - } - - if (!dataItems.IsNullOrEmpty()) - { - // Create SHDR string to send - var shdrLine = ShdrDataItem.ToString(dataItems); - - var success = WriteLine(shdrLine); - //if (success) - //{ - // Update Last Sent DataItems - UpdateLastDataItems(dataItems); - //} - - return success; - } - - return false; - } - - protected bool WriteLastDataItems(long timestamp = 0) - { - // Get a list of all Last DataItems - IEnumerable dataItems; - lock (_lock) dataItems = _lastDataItems.Values.ToList(); - - if (!dataItems.IsNullOrEmpty()) - { - var sendItems = new List(); - foreach (var dataItem in dataItems) - { - var sendItem = new ShdrDataItem(dataItem); - if (!OutputTimestamps) sendItem.Timestamp = 0; - sendItems.Add(sendItem); - } - - // Create SHDR string to send - var shdrLine = ShdrDataItem.ToString(sendItems); - var success = WriteLine(shdrLine); - //if (success) - //{ - // Update Last Sent DataItems - UpdateLastDataItems(dataItems); - //} - - return success; - } - - return false; - } - - - private void SetDataItemsUnavailable(long timestamp = 0) - { - // Get a list of all Current DataItems - IEnumerable dataItems; - lock (_lock) dataItems = _currentDataItems.Values.ToList(); - - if (!dataItems.IsNullOrEmpty()) - { - var unavailableObservations = new List(); - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - - // Set each Observation to Unavailable - foreach (var item in dataItems) - { - // Create new Unavailable Observation - var unavailableObservation = new ShdrDataItem(); - unavailableObservation.DeviceKey = item.DeviceKey; - unavailableObservation.DataItemKey = item.DataItemKey; - unavailableObservation.Timestamp = ts; - unavailableObservation.Unavailable(); - unavailableObservations.Add(unavailableObservation); - } - - // Add Observations (only will add those that are changed) - AddDataItems(unavailableObservations); - } - } - - #endregion - - #region "Messages" - - protected virtual void OnMessageAdd(ShdrMessage message) { } - - - public void AddMessage(string messageId, string value) - { - AddMessage(messageId, value, UnixDateTime.Now); - } - - public void AddMessage(string messageId, string value, DateTime timestamp) - { - AddMessage(messageId, value, timestamp.ToUnixTime()); - } - - public void AddMessage(string messageId, string value, long timestamp) - { - AddMessage(new ShdrMessage(messageId, value, timestamp)); - } - - public void AddMessage(string messageId, string value, string nativeCode) - { - AddMessage(messageId, value, nativeCode, UnixDateTime.Now); - } - - public void AddMessage(string messageId, string value, string nativeCode, DateTime timestamp) - { - AddMessage(messageId, value, nativeCode, timestamp.ToUnixTime()); - } - - public void AddMessage(string messageId, string value, string nativeCode, long timestamp) - { - AddMessage(new ShdrMessage(messageId, value, nativeCode, timestamp)); - } - - public void AddMessage(ShdrMessage message) - { - if (message != null) - { - var newMessage = new ShdrMessage(message); - - // Set the DeviceKey - newMessage.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newMessage.Timestamp = 0; - else if (newMessage.Timestamp <= 0) newMessage.Timestamp = UnixDateTime.Now; - - // Get the Current Observation (if exists) - ShdrMessage currentMessage; - lock (_lock) _currentMessages.TryGetValue(newMessage.DataItemKey, out currentMessage); - - // Check to see if new Observation is the same as the Current - var add = true; - if (currentMessage != null && FilterDuplicates) - { - add = !ObjectExtensions.ByteArraysEqual(newMessage.ChangeId, currentMessage.ChangeId); - } - - if (add) - { - // Add to Current - lock (_lock) - { - _currentMessages.Remove(newMessage.DataItemKey); - _currentMessages.Add(newMessage.DataItemKey, newMessage); - } - - // Call Overridable Method - OnMessageAdd(newMessage); - } - } - } - - public void AddMessages(IEnumerable messages) - { - if (!messages.IsNullOrEmpty()) - { - foreach (var message in messages) - { - AddMessage(message); - } - } - } - - - public bool SendMessage(string dataItemId, string value) - { - return SendMessage(dataItemId, value, UnixDateTime.Now); - } - - public bool SendMessage(string dataItemId, string value, DateTime timestamp) - { - return SendMessage(dataItemId, value, timestamp.ToUnixTime()); - } - - public bool SendMessage(string dataItemId, string value, long timestamp) - { - return SendMessage(new ShdrMessage(dataItemId, value, timestamp)); - } - - public bool SendMessage(string dataItemId, string value, string nativeCode) - { - return SendMessage(dataItemId, value, nativeCode, UnixDateTime.Now); - } - - public bool SendMessage(string dataItemId, string value, string nativeCode, DateTime timestamp) - { - return SendMessage(dataItemId, value, nativeCode, timestamp.ToUnixTime()); - } - - public bool SendMessage(string dataItemId, string value, string nativeCode, long timestamp) - { - return SendMessage(new ShdrMessage(dataItemId, value, nativeCode, timestamp)); - } - - public bool SendMessage(ShdrMessage message) - { - if (message != null) - { - var newMessage = new ShdrMessage(message); - - // Set the DeviceKey - newMessage.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newMessage.Timestamp = 0; - else if (newMessage.Timestamp <= 0) newMessage.Timestamp = UnixDateTime.Now; - - // Remove from Current - lock (_lock) _currentMessages.Remove(newMessage.DataItemKey); - - // Call Overridable Method - OnMessageAdd(newMessage); - - // Create SHDR string to send - var shdrLine = newMessage.ToString(); - - var success = WriteLine(shdrLine); - //if (success) - //{ - // Update Last Sent Messages - UpdateLastMessages(new List { newMessage }); - //} - - return success; - } - - return false; - } - - public bool SendMessages(IEnumerable messages) - { - var success = true; - - if (!messages.IsNullOrEmpty()) - { - foreach (var message in messages) - { - if (!SendMessage(message)) success = false; - } - - return success; - } - - return false; - } - - - protected void UpdateLastMessages(IEnumerable messages) - { - if (!messages.IsNullOrEmpty()) - { - // Find the most recent Observation for each DataItemKey - var messageKeys = messages.Select(o => o.DataItemKey).Distinct(); - foreach (var messageKey in messageKeys) - { - var keyMessages = messages.Where(o => o.DataItemKey == messageKey); - var mostRecent = keyMessages.OrderByDescending(o => o.Timestamp).FirstOrDefault(); - - lock (_lock) - { - _lastMessages.Remove(mostRecent.DataItemKey); - _lastMessages.Add(mostRecent.DataItemKey, mostRecent); - } - } - } - } - - - protected bool WriteChangedMessages() - { - // Get a list of all Current Messages - List messages; - lock (_lock) - { - // Get List of Messages that need to be Updated - messages = new List(); - var items = _currentMessages.Values; - foreach (var item in items) - { - if (!item.IsSent) - { - item.IsSent = true; - messages.Add(item); - } - } - } - - if (!messages.IsNullOrEmpty()) - { - var success = false; - - foreach (var item in messages) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent Messages - UpdateLastMessages(messages); - //} - - return success; - } - - return false; - } - - protected bool WriteLastMessages(long timestamp = 0) - { - // Get a list of all Last Messages - IEnumerable messages; - lock (_lock) messages = _lastMessages.Values.ToList(); - - if (!messages.IsNullOrEmpty()) - { - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - var success = false; - - foreach (var item in messages) - { - item.Timestamp = ts; - - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent Messages - UpdateLastMessages(messages); - //} - - return success; - } - - return false; - } - - - private void SetMessagesUnavailable(long timestamp = 0) - { - // Get a list of all Current Messages - IEnumerable messages; - lock (_lock) messages = _currentMessages.Values.ToList(); - - if (!messages.IsNullOrEmpty()) - { - var unavailableObservations = new List(); - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - - // Set each Observation to Unavailable - foreach (var item in messages) - { - // Create new Unavailable Observation - var unavailableObservation = new ShdrMessage(); - unavailableObservation.DeviceKey = item.DeviceKey; - unavailableObservation.DataItemKey = item.DataItemKey; - unavailableObservation.Timestamp = ts; - unavailableObservation.Unavailable(); - unavailableObservations.Add(unavailableObservation); - } - - // Add Observations (only will add those that are changed) - AddMessages(unavailableObservations); - } - } - - #endregion - - #region "Conditions" - - protected virtual void OnConditionAdd(ShdrCondition condition) { } - - - public void AddCondition(ShdrCondition condition) - { - if (condition != null) - { - var newCondition = new ShdrCondition(condition); - - // Set the DeviceKey - newCondition.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!newCondition.FaultStates.IsNullOrEmpty()) - { - foreach (var faultState in newCondition.FaultStates) - { - // Set Timestamp (if not already set) - if (!OutputTimestamps) faultState.Timestamp = 0; - else if (faultState.Timestamp <= 0) faultState.Timestamp = UnixDateTime.Now; - } - } - - // Get the Current Observation (if exists) - ShdrCondition currentCondition; - lock (_lock) _currentConditions.TryGetValue(newCondition.DataItemKey, out currentCondition); - - // Check to see if new Observation is the same as the Current - var add = true; - if (currentCondition != null && FilterDuplicates) - { - add = !ObjectExtensions.ByteArraysEqual(newCondition.ChangeId, currentCondition.ChangeId); - } - - if (add) - { - // Add to Current - lock (_lock) - { - _currentConditions.Remove(newCondition.DataItemKey); - _currentConditions.Add(newCondition.DataItemKey, newCondition); - } - - // Call Overridable Method - OnConditionAdd(newCondition); - } - } - } - - public void AddConditions(IEnumerable conditions) - { - if (!conditions.IsNullOrEmpty()) - { - foreach (var condition in conditions) - { - AddCondition(condition); - } - } - } - - - public bool SendCondition(ShdrCondition condition) - { - if (condition != null) - { - var newCondition = new ShdrCondition(condition); - - // Set the DeviceKey - newCondition.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!newCondition.FaultStates.IsNullOrEmpty()) - { - foreach (var faultState in newCondition.FaultStates) - { - // Set Timestamp (if not already set) - if (!OutputTimestamps) faultState.Timestamp = 0; - else if (faultState.Timestamp <= 0) faultState.Timestamp = UnixDateTime.Now; - } - } - - // Remove from Current - lock (_lock) _currentConditions.Remove(newCondition.DataItemKey); - - // Call Overridable Method - OnConditionAdd(newCondition); - - // Create SHDR string to send - var shdrLine = newCondition.ToString(); - - var success = WriteLine(shdrLine); - //if (success) - //{ - // Update Last Sent DataItems - UpdateLastConditions(new List { newCondition }); - //} - - return success; - } - - return false; - } - - public bool SendConditions(IEnumerable conditions) - { - var success = true; - - if (!conditions.IsNullOrEmpty()) - { - foreach (var condition in conditions) - { - if (!SendCondition(condition)) success = false; - } - - return success; - } - - return false; - } - - - protected void UpdateLastConditions(IEnumerable conditions) - { - if (!conditions.IsNullOrEmpty()) - { - foreach (var condition in conditions) - { - lock (_lock) - { - _lastConditions.Remove(condition.DataItemKey); - _lastConditions.Add(condition.DataItemKey, condition); - } - } - } - } - - - protected bool WriteChangedConditions() - { - var conditions = new List(); - var faultStates = new List(); - - lock (_lock) - { - // Get List of Conditions that need to be Updated - var items = _currentConditions.Values; - foreach (var item in items) - { - var add = false; - - if (!item.FaultStates.IsNullOrEmpty()) - { - foreach (var faultState in item.FaultStates) - { - if (!faultState.IsSent) - { - add = true; - faultState.IsSent = true; - faultStates.Add(faultState); - } - } - } - - if (add) conditions.Add(item); - } - } - - if (!conditions.IsNullOrEmpty() && !faultStates.IsNullOrEmpty()) - { - var success = false; - - foreach (var item in faultStates) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent Conditions - UpdateLastConditions(conditions); - //} - - return success; - } - - return false; - } - - - protected bool WriteLastConditions(long timestamp = 0) - { - // Get a list of all Last Conditions - IEnumerable conditions; - lock (_lock) conditions = _lastConditions.Values.ToList(); - - if (!conditions.IsNullOrEmpty()) - { - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - var success = false; - - foreach (var item in conditions) - { - if (!item.FaultStates.IsNullOrEmpty()) - { - foreach (var faultState in item.FaultStates) - { - faultState.Timestamp = ts; - } - } - - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent Conditions - UpdateLastConditions(conditions); - //} - - return success; - } - - return false; - } - - - private void SetConditionsUnavailable(long timestamp = 0) - { - // Get a list of all Current Conditions - IEnumerable conditions; - lock (_lock) conditions = _currentConditions.Values.ToList(); - - if (!conditions.IsNullOrEmpty()) - { - var unavailableConditions = new List(); - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - - // Set all of the Conditions to UNAVAILABLE - foreach (var condition in conditions) - { - var unavailableCondition = new ShdrCondition(condition.DataItemKey); - unavailableCondition.DeviceKey = condition.DeviceKey; - unavailableCondition.Unavailable(ts); - unavailableConditions.Add(unavailableCondition); - } - - // Add Conditions (only will add those that are changed) - AddConditions(unavailableConditions); - } - } - - #endregion - - #region "TimeSeries" - - protected virtual void OnTimeSeriesAdd(ShdrTimeSeries timeSeries) { } - - - public void AddTimeSeries(ShdrTimeSeries timeSeries) - { - if (timeSeries != null) - { - var newTimeSeries = new ShdrTimeSeries(timeSeries); - - // Set the DeviceKey - newTimeSeries.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newTimeSeries.Timestamp = 0; - else if (newTimeSeries.Timestamp <= 0) newTimeSeries.Timestamp = UnixDateTime.Now; - - // Get the Current Observation (if exists) - ShdrTimeSeries currentTimeSeries; - lock (_lock) _currentTimeSeries.TryGetValue(newTimeSeries.DataItemKey, out currentTimeSeries); - - // Check to see if new Observation is the same as the Current - var add = true; - if (currentTimeSeries != null && FilterDuplicates) - { - add = !ObjectExtensions.ByteArraysEqual(newTimeSeries.ChangeId, currentTimeSeries.ChangeId); - } - - if (add) - { - // Add to Current - lock (_lock) - { - _currentTimeSeries.Remove(newTimeSeries.DataItemKey); - _currentTimeSeries.Add(newTimeSeries.DataItemKey, newTimeSeries); - } - - // Call Overridable Method - OnTimeSeriesAdd(newTimeSeries); - } - } - } - - public void AddTimeSeries(IEnumerable timeSeries) - { - if (!timeSeries.IsNullOrEmpty()) - { - foreach (var item in timeSeries) - { - AddTimeSeries(item); - } - } - } - - - public bool SendTimeSeries(ShdrTimeSeries timeSeries) - { - if (timeSeries != null) - { - var newTimeSeries = new ShdrTimeSeries(timeSeries); - - // Set the DeviceKey - newTimeSeries.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newTimeSeries.Timestamp = 0; - else if (newTimeSeries.Timestamp <= 0) newTimeSeries.Timestamp = UnixDateTime.Now; - - // Remove from Current - lock (_lock) _currentTimeSeries.Remove(newTimeSeries.DataItemKey); - - // Call Overridable Method - OnTimeSeriesAdd(newTimeSeries); - - // Create SHDR string to send - var shdrLine = newTimeSeries.ToString(); - - var success = WriteLine(shdrLine); - //if (success) - //{ - // Update Last Sent TimeSeries - UpdateLastTimeSeries(new List { newTimeSeries }); - //} - - return success; - } - - return false; - } - - public bool SendTimeSeries(IEnumerable timeSeries) - { - var success = true; - - if (!timeSeries.IsNullOrEmpty()) - { - foreach (var item in timeSeries) - { - if (!SendTimeSeries(item)) success = false; - } - - return success; - } - - return false; - } - - - protected void UpdateLastTimeSeries(IEnumerable timeSeries) - { - if (!timeSeries.IsNullOrEmpty()) - { - // Find the most recent Observation for each DataItemKey - var timeSeriesKeys = timeSeries.Select(o => o.DataItemKey).Distinct(); - foreach (var timeSeriesKey in timeSeriesKeys) - { - var keyTimeSeriess = timeSeries.Where(o => o.DataItemKey == timeSeriesKey); - var mostRecent = keyTimeSeriess.OrderByDescending(o => o.Timestamp).FirstOrDefault(); - - lock (_lock) - { - _lastTimeSeries.Remove(mostRecent.DataItemKey); - _lastTimeSeries.Add(mostRecent.DataItemKey, mostRecent); - } - } - } - } - - - protected bool WriteChangedTimeSeries() - { - // Get a list of all Current TimeSeriess - List timeSeries; - lock (_lock) - { - // Get List of TimeSeries that need to be Updated - timeSeries = new List(); - var items = _currentTimeSeries.Values; - foreach (var item in items) - { - if (!item.IsSent) - { - item.IsSent = true; - timeSeries.Add(item); - } - } - } - - if (!timeSeries.IsNullOrEmpty()) - { - bool success = false; - - foreach (var item in timeSeries) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent TimeSeries - UpdateLastTimeSeries(timeSeries); - //} - - return success; - } - - return false; - } - - protected bool WriteLastTimeSeries(long timestamp = 0) - { - // Get a list of all Last TimeSeries - IEnumerable timeSeries; - lock (_lock) timeSeries = _lastTimeSeries.Values.ToList(); - - if (!timeSeries.IsNullOrEmpty()) - { - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - bool success = false; - - foreach (var item in timeSeries) - { - item.Timestamp = ts; - - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent TimeSeries - UpdateLastTimeSeries(timeSeries); - //} - - return success; - } - - return false; - } - - - private void SetTimeSeriesUnavailable(long timestamp = 0) - { - // Get a list of all Current TimeSeriess - IEnumerable timeSeries; - lock (_lock) timeSeries = _currentTimeSeries.Values.ToList(); - - if (!timeSeries.IsNullOrEmpty()) - { - var unavailableObservations = new List(); - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - - // Set each Observation to Unavailable - foreach (var item in timeSeries) - { - // Create new Unavailable Observation - var unavailableObservation = new ShdrTimeSeries(); - unavailableObservation.DeviceKey = item.DeviceKey; - unavailableObservation.DataItemKey = item.DataItemKey; - unavailableObservation.Timestamp = ts; - unavailableObservation.IsUnavailable = true; - unavailableObservations.Add(unavailableObservation); - } - - // Add Observations (only will add those that are changed) - AddTimeSeries(unavailableObservations); - } - } - - #endregion - - #region "DataSet" - - protected virtual void OnDataSetAdd(ShdrDataSet dataSet) { } - - - public void AddDataSet(ShdrDataSet dataSet) - { - if (dataSet != null) - { - var newDataSet = new ShdrDataSet(dataSet); - - // Set the DeviceKey - newDataSet.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newDataSet.Timestamp = 0; - else if (newDataSet.Timestamp <= 0) newDataSet.Timestamp = UnixDateTime.Now; - - // Get the Current Observation (if exists) - ShdrDataSet currentDataSet; - lock (_lock) _currentDataSets.TryGetValue(newDataSet.DataItemKey, out currentDataSet); - - // Check to see if new Observation is the same as the Current - var add = true; - if (currentDataSet != null && FilterDuplicates) - { - add = !ObjectExtensions.ByteArraysEqual(newDataSet.ChangeId, currentDataSet.ChangeId); - } - - if (add) - { - // Add to Current - lock (_lock) - { - _currentDataSets.Remove(newDataSet.DataItemKey); - _currentDataSets.Add(newDataSet.DataItemKey, newDataSet); - } - - // Call Overridable Method - OnDataSetAdd(newDataSet); - } - } - } - - public void AddDataSets(IEnumerable dataSets) - { - if (!dataSets.IsNullOrEmpty()) - { - foreach (var item in dataSets) - { - AddDataSet(item); - } - } - } - - - public bool SendDataSet(ShdrDataSet dataSet) - { - if (dataSet != null) - { - var newDataSet = new ShdrDataSet(dataSet); - - // Set the DeviceKey - newDataSet.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newDataSet.Timestamp = 0; - else if (newDataSet.Timestamp <= 0) newDataSet.Timestamp = UnixDateTime.Now; - - // Remove from Current - lock (_lock) _currentDataSets.Remove(newDataSet.DataItemKey); - - // Call Overridable Method - OnDataSetAdd(newDataSet); - - // Create SHDR string to send - var shdrLine = newDataSet.ToString(); - - var success = WriteLine(shdrLine); - //if (success) - //{ - // Update Last Sent TimeSeries - UpdateLastDataSets(new List { newDataSet }); - //} - - return success; - } - - return false; - } - - public bool SendDataSets(IEnumerable dataSets) - { - var success = true; - - if (!dataSets.IsNullOrEmpty()) - { - foreach (var item in dataSets) - { - if (!SendDataSet(item)) success = false; - } - - return success; - } - - return false; - } - - - protected void UpdateLastDataSets(IEnumerable dataSets) - { - if (!dataSets.IsNullOrEmpty()) - { - // Find the most recent Observation for each DataItemKey - var dataSetKeys = dataSets.Select(o => o.DataItemKey).Distinct(); - foreach (var dataSetKey in dataSetKeys) - { - var keyDataSets = dataSets.Where(o => o.DataItemKey == dataSetKey); - var mostRecent = keyDataSets.OrderByDescending(o => o.Timestamp).FirstOrDefault(); - - lock (_lock) - { - _lastDataSets.Remove(mostRecent.DataItemKey); - _lastDataSets.Add(mostRecent.DataItemKey, mostRecent); - } - } - } - } - - - protected bool WriteChangedDataSets() - { - // Get a list of all Current DataSets - List dataSets; - lock (_lock) - { - // Get List of DataSet that need to be Updated - dataSets = new List(); - var items = _currentDataSets.Values; - foreach (var item in items) - { - if (!item.IsSent) - { - item.IsSent = true; - dataSets.Add(item); - } - } - } - - if (!dataSets.IsNullOrEmpty()) - { - bool success = false; - - foreach (var item in dataSets) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent DataSet - UpdateLastDataSets(dataSets); - //} - - return success; - } - - return false; - } - - protected bool WriteLastDataSets(long timestamp = 0) - { - // Get a list of all Last DataSet - IEnumerable dataSets; - lock (_lock) dataSets = _lastDataSets.Values.ToList(); - - if (!dataSets.IsNullOrEmpty()) - { - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - bool success = false; - - foreach (var item in dataSets) - { - item.Timestamp = ts; - - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent DataSet - UpdateLastDataSets(dataSets); - //} - - return success; - } - - return false; - } - - - private void SetDataSetsUnavailable(long timestamp = 0) - { - // Get a list of all Current DataSets - IEnumerable dataSet; - lock (_lock) dataSet = _currentDataSets.Values.ToList(); - - if (!dataSet.IsNullOrEmpty()) - { - var unavailableObservations = new List(); - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - - // Set each Observation to Unavailable - foreach (var item in dataSet) - { - // Create new Unavailable Observation - var unavailableObservation = new ShdrDataSet(); - unavailableObservation.DeviceKey = item.DeviceKey; - unavailableObservation.DataItemKey = item.DataItemKey; - unavailableObservation.Timestamp = ts; - unavailableObservation.IsUnavailable = true; - unavailableObservations.Add(unavailableObservation); - } - - // Add Observations (only will add those that are changed) - AddDataSets(unavailableObservations); - } - } - - #endregion - - #region "Table" - - protected virtual void OnTableAdd(ShdrTable table) { } - - - public void AddTable(ShdrTable table) - { - if (table != null) - { - var newTable = new ShdrTable(table); - - // Set the DeviceKey - newTable.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newTable.Timestamp = 0; - else if (newTable.Timestamp <= 0) newTable.Timestamp = UnixDateTime.Now; - - // Get the Current Observation (if exists) - ShdrTable currentTable; - lock (_lock) _currentTables.TryGetValue(newTable.DataItemKey, out currentTable); - - // Check to see if new Observation is the same as the Current - var add = true; - if (currentTable != null && FilterDuplicates) - { - add = !ObjectExtensions.ByteArraysEqual(newTable.ChangeId, currentTable.ChangeId); - } - - if (add) - { - // Add to Current - lock (_lock) - { - _currentTables.Remove(newTable.DataItemKey); - _currentTables.Add(newTable.DataItemKey, newTable); - } - - // Call Overridable Method - OnTableAdd(newTable); - } - } - } - - public void AddTables(IEnumerable tables) - { - if (!tables.IsNullOrEmpty()) - { - foreach (var item in tables) - { - AddTable(item); - } - } - } - - - public bool SendTable(ShdrTable table) - { - if (table != null) - { - var newTable = new ShdrTable(table); - - // Set the DeviceKey - newTable.DeviceKey = DeviceKey; - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newTable.Timestamp = 0; - else if (newTable.Timestamp <= 0) newTable.Timestamp = UnixDateTime.Now; - - // Remove from Current - lock (_lock) _currentTables.Remove(newTable.DataItemKey); - - // Call Overridable Method - OnTableAdd(newTable); - - // Create SHDR string to send - var shdrLine = newTable.ToString(); - - var success = WriteLine(shdrLine); - //if (success) - //{ - // Update Last Sent - UpdateLastTables(new List { newTable }); - //} - - return success; - } - - return false; - } - - public bool SendTables(IEnumerable tables) - { - var success = true; - - if (!tables.IsNullOrEmpty()) - { - foreach (var item in tables) - { - if (!SendTable(item)) success = false; - } - - return success; - } - - return false; - } - - - protected void UpdateLastTables(IEnumerable tables) - { - if (!tables.IsNullOrEmpty()) - { - // Find the most recent Observation for each DataItemKey - var tableKeys = tables.Select(o => o.DataItemKey).Distinct(); - foreach (var tableKey in tableKeys) - { - var keyTables = tables.Where(o => o.DataItemKey == tableKey); - var mostRecent = keyTables.OrderByDescending(o => o.Timestamp).FirstOrDefault(); - - lock (_lock) - { - _lastTables.Remove(mostRecent.DataItemKey); - _lastTables.Add(mostRecent.DataItemKey, mostRecent); - } - } - } - } - - - protected bool WriteChangedTables() - { - // Get a list of all Current Tables - List tables; - lock (_lock) - { - // Get List of Table that need to be Updated - tables = new List(); - var items = _currentTables.Values; - foreach (var item in items) - { - if (!item.IsSent) - { - item.IsSent = true; - tables.Add(item); - } - } - } - - if (!tables.IsNullOrEmpty()) - { - bool success = false; - - foreach (var item in tables) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent Table - UpdateLastTables(tables); - //} - - return success; - } - - return false; - } - - protected bool WriteLastTables(long timestamp = 0) - { - // Get a list of all Last Table - IEnumerable tables; - lock (_lock) tables = _lastTables.Values.ToList(); - - if (!tables.IsNullOrEmpty()) - { - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - bool success = false; - - foreach (var item in tables) - { - item.Timestamp = ts; - - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent Table - UpdateLastTables(tables); - //} - - return success; - } - - return false; - } - - - private void SetTablesUnavailable(long timestamp = 0) - { - // Get a list of all Current Tables - IEnumerable table; - lock (_lock) table = _currentTables.Values.ToList(); - - if (!table.IsNullOrEmpty()) - { - var unavailableObservations = new List(); - var ts = timestamp > 0 ? timestamp : UnixDateTime.Now; - - // Set each Observation to Unavailable - foreach (var item in table) - { - // Create new Unavailable Observation - var unavailableObservation = new ShdrTable(); - unavailableObservation.DeviceKey = item.DeviceKey; - unavailableObservation.DataItemKey = item.DataItemKey; - unavailableObservation.Timestamp = ts; - unavailableObservation.IsUnavailable = true; - unavailableObservations.Add(unavailableObservation); - } - - // Add Observations (only will add those that are changed) - AddTables(unavailableObservations); - } - } - - #endregion - - - #region "Assets" - - protected virtual void OnAssetAdd(ShdrAsset asset) { } - - - /// - /// Add the specified MTConnect Asset and sends it to the Agent - /// - /// The Asset to send - public void SendAsset(Assets.IAsset asset) - { - SendAsset(new ShdrAsset(asset)); - } - - /// - /// Add the specified MTConnect Asset and sends it to the Agent - /// - /// The Asset to send - private void SendAsset(ShdrAsset asset) - { - if (asset != null) - { - // Set Timestamp (if not already set) - if (!OutputTimestamps) asset.Timestamp = 0; - else if (asset.Timestamp <= 0) asset.Timestamp = UnixDateTime.Now; - - lock (_lock) - { - // Check to see if Asset already exists in list - var existing = _lastAssets.FirstOrDefault(o => o.Key == asset.AssetId).Value; - if (existing == null) - { - _lastAssets.Add(asset.AssetId, asset); - } - else - { - _lastAssets.Remove(asset.AssetId); - _lastAssets.Add(asset.AssetId, asset); - } - } - - var shdrLine = asset.ToString(MultilineAssets); - WriteLine(shdrLine); - } - } - - /// - /// Add the specified MTConnect Assets and sends them to the Agent - /// - /// The Assets to send - public void SendAssets(IEnumerable assets) - { - if (!assets.IsNullOrEmpty()) - { - var items = new List(); - foreach (var item in assets) - { - items.Add(new ShdrAsset(item)); - } - - SendAssets(items); - } - } - - /// - /// Add the specified MTConnect Assets and sends them to the Agent - /// - /// The Assets to send - private void SendAssets(IEnumerable assets) - { - if (!assets.IsNullOrEmpty()) - { - foreach (var item in assets) - { - SendAsset(item); - } - } - } - - - /// - /// Add the specified MTConnect Asset - /// - /// The Asset to add - public void AddAsset(Assets.IAsset asset) - { - if (asset != null) - { - var newAsset = new ShdrAsset(asset); - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newAsset.Timestamp = 0; - else if (newAsset.Timestamp <= 0) newAsset.Timestamp = UnixDateTime.Now; - - // Get the Current Asset (if exists) - ShdrAsset currentAsset; - lock (_lock) _currentAssets.TryGetValue(newAsset.AssetId, out currentAsset); - - // Check to see if new Asset is the same as the Current - var add = true; - if (currentAsset != null && FilterDuplicates) - { - add = !ObjectExtensions.ByteArraysEqual(newAsset.ChangeId, currentAsset.ChangeId); - } - - if (add) - { - // Add to Current - lock (_lock) - { - _currentAssets.Remove(newAsset.AssetId); - _currentAssets.Add(newAsset.AssetId, newAsset); - } - - // Call Overridable Method - OnAssetAdd(newAsset); - } - } - } - - /// - /// Add the specified MTConnect Asset - /// - /// The Asset to add - private void AddAsset(ShdrAsset asset) - { - if (asset != null) - { - var newAsset = new ShdrAsset(asset.AssetId, asset.AssetType, asset.Xml, asset.Timestamp); - - // Set Timestamp (if not already set) - if (!OutputTimestamps) newAsset.Timestamp = 0; - else if (newAsset.Timestamp <= 0) newAsset.Timestamp = UnixDateTime.Now; - - // Get the Current Asset (if exists) - ShdrAsset currentAsset; - lock (_lock) _currentAssets.TryGetValue(newAsset.AssetId, out currentAsset); - - // Check to see if new Asset is the same as the Current - var add = true; - if (currentAsset != null && FilterDuplicates) - { - add = !ObjectExtensions.ByteArraysEqual(newAsset.ChangeId, currentAsset.ChangeId); - } - - if (add) - { - // Add to Current - lock (_lock) - { - _currentAssets.Remove(newAsset.AssetId); - _currentAssets.Add(newAsset.AssetId, newAsset); - } - - // Call Overridable Method - OnAssetAdd(newAsset); - } - } - } - - /// - /// Add the specified MTConnect Assets - /// - /// The Assets to add - public void AddAssets(IEnumerable assets) - { - if (!assets.IsNullOrEmpty()) - { - var items = new List(); - foreach (var item in assets) - { - items.Add(new ShdrAsset(item)); - } - - AddAssets(items); - } - } - - /// - /// Add the specified MTConnect Assets - /// - /// The Assets to send - private void AddAssets(IEnumerable assets) - { - if (!assets.IsNullOrEmpty()) - { - foreach (var item in assets) - { - AddAsset(item); - } - } - } - - - protected void UpdateLastAsset(IEnumerable assets) - { - if (!assets.IsNullOrEmpty()) - { - // Find the most recent Asset for each AssetId - var assetKeys = assets.Select(o => o.AssetId).Distinct(); - foreach (var assetKey in assetKeys) - { - var keyAssets = assets.Where(o => o.AssetId == assetKey); - var mostRecent = keyAssets.OrderByDescending(o => o.Timestamp).FirstOrDefault(); - - lock (_lock) - { - _lastAssets.Remove(mostRecent.AssetId); - _lastAssets.Add(mostRecent.AssetId, mostRecent); - } - } - } - } - - - protected bool WriteChangedAssets() - { - // Get a list of all Current Assets - List assets; - lock (_lock) - { - // Get List of Table that need to be Updated - assets = new List(); - var items = _currentAssets.Values; - foreach (var item in items) - { - if (!item.IsSent) - { - item.IsSent = true; - assets.Add(item); - } - } - } - - if (!assets.IsNullOrEmpty()) - { - bool success = false; - - foreach (var item in assets) - { - // Create SHDR string to send - var shdrLine = item.ToString(MultilineAssets); - success = WriteLine(shdrLine); - if (!success) break; - } - - //if (success) - //{ - // Update Last Sent Asset - UpdateLastAsset(assets); - //} - - return success; - } - - return false; - } - - protected bool WriteAllAssets() - { - // Get a list of all Assets - IEnumerable assets; - lock (_lock) assets = _lastAssets.Values.ToList(); - - if (!assets.IsNullOrEmpty()) - { - bool success = false; - - foreach (var item in assets) - { - // Create SHDR string to send - var shdrLine = item.ToString(MultilineAssets); - success = WriteLine(shdrLine); - if (!success) break; - } - - return success; - } - - return false; - } - - - /// - /// Remove the specified Asset using the SHDR command @REMOVE_ASSET@ - /// - /// The AssetId of the Asset to remove - /// The timestamp to send as part of the SHDR command - public void RemoveAsset(string assetId, long timestamp = 0) - { - // Create SHDR string to send - var shdrLine = ShdrAsset.Remove(assetId, timestamp); - - // Write line to stream - WriteLine(shdrLine); - } - - /// - /// Remove all Assets of the specified Type using the SHDR command @REMOVE_ALL_ASSETS@ - /// - /// The Type of the Assets to remove - /// The timestamp to send as part of the SHDR command - public void RemoveAllAssets(string assetType, long timestamp = 0) - { - // Create SHDR string to send - var shdrLine = ShdrAsset.RemoveAll(assetType, timestamp); - - // Write line to stream - WriteLine(shdrLine); - } - - #endregion - - #region "Devices" - - /// - /// Add the specified MTConnect Device to the queue to be written to the adapter stream - /// - /// The Device to add - public void AddDevice(Devices.IDevice device) - { - AddDevice(new ShdrDevice(device)); - } - - /// - /// Add the specified MTConnect Device to the queue to be written to the adapter stream - /// - /// The Device to add - private void AddDevice(ShdrDevice device) - { - if (device != null) - { - lock (_lock) - { - // Check to see if Device already exists in list - var existing = _devices.FirstOrDefault(o => o.Key == device.DeviceUuid).Value; - if (existing == null) - { - _devices.Add(device.DeviceUuid, device); - } - else - { - if (existing.ChangeId != device.ChangeId) - { - _devices.Remove(device.DeviceUuid); - _devices.Add(device.DeviceUuid, device); - } - } - } - - var shdrLine = device.ToString(); - WriteLine(shdrLine); - } - } - - /// - /// Add the specified MTConnect Devices to the queue to be written to the adapter stream - /// - /// The Devices to add - public void AddDevices(IEnumerable devices) - { - if (!devices.IsNullOrEmpty()) - { - var items = new List(); - foreach (var item in devices) - { - items.Add(new ShdrDevice(item)); - } - - AddDevices(items); - } - } - - /// - /// Add the specified MTConnect Devices to the queue to be written to the adapter stream - /// - /// The Devices to add - private void AddDevices(IEnumerable devices) - { - if (!devices.IsNullOrEmpty()) - { - foreach (var item in devices) - { - AddDevice(item); - } - } - } - - protected bool WriteAllDevices() - { - // Get a list of all Devices - IEnumerable devices; - lock (_lock) devices = _devices.Values.ToList(); - - if (!devices.IsNullOrEmpty()) - { - bool success = false; - - foreach (var item in devices) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - return success; - } - - return false; - } - - - /// - /// Remove the specified Device using the SHDR command @REMOVE_ASSET@ - /// - /// The DeviceId of the Device to remove - /// The timestamp to send as part of the SHDR command - public void RemoveDevice(string deviceId, long timestamp = 0) - { - // Create SHDR string to send - var shdrLine = ShdrDevice.Remove(deviceId, timestamp); - - // Write line to stream - WriteLine(shdrLine); - } - - /// - /// Remove all Devices of the specified Type using the SHDR command @REMOVE_ALL_ASSETS@ - /// - /// The Type of the Devices to remove - /// The timestamp to send as part of the SHDR command - public void RemoveAllDevices(string deviceType, long timestamp = 0) - { - // Create SHDR string to send - var shdrLine = ShdrDevice.RemoveAll(deviceType, timestamp); - - // Write line to stream - WriteLine(shdrLine); - } - - #endregion - - } -} \ No newline at end of file diff --git a/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter.cs b/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter.cs index 581208d1..7c07a240 100644 --- a/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter.cs +++ b/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter.cs @@ -209,6 +209,69 @@ public ShdrAdapter(ShdrAdapterClientConfiguration configuration) } } + protected ShdrAdapter(int port = 7878, int heartbeat = 10000, int? interval = null, bool bufferEnabled = false) + { + FilterDuplicates = true; + OutputTimestamps = true; + Port = port; + Heartbeat = heartbeat; + Timeout = 5000; + + var adapter = new MTConnectAdapter(interval, bufferEnabled); + adapter.WriteObservationsFunction = WriteDataItems; + _adapter = adapter; + + _connectionListener = new AgentClientConnectionListener(Port, heartbeat); + _connectionListener.ClientConnected += ClientConnected; + _connectionListener.ClientDisconnected += ClientDisconnected; + _connectionListener.ClientPingReceived += ClientPingReceived; + _connectionListener.ClientPongSent += ClientPongSent; + } + + protected ShdrAdapter(string deviceKey, int port = 7878, int heartbeat = 10000, int? interval = null, bool bufferEnabled = false) + { + FilterDuplicates = true; + OutputTimestamps = true; + DeviceKey = deviceKey; + Port = port; + Heartbeat = heartbeat; + Timeout = 5000; + + var adapter = new MTConnectAdapter(interval, bufferEnabled); + adapter.WriteObservationsFunction = WriteDataItems; + _adapter = adapter; + + _connectionListener = new AgentClientConnectionListener(Port, heartbeat); + _connectionListener.ClientConnected += ClientConnected; + _connectionListener.ClientDisconnected += ClientDisconnected; + _connectionListener.ClientPingReceived += ClientPingReceived; + _connectionListener.ClientPongSent += ClientPongSent; + } + + protected ShdrAdapter(ShdrAdapterClientConfiguration configuration, int? interval = null, bool bufferEnabled = false) + { + FilterDuplicates = true; + OutputTimestamps = true; + + if (configuration != null) + { + DeviceKey = configuration.DeviceKey; + Port = configuration.Port; + Heartbeat = configuration.Heartbeat; + Timeout = 5000; + + var adapter = new MTConnectAdapter(interval, bufferEnabled); + adapter.WriteObservationsFunction = WriteDataItems; + _adapter = adapter; + + _connectionListener = new AgentClientConnectionListener(Port, Heartbeat); + _connectionListener.ClientConnected += ClientConnected; + _connectionListener.ClientDisconnected += ClientDisconnected; + _connectionListener.ClientPingReceived += ClientPingReceived; + _connectionListener.ClientPongSent += ClientPongSent; + } + } + /// /// Starts the Adapter to begins listening for Agent connections as well as starts the Queue for collecting and sending data to the Agent(s). diff --git a/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalAdapter.cs b/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalAdapter.cs index 8ba59b33..dd9c6f6d 100644 --- a/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalAdapter.cs +++ b/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalAdapter.cs @@ -2,9 +2,6 @@ // TrakHound Inc. licenses this file to you under the MIT license. using MTConnect.Configurations; -using System; -using System.Threading; -using System.Threading.Tasks; namespace MTConnect.Adapters { @@ -15,70 +12,13 @@ namespace MTConnect.Adapters /// public class ShdrIntervalAdapter : ShdrAdapter { - private const int _defualtInterval = 100; + private const int _defaultInterval = 100; - /// - /// The interval (in milliseconds) at which new data is sent to the Agent - /// - public int Interval { get; set; } + public ShdrIntervalAdapter(int port = 7878, int heartbeat = 10000, int interval = _defaultInterval) : base(port, heartbeat, interval) { } + public ShdrIntervalAdapter(string deviceKey, int port = 7878, int heartbeat = 10000, int interval = _defaultInterval) : base(deviceKey, port, heartbeat, interval) { } - public ShdrIntervalAdapter(int port = 7878, int heartbeat = 10000, int interval = _defualtInterval) : base(port, heartbeat) - { - Interval = interval; - } - - public ShdrIntervalAdapter(string deviceKey, int port = 7878, int heartbeat = 10000, int interval = _defualtInterval) : base(deviceKey, port, heartbeat) - { - Interval = interval; - } - - public ShdrIntervalAdapter(ShdrAdapterClientConfiguration configuration, int interval = _defualtInterval) : base(configuration) - { - Interval = interval; - } - - - protected override void OnStart() - { - // Start Write Queue - _ = Task.Run(() => Worker(StopToken.Token)); - } - - - private async Task Worker(CancellationToken cancellationToken) - { - try - { - do - { - int interval = Math.Max(1, Interval); // Set Minimum of 1ms to prevent high CPU usage - - var stpw = System.Diagnostics.Stopwatch.StartNew(); - - // Call Overridable Method - OnIntervalElapsed(); - - stpw.Stop(); - - if (stpw.ElapsedMilliseconds < interval) - { - var waitInterval = interval - (int)stpw.ElapsedMilliseconds; - - await Task.Delay(waitInterval, cancellationToken); - } - - } while (!cancellationToken.IsCancellationRequested); - } - catch (TaskCanceledException) { } - catch (Exception) { } - } - - protected virtual void OnIntervalElapsed() - { - // Send only the changed items - SendChanged(); - } + public ShdrIntervalAdapter(ShdrAdapterClientConfiguration configuration, int interval = _defaultInterval) : base(configuration, interval) { } } } \ No newline at end of file diff --git a/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalQueueAdapter.cs b/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalQueueAdapter.cs index 867a6006..624afddd 100644 --- a/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalQueueAdapter.cs +++ b/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalQueueAdapter.cs @@ -2,9 +2,6 @@ // TrakHound Inc. licenses this file to you under the MIT license. using MTConnect.Configurations; -using System; -using System.Threading; -using System.Threading.Tasks; namespace MTConnect.Adapters { @@ -13,72 +10,15 @@ namespace MTConnect.Adapters /// Supports multiple concurrent Agent connections. /// Uses a queue to collect changes to Observations and sends the entire buffer at the specified interval. /// - public class ShdrIntervalQueueAdapter : ShdrQueueAdapter + public class ShdrIntervalQueueAdapter : ShdrAdapter { - private const int _defualtInterval = 100; + private const int _defaultInterval = 100; - /// - /// The interval (in milliseconds) at which new data is sent to the Agent - /// - public int Interval { get; set; } + public ShdrIntervalQueueAdapter(int port = 7878, int heartbeat = 10000, int interval = _defaultInterval) : base(port, heartbeat, interval, true) { } + public ShdrIntervalQueueAdapter(string deviceKey, int port = 7878, int heartbeat = 10000, int interval = _defaultInterval) : base(deviceKey, port, heartbeat, interval, true) { } - public ShdrIntervalQueueAdapter(int port = 7878, int heartbeat = 10000, int interval = _defualtInterval) : base(port, heartbeat) - { - Interval = interval; - } - - public ShdrIntervalQueueAdapter(string deviceKey, int port = 7878, int heartbeat = 10000, int interval = _defualtInterval) : base(deviceKey, port, heartbeat) - { - Interval = interval; - } - - public ShdrIntervalQueueAdapter(ShdrAdapterClientConfiguration configuration, int interval = _defualtInterval) : base(configuration) - { - Interval = interval; - } - - - protected override void OnStart() - { - // Start Write Queue - _ = Task.Run(() => Worker(StopToken.Token)); - } - - - private async Task Worker(CancellationToken cancellationToken) - { - try - { - do - { - int interval = Math.Max(1, Interval); // Set Minimum of 1ms to prevent high CPU usage - - var stpw = System.Diagnostics.Stopwatch.StartNew(); - - // Call Overridable Method - OnIntervalElapsed(); - - stpw.Stop(); - - if (stpw.ElapsedMilliseconds < interval) - { - var waitInterval = interval - (int)stpw.ElapsedMilliseconds; - - await Task.Delay(waitInterval, cancellationToken); - } - - } while (!cancellationToken.IsCancellationRequested); - } - catch (TaskCanceledException) { } - catch (Exception) { } - } - - protected virtual void OnIntervalElapsed() - { - // Send the buffered items - SendBuffer(); - } + public ShdrIntervalQueueAdapter(ShdrAdapterClientConfiguration configuration, int interval = _defaultInterval) : base(configuration, interval, true) { } } } \ No newline at end of file diff --git a/libraries/MTConnect.NET-SHDR/Adapters/ShdrQueueAdapter.cs b/libraries/MTConnect.NET-SHDR/Adapters/ShdrQueueAdapter.cs index e3295b61..cb5df0e4 100644 --- a/libraries/MTConnect.NET-SHDR/Adapters/ShdrQueueAdapter.cs +++ b/libraries/MTConnect.NET-SHDR/Adapters/ShdrQueueAdapter.cs @@ -2,10 +2,6 @@ // TrakHound Inc. licenses this file to you under the MIT license. using MTConnect.Configurations; -using MTConnect.Input; -using MTConnect.Shdr; -using System.Collections.Generic; -using System.Linq; namespace MTConnect.Adapters { @@ -16,299 +12,10 @@ namespace MTConnect.Adapters /// public class ShdrQueueAdapter : ShdrAdapter { - private readonly ItemQueue _dataItemsBuffer = new ItemQueue(); - private readonly ItemQueue _messagesBuffer = new ItemQueue(); - private readonly ItemQueue _conditionsBuffer = new ItemQueue(); - private readonly ItemQueue _timeSeriesBuffer = new ItemQueue(); - private readonly ItemQueue _dataSetsBuffer = new ItemQueue(); - private readonly ItemQueue _tablesBuffer = new ItemQueue(); + public ShdrQueueAdapter(int port = 7878, int heartbeat = 10000) : base(port, heartbeat, null, true) { } + public ShdrQueueAdapter(string deviceKey, int port = 7878, int heartbeat = 10000) : base(deviceKey, port, heartbeat, null, true) { } - public ShdrQueueAdapter(int port = 7878, int heartbeat = 10000) : base(port, heartbeat) - { - FilterDuplicates = false; - } - - public ShdrQueueAdapter(string deviceKey, int port = 7878, int heartbeat = 10000) : base(deviceKey, port, heartbeat) - { - FilterDuplicates = false; - } - - public ShdrQueueAdapter(ShdrAdapterClientConfiguration configuration) : base(configuration) - { - FilterDuplicates = false; - } - - - /// - /// Sends the buffered items to the Agent - /// - public void SendBuffer() - { - WriteBufferDataItems(); - WriteBufferMessages(); - WriteBufferConditions(); - WriteBufferTimeSeries(); - WriteBufferDataSets(); - WriteBufferTables(); - } - - - protected override void OnChangedSent() - { - // Clear Buffer (to prevent duplicates) - _dataItemsBuffer.Clear(); - _messagesBuffer.Clear(); - _conditionsBuffer.Clear(); - _timeSeriesBuffer.Clear(); - _dataSetsBuffer.Clear(); - _tablesBuffer.Clear(); - } - - - #region "DataItems" - - protected override void OnDataItemAdd(ShdrDataItem dataItem) - { - var newDataItem = new ShdrDataItem(dataItem); - var key = CreateUniqueId(newDataItem); - if (newDataItem.Timestamp <= 0) newDataItem.Timestamp = UnixDateTime.Now; - _dataItemsBuffer.Add(key, newDataItem); - } - - private bool WriteBufferDataItems(int count = 1000) - { - var dataItems = _dataItemsBuffer.Take(count); - if (!dataItems.IsNullOrEmpty()) - { - var sendDataItems = new List(); - foreach (var dataItem in dataItems) - { - var sendDataItem = new ShdrDataItem(dataItem); - if (!OutputTimestamps) sendDataItem.Timestamp = 0; - sendDataItems.Add(sendDataItem); - } - - // Create SHDR string to send - var shdrLine = ShdrDataItem.ToString(sendDataItems); - - var success = WriteLine(shdrLine); - if (success) - { - // Update Last Sent DataItems - UpdateLastDataItems(dataItems); - } - } - - return false; - } - - #endregion - - #region "Messages" - - protected override void OnMessageAdd(ShdrMessage message) - { - // Add to Buffer - var key = CreateUniqueId(message); - _messagesBuffer.Add(key, message); - } - - private bool WriteBufferMessages(int count = 1000) - { - var messages = _messagesBuffer.Take(count); - if (!messages.IsNullOrEmpty()) - { - var success = false; - - foreach (var message in messages) - { - // Create SHDR string to send - var shdrLine = message.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - if (success) - { - // Update Last Sent Messages - UpdateLastMessages(messages); - } - } - - return false; - } - - #endregion - - #region "Conditions" - - protected override void OnConditionAdd(ShdrCondition condition) - { - // Add to Buffer - var key = CreateUniqueId(condition); - _conditionsBuffer.Add(key, condition); - } - - private bool WriteBufferConditions(int count = 1000) - { - var conditions = _conditionsBuffer.Take(count); - if (!conditions.IsNullOrEmpty()) - { - var success = false; - - foreach (var condition in conditions) - { - // Create SHDR string to send - var shdrLine = condition.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - if (success) - { - // Update Last Sent Conditions - UpdateLastConditions(conditions); - } - } - - return false; - } - - #endregion - - #region "TimeSeries" - - protected override void OnTimeSeriesAdd(ShdrTimeSeries timeSeries) - { - // Add to Buffer - var key = CreateUniqueId(timeSeries); - _timeSeriesBuffer.Add(key, timeSeries); - } - - private bool WriteBufferTimeSeries(int count = 1000) - { - var timeSeries = _timeSeriesBuffer.Take(count); - if (!timeSeries.IsNullOrEmpty()) - { - var success = false; - - foreach (var item in timeSeries) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - if (success) - { - // Update Last Sent TimeSeries - UpdateLastTimeSeries(timeSeries); - } - } - - return false; - } - - #endregion - - #region "DataSet" - - protected override void OnDataSetAdd(ShdrDataSet dataSet) - { - // Add to Buffer - var key = CreateUniqueId(dataSet); - _dataSetsBuffer.Add(key, dataSet); - } - - private bool WriteBufferDataSets(int count = 1000) - { - var dataSets = _dataSetsBuffer.Take(count); - if (!dataSets.IsNullOrEmpty()) - { - var success = false; - - foreach (var item in dataSets) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - if (success) - { - // Update Last Sent DataSet - UpdateLastDataSets(dataSets); - } - } - - return false; - } - - #endregion - - #region "Table" - - protected override void OnTableAdd(ShdrTable table) - { - // Add to Buffer - var key = CreateUniqueId(table); - _tablesBuffer.Add(key, table); - } - - private bool WriteBufferTables(int count = 1000) - { - var tables = _tablesBuffer.Take(count); - if (!tables.IsNullOrEmpty()) - { - var success = false; - - foreach (var item in tables) - { - // Create SHDR string to send - var shdrLine = item.ToString(); - success = WriteLine(shdrLine); - if (!success) break; - } - - if (success) - { - // Update Last Sent Table - UpdateLastTables(tables); - } - } - - return false; - } - - #endregion - - - - private static ulong CreateUniqueId(IObservationInput observationInput) - { - if (observationInput != null) - { - var hashBytes = observationInput.ChangeIdWithTimestamp; - var hash = string.Concat(hashBytes.Select(b => b.ToString("x2"))); - return hash.GetUInt64Hash(); - } - - return 0; - } - - private static ulong CreateUniqueId(ShdrCondition condition) - { - if (condition != null) - { - var hashBytes = condition.ChangeIdWithTimestamp; - var hash = string.Concat(hashBytes.Select(b => b.ToString("x2"))); - return hash.GetUInt64Hash(); - } - - return 0; - } + public ShdrQueueAdapter(ShdrAdapterClientConfiguration configuration) : base(configuration, null, true) { } } } \ No newline at end of file diff --git a/libraries/MTConnect.NET-SHDR/MTConnect.NET-SHDR.csproj b/libraries/MTConnect.NET-SHDR/MTConnect.NET-SHDR.csproj index 27af8f89..04a4b0ce 100644 --- a/libraries/MTConnect.NET-SHDR/MTConnect.NET-SHDR.csproj +++ b/libraries/MTConnect.NET-SHDR/MTConnect.NET-SHDR.csproj @@ -53,13 +53,6 @@ true - - - - - - - @@ -73,10 +66,6 @@ - - - - True \