diff --git a/MTConnect.NET.sln b/MTConnect.NET.sln
index 450946b3..08e55d65 100644
--- a/MTConnect.NET.sln
+++ b/MTConnect.NET.sln
@@ -108,7 +108,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MTConnect.NET-Client-MQTT",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MTConnect.NET-Client-SHDR", "examples\MTConnect.NET-Client-SHDR\MTConnect.NET-Client-SHDR.csproj", "{A9DF36FC-4EF7-4BFB-B47D-F1C10227631A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MTConnect.NET-Agent-Embedded", "examples\MTConnect.NET-Agent-Embedded\MTConnect.NET-Agent-Embedded.csproj", "{24C98CF3-CC93-4696-A036-8FD1E16F2E7E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MTConnect.NET-Agent-Embedded", "examples\MTConnect.NET-Agent-Embedded\MTConnect.NET-Agent-Embedded.csproj", "{24C98CF3-CC93-4696-A036-8FD1E16F2E7E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/agent/MTConnect.NET-Agent/agent.config.yaml b/agent/MTConnect.NET-Agent/agent.config.yaml
index fbb3007b..298c73f4 100644
--- a/agent/MTConnect.NET-Agent/agent.config.yaml
+++ b/agent/MTConnect.NET-Agent/agent.config.yaml
@@ -81,23 +81,23 @@ modules:
# privateKeyPath: c:\test-cert\trakhound.key
# privateKeyPassword: trakhound
-# - mqtt-relay: # - Add MQTT Relay module (Document Structure)
-# server: localhost
-# port: 1883
-# currentInterval: 10000
-# sampleInterval: 500
-# documentFormat: JSON-CPPAGENT
-# topicPrefix: MTConnect/Document
-# topicStructure: Document
-
-- mqtt-relay: # - Add MQTT Relay module (Entity Structure)
+- mqtt-relay: # - Add MQTT Relay module (Document Structure)
server: localhost
port: 1883
currentInterval: 10000
sampleInterval: 500
- documentFormat: JSON
- topicPrefix: MTConnect/Entity
- topicStructure: Entity
+ documentFormat: JSON-CPPAGENT-MQTT
+ topicPrefix: MTConnect/Document
+ topicStructure: Document
+
+# - mqtt-relay: # - Add MQTT Relay module (Entity Structure)
+# server: localhost
+# port: 1883
+# currentInterval: 10000
+# sampleInterval: 500
+# documentFormat: JSON
+# topicPrefix: MTConnect/Entity
+# topicStructure: Entity
# - mqtt-relay: # - Add MQTT Relay module (TLS)
# server: localhost
diff --git a/build/AssemblyInfo.cs b/build/AssemblyInfo.cs
index c0e501d1..b2ba11b0 100644
--- a/build/AssemblyInfo.cs
+++ b/build/AssemblyInfo.cs
@@ -1,6 +1,6 @@
using System.Reflection;
-[assembly: AssemblyVersion("6.2.2")]
-[assembly: AssemblyFileVersion("6.2.2")]
+[assembly: AssemblyVersion("6.3.0")]
+[assembly: AssemblyFileVersion("6.3.0")]
[assembly: AssemblyCompany("TrakHound Inc.")]
[assembly: AssemblyCopyright("Copyright (c) 2024 TrakHound Inc., All Rights Reserved.")]
diff --git a/examples/MTConnect.NET-Agent-Embedded/MTConnect.NET-Agent-Embedded.csproj b/examples/MTConnect.NET-Agent-Embedded/MTConnect.NET-Agent-Embedded.csproj
index 972be305..79e5c6f0 100644
--- a/examples/MTConnect.NET-Agent-Embedded/MTConnect.NET-Agent-Embedded.csproj
+++ b/examples/MTConnect.NET-Agent-Embedded/MTConnect.NET-Agent-Embedded.csproj
@@ -5,7 +5,6 @@
net8.0
MTConnect.NET_Agent_Embedded
enable
- enable
diff --git a/examples/MTConnect.NET-Agent-Embedded/Program.cs b/examples/MTConnect.NET-Agent-Embedded/Program.cs
index 7a18df53..53aef55e 100644
--- a/examples/MTConnect.NET-Agent-Embedded/Program.cs
+++ b/examples/MTConnect.NET-Agent-Embedded/Program.cs
@@ -18,6 +18,7 @@ public class ModuleConfiguration
{
public string DeviceUuid { get; set; }
public string DeviceName { get; set; }
+ public string SerialNumber { get; set; }
}
@@ -46,12 +47,14 @@ public Module(IMTConnectAgentBroker agent, object configuration) : base(agent)
protected override IDevice OnAddDevice()
{
var device = new Device();
- device.Uuid = "7E647B2D-C6A3-40BF-9CE9-FB09834850C9";
- device.Id = "dev-001";
+ device.Uuid = _configuration.DeviceUuid;
+ device.Id = _configuration.DeviceName;
+ device.Name = _configuration.DeviceName;
device.Description = new Description()
{
Manufacturer = "ACME",
- Model = "dm-500"
+ Model = "dm-500",
+ SerialNumber = _configuration.SerialNumber
};
// Add an Availability DataItem to the Device
diff --git a/examples/MTConnect.NET-Agent-Embedded/agent.config.yaml b/examples/MTConnect.NET-Agent-Embedded/agent.config.yaml
index d36e92fa..fc9959d8 100644
--- a/examples/MTConnect.NET-Agent-Embedded/agent.config.yaml
+++ b/examples/MTConnect.NET-Agent-Embedded/agent.config.yaml
@@ -1,6 +1,9 @@
modules:
- demo:
+ deviceUuid: 7E647B2D-C6A3-40BF-9CE9-FB09834850C9
+ deviceName: dev-001
+ serialNumber: 123456
readInterval: 1000
- http-server:
diff --git a/examples/MTConnect.NET-Client-HTTP/Program.cs b/examples/MTConnect.NET-Client-HTTP/Program.cs
index 8b0ece42..af67f8dc 100644
--- a/examples/MTConnect.NET-Client-HTTP/Program.cs
+++ b/examples/MTConnect.NET-Client-HTTP/Program.cs
@@ -17,7 +17,9 @@ static void Main(string[] args)
static void DocumentClient()
{
//var client = new MTConnectHttpClient("http://mtconnect.mazakcorp.com/", 5719);
- var client = new MTConnectHttpClient("localhost", 5000);
+ //var client = new MTConnectHttpClient("localhost", 5006, "OKUMA-Lathe");
+ //var client = new MTConnectHttpClient("localhost", 5006);
+ var client = new MTConnectHttpClient("localhost", 5000, "Okuma-Lathe");
//var client = new MTConnectHttpClient("localhost", 5001);
client.Interval = 100;
//client.Heartbeat = 0;
@@ -40,8 +42,8 @@ static void DocumentClient()
{
Console.WriteLine($"Observation Received : {observation.DataItemId} : {string.Join(";", observation.Values.Select(o => o.Value))}");
- var validationResult = observation.Validate();
- Console.WriteLine($"Observation Validation : {observation.DataItemId} : {validationResult.IsValid} : {validationResult.Message}");
+ //var validationResult = observation.Validate();
+ //Console.WriteLine($"Observation Validation : {observation.DataItemId} : {validationResult.IsValid} : {validationResult.Message}");
}
}
}
@@ -57,8 +59,8 @@ static void DocumentClient()
{
Console.WriteLine($"Observation Received : {observation.DataItemId} : {string.Join(";", observation.Values.Select(o => o.Value))}");
- var validationResult = observation.Validate();
- Console.WriteLine($"Observation Validation : {observation.DataItemId} : {validationResult.IsValid} : {validationResult.Message}");
+ //var validationResult = observation.Validate();
+ //Console.WriteLine($"Observation Validation : {observation.DataItemId} : {validationResult.IsValid} : {validationResult.Message}");
}
}
}
@@ -72,7 +74,8 @@ static void DocumentClient()
}
};
- client.Start();
+ client.StartFromBuffer();
+ //client.Start();
}
static void EntityClient()
diff --git a/examples/MTConnect.NET-Client-MQTT/Program.cs b/examples/MTConnect.NET-Client-MQTT/Program.cs
index 21c68bfb..bbfb0db5 100644
--- a/examples/MTConnect.NET-Client-MQTT/Program.cs
+++ b/examples/MTConnect.NET-Client-MQTT/Program.cs
@@ -1,4 +1,6 @@
-using MTConnect.Formatters;
+using MTConnect.Configurations;
+using MTConnect.Formatters;
+using MTConnect.Observations;
namespace MTConnect.Clients.HTTP
{
@@ -14,53 +16,60 @@ static void Main(string[] args)
static void DocumentClient()
{
- var client = new MTConnectMqttClient("localhost", 1883);
+ var config = new MTConnectMqttClientConfiguration();
+ config.Server = "localhost";
+ config.Port = 1883;
+ config.TopicPrefix = "MTConnect/Document";
+
+ var client = new MTConnectMqttClient(config);
client.ClientStarted += (s, args) => { Console.WriteLine("Client Started"); };
client.ClientStopped += (s, args) => { Console.WriteLine("Client Stopped"); };
//client.MessageReceived += (topic, payload) => Console.WriteLine($"Message Received : {topic} : {payload.Length}");
+ client.DeviceReceived += (topic, device) => Console.WriteLine($"Device Received : {device.Uuid} : {device.Name}");
+ client.ObservationReceived += (topic, observation) => Console.WriteLine($"Observation Received : {observation.DataItemId} : {string.Join(";", observation.Values.Select(o => o.Value))}");
- client.ProbeReceived += (s, response) =>
- {
- foreach (var device in response.Devices) Console.WriteLine($"Device Received : {device.Uuid} : {device.Name}");
- };
+ //client.ProbeReceived += (s, response) =>
+ //{
+ // foreach (var device in response.Devices) Console.WriteLine($"Device Received : {device.Uuid} : {device.Name}");
+ //};
- client.CurrentReceived += (s, response) =>
- {
- foreach (var stream in response.Streams)
- {
- foreach (var componentStream in stream.ComponentStreams)
- {
- foreach (var observation in componentStream.Observations)
- {
- Console.WriteLine($"Observation Received : {observation.DataItemId} : {string.Join(";", observation.Values.Select(o => o.Value))}");
- }
- }
- }
- };
+ //client.CurrentReceived += (s, response) =>
+ //{
+ // foreach (var stream in response.Streams)
+ // {
+ // foreach (var componentStream in stream.ComponentStreams)
+ // {
+ // foreach (var observation in componentStream.Observations)
+ // {
+ // Console.WriteLine($"Observation Received : {observation.DataItemId} : {string.Join(";", observation.Values.Select(o => o.Value))}");
+ // }
+ // }
+ // }
+ //};
- client.SampleReceived += (s, response) =>
- {
- foreach (var stream in response.Streams)
- {
- foreach (var componentStream in stream.ComponentStreams)
- {
- foreach (var observation in componentStream.Observations)
- {
- Console.WriteLine($"Observation Received : {observation.DataItemId} : {string.Join(";", observation.Values.Select(o => o.Value))}");
- }
- }
- }
- };
+ //client.SampleReceived += (s, response) =>
+ //{
+ // foreach (var stream in response.Streams)
+ // {
+ // foreach (var componentStream in stream.ComponentStreams)
+ // {
+ // foreach (var observation in componentStream.Observations)
+ // {
+ // Console.WriteLine($"Observation Received : {observation.DataItemId} : {string.Join(";", observation.Values.Select(o => o.Value))}");
+ // }
+ // }
+ // }
+ //};
- client.AssetsReceived += (s, response) =>
- {
- foreach (var asset in response.Assets)
- {
- var result = EntityFormatter.Format("XML", asset);
- //if (result.Success) Console.WriteLine(System.Text.Encoding.UTF8.GetString(result.Content));
- }
- };
+ //client.AssetsReceived += (s, response) =>
+ //{
+ // foreach (var asset in response.Assets)
+ // {
+ // var result = EntityFormatter.Format("XML", asset);
+ // //if (result.Success) Console.WriteLine(System.Text.Encoding.UTF8.GetString(result.Content));
+ // }
+ //};
client.Start();
}
diff --git a/libraries/MTConnect.NET-Common/Adapters/IMTConnectAdapter.cs b/libraries/MTConnect.NET-Common/Adapters/IMTConnectAdapter.cs
index 262bbd3c..f64f3eff 100644
--- a/libraries/MTConnect.NET-Common/Adapters/IMTConnectAdapter.cs
+++ b/libraries/MTConnect.NET-Common/Adapters/IMTConnectAdapter.cs
@@ -60,6 +60,8 @@ public interface IMTConnectAdapter
///
bool SendLast(long timestamp = 0);
+ bool SendBuffer();
+
///
/// Set all items to Unavailable
diff --git a/libraries/MTConnect.NET-Common/Agents/IMTConnectAgentBroker.cs b/libraries/MTConnect.NET-Common/Agents/IMTConnectAgentBroker.cs
index bef6bbe5..bd2bb3db 100644
--- a/libraries/MTConnect.NET-Common/Agents/IMTConnectAgentBroker.cs
+++ b/libraries/MTConnect.NET-Common/Agents/IMTConnectAgentBroker.cs
@@ -129,6 +129,15 @@ public interface IMTConnectAgentBroker : IMTConnectAgent
/// MTConnectStreams Response Document
IStreamsResponseOutputDocument GetDeviceStreamsResponseDocument(ulong at, uint count = 0, Version mtconnectVersion = null, string deviceType = null);
+ ///
+ /// Get a MTConnectStreams Document containing all devices.
+ ///
+ /// A list of DataItemId's to specify what observations to include in the response
+ /// The maximum number of observations to include in the response
+ /// MTConnectStreams Response Document
+ IStreamsResponseOutputDocument GetDeviceStreamsResponseDocument(IEnumerable dataItemIds, uint count = 0, Version mtconnectVersion = null, string deviceType = null);
+
+
///
/// Get a MTConnectStreams Document containing all devices.
///
diff --git a/libraries/MTConnect.NET-Common/Agents/MTConnectAgent.cs b/libraries/MTConnect.NET-Common/Agents/MTConnectAgent.cs
index b4e991cd..fe37a0f8 100644
--- a/libraries/MTConnect.NET-Common/Agents/MTConnectAgent.cs
+++ b/libraries/MTConnect.NET-Common/Agents/MTConnectAgent.cs
@@ -43,8 +43,6 @@ public class MTConnectAgent : IMTConnectAgent, IDisposable
private readonly ConcurrentDictionary _currentObservations = new ConcurrentDictionary();
private readonly ConcurrentDictionary> _currentConditions = new ConcurrentDictionary>();
- //private readonly ConcurrentDictionary _currentObservations = new ConcurrentDictionary();
- //private readonly ConcurrentDictionary> _currentConditions = new ConcurrentDictionary>();
private readonly List _assetIds = new List();
private MTConnectAgentMetrics _metrics;
private readonly string _uuid;
diff --git a/libraries/MTConnect.NET-Common/Agents/MTConnectAgentBroker.cs b/libraries/MTConnect.NET-Common/Agents/MTConnectAgentBroker.cs
index a0c47d22..66bea397 100644
--- a/libraries/MTConnect.NET-Common/Agents/MTConnectAgentBroker.cs
+++ b/libraries/MTConnect.NET-Common/Agents/MTConnectAgentBroker.cs
@@ -608,7 +608,7 @@ public IDevicesResponseDocument GetDevicesResponseDocument(string deviceKey, Ver
#region "Internal"
- private IObservationBufferResults GetObservations(IEnumerable bufferKeys, ulong from = 0, ulong to = 0, ulong at = 0, uint count = 0)
+ private IObservationBufferResults GetObservations(IEnumerable bufferKeys, ulong from = 0, ulong to = 0, ulong? at = null, uint count = 0)
{
IObservationBufferResults results;
if (from > 0 || to > 0)
@@ -619,9 +619,9 @@ private IObservationBufferResults GetObservations(IEnumerable bufferKeys, u
{
results = _observationBuffer.GetObservations(bufferKeys, count: count);
}
- else if (at > 0)
+ else if (at.HasValue)
{
- results = _observationBuffer.GetCurrentObservations(bufferKeys, at);
+ results = _observationBuffer.GetCurrentObservations(bufferKeys, at.Value);
}
else
{
@@ -701,6 +701,45 @@ public IStreamsResponseOutputDocument GetDeviceStreamsResponseDocument(ulong at,
return null;
}
+ ///
+ /// Get a MTConnectStreams Document containing all devices.
+ ///
+ /// A list of DataItemId's to specify what observations to include in the response
+ /// The maximum number of observations to include in the response
+ /// MTConnectStreams Response Document
+ public IStreamsResponseOutputDocument GetDeviceStreamsResponseDocument(IEnumerable dataItemIds, uint count = 0, Version mtconnectVersion = null, string deviceType = null)
+ {
+ StreamsRequestReceived?.Invoke(null);
+
+ if (_observationBuffer != null)
+ {
+ var devices = GetDevices(deviceType);
+ if (!devices.IsNullOrEmpty())
+ {
+ // Create list of BufferKeys
+ var bufferKeys = new List();
+ foreach (var device in devices)
+ {
+ var deviceBufferKeys = GenerateBufferKeys(device.Uuid, dataItemIds);
+ if (!deviceBufferKeys.IsNullOrEmpty()) bufferKeys.AddRange(deviceBufferKeys);
+ }
+
+ // Query the Observation Buffer
+ var results = GetObservations(bufferKeys, count: count);
+
+ // Create Response Document
+ var document = CreateDeviceStreamsDocument(devices, ref results, mtconnectVersion);
+ if (document != null)
+ {
+ StreamsResponseSent?.Invoke(this, new EventArgs());
+ return document;
+ }
+ }
+ }
+
+ return null;
+ }
+
///
/// Get a MTConnectStreams Document containing all devices.
///
diff --git a/libraries/MTConnect.NET-Common/Buffers/MTConnectObservationBuffer.cs b/libraries/MTConnect.NET-Common/Buffers/MTConnectObservationBuffer.cs
index 134aefdb..e362f654 100644
--- a/libraries/MTConnect.NET-Common/Buffers/MTConnectObservationBuffer.cs
+++ b/libraries/MTConnect.NET-Common/Buffers/MTConnectObservationBuffer.cs
@@ -390,12 +390,14 @@ public IObservationBufferResults GetCurrentObservations(IEnumerable bufferK
lock (_lock)
{
- firstSequence = Math.Max(1, _sequence - BufferSize);
+ firstSequence = _sequence > BufferSize ? _sequence - BufferSize : 1;
lastSequence = _sequence > 1 ? _sequence - 1 : 1;
nextSequence = _sequence;
// Determine Indexes
- var atIndex = (int)(at - firstSequence);
+ int atIndex;
+ if (at < 1) atIndex = 0;
+ else atIndex = (int)(at - firstSequence);
if (_archiveObservations.Size > 0)
{
@@ -420,13 +422,21 @@ public IObservationBufferResults GetCurrentObservations(IEnumerable bufferK
// Get From Current Observations
if (_currentObservations.TryGetValue(oBufferKeys[i], out var observation))
{
- observations[i] = observation;
+ if (observation.IsValid)
+ {
+ if (at < 1 && observation.Sequence <= firstSequence) observations[i] = observation;
+ else if (observation.Sequence <= at) observations[i] = observation;
+ }
}
// Get From Current Observations
if (_currentConditions.TryGetValue(oBufferKeys[i], out var conditions))
{
- observations[i] = observation;
+ if (observation.IsValid)
+ {
+ if (at < 1 && observation.Sequence <= firstSequence) observations[i] = observation;
+ else if (observation.Sequence <= at) observations[i] = observation;
+ }
}
}
}
@@ -483,7 +493,6 @@ public IObservationBufferResults GetObservations(IEnumerable bufferKeys, ul
nextSequence = _sequence;
// Determine Indexes
- //var fromIndex = (int)Math.Max(0, from - firstSequence);
int fromIndex = from > firstSequence ? (int)(from - firstSequence) : 0;
int toIndex = (int)(lastSequence - firstSequence);
if (to > 0)
diff --git a/libraries/MTConnect.NET-Common/Devices/Component.cs b/libraries/MTConnect.NET-Common/Devices/Component.cs
index 38484b45..d28ae027 100644
--- a/libraries/MTConnect.NET-Common/Devices/Component.cs
+++ b/libraries/MTConnect.NET-Common/Devices/Component.cs
@@ -53,8 +53,13 @@ private struct IdFormatConfiguration
///
public IContainer Parent { get; set; }
+ ///
+ /// The Agent InstanceId that produced this Device
+ ///
+ public ulong InstanceId { get; set; }
- private string _hash;
+
+ private string _hash;
///
/// Condensed message digest from a secure one-way hash function. FIPS PUB 180-4
///
@@ -1461,12 +1466,14 @@ public static bool IsCompatible(IComponent component, Version mtconnectVersion)
return false;
}
- public static IComponent Process(IComponent component, Version mtconnectVersion)
+ public static Component Process(IComponent component, Version mtconnectVersion = null)
{
if (component != null)
{
+ var version = mtconnectVersion != null ? mtconnectVersion : MTConnectVersions.Max;
+
// Check Version Compatibilty
- if (component.MinimumVersion != null && mtconnectVersion < component.MinimumVersion) return null;
+ if (component.MinimumVersion != null && version < component.MinimumVersion) return null;
// Create a new Instance of the Component that will instantiate a new Derived class (if found)
var obj = Create(component.Type);
@@ -1482,18 +1489,18 @@ public static IComponent Process(IComponent component, Version mtconnectVersion)
{
var description = new Description();
description.Manufacturer = component.Description.Manufacturer;
- if (mtconnectVersion >= MTConnectVersions.Version12) description.Model = component.Description.Model;
+ if (version >= MTConnectVersions.Version12) description.Model = component.Description.Model;
description.SerialNumber = component.Description.SerialNumber;
description.Station = component.Description.Station;
description.Value = component.Description.Value;
obj.Description = description;
}
- if (mtconnectVersion < MTConnectVersions.Version12) obj.SampleRate = component.SampleRate;
- if (mtconnectVersion >= MTConnectVersions.Version12) obj.SampleInterval = component.SampleInterval;
- if (mtconnectVersion >= MTConnectVersions.Version13) obj.References = component.References;
- if (mtconnectVersion >= MTConnectVersions.Version17) obj.Configuration = component.Configuration;
- if (mtconnectVersion >= MTConnectVersions.Version18) obj.CoordinateSystemIdRef = component.CoordinateSystemIdRef;
+ if (version < MTConnectVersions.Version12) obj.SampleRate = component.SampleRate;
+ if (version >= MTConnectVersions.Version12) obj.SampleInterval = component.SampleInterval;
+ if (version >= MTConnectVersions.Version13) obj.References = component.References;
+ if (version >= MTConnectVersions.Version17) obj.Configuration = component.Configuration;
+ if (version >= MTConnectVersions.Version18) obj.CoordinateSystemIdRef = component.CoordinateSystemIdRef;
// Add DataItems
if (!component.DataItems.IsNullOrEmpty())
@@ -1502,7 +1509,7 @@ public static IComponent Process(IComponent component, Version mtconnectVersion)
foreach (var dataItem in component.DataItems)
{
- var dataItemObj = DataItem.Process(dataItem, mtconnectVersion);
+ var dataItemObj = DataItem.Process(dataItem, version);
if (dataItemObj != null) dataItems.Add(dataItemObj);
}
@@ -1516,7 +1523,7 @@ public static IComponent Process(IComponent component, Version mtconnectVersion)
foreach (var composition in component.Compositions)
{
- var compositionObj = Composition.Process(composition, mtconnectVersion);
+ var compositionObj = Composition.Process(composition, version);
if (compositionObj != null) compositions.Add(compositionObj);
}
@@ -1530,7 +1537,7 @@ public static IComponent Process(IComponent component, Version mtconnectVersion)
foreach (var subcomponent in component.Components)
{
- var subcomponentObj = Process(subcomponent, mtconnectVersion);
+ var subcomponentObj = Process(subcomponent, version);
if (subcomponentObj != null) subcomponents.Add(subcomponentObj);
}
diff --git a/libraries/MTConnect.NET-Common/Devices/Composition.cs b/libraries/MTConnect.NET-Common/Devices/Composition.cs
index edb38e66..962845f7 100644
--- a/libraries/MTConnect.NET-Common/Devices/Composition.cs
+++ b/libraries/MTConnect.NET-Common/Devices/Composition.cs
@@ -43,11 +43,16 @@ public string Hash
}
}
+ ///
+ /// The Agent InstanceId that produced this Device
+ ///
+ public ulong InstanceId { get; set; }
- ///
- /// The text description that describes what the Composition Type represents
- ///
- public virtual string TypeDescription => DescriptionText;
+
+ ///
+ /// The text description that describes what the Composition Type represents
+ ///
+ public virtual string TypeDescription => DescriptionText;
///
@@ -338,12 +343,14 @@ private static Dictionary GetAllTypes()
}
- public static IComposition Process(IComposition composition, Version mtconnectVersion)
+ public static Composition Process(IComposition composition, Version mtconnectVersion = null)
{
if (composition != null)
{
+ var version = mtconnectVersion != null ? mtconnectVersion : MTConnectVersions.Max;
+
// Check Version Compatibilty
- if (composition.MinimumVersion != null && mtconnectVersion < composition.MinimumVersion) return null;
+ if (composition.MinimumVersion != null && version < composition.MinimumVersion) return null;
// Create a new Instance of the Composition that will instantiate a new Derived class (if found)
var obj = Create(composition.Type);
@@ -359,18 +366,18 @@ public static IComposition Process(IComposition composition, Version mtconnectVe
{
var description = new Description();
description.Manufacturer = composition.Description.Manufacturer;
- if (mtconnectVersion >= MTConnectVersions.Version12) description.Model = composition.Description.Model;
+ if (version >= MTConnectVersions.Version12) description.Model = composition.Description.Model;
description.SerialNumber = composition.Description.SerialNumber;
description.Station = composition.Description.Station;
description.Value = composition.Description.Value;
obj.Description = description;
}
- if (mtconnectVersion < MTConnectVersions.Version12) obj.SampleRate = composition.SampleRate;
- if (mtconnectVersion >= MTConnectVersions.Version12) obj.SampleInterval = composition.SampleInterval;
- if (mtconnectVersion >= MTConnectVersions.Version13) obj.References = composition.References;
- if (mtconnectVersion >= MTConnectVersions.Version17) obj.Configuration = composition.Configuration;
- if (mtconnectVersion >= MTConnectVersions.Version18) obj.CoordinateSystemIdRef = composition.CoordinateSystemIdRef;
+ if (version < MTConnectVersions.Version12) obj.SampleRate = composition.SampleRate;
+ if (version >= MTConnectVersions.Version12) obj.SampleInterval = composition.SampleInterval;
+ if (version >= MTConnectVersions.Version13) obj.References = composition.References;
+ if (version >= MTConnectVersions.Version17) obj.Configuration = composition.Configuration;
+ if (version >= MTConnectVersions.Version18) obj.CoordinateSystemIdRef = composition.CoordinateSystemIdRef;
// Add DataItems
if (!composition.DataItems.IsNullOrEmpty())
@@ -379,7 +386,7 @@ public static IComposition Process(IComposition composition, Version mtconnectVe
foreach (var dataItem in composition.DataItems)
{
- var dataItemObj = DataItem.Process(dataItem, mtconnectVersion);
+ var dataItemObj = DataItem.Process(dataItem, version);
if (dataItemObj != null) dataItems.Add(dataItemObj);
}
diff --git a/libraries/MTConnect.NET-Common/Devices/DataItem.cs b/libraries/MTConnect.NET-Common/Devices/DataItem.cs
index 82176f11..b61211da 100644
--- a/libraries/MTConnect.NET-Common/Devices/DataItem.cs
+++ b/libraries/MTConnect.NET-Common/Devices/DataItem.cs
@@ -58,8 +58,13 @@ public string Uuid
///
public IContainer Container { get; set; }
+ ///
+ /// The Agent InstanceId that produced this Device
+ ///
+ public ulong InstanceId { get; set; }
+
- private string _hash;
+ private string _hash;
///
/// Condensed message digest from a secure one-way hash function. FIPS PUB 180-4
///
@@ -258,12 +263,12 @@ public static string GenerateTypePath(IDataItem dataItem)
}
- public IDataItem Process(Version mtconnectVersion)
+ public DataItem Process(Version mtconnectVersion)
{
return Process(this, mtconnectVersion);
}
- protected virtual IDataItem OnProcess(IDataItem dataItem, Version mtconnectVersion)
+ protected virtual DataItem OnProcess(DataItem dataItem, Version mtconnectVersion)
{
return dataItem;
}
@@ -484,12 +489,12 @@ public static string GetPascalCaseType(string type)
switch (type)
{
- case Devices.DataItems.AdapterUriDataItem.TypeId: return "AdapterURI";
- case Devices.DataItems.MTConnectVersionDataItem.TypeId: return "MTConnectVersion";
- case Devices.DataItems.AmperageACDataItem.TypeId: return "AmperageAC";
- case Devices.DataItems.AmperageDCDataItem.TypeId: return "AmperageDC";
- case Devices.DataItems.VoltageACDataItem.TypeId: return "VoltageAC";
- case Devices.DataItems.VoltageDCDataItem.TypeId: return "VoltageDC";
+ case AdapterUriDataItem.TypeId: return "AdapterURI";
+ case MTConnectVersionDataItem.TypeId: return "MTConnectVersion";
+ case AmperageACDataItem.TypeId: return "AmperageAC";
+ case AmperageDCDataItem.TypeId: return "AmperageDC";
+ case VoltageACDataItem.TypeId: return "VoltageAC";
+ case VoltageDCDataItem.TypeId: return "VoltageDC";
}
lock (_lock)
@@ -554,25 +559,29 @@ public static DataItem Create(Type type)
{
if (type != null)
{
- var constructor = type.GetConstructor(System.Type.EmptyTypes);
- if (constructor != null)
+ try
{
- try
+ var constructor = type.GetConstructor(System.Type.EmptyTypes);
+ if (constructor != null)
{
+
return (DataItem)Activator.CreateInstance(type);
}
- catch { }
}
- }
+ catch { }
+ }
return new DataItem();
}
public static IEnumerable GetTypes()
{
- if (_types == null) _types = GetAllTypes();
+ lock (_lock)
+ {
+ if (_types == null) _types = GetAllTypes();
- return _types.Keys;
+ return _types.Keys;
+ }
}
public static IEnumerable GetConditionTypes()
@@ -718,9 +727,14 @@ public static IEnumerable> GetSubTypeDescriptions()
{
if (_subtypeDescriptions == null)
{
- if (_types == null) _types = GetAllTypes();
+ bool typesFound;
+ lock (_lock)
+ {
+ if (_types == null) _types = GetAllTypes();
+ typesFound = !_types.IsNullOrEmpty();
+ }
- if (!_types.IsNullOrEmpty())
+ if (typesFound)
{
_subtypeDescriptions = new Dictionary();
@@ -850,19 +864,16 @@ public static Type GetDataItemType(string type)
{
if (!string.IsNullOrEmpty(type))
{
- if (_types == null) _types = GetAllTypes();
-
- if (_types != null)
+ lock (_lock)
{
- string typeId;
- lock (_lock)
+ // Initialize Type List
+ if (_types == null) _types = GetAllTypes();
+
+ _typeIds.TryGetValue(type, out string typeId);
+ if (typeId == null)
{
- _typeIds.TryGetValue(type, out typeId);
- if (typeId == null)
- {
- typeId = type.ToPascalCase();
- _typeIds.Add(type, typeId);
- }
+ typeId = type.ToPascalCase();
+ _typeIds.Add(type, typeId);
}
if (_types.TryGetValue(typeId, out Type t))
@@ -1009,27 +1020,29 @@ public static bool IsCompatible(IDataItem dataItem, Version mtconnectVersion)
return false;
}
- public static IDataItem Process(IDataItem dataItem, Version mtconnectVersion)
+ public static DataItem Process(IDataItem dataItem, Version mtconnectVersion = null)
{
if (dataItem != null)
{
+ var version = mtconnectVersion != null ? mtconnectVersion : MTConnectVersions.Max;
+
// Check Version Compatibilty
- if (dataItem.MinimumVersion != null && mtconnectVersion < dataItem.MinimumVersion) return null;
+ if (dataItem.MinimumVersion != null && version < dataItem.MinimumVersion) return null;
// Don't return if Condition and Version < 1.1
- if (dataItem.Category == DataItemCategory.CONDITION && mtconnectVersion < MTConnectVersions.Version11) return null;
+ if (dataItem.Category == DataItemCategory.CONDITION && version < MTConnectVersions.Version11) return null;
// Don't return if TimeSeries and Version < 1.2
- if (dataItem.Representation == DataItemRepresentation.TIME_SERIES && mtconnectVersion < MTConnectVersions.Version12) return null;
+ if (dataItem.Representation == DataItemRepresentation.TIME_SERIES && version < MTConnectVersions.Version12) return null;
// Don't return if Discrete and Version < 1.3 OR Version >= 1.5
- if (dataItem.Representation == DataItemRepresentation.DISCRETE && (mtconnectVersion < MTConnectVersions.Version13 || mtconnectVersion >= MTConnectVersions.Version15)) return null;
+ if (dataItem.Representation == DataItemRepresentation.DISCRETE && (version < MTConnectVersions.Version13 || version >= MTConnectVersions.Version15)) return null;
// Don't return if DataSet and Version < 1.3
- if (dataItem.Representation == DataItemRepresentation.DATA_SET && mtconnectVersion < MTConnectVersions.Version13) return null;
+ if (dataItem.Representation == DataItemRepresentation.DATA_SET && version < MTConnectVersions.Version13) return null;
// Don't return if Table and Version < 1.6
- if (dataItem.Representation == DataItemRepresentation.TABLE && mtconnectVersion < MTConnectVersions.Version16) return null;
+ if (dataItem.Representation == DataItemRepresentation.TABLE && version < MTConnectVersions.Version16) return null;
// Create a new Instance of the DataItem that will instantiate a new Derived class (if found)
var obj = Create(dataItem.Type);
@@ -1048,14 +1061,14 @@ public static IDataItem Process(IDataItem dataItem, Version mtconnectVersion)
obj.Device = dataItem.Device;
// Check SampleRate
- if (mtconnectVersion >= MTConnectVersions.Version12) obj.SampleRate = dataItem.SampleRate;
+ if (version >= MTConnectVersions.Version12) obj.SampleRate = dataItem.SampleRate;
// Check Source
- if (dataItem.Source != null && mtconnectVersion >= MTConnectVersions.Version12)
+ if (dataItem.Source != null && version >= MTConnectVersions.Version12)
{
var source = new Source();
source.ComponentId = dataItem.Source.ComponentId;
- if (mtconnectVersion >= MTConnectVersions.Version14) source.CompositionId = dataItem.Source.CompositionId;
+ if (version >= MTConnectVersions.Version14) source.CompositionId = dataItem.Source.CompositionId;
source.DataItemId = dataItem.Source.DataItemId;
if (!string.IsNullOrEmpty(source.ComponentId) || !string.IsNullOrEmpty(source.CompositionId) || !string.IsNullOrEmpty(source.DataItemId))
@@ -1065,7 +1078,7 @@ public static IDataItem Process(IDataItem dataItem, Version mtconnectVersion)
}
// Check Relationships
- if (dataItem.Relationships != null && mtconnectVersion >= MTConnectVersions.Version15)
+ if (dataItem.Relationships != null && version >= MTConnectVersions.Version15)
{
var relationships = new List();
foreach (var relationship in dataItem.Relationships)
@@ -1079,7 +1092,7 @@ public static IDataItem Process(IDataItem dataItem, Version mtconnectVersion)
// DataItem Relationship
if (relationship.GetType() == typeof(DataItemRelationship))
{
- if (mtconnectVersion >= MTConnectVersions.Version17) relationships.Add(relationship);
+ if (version >= MTConnectVersions.Version17) relationships.Add(relationship);
}
// Device Relationship
@@ -1091,7 +1104,7 @@ public static IDataItem Process(IDataItem dataItem, Version mtconnectVersion)
// Specification Relationship
if (relationship.GetType() == typeof(SpecificationRelationship))
{
- if (mtconnectVersion >= MTConnectVersions.Version17) relationships.Add(relationship);
+ if (version >= MTConnectVersions.Version17) relationships.Add(relationship);
}
}
@@ -1099,19 +1112,19 @@ public static IDataItem Process(IDataItem dataItem, Version mtconnectVersion)
}
// Check Representation
- if (mtconnectVersion >= MTConnectVersions.Version12) obj.Representation = dataItem.Representation;
+ if (version >= MTConnectVersions.Version12) obj.Representation = dataItem.Representation;
// Check ResetTrigger
- if (mtconnectVersion >= MTConnectVersions.Version14) obj.ResetTrigger = dataItem.ResetTrigger;
+ if (version >= MTConnectVersions.Version14) obj.ResetTrigger = dataItem.ResetTrigger;
// Check CoordinateSystem
- if (mtconnectVersion < MTConnectVersions.Version20) obj.CoordinateSystem = dataItem.CoordinateSystem;
+ if (version < MTConnectVersions.Version20) obj.CoordinateSystem = dataItem.CoordinateSystem;
// Check CoordinateSystemIdRef
- if (mtconnectVersion >= MTConnectVersions.Version15) obj.CoordinateSystemIdRef = dataItem.CoordinateSystemIdRef;
+ if (version >= MTConnectVersions.Version15) obj.CoordinateSystemIdRef = dataItem.CoordinateSystemIdRef;
// Check CompositionId
- if (mtconnectVersion >= MTConnectVersions.Version14)
+ if (version >= MTConnectVersions.Version14)
{
obj.CompositionId = dataItem.CompositionId;
}
@@ -1122,26 +1135,26 @@ public static IDataItem Process(IDataItem dataItem, Version mtconnectVersion)
}
// Check Constraints
- if (mtconnectVersion >= MTConnectVersions.Version11) obj.Constraints = dataItem.Constraints;
+ if (version >= MTConnectVersions.Version11) obj.Constraints = dataItem.Constraints;
// Check Definition
- if (mtconnectVersion >= MTConnectVersions.Version16) obj.Definition = dataItem.Definition;
+ if (version >= MTConnectVersions.Version16) obj.Definition = dataItem.Definition;
// Check Statistic
- if (mtconnectVersion >= MTConnectVersions.Version12) obj.Statistic = dataItem.Statistic;
+ if (version >= MTConnectVersions.Version12) obj.Statistic = dataItem.Statistic;
// Check Filters
- if (mtconnectVersion >= MTConnectVersions.Version13) obj.Filters = dataItem.Filters;
+ if (version >= MTConnectVersions.Version13) obj.Filters = dataItem.Filters;
// Check InitialValue
- if (mtconnectVersion >= MTConnectVersions.Version14) obj.InitialValue = dataItem.InitialValue;
+ if (version >= MTConnectVersions.Version14) obj.InitialValue = dataItem.InitialValue;
// Check Discrete
- if (mtconnectVersion >= MTConnectVersions.Version15) obj.Discrete = dataItem.Discrete;
+ if (version >= MTConnectVersions.Version15) obj.Discrete = dataItem.Discrete;
}
// Call overridable method (used to process based on Type)
- return obj.OnProcess(obj, mtconnectVersion);
+ return obj.OnProcess(obj, version);
}
return null;
diff --git a/libraries/MTConnect.NET-Common/Devices/Device.cs b/libraries/MTConnect.NET-Common/Devices/Device.cs
index df126f08..56c28b38 100644
--- a/libraries/MTConnect.NET-Common/Devices/Device.cs
+++ b/libraries/MTConnect.NET-Common/Devices/Device.cs
@@ -996,17 +996,19 @@ public void RemoveDataItem(string dataItemId)
#endregion
- public static Device Process(IDevice device, Version mtconnectVersion)
+ public static Device Process(IDevice device, Version mtconnectVersion = null)
{
if (device != null)
{
+ var version = mtconnectVersion != null ? mtconnectVersion : MTConnectVersions.Max;
+
Device obj = null;
if (device.Type == TypeId) obj = new Device();
else if (device.Type == Agent.TypeId) obj = new Agent();
// Don't Ouput Agent Device if Version < 1.7
- if (device.Type == Agent.TypeId && mtconnectVersion < MTConnectVersions.Version17) return null;
+ if (device.Type == Agent.TypeId && version < MTConnectVersions.Version17) return null;
if (obj != null)
{
@@ -1023,21 +1025,21 @@ public static Device Process(IDevice device, Version mtconnectVersion)
{
var description = new Description();
description.Manufacturer = device.Description.Manufacturer;
- if (mtconnectVersion >= MTConnectVersions.Version12) description.Model = device.Description.Model;
+ if (version >= MTConnectVersions.Version12) description.Model = device.Description.Model;
description.SerialNumber = device.Description.SerialNumber;
description.Station = device.Description.Station;
description.Value = device.Description.Value;
obj.Description = description;
}
- if (mtconnectVersion < MTConnectVersions.Version12) obj.Iso841Class = device.Iso841Class;
- if (mtconnectVersion < MTConnectVersions.Version12) obj.SampleRate = device.SampleRate;
- if (mtconnectVersion >= MTConnectVersions.Version12) obj.SampleInterval = device.SampleInterval;
- if (mtconnectVersion >= MTConnectVersions.Version13) obj.References = device.References;
- if (mtconnectVersion >= MTConnectVersions.Version17) obj.Configuration = device.Configuration;
- if (mtconnectVersion >= MTConnectVersions.Version18) obj.CoordinateSystemIdRef = device.CoordinateSystemIdRef;
- if (mtconnectVersion >= MTConnectVersions.Version17) obj.MTConnectVersion = device.MTConnectVersion != null ? device.MTConnectVersion : mtconnectVersion;
- if (mtconnectVersion >= MTConnectVersions.Version22) obj.Hash = device.Hash;
+ if (version < MTConnectVersions.Version12) obj.Iso841Class = device.Iso841Class;
+ if (version < MTConnectVersions.Version12) obj.SampleRate = device.SampleRate;
+ if (version >= MTConnectVersions.Version12) obj.SampleInterval = device.SampleInterval;
+ if (version >= MTConnectVersions.Version13) obj.References = device.References;
+ if (version >= MTConnectVersions.Version17) obj.Configuration = device.Configuration;
+ if (version >= MTConnectVersions.Version18) obj.CoordinateSystemIdRef = device.CoordinateSystemIdRef;
+ if (version >= MTConnectVersions.Version17) obj.MTConnectVersion = device.MTConnectVersion != null ? device.MTConnectVersion : version;
+ if (version >= MTConnectVersions.Version22) obj.Hash = device.Hash;
// Add DataItems
if (!device.DataItems.IsNullOrEmpty())
@@ -1046,7 +1048,7 @@ public static Device Process(IDevice device, Version mtconnectVersion)
foreach (var dataItem in device.DataItems)
{
- var dataItemObj = DataItem.Process(dataItem, mtconnectVersion);
+ var dataItemObj = DataItem.Process(dataItem, version);
if (dataItemObj != null) dataItems.Add(dataItemObj);
}
@@ -1060,7 +1062,7 @@ public static Device Process(IDevice device, Version mtconnectVersion)
foreach (var composition in device.Compositions)
{
- var compositionObj = Composition.Process(composition, mtconnectVersion);
+ var compositionObj = Composition.Process(composition, version);
if (compositionObj != null) compositions.Add(compositionObj);
}
@@ -1074,7 +1076,7 @@ public static Device Process(IDevice device, Version mtconnectVersion)
foreach (var component in device.Components)
{
- var componentObj = Component.Process(component, mtconnectVersion);
+ var componentObj = Component.Process(component, version);
if (componentObj != null) components.Add(componentObj);
}
diff --git a/libraries/MTConnect.NET-Common/Devices/IContainer.cs b/libraries/MTConnect.NET-Common/Devices/IContainer.cs
index 42dc5bd0..02dcfff2 100644
--- a/libraries/MTConnect.NET-Common/Devices/IContainer.cs
+++ b/libraries/MTConnect.NET-Common/Devices/IContainer.cs
@@ -18,11 +18,15 @@ public partial interface IContainer : IMTConnectEntity
///
IContainer Parent { get; set; }
+ ///
+ /// The Agent InstanceId that produced this Device
+ ///
+ ulong InstanceId { get; }
- ///
- /// Condensed message digest from a secure one-way hash function. FIPS PUB 180-4
- ///
- string Hash { get; }
+ ///
+ /// Condensed message digest from a secure one-way hash function. FIPS PUB 180-4
+ ///
+ string Hash { get; }
///
///
diff --git a/libraries/MTConnect.NET-Common/Devices/IDataItem.cs b/libraries/MTConnect.NET-Common/Devices/IDataItem.cs
index 1d068e87..3487df16 100644
--- a/libraries/MTConnect.NET-Common/Devices/IDataItem.cs
+++ b/libraries/MTConnect.NET-Common/Devices/IDataItem.cs
@@ -20,11 +20,16 @@ public partial interface IDataItem : IMTConnectEntity
///
IContainer Container { get; }
+ ///
+ /// The Agent InstanceId that produced this Device
+ ///
+ ulong InstanceId { get; }
- ///
- /// Condensed message digest from a secure one-way hash function. FIPS PUB 180-4
- ///
- string Hash { get; }
+
+ ///
+ /// Condensed message digest from a secure one-way hash function. FIPS PUB 180-4
+ ///
+ string Hash { get; }
///
diff --git a/libraries/MTConnect.NET-Common/Devices/IDevice.cs b/libraries/MTConnect.NET-Common/Devices/IDevice.cs
index 98ddf388..0a272e27 100644
--- a/libraries/MTConnect.NET-Common/Devices/IDevice.cs
+++ b/libraries/MTConnect.NET-Common/Devices/IDevice.cs
@@ -5,11 +5,6 @@ namespace MTConnect.Devices
{
public partial interface IDevice : IComponent, IContainer
{
- ///
- /// The Agent InstanceId that produced this Device
- ///
- ulong InstanceId { get; }
-
///
/// DEPRECATED IN REL. 1.1
///
diff --git a/libraries/MTConnect.NET-Common/Observations/ConditionObservation.cs b/libraries/MTConnect.NET-Common/Observations/ConditionObservation.cs
index 949b3096..d93b7cdd 100644
--- a/libraries/MTConnect.NET-Common/Observations/ConditionObservation.cs
+++ b/libraries/MTConnect.NET-Common/Observations/ConditionObservation.cs
@@ -140,35 +140,39 @@ public static ConditionObservation Create(string type, DataItemRepresentation re
{
if (!string.IsNullOrEmpty(type))
{
- if (_types == null) _types = GetAllTypes();
-
- if (!_types.IsNullOrEmpty())
+ Type dataItemType = null;
+ lock (_typeLock)
{
- var key = string.Intern(type + ":" + (int)representation);
+ // Initialize Type List
+ if (_types == null) _types = GetAllTypes();
- // Lookup Type ID (Type as PascalCase)
- _typeIds.TryGetValue(key, out var typeId);
- if (typeId == null)
+ if (!_types.IsNullOrEmpty())
{
- typeId = $"{type.ToPascalCase()}{representation.ToString().ToPascalCase()}";
- _typeIds.Add(key, typeId);
+ var key = string.Intern(type + ":" + (int)representation);
+
+ // Lookup Type ID (Type as PascalCase)
+ _typeIds.TryGetValue(key, out string typeId);
+ if (typeId == null)
+ {
+ typeId = $"{type.ToPascalCase()}{representation.ToString().ToPascalCase()}";
+ _typeIds.Add(key, typeId);
+ }
+
+ _types.TryGetValue(key, out dataItemType);
}
+ }
- if (_types.TryGetValue(key, out Type t))
+ if (dataItemType != null)
+ {
+ try
{
- var constructor = t.GetConstructor(System.Type.EmptyTypes);
- if (constructor != null)
+ var constructor = dataItemType.GetConstructor(System.Type.EmptyTypes);
+ if (constructor != null && representation == DataItemRepresentation.VALUE)
{
- try
- {
- switch (representation)
- {
- case DataItemRepresentation.VALUE: return (ConditionObservation)Activator.CreateInstance(t);
- }
- }
- catch { }
+ return (ConditionObservation)Activator.CreateInstance(dataItemType);
}
}
+ catch { }
}
}
diff --git a/libraries/MTConnect.NET-Common/Observations/EventObservation.cs b/libraries/MTConnect.NET-Common/Observations/EventObservation.cs
index 0495cb5f..c5be3525 100644
--- a/libraries/MTConnect.NET-Common/Observations/EventObservation.cs
+++ b/libraries/MTConnect.NET-Common/Observations/EventObservation.cs
@@ -79,37 +79,44 @@ public static EventObservation Create(string type, DataItemRepresentation repres
{
if (!string.IsNullOrEmpty(type))
{
- if (_types == null) _types = GetAllTypes();
-
- if (!_types.IsNullOrEmpty())
+ Type dataItemType = null;
+ lock (_typeLock)
{
- var key = string.Intern(type + ":" + (int)representation);
+ // Initialize Type List
+ if (_types == null) _types = GetAllTypes();
- // Lookup Type ID (Type as PascalCase)
- _typeIds.TryGetValue(key, out var typeId);
- if (typeId == null)
+ if (!_types.IsNullOrEmpty())
{
- typeId = $"{type.ToPascalCase()}{representation.ToString().ToPascalCase()}";
- _typeIds.Add(key, typeId);
+ var key = string.Intern(type + ":" + (int)representation);
+
+ // Lookup Type ID (Type as PascalCase)
+ _typeIds.TryGetValue(key, out string typeId);
+ if (typeId == null)
+ {
+ typeId = $"{type.ToPascalCase()}{representation.ToString().ToPascalCase()}";
+ _typeIds.Add(key, typeId);
+ }
+
+ _types.TryGetValue(key, out dataItemType);
}
+ }
- if (_types.TryGetValue(key, out Type t))
+ if (dataItemType != null)
+ {
+ try
{
- var constructor = t.GetConstructor(System.Type.EmptyTypes);
+ var constructor = dataItemType.GetConstructor(System.Type.EmptyTypes);
if (constructor != null)
{
- try
+ switch (representation)
{
- switch (representation)
- {
- case DataItemRepresentation.VALUE: return (EventValueObservation)Activator.CreateInstance(t);
- case DataItemRepresentation.DATA_SET: return (EventDataSetObservation)Activator.CreateInstance(t);
- case DataItemRepresentation.TABLE: return (EventTableObservation)Activator.CreateInstance(t);
- }
+ case DataItemRepresentation.VALUE: return (EventValueObservation)Activator.CreateInstance(dataItemType);
+ case DataItemRepresentation.DATA_SET: return (EventDataSetObservation)Activator.CreateInstance(dataItemType);
+ case DataItemRepresentation.TABLE: return (EventTableObservation)Activator.CreateInstance(dataItemType);
}
- catch { }
}
}
+ catch { }
}
}
diff --git a/libraries/MTConnect.NET-Common/Observations/Observation.cs b/libraries/MTConnect.NET-Common/Observations/Observation.cs
index cf3b6303..2566750d 100644
--- a/libraries/MTConnect.NET-Common/Observations/Observation.cs
+++ b/libraries/MTConnect.NET-Common/Observations/Observation.cs
@@ -24,11 +24,12 @@ public class Observation : IObservation
private const string UppercaseValuePattern = "^[a-zA-Z_]*$";
private static readonly Regex _uppercaseValueRegex = new Regex(UppercaseValuePattern);
- protected static readonly Dictionary _typeIds = new Dictionary();
+ protected static readonly Dictionary _typeIds = new Dictionary();
protected static Dictionary _types;
+ protected static readonly object _typeLock = new object();
- private readonly object _lock = new object();
+ protected readonly object _valueLock = new object();
protected readonly Dictionary _values = new Dictionary();
@@ -224,7 +225,7 @@ public string GetValue(string valueKey)
try
{
ObservationValue value;
- lock (_lock) _values.TryGetValue(valueKey, out value);
+ lock (_valueLock) _values.TryGetValue(valueKey, out value);
return value.Value;
}
catch { }
@@ -258,7 +259,7 @@ public void AddValue(ObservationValue observationValue)
{
try
{
- lock (_lock)
+ lock (_valueLock)
{
_values.Remove(observationValue.Key);
_values.Add(observationValue.Key, observationValue);
diff --git a/libraries/MTConnect.NET-Common/Observations/SampleObservation.cs b/libraries/MTConnect.NET-Common/Observations/SampleObservation.cs
index 6551cb15..132cb1c7 100644
--- a/libraries/MTConnect.NET-Common/Observations/SampleObservation.cs
+++ b/libraries/MTConnect.NET-Common/Observations/SampleObservation.cs
@@ -127,8 +127,10 @@ public static SampleObservation Create(IObservation observation)
public static SampleObservation Create(string type, DataItemRepresentation representation)
{
- if (!string.IsNullOrEmpty(type))
+ Type dataItemType = null;
+ lock (_typeLock)
{
+ // Initialize Type List
if (_types == null) _types = GetAllTypes();
if (!_types.IsNullOrEmpty())
@@ -136,32 +138,34 @@ public static SampleObservation Create(string type, DataItemRepresentation repre
var key = string.Intern(type + ":" + (int)representation);
// Lookup Type ID (Type as PascalCase)
- _typeIds.TryGetValue(key, out var typeId);
+ _typeIds.TryGetValue(key, out string typeId);
if (typeId == null)
{
typeId = $"{type.ToPascalCase()}{representation.ToString().ToPascalCase()}";
_typeIds.Add(key, typeId);
}
- if (_types.TryGetValue(typeId, out Type t))
+ _types.TryGetValue(key, out dataItemType);
+ }
+ }
+
+ if (dataItemType != null)
+ {
+ try
+ {
+ var constructor = dataItemType.GetConstructor(System.Type.EmptyTypes);
+ if (constructor != null)
{
- var constructor = t.GetConstructor(System.Type.EmptyTypes);
- if (constructor != null)
+ switch (representation)
{
- try
- {
- switch (representation)
- {
- case DataItemRepresentation.VALUE: return (SampleValueObservation)Activator.CreateInstance(t);
- case DataItemRepresentation.DATA_SET: return (SampleDataSetObservation)Activator.CreateInstance(t);
- case DataItemRepresentation.TABLE: return (SampleTableObservation)Activator.CreateInstance(t);
- case DataItemRepresentation.TIME_SERIES: return (SampleTimeSeriesObservation)Activator.CreateInstance(t);
- }
- }
- catch { }
+ case DataItemRepresentation.VALUE: return (SampleValueObservation)Activator.CreateInstance(dataItemType);
+ case DataItemRepresentation.DATA_SET: return (SampleDataSetObservation)Activator.CreateInstance(dataItemType);
+ case DataItemRepresentation.TABLE: return (SampleTableObservation)Activator.CreateInstance(dataItemType);
+ case DataItemRepresentation.TIME_SERIES: return (SampleTimeSeriesObservation)Activator.CreateInstance(dataItemType);
}
}
}
+ catch { }
}
switch (representation)
diff --git a/libraries/MTConnect.NET-Common/Streams/ComponentStream.cs b/libraries/MTConnect.NET-Common/Streams/ComponentStream.cs
index 04d7754e..8884491c 100644
--- a/libraries/MTConnect.NET-Common/Streams/ComponentStream.cs
+++ b/libraries/MTConnect.NET-Common/Streams/ComponentStream.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Devices;
@@ -9,7 +9,7 @@
namespace MTConnect.Streams
{
///
- /// ComponentStream is a XML container that organizes the data associated with each Structural Element defined for that piece of equipment in the associated MTConnectDevices XML document
+ /// Organizes the data associated with each Component entity defined for a Device in the associated MTConnectDevices Response Document.
///
public class ComponentStream : IComponentStream
{
diff --git a/libraries/MTConnect.NET-Common/Streams/DeviceStream.cs b/libraries/MTConnect.NET-Common/Streams/DeviceStream.cs
index 1f089157..ab22af5e 100644
--- a/libraries/MTConnect.NET-Common/Streams/DeviceStream.cs
+++ b/libraries/MTConnect.NET-Common/Streams/DeviceStream.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Observations;
@@ -7,22 +7,22 @@
namespace MTConnect.Streams
{
///
- /// DeviceStream is a XML container that organizes data reported from a single piece of equipment.A DeviceStream element MUST be provided for each piece of equipment reporting data in an MTConnectStreams document.
+ /// Organizes data reported from a Device.
///
public class DeviceStream : IDeviceStream
{
///
- /// The name of an element or a piece of equipment. The name associated with the piece of equipment reporting the data contained in this DeviceStream container.
+ /// Name of the Device.
///
public string Name { get; set; }
///
- /// The uuid associated with the piece of equipment reporting the data contained in this DeviceStream container.
+ /// Uuid of the Device.
///
public string Uuid { get; set; }
///
- /// An XML container type element that organizes data returned from an Agent in response to a current or sample HTTP request.
+ /// Organizes the data associated with each Component entity defined for a Device in the associated MTConnectDevices Response Document.
///
public IEnumerable ComponentStreams { get; set; }
diff --git a/libraries/MTConnect.NET-Common/Streams/IComponentStream.cs b/libraries/MTConnect.NET-Common/Streams/IComponentStream.cs
index 832fd792..a1555336 100644
--- a/libraries/MTConnect.NET-Common/Streams/IComponentStream.cs
+++ b/libraries/MTConnect.NET-Common/Streams/IComponentStream.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Devices;
@@ -8,7 +8,7 @@
namespace MTConnect.Streams
{
///
- /// ComponentStream is a XML container that organizes the data associated with each Structural Element defined for that piece of equipment in the associated MTConnectDevices XML document
+ /// Organizes the data associated with each Component entity defined for a Device in the associated MTConnectDevices Response Document.
///
public interface IComponentStream
{
diff --git a/libraries/MTConnect.NET-Common/Streams/IDeviceStream.cs b/libraries/MTConnect.NET-Common/Streams/IDeviceStream.cs
index 6d74ff53..697e01e9 100644
--- a/libraries/MTConnect.NET-Common/Streams/IDeviceStream.cs
+++ b/libraries/MTConnect.NET-Common/Streams/IDeviceStream.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Observations;
@@ -7,22 +7,22 @@
namespace MTConnect.Streams
{
///
- /// DeviceStream is a XML container that organizes data reported from a single piece of equipment.A DeviceStream element MUST be provided for each piece of equipment reporting data in an MTConnectStreams document.
+ /// Organizes data reported from a Device.
///
public interface IDeviceStream
{
///
- /// The name of an element or a piece of equipment. The name associated with the piece of equipment reporting the data contained in this DeviceStream container.
+ /// Name of the Device.
///
string Name { get; }
///
- /// The uuid associated with the piece of equipment reporting the data contained in this DeviceStream container.
+ /// Uuid of the Device.
///
string Uuid { get; }
///
- /// An XML container type element that organizes data returned from an Agent in response to a current or sample HTTP request.
+ /// Organizes the data associated with each Component entity defined for a Device in the associated MTConnectDevices Response Document.
///
IEnumerable ComponentStreams { get; }
diff --git a/libraries/MTConnect.NET-Common/Streams/IStreamsResponseDocument.cs b/libraries/MTConnect.NET-Common/Streams/IStreamsResponseDocument.cs
index 6b5d1825..fea4b6a3 100644
--- a/libraries/MTConnect.NET-Common/Streams/IStreamsResponseDocument.cs
+++ b/libraries/MTConnect.NET-Common/Streams/IStreamsResponseDocument.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Headers;
@@ -9,17 +9,17 @@
namespace MTConnect.Streams
{
///
- /// The Streams Information Model provides a representation of the data reported by a piece of equipment used for a manufacturing process, or used for any other purpose.
+ /// Root entity of an MTConnectStreams Response Document that contains the Observation Information Model of one or more Device entities.
///
public interface IStreamsResponseDocument
{
///
- /// Contains the Header information in an MTConnect Streams XML document
+ /// Provides information from an agent defining version information, storage capacity, and parameters associated with the data management within the agent.
///
IMTConnectStreamsHeader Header { get; }
///
- /// Streams is a container type XML element used to group the data reported from one or more pieces of equipment into a single XML document.
+ /// Streams groups one or more DeviceStream entities.
///
IEnumerable Streams { get; }
diff --git a/libraries/MTConnect.NET-Common/Streams/StreamsResponseDocument.cs b/libraries/MTConnect.NET-Common/Streams/StreamsResponseDocument.cs
index 2c8df206..c4b5aad3 100644
--- a/libraries/MTConnect.NET-Common/Streams/StreamsResponseDocument.cs
+++ b/libraries/MTConnect.NET-Common/Streams/StreamsResponseDocument.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Headers;
@@ -9,17 +9,17 @@
namespace MTConnect.Streams
{
///
- /// The Streams Information Model provides a representation of the data reported by a piece of equipment used for a manufacturing process, or used for any other purpose.
+ /// Root entity of an MTConnectStreams Response Document that contains the Observation Information Model of one or more Device entities.
///
public class StreamsResponseDocument : IStreamsResponseDocument
{
///
- /// Contains the Header information in an MTConnect Streams XML document
+ /// Provides information from an agent defining version information, storage capacity, and parameters associated with the data management within the agent.
///
public IMTConnectStreamsHeader Header { get; set; }
///
- /// Streams is a container type XML element used to group the data reported from one or more pieces of equipment into a single XML document.
+ /// Streams groups one or more DeviceStream entities.
///
public IEnumerable Streams { get; set; }
diff --git a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs
index 38852eec..bfc91881 100644
--- a/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs
+++ b/libraries/MTConnect.NET-HTTP/Clients/MTConnectHttpClient.cs
@@ -5,6 +5,7 @@
using MTConnect.Devices;
using MTConnect.Errors;
using MTConnect.Formatters;
+using MTConnect.Headers;
using MTConnect.Http;
using MTConnect.Observations;
using MTConnect.Streams;
@@ -669,26 +670,6 @@ private async Task Worker()
}
}
- // Clear Cached DataItems and Components
- lock (_lock)
- {
- _cachedComponents.Clear();
- _cachedDataItems.Clear();
- }
-
- // Add to cached list
- if (!probe.Devices.IsNullOrEmpty())
- {
- foreach (var device in probe.Devices)
- {
- lock (_lock)
- {
- _devices.Remove(device.Uuid);
- _devices.Add(device.Uuid, device);
- }
- }
- }
-
if (UseStreaming)
{
// Run Current Request
@@ -843,14 +824,30 @@ private async Task Worker()
private void ProcessProbeDocument(IDevicesResponseDocument document)
{
- // Raise ProbeReceived Event
- ProbeReceived?.Invoke(this, document);
-
if (document != null && !document.Devices.IsNullOrEmpty())
{
+ // Clear Cached DataItems and Components
+ lock (_lock)
+ {
+ _cachedComponents.Clear();
+ _cachedDataItems.Clear();
+ }
+
+ // Raise ProbeReceived Event
+ ProbeReceived?.Invoke(this, document);
+
foreach (var device in document.Devices)
{
- DeviceReceived?.Invoke(this, device);
+ var outputDevice = ProcessDevice(document.Header, device);
+
+ // Add to cached list
+ lock (_lock)
+ {
+ _devices.Remove(outputDevice.Uuid);
+ _devices.Add(outputDevice.Uuid, outputDevice);
+ }
+
+ DeviceReceived?.Invoke(this, outputDevice);
}
}
}
@@ -862,33 +859,31 @@ private void ProcessCurrentDocument(IStreamsResponseDocument document, Cancellat
if (document != null)
{
- if (!document.Streams.IsNullOrEmpty())
+ if (document.Header != null && !document.Streams.IsNullOrEmpty())
{
- IDeviceStream deviceStream = null;
-
- // Get the DeviceStream for the Device or default to the first
- if (!string.IsNullOrEmpty(Device)) deviceStream = document.Streams.FirstOrDefault(o => o.Uuid == Device || o.Name == Device);
- else deviceStream = document.Streams.FirstOrDefault();
+ // Recreate Response Document (to set DataItem property for Observations)
+ var response = new StreamsResponseDocument();
+ response.Header = document.Header;
- var observations = deviceStream.Observations;
- if (deviceStream != null && !observations.IsNullOrEmpty())
+ var deviceStreams = new List();
+ foreach (var stream in document.Streams)
{
- // Recreate Response Document (to set DataItem property for Observations)
- var response = new StreamsResponseDocument();
- response.Header = document.Header;
+ deviceStreams.Add(ProcessDeviceStream(response.Header, stream));
+ }
+ response.Streams = deviceStreams;
- var deviceStreams = new List();
- foreach (var stream in document.Streams)
- {
- deviceStreams.Add(ProcessDeviceStream(stream));
- }
- response.Streams = deviceStreams;
- CheckAssetChanged(deviceStream.Observations, cancel);
+ CurrentReceived?.Invoke(this, response);
+
- CurrentReceived?.Invoke(this, response);
+ // Process Device Streams
+ foreach (var deviceStream in response.Streams)
+ {
+ // Check to see if any Assets have changed
+ CheckAssetChanged(deviceStream.Observations, cancel);
- observations = response.GetObservations();
+ // Get Observations from Device Stream
+ var observations = response.GetObservations();
if (!observations.IsNullOrEmpty())
{
foreach (var observation in observations)
@@ -908,37 +903,36 @@ private void ProcessSampleDocument(IStreamsResponseDocument document, Cancellati
if (document != null)
{
- // Set Agent Instance ID
- if (document.Header != null) _lastInstanceId = document.Header.InstanceId;
-
- if (!document.Streams.IsNullOrEmpty())
+ if (document.Header != null && !document.Streams.IsNullOrEmpty())
{
- IDeviceStream deviceStream = null;
+ // Set Agent Instance ID
+ _lastInstanceId = document.Header.InstanceId;
- // Get the DeviceStream for the Device or default to the first
- if (!string.IsNullOrEmpty(Device)) deviceStream = document.Streams.FirstOrDefault(o => o.Uuid == Device || o.Name == Device);
- else deviceStream = document.Streams.FirstOrDefault();
+ // Recreate Response Document (to set DataItem property for Observations)
+ var response = new StreamsResponseDocument();
+ response.Header = document.Header;
- if (deviceStream != null && deviceStream.Observations != null && deviceStream.Observations.Count() > 0)
+ var deviceStreams = new List();
+ foreach (var stream in document.Streams)
{
- // Recreate Response Document (to set DataItem property for Observations)
- var response = new StreamsResponseDocument();
- response.Header = document.Header;
+ deviceStreams.Add(ProcessDeviceStream(response.Header, stream));
+ }
+ response.Streams = deviceStreams;
- var deviceStreams = new List();
- foreach (var stream in document.Streams)
- {
- deviceStreams.Add(ProcessDeviceStream(stream));
- }
- response.Streams = deviceStreams;
- CheckAssetChanged(deviceStream.Observations, cancel);
+ SampleReceived?.Invoke(this, response);
+
+ // Process Device Streams
+ foreach (var deviceStream in response.Streams)
+ {
// Save the most recent Sequence that was read
_lastSequence = deviceStream.Observations.Max(o => o.Sequence);
- SampleReceived?.Invoke(this, response);
+ // Check to see if any Assets have changed
+ CheckAssetChanged(deviceStream.Observations, cancel);
+ // Get Observations from Device Stream
var observations = response.GetObservations();
if (!observations.IsNullOrEmpty())
{
@@ -952,7 +946,116 @@ private void ProcessSampleDocument(IStreamsResponseDocument document, Cancellati
}
}
- private IDeviceStream ProcessDeviceStream(IDeviceStream inputDeviceStream)
+ private static IDevice ProcessDevice(IMTConnectDevicesHeader header, IDevice inputDevice)
+ {
+ var outputDevice = (Device)inputDevice;
+ outputDevice.InstanceId = header.InstanceId;
+
+ // Add DataItems
+ if (!inputDevice.DataItems.IsNullOrEmpty())
+ {
+ var outputDataItems = new List();
+ foreach (var inputDataItem in inputDevice.DataItems)
+ {
+ outputDataItems.Add(ProcessDataItem(header, inputDataItem));
+ }
+ outputDevice.DataItems = outputDataItems;
+ }
+
+ // Add Compositions
+ if (!inputDevice.Compositions.IsNullOrEmpty())
+ {
+ var outputCompositions = new List();
+ foreach (var inputComposition in inputDevice.Compositions)
+ {
+ outputCompositions.Add(ProcessComposition(header, inputComposition));
+ }
+ outputDevice.Compositions = outputCompositions;
+ }
+
+ // Add Components
+ if (!inputDevice.Components.IsNullOrEmpty())
+ {
+ var outputSubComponents = new List();
+ foreach (var inputSubComponent in inputDevice.Components)
+ {
+ outputSubComponents.Add(ProcessComponent(header, inputSubComponent));
+ }
+ outputDevice.Components = outputSubComponents;
+ }
+
+ return outputDevice;
+ }
+
+ private static IComponent ProcessComponent(IMTConnectDevicesHeader header, IComponent inputComponent)
+ {
+ var outputComponent = (Component)inputComponent;
+ outputComponent.InstanceId = header.InstanceId;
+
+ // Add DataItems
+ if (!inputComponent.DataItems.IsNullOrEmpty())
+ {
+ var outputDataItems = new List();
+ foreach (var inputDataItem in inputComponent.DataItems)
+ {
+ outputDataItems.Add(ProcessDataItem(header, inputDataItem));
+ }
+ outputComponent.DataItems = outputDataItems;
+ }
+
+ // Add Compositions
+ if (!inputComponent.Compositions.IsNullOrEmpty())
+ {
+ var outputCompositions = new List();
+ foreach (var inputComposition in inputComponent.Compositions)
+ {
+ outputCompositions.Add(ProcessComposition(header, inputComposition));
+ }
+ outputComponent.Compositions = outputCompositions;
+ }
+
+ // Add Components
+ if (!inputComponent.Components.IsNullOrEmpty())
+ {
+ var outputSubComponents = new List();
+ foreach (var inputSubComponent in inputComponent.Components)
+ {
+ outputSubComponents.Add(ProcessComponent(header, inputSubComponent));
+ }
+ outputComponent.Components = outputSubComponents;
+ }
+
+ return outputComponent;
+ }
+
+ private static IComposition ProcessComposition(IMTConnectDevicesHeader header, IComposition inputComposition)
+ {
+ var outputComposition = (Composition)inputComposition;
+ outputComposition.InstanceId = header.InstanceId;
+
+ // Add DataItems
+ if (!inputComposition.DataItems.IsNullOrEmpty())
+ {
+ var outputDataItems = new List();
+ foreach (var inputDataItem in inputComposition.DataItems)
+ {
+ outputDataItems.Add(ProcessDataItem(header, inputDataItem));
+ }
+ outputComposition.DataItems = outputDataItems;
+ }
+
+ return outputComposition;
+ }
+
+ private static IDataItem ProcessDataItem(IMTConnectDevicesHeader header, IDataItem inputDataItem)
+ {
+ var outputDataItem = (DataItem)inputDataItem;
+ outputDataItem.InstanceId = header.InstanceId;
+ return outputDataItem;
+ }
+
+
+ private IDeviceStream ProcessDeviceStream(IMTConnectStreamsHeader header, IDeviceStream inputDeviceStream)
{
var outputDeviceStream = new DeviceStream();
outputDeviceStream.Name = inputDeviceStream.Name;
@@ -963,7 +1066,7 @@ private IDeviceStream ProcessDeviceStream(IDeviceStream inputDeviceStream)
{
foreach (var componentStream in inputDeviceStream.ComponentStreams)
{
- componentStreams.Add(ProcessComponentStream(outputDeviceStream.Uuid, componentStream));
+ componentStreams.Add(ProcessComponentStream(header, outputDeviceStream.Uuid, componentStream));
}
}
outputDeviceStream.ComponentStreams = componentStreams;
@@ -971,13 +1074,23 @@ private IDeviceStream ProcessDeviceStream(IDeviceStream inputDeviceStream)
return outputDeviceStream;
}
- private IComponentStream ProcessComponentStream(string deviceUuid, IComponentStream inputComponentStream)
+ private IComponentStream ProcessComponentStream(IMTConnectStreamsHeader header, string deviceUuid, IComponentStream inputComponentStream)
{
var outputComponentStream = new ComponentStream();
+ outputComponentStream.ComponentId = inputComponentStream.ComponentId;
+ outputComponentStream.ComponentType = inputComponentStream.ComponentType;
outputComponentStream.Name = inputComponentStream.Name;
outputComponentStream.NativeName = inputComponentStream.NativeName;
outputComponentStream.Uuid = inputComponentStream.Uuid;
- outputComponentStream.Component = GetCachedComponent(deviceUuid, inputComponentStream.ComponentId);
+
+ if (inputComponentStream.ComponentType == Agent.TypeId || inputComponentStream.ComponentType == Devices.Device.TypeId)
+ {
+ outputComponentStream.Component = GetCachedDevice(deviceUuid);
+ }
+ else
+ {
+ outputComponentStream.Component = GetCachedComponent(deviceUuid, inputComponentStream.ComponentId);
+ }
var observations = new List();
if (!inputComponentStream.Observations.IsNullOrEmpty())
@@ -997,6 +1110,7 @@ private IComponentStream ProcessComponentStream(string deviceUuid, IComponentStr
outputObservation.Type = inputObservation.Type;
outputObservation.SubType = inputObservation.SubType;
outputObservation.Name = inputObservation.Name;
+ outputObservation.InstanceId = header.InstanceId;
outputObservation.Sequence = inputObservation.Sequence;
outputObservation.Timestamp = inputObservation.Timestamp;
outputObservation.AddValues(inputObservation.Values);
diff --git a/libraries/MTConnect.NET-HTTP/Servers/MTConnectCurrentResponseHandler.cs b/libraries/MTConnect.NET-HTTP/Servers/MTConnectCurrentResponseHandler.cs
index 50ac3495..3aff9ed5 100644
--- a/libraries/MTConnect.NET-HTTP/Servers/MTConnectCurrentResponseHandler.cs
+++ b/libraries/MTConnect.NET-HTTP/Servers/MTConnectCurrentResponseHandler.cs
@@ -41,8 +41,8 @@ protected async override Task OnRequestReceived(IHttpCont
var path = httpRequest.QueryString["path"];
// Read "at" parameter from Query string
- var at = httpRequest.QueryString["at"].ToULong();
- if (at < 1) at = 0;
+ ulong? at = null;
+ if (httpRequest.QueryString.ContainsKey("at")) at = httpRequest.QueryString["at"].ToULong();
// Read "interval" parameter from Query string
var interval = httpRequest.QueryString["interval"].ToInt();
diff --git a/libraries/MTConnect.NET-HTTP/Servers/MTConnectHttpRequests.cs b/libraries/MTConnect.NET-HTTP/Servers/MTConnectHttpRequests.cs
index 217ed3f5..e547ef6a 100644
--- a/libraries/MTConnect.NET-HTTP/Servers/MTConnectHttpRequests.cs
+++ b/libraries/MTConnect.NET-HTTP/Servers/MTConnectHttpRequests.cs
@@ -149,7 +149,7 @@ public static MTConnectHttpResponse GetCurrentRequest(
IMTConnectAgentBroker mtconnectAgent,
string deviceType = null,
string path = null,
- ulong at = 0,
+ ulong? at = null,
int interval = 0,
Version mtconnectVersion = null,
string documentFormat = DocumentFormat.XML,
@@ -192,8 +192,16 @@ public static MTConnectHttpResponse GetCurrentRequest(
IStreamsResponseOutputDocument document;
// Get MTConnectStreams document from the MTConnectAgent
- if (dataItemIds != null) document = mtconnectAgent.GetDeviceStreamsResponseDocument(dataItemIds, at, mtconnectVersion: mtconnectVersion, deviceType: deviceType);
- else document = mtconnectAgent.GetDeviceStreamsResponseDocument(at, mtconnectVersion: mtconnectVersion, deviceType: deviceType);
+ if (dataItemIds != null)
+ {
+ if (at.HasValue) document = mtconnectAgent.GetDeviceStreamsResponseDocument(dataItemIds, at.Value, mtconnectVersion: mtconnectVersion, deviceType: deviceType);
+ else document = mtconnectAgent.GetDeviceStreamsResponseDocument(dataItemIds, mtconnectVersion: mtconnectVersion, deviceType: deviceType);
+ }
+ else
+ {
+ if (at.HasValue) document = mtconnectAgent.GetDeviceStreamsResponseDocument(at.Value, mtconnectVersion: mtconnectVersion, deviceType: deviceType);
+ else document = mtconnectAgent.GetDeviceStreamsResponseDocument(mtconnectVersion: mtconnectVersion, deviceType: deviceType);
+ }
stpw.Stop();
double duration = stpw.GetElapsedMilliseconds();
@@ -245,7 +253,7 @@ public static MTConnectHttpResponse GetDeviceCurrentRequest(
IMTConnectAgentBroker mtconnectAgent,
string deviceKey,
string path = null,
- ulong at = 0,
+ ulong? at = null,
int interval = -1,
Version mtconnectVersion = null,
string documentFormat = DocumentFormat.XML,
@@ -290,8 +298,16 @@ public static MTConnectHttpResponse GetDeviceCurrentRequest(
IStreamsResponseOutputDocument document;
// Get MTConnectStreams document from the MTConnectAgent
- if (dataItemIds != null) document = mtconnectAgent.GetDeviceStreamsResponseDocument(deviceKey, dataItemIds, at, mtconnectVersion: mtconnectVersion);
- else document = mtconnectAgent.GetDeviceStreamsResponseDocument(deviceKey, at, mtconnectVersion: mtconnectVersion);
+ if (dataItemIds != null)
+ {
+ if (at.HasValue) document = mtconnectAgent.GetDeviceStreamsResponseDocument(deviceKey, dataItemIds, at.Value, mtconnectVersion: mtconnectVersion);
+ else document = mtconnectAgent.GetDeviceStreamsResponseDocument(deviceKey, dataItemIds, mtconnectVersion: mtconnectVersion);
+ }
+ else
+ {
+ if (at.HasValue) document = mtconnectAgent.GetDeviceStreamsResponseDocument(deviceKey, at.Value, mtconnectVersion: mtconnectVersion);
+ else document = mtconnectAgent.GetDeviceStreamsResponseDocument(deviceKey, mtconnectVersion: mtconnectVersion);
+ }
stpw.Stop();
double duration = stpw.GetElapsedMilliseconds();
diff --git a/libraries/MTConnect.NET-JSON-cppagent/Formatters/JsonHttpResponseDocumentFormatter.cs b/libraries/MTConnect.NET-JSON-cppagent/Formatters/JsonHttpResponseDocumentFormatter.cs
index f6c621b3..ef389e0f 100644
--- a/libraries/MTConnect.NET-JSON-cppagent/Formatters/JsonHttpResponseDocumentFormatter.cs
+++ b/libraries/MTConnect.NET-JSON-cppagent/Formatters/JsonHttpResponseDocumentFormatter.cs
@@ -24,7 +24,7 @@ public class JsonHttpResponseDocumentFormatter : IResponseDocumentFormatter
public virtual string ContentType => "application/json";
- public FormatWriteResult Format(IDevicesResponseDocument document, IEnumerable> options = null)
+ public virtual FormatWriteResult Format(IDevicesResponseDocument document, IEnumerable> options = null)
{
// Read Indent Option passed to Formatter
var indentOutput = GetFormatterOption(options, "indentOutput");
@@ -40,7 +40,7 @@ public FormatWriteResult Format(IDevicesResponseDocument document, IEnumerable> options = null)
+ public virtual FormatWriteResult Format(ref IStreamsResponseOutputDocument document, IEnumerable> options = null)
{
// Read Indent Option passed to Formatter
var indentOutput = GetFormatterOption(options, "indentOutput");
@@ -89,7 +89,7 @@ public FormatWriteResult Format(IErrorResponseDocument document, IEnumerable CreateDevicesResponseDocument(Stream content, IEnumerable> options = null)
+ public virtual FormatReadResult CreateDevicesResponseDocument(Stream content, IEnumerable> options = null)
{
// Read Document
var document = JsonSerializer.Deserialize(content);
@@ -98,7 +98,7 @@ public FormatReadResult CreateDevicesResponseDocument(
return new FormatReadResult(document.ToDocument(), success);
}
- public FormatReadResult CreateStreamsResponseDocument(Stream content, IEnumerable> options = null)
+ public virtual FormatReadResult CreateStreamsResponseDocument(Stream content, IEnumerable> options = null)
{
// Read Document
var document = JsonSerializer.Deserialize(content);
diff --git a/libraries/MTConnect.NET-JSON-cppagent/Formatters/JsonMqttResponseDocumentFormatter.cs b/libraries/MTConnect.NET-JSON-cppagent/Formatters/JsonMqttResponseDocumentFormatter.cs
index 914f0dc6..394bc60c 100644
--- a/libraries/MTConnect.NET-JSON-cppagent/Formatters/JsonMqttResponseDocumentFormatter.cs
+++ b/libraries/MTConnect.NET-JSON-cppagent/Formatters/JsonMqttResponseDocumentFormatter.cs
@@ -3,8 +3,12 @@
using MTConnect.Assets;
using MTConnect.Assets.Json;
+using MTConnect.Devices;
+using MTConnect.Devices.Json;
+using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text.Json;
namespace MTConnect.Formatters
@@ -16,6 +20,26 @@ public class JsonMqttResponseDocumentFormatter : JsonHttpResponseDocumentFormatt
public override string ContentType => "application/json";
+ public override FormatWriteResult Format(IDevicesResponseDocument document, IEnumerable> options = null)
+ {
+ // Read Indent Option passed to Formatter
+ var indentOutput = GetFormatterOption(options, "indentOutput");
+ var jsonOptions = indentOutput ? JsonFunctions.IndentOptions : JsonFunctions.DefaultOptions;
+
+ if (!document.Devices.IsNullOrEmpty())
+ {
+ var device = document.Devices.FirstOrDefault();
+ var outputStream = new MemoryStream();
+ JsonSerializer.Serialize(outputStream, new JsonDeviceContainer(device), jsonOptions);
+ if (outputStream != null && outputStream.Length > 0)
+ {
+ return FormatWriteResult.Successful(outputStream, ContentType);
+ }
+ }
+
+ return FormatWriteResult.Error();
+ }
+
public override FormatWriteResult Format(IAssetsResponseDocument document, IEnumerable> options = null)
{
// Read Indent Option passed to Formatter
@@ -32,6 +56,33 @@ public override FormatWriteResult Format(IAssetsResponseDocument document, IEnum
return FormatWriteResult.Error();
}
+
+ public override FormatReadResult CreateDevicesResponseDocument(Stream content, IEnumerable> options = null)
+ {
+ try
+ {
+ // Read Document
+ var devices = JsonSerializer.Deserialize(content);
+ var success = devices != null;
+
+ var responseDocument = new DevicesResponseDocument();
+
+ var device = devices.ToDevice();
+ if (device != null)
+ {
+ responseDocument.Devices = new IDevice[] { device };
+ }
+
+ return new FormatReadResult(responseDocument, success);
+ }
+ catch (Exception ex)
+ {
+ var messages = ex.Message != null ? new string[] { ex.Message } : null;
+
+ return new FormatReadResult(null, false, errors: messages);
+ }
+ }
+
public override FormatReadResult CreateAssetsResponseDocument(Stream content, IEnumerable> options = null)
{
// Read Document
diff --git a/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonDataSetEntries.cs b/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonDataSetEntries.cs
index a5194d37..0410f976 100644
--- a/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonDataSetEntries.cs
+++ b/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonDataSetEntries.cs
@@ -54,7 +54,7 @@ public override JsonDataSetEntries Read(ref Utf8JsonReader reader, Type typeToCo
}
else
{
- reader.Skip(); // Unavailable
+ reader.TrySkip(); // Unavailable
}
return null;
diff --git a/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonTableEntries.cs b/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonTableEntries.cs
index febe09ab..632ee3dc 100644
--- a/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonTableEntries.cs
+++ b/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonTableEntries.cs
@@ -54,7 +54,7 @@ public override JsonTableEntries Read(ref Utf8JsonReader reader, Type typeToConv
}
else
{
- reader.Skip(); // Unavailable
+ reader.TrySkip(); // Unavailable
}
return null;
diff --git a/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonTimeSeriesSamples.cs b/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonTimeSeriesSamples.cs
index a71ea7a2..e99f87c0 100644
--- a/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonTimeSeriesSamples.cs
+++ b/libraries/MTConnect.NET-JSON-cppagent/Streams/JsonTimeSeriesSamples.cs
@@ -55,7 +55,7 @@ public override JsonTimeSeriesSamples Read(ref Utf8JsonReader reader, Type typeT
}
else
{
- reader.Skip(); // Unavailable
+ reader.TrySkip(); // Unavailable
}
return null;
diff --git a/libraries/MTConnect.NET-MQTT/Clients/MTConnectMqttClient.cs b/libraries/MTConnect.NET-MQTT/Clients/MTConnectMqttClient.cs
index f12f04fc..01f958bd 100644
--- a/libraries/MTConnect.NET-MQTT/Clients/MTConnectMqttClient.cs
+++ b/libraries/MTConnect.NET-MQTT/Clients/MTConnectMqttClient.cs
@@ -8,6 +8,7 @@
using MTConnect.Devices;
using MTConnect.Errors;
using MTConnect.Formatters;
+using MTConnect.Headers;
using MTConnect.Observations;
using MTConnect.Streams;
using System;
@@ -169,7 +170,7 @@ public class MTConnectMqttClient : IMTConnectClient, IMTConnectEntityClient, IDi
/// Initializes a new instance of the MTConnectMqttClient class that is used to perform
/// the full protocol from an MTConnect Agent using the MTConnect MQTT Api protocol
///
- public MTConnectMqttClient(string server, int port = 1883, string deviceUuid = null, string topicPrefix = _defaultTopicPrefix, string documentFormat = _defaultDocumentFormat, string clientId = null, int qos = 1)
+ public MTConnectMqttClient(string server, int port = 1883, string deviceUuid = null, string topicPrefix = _defaultTopicPrefix, string documentFormat = _defaultDocumentFormat, string clientId = null, int qos = 0)
{
var configuration = new MTConnectMqttClientConfiguration();
configuration.Server = server;
@@ -363,18 +364,26 @@ private async Task Worker()
private async Task StartAllDevicesProtocol()
{
- await _mqttClient.SubscribeAsync("MTConnect/Probe/#");
- await _mqttClient.SubscribeAsync("MTConnect/Current/#");
- await _mqttClient.SubscribeAsync("MTConnect/Sample/#");
- await _mqttClient.SubscribeAsync("MTConnect/Asset/#");
+ var topicPrefix = _configuration.TopicPrefix != null ? _configuration.TopicPrefix : "";
+ topicPrefix = topicPrefix.Trim('/');
+
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Probe/+");
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Probe/+/Availability");
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Current/+");
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Sample/+");
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Asset/+");
}
private async Task StartDeviceProtocol(string deviceUuid)
{
- await _mqttClient.SubscribeAsync($"MTConnect/Probe/{deviceUuid}");
- await _mqttClient.SubscribeAsync($"MTConnect/Current/{deviceUuid}");
- await _mqttClient.SubscribeAsync($"MTConnect/Sample/{deviceUuid}");
- await _mqttClient.SubscribeAsync($"MTConnect/Asset/{deviceUuid}/#");
+ var topicPrefix = _configuration.TopicPrefix != null ? _configuration.TopicPrefix : "";
+ topicPrefix = topicPrefix.Trim('/');
+
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Probe/{deviceUuid}");
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Probe/{deviceUuid}/Availability");
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Current/{deviceUuid}");
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Sample/{deviceUuid}");
+ await _mqttClient.SubscribeAsync($"{topicPrefix}/Asset/{deviceUuid}/+");
}
@@ -455,20 +464,33 @@ private bool IsAssetTopic(string topic)
private void ProcessProbeMessage(MqttApplicationMessage message)
{
- var result = EntityFormatter.CreateDevice(_documentFormat, new MemoryStream(message.Payload));
- if (result.Success)
+ using (var contentStream = new MemoryStream(message.Payload))
{
- var device = result.Content;
- if (device != null && device.Uuid != null)
+ var result = ResponseDocumentFormatter.CreateDevicesResponseDocument(_documentFormat, contentStream);
+ if (result.Success)
{
- // Add to cached list
- lock (_lock)
+ var responseDocument = result.Content;
+ if (responseDocument != null && !responseDocument.Devices.IsNullOrEmpty())
{
- _devices.Remove(device.Uuid);
- _devices.Add(device.Uuid, device);
- }
+ foreach (var device in responseDocument.Devices)
+ {
+ if (device != null && device.Uuid != null)
+ {
+ var outputDevice = ProcessDevice(responseDocument.Header, device);
- DeviceReceived?.Invoke(this, device);
+ // Add to cached list
+ lock (_lock)
+ {
+ _devices.Remove(outputDevice.Uuid);
+ _devices.Add(outputDevice.Uuid, outputDevice);
+ }
+
+ DeviceReceived?.Invoke(this, outputDevice);
+ }
+ }
+
+ ProbeReceived?.Invoke(this, responseDocument);
+ }
}
}
}
@@ -477,10 +499,13 @@ private void ProcessCurrentMessage(MqttApplicationMessage message)
{
if (!message.Retain)
{
- var result = ResponseDocumentFormatter.CreateStreamsResponseDocument(_documentFormat, new MemoryStream(message.Payload));
- if (result.Success)
+ using (var contentStream = new MemoryStream(message.Payload))
{
- ProcessCurrentDocument(result.Content);
+ var result = ResponseDocumentFormatter.CreateStreamsResponseDocument(_documentFormat, contentStream);
+ if (result.Success)
+ {
+ ProcessCurrentDocument(result.Content);
+ }
}
}
}
@@ -489,20 +514,26 @@ private void ProcessSampleMessage(MqttApplicationMessage message)
{
if (!message.Retain)
{
- var result = ResponseDocumentFormatter.CreateStreamsResponseDocument(_documentFormat, new MemoryStream(message.Payload));
- if (result.Success)
+ using (var contentStream = new MemoryStream(message.Payload))
{
- ProcessSampleDocument(result.Content);
+ var result = ResponseDocumentFormatter.CreateStreamsResponseDocument(_documentFormat, contentStream);
+ if (result.Success)
+ {
+ ProcessSampleDocument(result.Content);
+ }
}
}
}
private void ProcessAssetMessage(MqttApplicationMessage message)
{
- var result = ResponseDocumentFormatter.CreateAssetsResponseDocument(_documentFormat, new MemoryStream(message.Payload));
- if (result.Success)
+ using (var contentStream = new MemoryStream(message.Payload))
{
- ProcessAssetsDocument(result.Content);
+ var result = ResponseDocumentFormatter.CreateAssetsResponseDocument(_documentFormat, contentStream);
+ if (result.Success)
+ {
+ ProcessAssetsDocument(result.Content);
+ }
}
}
@@ -516,14 +547,23 @@ private void ProcessCurrentDocument(IStreamsResponseDocument document)
{
if (!document.Streams.IsNullOrEmpty())
{
- IDeviceStream deviceStream = null;
+ // Recreate Response Document (to set DataItem property for Observations)
+ var response = new StreamsResponseDocument();
+ response.Header = document.Header;
+
+ var deviceStreams = new List();
+ foreach (var stream in document.Streams)
+ {
+ deviceStreams.Add(ProcessDeviceStream(response.Header, stream));
+ }
+ response.Streams = deviceStreams;
+
+
+ CurrentReceived?.Invoke(this, response);
- // Get the DeviceStream for the Device or default to the first
- if (!string.IsNullOrEmpty(_configuration.DeviceUuid)) deviceStream = document.Streams.FirstOrDefault(o => o.Uuid == _configuration.DeviceUuid);
- else deviceStream = document.Streams.FirstOrDefault();
- var observations = deviceStream.Observations;
- if (deviceStream != null && deviceStream.Uuid != null && !observations.IsNullOrEmpty())
+ // Process Device Streams
+ foreach (var deviceStream in response.Streams)
{
ulong lastSequence;
ulong lastInstanceId;
@@ -533,48 +573,34 @@ private void ProcessCurrentDocument(IStreamsResponseDocument document)
_deviceInstanceId.TryGetValue(deviceStream.Uuid, out lastInstanceId);
}
- // Recreate Response Document (to set DataItem property for Observations)
- var response = new StreamsResponseDocument();
- response.Header = document.Header;
+ // Check to see if any Assets have changed
+ //CheckAssetChanged(deviceStream.Observations, cancel);
- if (lastInstanceId < 1 || response.Header.InstanceId != lastInstanceId)
+ // Get Observations from Device Stream
+ var observations = response.GetObservations();
+ if (!observations.IsNullOrEmpty())
{
- var deviceStreams = new List();
- foreach (var stream in document.Streams)
- {
- deviceStreams.Add(ProcessDeviceStream(stream));
- }
- response.Streams = deviceStreams;
-
- //CheckAssetChanged(deviceStream.Observations, cancel);
-
- CurrentReceived?.Invoke(this, response);
-
- observations = response.GetObservations();
- if (!observations.IsNullOrEmpty())
+ foreach (var observation in observations)
{
- foreach (var observation in observations)
+ if (observation.Sequence > lastSequence)
{
- if (observation.Sequence > lastSequence)
- {
- ObservationReceived?.Invoke(this, observation);
- }
+ ObservationReceived?.Invoke(this, observation);
}
+ }
- var maxSequence = observations.Max(o => o.Sequence);
+ var maxSequence = observations.Max(o => o.Sequence);
- // Save the most recent Sequence that was read
- lock (_lock)
- {
- _deviceLastCurrentSequence.Remove(deviceStream.Uuid);
- _deviceLastCurrentSequence.Add(deviceStream.Uuid, maxSequence);
+ // Save the most recent Sequence that was read
+ lock (_lock)
+ {
+ _deviceLastCurrentSequence.Remove(deviceStream.Uuid);
+ _deviceLastCurrentSequence.Add(deviceStream.Uuid, maxSequence);
- _deviceLastSequence.Remove(deviceStream.Uuid);
- _deviceLastSequence.Add(deviceStream.Uuid, maxSequence);
+ _deviceLastSequence.Remove(deviceStream.Uuid);
+ _deviceLastSequence.Add(deviceStream.Uuid, maxSequence);
- _deviceInstanceId.Remove(deviceStream.Uuid);
- _deviceInstanceId.Add(deviceStream.Uuid, response.Header.InstanceId);
- }
+ _deviceInstanceId.Remove(deviceStream.Uuid);
+ _deviceInstanceId.Add(deviceStream.Uuid, response.Header.InstanceId);
}
}
}
@@ -589,64 +615,53 @@ private void ProcessSampleDocument(IStreamsResponseDocument document)
if (document != null)
{
- // Set Agent Instance ID
- //if (document.Header != null) _lastInstanceId = document.Header.InstanceId;
+ // Recreate Response Document (to set DataItem property for Observations)
+ var response = new StreamsResponseDocument();
+ response.Header = document.Header;
- if (!document.Streams.IsNullOrEmpty())
+ var deviceStreams = new List();
+ foreach (var stream in document.Streams)
{
- IDeviceStream deviceStream = null;
-
- // Get the DeviceStream for the Device or default to the first
- if (!string.IsNullOrEmpty(_configuration.DeviceUuid)) deviceStream = document.Streams.FirstOrDefault(o => o.Uuid == _configuration.DeviceUuid);
- else deviceStream = document.Streams.FirstOrDefault();
-
- if (deviceStream != null && deviceStream.Observations != null && deviceStream.Observations.Count() > 0)
- {
- ulong lastCurrentSequence;
- ulong lastSequence;
- lock (_lock)
- {
- _deviceLastCurrentSequence.TryGetValue(deviceStream.Uuid, out lastCurrentSequence);
- _deviceLastSequence.TryGetValue(deviceStream.Uuid, out lastSequence);
- }
+ deviceStreams.Add(ProcessDeviceStream(response.Header, stream));
+ }
+ response.Streams = deviceStreams;
- if (lastCurrentSequence > 0)
- {
- // Recreate Response Document (to set DataItem property for Observations)
- var response = new StreamsResponseDocument();
- response.Header = document.Header;
- var deviceStreams = new List();
- foreach (var stream in document.Streams)
- {
- deviceStreams.Add(ProcessDeviceStream(stream));
- }
- response.Streams = deviceStreams;
+ SampleReceived?.Invoke(this, response);
- //CheckAssetChanged(deviceStream.Observations, cancel);
- SampleReceived?.Invoke(this, response);
+ // Process Device Streams
+ foreach (var deviceStream in response.Streams)
+ {
+ ulong lastCurrentSequence;
+ ulong lastSequence;
+ lock (_lock)
+ {
+ _deviceLastCurrentSequence.TryGetValue(deviceStream.Uuid, out lastCurrentSequence);
+ _deviceLastSequence.TryGetValue(deviceStream.Uuid, out lastSequence);
+ }
- var observations = response.GetObservations();
- if (!observations.IsNullOrEmpty())
+ if (lastCurrentSequence > 0)
+ {
+ var observations = response.GetObservations();
+ if (!observations.IsNullOrEmpty())
+ {
+ foreach (var observation in observations)
{
- foreach (var observation in observations)
+ if (observation.Sequence > lastSequence && observation.Sequence > lastCurrentSequence)
{
- if (observation.Sequence > lastSequence && observation.Sequence > lastCurrentSequence)
- {
- ObservationReceived?.Invoke(this, observation);
- }
+ ObservationReceived?.Invoke(this, observation);
}
+ }
- // Save the most recent Sequence that was read
- var maxSequence = observations.Max(o => o.Sequence);
+ // Save the most recent Sequence that was read
+ var maxSequence = observations.Max(o => o.Sequence);
- // Save the most recent Sequence that was read
- lock (_lock)
- {
- _deviceLastSequence.Remove(deviceStream.Uuid);
- _deviceLastSequence.Add(deviceStream.Uuid, maxSequence);
- }
+ // Save the most recent Sequence that was read
+ lock (_lock)
+ {
+ _deviceLastSequence.Remove(deviceStream.Uuid);
+ _deviceLastSequence.Add(deviceStream.Uuid, maxSequence);
}
}
}
@@ -668,7 +683,116 @@ private void ProcessAssetsDocument(IAssetsResponseDocument document)
}
- private IDeviceStream ProcessDeviceStream(IDeviceStream inputDeviceStream)
+ private static IDevice ProcessDevice(IMTConnectDevicesHeader header, IDevice inputDevice)
+ {
+ var outputDevice = (Device)inputDevice;
+ outputDevice.InstanceId = header != null ? header.InstanceId : 0;
+
+ // Add DataItems
+ if (!inputDevice.DataItems.IsNullOrEmpty())
+ {
+ var outputDataItems = new List();
+ foreach (var inputDataItem in inputDevice.DataItems)
+ {
+ outputDataItems.Add(ProcessDataItem(header, inputDataItem));
+ }
+ outputDevice.DataItems = outputDataItems;
+ }
+
+ // Add Compositions
+ if (!inputDevice.Compositions.IsNullOrEmpty())
+ {
+ var outputCompositions = new List();
+ foreach (var inputComposition in inputDevice.Compositions)
+ {
+ outputCompositions.Add(ProcessComposition(header, inputComposition));
+ }
+ outputDevice.Compositions = outputCompositions;
+ }
+
+ // Add Components
+ if (!inputDevice.Components.IsNullOrEmpty())
+ {
+ var outputSubComponents = new List();
+ foreach (var inputSubComponent in inputDevice.Components)
+ {
+ outputSubComponents.Add(ProcessComponent(header, inputSubComponent));
+ }
+ outputDevice.Components = outputSubComponents;
+ }
+
+ return outputDevice;
+ }
+
+ private static IComponent ProcessComponent(IMTConnectDevicesHeader header, IComponent inputComponent)
+ {
+ var outputComponent = (Component)inputComponent;
+ outputComponent.InstanceId = header != null ? header.InstanceId : 0;
+
+ // Add DataItems
+ if (!inputComponent.DataItems.IsNullOrEmpty())
+ {
+ var outputDataItems = new List();
+ foreach (var inputDataItem in inputComponent.DataItems)
+ {
+ outputDataItems.Add(ProcessDataItem(header, inputDataItem));
+ }
+ outputComponent.DataItems = outputDataItems;
+ }
+
+ // Add Compositions
+ if (!inputComponent.Compositions.IsNullOrEmpty())
+ {
+ var outputCompositions = new List();
+ foreach (var inputComposition in inputComponent.Compositions)
+ {
+ outputCompositions.Add(ProcessComposition(header, inputComposition));
+ }
+ outputComponent.Compositions = outputCompositions;
+ }
+
+ // Add Components
+ if (!inputComponent.Components.IsNullOrEmpty())
+ {
+ var outputSubComponents = new List();
+ foreach (var inputSubComponent in inputComponent.Components)
+ {
+ outputSubComponents.Add(ProcessComponent(header, inputSubComponent));
+ }
+ outputComponent.Components = outputSubComponents;
+ }
+
+ return outputComponent;
+ }
+
+ private static IComposition ProcessComposition(IMTConnectDevicesHeader header, IComposition inputComposition)
+ {
+ var outputComposition = (Composition)inputComposition;
+ outputComposition.InstanceId = header != null ? header.InstanceId : 0;
+
+ // Add DataItems
+ if (!inputComposition.DataItems.IsNullOrEmpty())
+ {
+ var outputDataItems = new List();
+ foreach (var inputDataItem in inputComposition.DataItems)
+ {
+ outputDataItems.Add(ProcessDataItem(header, inputDataItem));
+ }
+ outputComposition.DataItems = outputDataItems;
+ }
+
+ return outputComposition;
+ }
+
+ private static IDataItem ProcessDataItem(IMTConnectDevicesHeader header, IDataItem inputDataItem)
+ {
+ var outputDataItem = (DataItem)inputDataItem;
+ outputDataItem.InstanceId = header != null ? header.InstanceId : 0;
+ return outputDataItem;
+ }
+
+
+ private IDeviceStream ProcessDeviceStream(IMTConnectStreamsHeader header, IDeviceStream inputDeviceStream)
{
var outputDeviceStream = new DeviceStream();
outputDeviceStream.Name = inputDeviceStream.Name;
@@ -679,7 +803,7 @@ private IDeviceStream ProcessDeviceStream(IDeviceStream inputDeviceStream)
{
foreach (var componentStream in inputDeviceStream.ComponentStreams)
{
- componentStreams.Add(ProcessComponentStream(outputDeviceStream.Uuid, componentStream));
+ componentStreams.Add(ProcessComponentStream(header, outputDeviceStream.Uuid, componentStream));
}
}
outputDeviceStream.ComponentStreams = componentStreams;
@@ -687,13 +811,23 @@ private IDeviceStream ProcessDeviceStream(IDeviceStream inputDeviceStream)
return outputDeviceStream;
}
- private IComponentStream ProcessComponentStream(string deviceUuid, IComponentStream inputComponentStream)
+ private IComponentStream ProcessComponentStream(IMTConnectStreamsHeader header, string deviceUuid, IComponentStream inputComponentStream)
{
var outputComponentStream = new ComponentStream();
+ outputComponentStream.ComponentId = inputComponentStream.ComponentId;
+ outputComponentStream.ComponentType = inputComponentStream.ComponentType;
outputComponentStream.Name = inputComponentStream.Name;
outputComponentStream.NativeName = inputComponentStream.NativeName;
outputComponentStream.Uuid = inputComponentStream.Uuid;
- outputComponentStream.Component = GetCachedComponent(deviceUuid, inputComponentStream.ComponentId);
+
+ if (inputComponentStream.ComponentType == Agent.TypeId || inputComponentStream.ComponentType == Devices.Device.TypeId)
+ {
+ outputComponentStream.Component = GetCachedDevice(deviceUuid);
+ }
+ else
+ {
+ outputComponentStream.Component = GetCachedComponent(deviceUuid, inputComponentStream.ComponentId);
+ }
var observations = new List();
if (!inputComponentStream.Observations.IsNullOrEmpty())
@@ -713,6 +847,7 @@ private IComponentStream ProcessComponentStream(string deviceUuid, IComponentStr
outputObservation.Type = inputObservation.Type;
outputObservation.SubType = inputObservation.SubType;
outputObservation.Name = inputObservation.Name;
+ outputObservation.InstanceId = header.InstanceId;
outputObservation.Sequence = inputObservation.Sequence;
outputObservation.Timestamp = inputObservation.Timestamp;
outputObservation.AddValues(inputObservation.Values);
diff --git a/libraries/MTConnect.NET-MQTT/Configurations/MTConnectMqttClientConfiguration.cs b/libraries/MTConnect.NET-MQTT/Configurations/MTConnectMqttClientConfiguration.cs
index 285ea95b..850ea7bb 100644
--- a/libraries/MTConnect.NET-MQTT/Configurations/MTConnectMqttClientConfiguration.cs
+++ b/libraries/MTConnect.NET-MQTT/Configurations/MTConnectMqttClientConfiguration.cs
@@ -63,6 +63,7 @@ public MTConnectMqttClientConfiguration()
Port = 1883;
QoS = 1;
RetryInterval = 5000;
+ TopicPrefix = "MTConnect";
}
}
}
\ 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 1001b042..e6b27311 100644
--- a/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter.cs
+++ b/libraries/MTConnect.NET-SHDR/Adapters/ShdrAdapter.cs
@@ -33,6 +33,9 @@ public class ShdrAdapter
protected CancellationTokenSource StopToken => _stop;
+ protected IMTConnectAdapter Adapter => _adapter;
+
+
///
/// Get a unique identifier for the Adapter
///
diff --git a/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalQueueAdapter.cs b/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalQueueAdapter.cs
index 624afddd..3e1606ca 100644
--- a/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalQueueAdapter.cs
+++ b/libraries/MTConnect.NET-SHDR/Adapters/ShdrIntervalQueueAdapter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Configurations;
@@ -20,5 +20,11 @@ public ShdrIntervalQueueAdapter(int port = 7878, int heartbeat = 10000, int inte
public ShdrIntervalQueueAdapter(string deviceKey, int port = 7878, int heartbeat = 10000, int interval = _defaultInterval) : base(deviceKey, port, heartbeat, interval, true) { }
public ShdrIntervalQueueAdapter(ShdrAdapterClientConfiguration configuration, int interval = _defaultInterval) : base(configuration, interval, true) { }
+
+
+ public bool SendBuffer()
+ {
+ return Adapter.SendBuffer();
+ }
}
}
\ 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 cb5df0e4..f1c69053 100644
--- a/libraries/MTConnect.NET-SHDR/Adapters/ShdrQueueAdapter.cs
+++ b/libraries/MTConnect.NET-SHDR/Adapters/ShdrQueueAdapter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 TrakHound Inc., All Rights Reserved.
+// Copyright (c) 2024 TrakHound Inc., All Rights Reserved.
// TrakHound Inc. licenses this file to you under the MIT license.
using MTConnect.Configurations;
@@ -17,5 +17,11 @@ public ShdrQueueAdapter(int port = 7878, int heartbeat = 10000) : base(port, hea
public ShdrQueueAdapter(string deviceKey, int port = 7878, int heartbeat = 10000) : base(deviceKey, port, heartbeat, null, true) { }
public ShdrQueueAdapter(ShdrAdapterClientConfiguration configuration) : base(configuration, null, true) { }
+
+
+ public bool SendBuffer()
+ {
+ return Adapter.SendBuffer();
+ }
}
}
\ No newline at end of file