diff --git a/.dockerignore b/.dockerignore index 0adc29ee98..0aa59930f1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -88,6 +88,9 @@ data-visualization/grafana/hm-panel-plugin/.config desktop-qt/CMakeLists.txt.user embedded/decode-can-data/data hardware-in-the-loop/national-instruments/hm-tdms/data +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj hm-kafka/kafka-client/kafka-c/*/config.ini kubernetes/certificates kubernetes/data/config-loader diff --git a/.gitignore b/.gitignore index 7c111dd061..0bf92d64b0 100644 --- a/.gitignore +++ b/.gitignore @@ -88,8 +88,9 @@ data-visualization/metabase/plugins desktop-qt/CMakeLists.txt.user embedded/decode-can-data/data hardware-in-the-loop/national-instruments/hm-tdms/data -hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/bin -hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/obj +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj hm-kafka/kafka-client/kafka-c/*/config.ini kubernetes/certificates kubernetes/data/config-loader diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc index 09e5151dc6..265aeddc15 100644 --- a/.markdownlint-cli2.jsonc +++ b/.markdownlint-cli2.jsonc @@ -98,6 +98,9 @@ "desktop-qt/CMakeLists.txt.user", "embedded/decode-can-data/data", "hardware-in-the-loop/national-instruments/hm-tdms/data", + "hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages", + "hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin", + "hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj", "hm-kafka/kafka-client/kafka-c/*/config.ini", "kubernetes/certificates", "kubernetes/data/config-loader", diff --git a/.prettierignore b/.prettierignore index 450b618623..3b6db89116 100644 --- a/.prettierignore +++ b/.prettierignore @@ -88,6 +88,9 @@ data-visualization/metabase/plugins desktop-qt/CMakeLists.txt.user embedded/decode-can-data/data hardware-in-the-loop/national-instruments/hm-tdms/data +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj hm-kafka/kafka-client/kafka-c/*/config.ini kubernetes/certificates kubernetes/data/config-loader diff --git a/.rubocop.yml b/.rubocop.yml index 64e5e65cdc..2712b38525 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -92,6 +92,9 @@ AllCops: - 'desktop-qt/CMakeLists.txt.user' - 'embedded/decode-can-data/data/**/*' - 'hardware-in-the-loop/national-instruments/hm-tdms/data/**/*' + - 'hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages/**/*' + - 'hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin/**/*' + - 'hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj/**/*' - 'hm-kafka/kafka-client/kafka-c/*/config.ini' - 'kubernetes/certificates/**/*' - 'kubernetes/data/config-loader/**/*' diff --git a/.ruff.toml b/.ruff.toml index 2e71793cf8..3fdfb5c444 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -90,6 +90,9 @@ exclude = [ "desktop-qt/CMakeLists.txt.user", "embedded/decode-can-data/data", "hardware-in-the-loop/national-instruments/hm-tdms/data", + "hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages", + "hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin", + "hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj", "hm-kafka/kafka-client/kafka-c/*/config.ini", "kubernetes/certificates", "kubernetes/data/config-loader", diff --git a/.solhintignore b/.solhintignore index 47a3cf8595..6f0a9f2427 100644 --- a/.solhintignore +++ b/.solhintignore @@ -86,6 +86,9 @@ data-visualization/metabase/plugins desktop-qt/CMakeLists.txt.user embedded/decode-can-data/data hardware-in-the-loop/national-instruments/hm-tdms/data +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj hm-kafka/kafka-client/kafka-c/*/config.ini kubernetes/certificates kubernetes/data/config-loader diff --git a/.sqlfluffignore b/.sqlfluffignore index f1d7ef0360..f9ef8c23a1 100644 --- a/.sqlfluffignore +++ b/.sqlfluffignore @@ -87,6 +87,9 @@ data-visualization/grafana/hm-panel-plugin/.config data-visualization/metabase/plugins desktop-qt/CMakeLists.txt.user hardware-in-the-loop/national-instruments/hm-tdms/data +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj hm-kafka/kafka-client/kafka-c/*/config.ini kubernetes/certificates kubernetes/data/config-loader diff --git a/.stylelintignore b/.stylelintignore index 8958d74550..771f70569c 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -88,6 +88,9 @@ data-visualization/metabase/plugins desktop-qt/CMakeLists.txt.user embedded/decode-can-data/data hardware-in-the-loop/national-instruments/hm-tdms/data +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin +hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj hm-kafka/kafka-client/kafka-c/*/config.ini kubernetes/certificates kubernetes/data/config-loader diff --git a/.yamllint.yaml b/.yamllint.yaml index ecd3998af2..5101676c00 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -93,6 +93,9 @@ ignore: | desktop-qt/CMakeLists.txt.user embedded/decode-can-data/data hardware-in-the-loop/national-instruments/hm-tdms/data + hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages + hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin + hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj hm-kafka/kafka-client/kafka-c/*/config.ini kubernetes/certificates kubernetes/data/config-loader diff --git a/README.md b/README.md index 7601c6f248..7ef25ce980 100644 --- a/README.md +++ b/README.md @@ -762,6 +762,8 @@ make kubernetes-clean ### Network Programmability - **P4** - Programming Protocol-independent Packet Processors +- **ZeroMQ** - High-performance asynchronous messaging library + - **NetMQ** - C# implementation of ZeroMQ ### Communication Standards diff --git a/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/VeriStandController.csproj b/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/VeriStandController.csproj deleted file mode 100644 index 483648787f..0000000000 --- a/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/VeriStandController.csproj +++ /dev/null @@ -1,60 +0,0 @@ - - - - - Debug - AnyCPU - {D99D3F07-09BA-49F2-B4A4-D65AAB41C037} - Exe - Properties - VeriStandController - VeriStandController - v4.8 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\..\..\..\..\Program Files\National Instruments\VeriStand 2024\nivs.lib\Reference Assemblies\NationalInstruments.VeriStand.dll - - - ..\..\..\..\..\..\Program Files\National Instruments\VeriStand 2024\nivs.lib\Reference Assemblies\NationalInstruments.VeriStand.ClientAPI.dll - - - - - - - - - - - - - diff --git a/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController.sln b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge.sln similarity index 78% rename from hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController.sln rename to hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge.sln index 85e9253772..548b351fed 100644 --- a/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController.sln +++ b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge.sln @@ -1,5 +1,5 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeriStandController", "VeriStandController\VeriStandController.csproj", "{D99D3F07-09BA-49F2-B4A4-D65AAB41C037}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeriStandZeroMQBridge", "VeriStandZeroMQBridge\VeriStandZeroMQBridge.csproj", "{D99D3F07-09BA-49F2-B4A4-D65AAB41C037}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/Program.cs b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Program.cs similarity index 56% rename from hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/Program.cs rename to hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Program.cs index 0397750275..56561c4eb3 100644 --- a/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/Program.cs +++ b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Program.cs @@ -1,57 +1,75 @@ -using NationalInstruments.VeriStand.ClientAPI; +using NetMQ; +using NetMQ.Sockets; +using NationalInstruments.VeriStand.ClientAPI; using System; using System.Diagnostics; +using Google.Protobuf; +using System.Linq; +using VeriStandZeroMQBridge; -namespace VeriStandController +public class Program { - internal class Program - { - private const string GATEWAY_IP = "localhost"; - private const string SYSTEM_DEFINITION_PATH = @"C:\Users\Public\Documents\National Instruments\NI VeriStand 2024\Examples\Stimulus Profile\Engine Demo\Engine Demo.nivssdf"; - private const int TOTAL_MESSAGES = 100000; - private const int INTERVAL_MS = 5000; - private const int CONNECTION_TIMEOUT_MS = 60000; + private const string GATEWAY_IP = "localhost"; + private const string SYSTEM_DEFINITION_PATH = @"C:\Users\Public\Documents\National Instruments\NI VeriStand 2024\Examples\Stimulus Profile\Engine Demo\Engine Demo.nivssdf"; + private const int TOTAL_MESSAGES = 100000; + private const int INTERVAL_MS = 5000; + private const int CONNECTION_TIMEOUT_MS = 60000; + private const string ZMQ_ADDRESS = "tcp://*:5555"; - public static void Main(string[] args) + public static void Main(string[] args) + { + using (var publisher = new PublisherSocket()) { + publisher.Bind(ZMQ_ADDRESS); + Console.WriteLine($"[ZMQ] Publisher bound to {ZMQ_ADDRESS}"); + try { var workspace = new Factory().GetIWorkspace2(GATEWAY_IP); - - // Get aliases and channels string[] aliases, channels; workspace.GetAliasList(out aliases, out channels); Console.WriteLine($"[Config] Aliases: {string.Join(", ", aliases)} | Channels: {string.Join(", ", channels)}"); - // Initialize values array and connect to system double[] values = new double[aliases.Length]; workspace.ConnectToSystem(SYSTEM_DEFINITION_PATH, true, CONNECTION_TIMEOUT_MS); Console.WriteLine("[Status] Data collection started"); - // Setup monitoring variables int messageCount = 0; int messagesLastInterval = 0; var totalStopwatch = Stopwatch.StartNew(); var intervalStopwatch = Stopwatch.StartNew(); - // Main data collection loop while (messageCount < TOTAL_MESSAGES) { workspace.GetMultipleChannelValues(aliases, out values); + var signals = new Signals + { + Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), + Signals_ = { aliases.Zip(values, (alias, value) => + new Signal { + Alias = alias, + Value = value + }) } + }; + + // Serialize and send + byte[] data = signals.ToByteArray(); + publisher.SendFrame(data); + messageCount++; messagesLastInterval++; if (intervalStopwatch.ElapsedMilliseconds >= INTERVAL_MS) { double messagesPerSecond = messagesLastInterval / (intervalStopwatch.ElapsedMilliseconds / 1000.0); - Console.WriteLine($"[Update] Speed: {messagesPerSecond:F2} msg/s | Total: {messageCount:N0} | Values: {string.Join(", ", values)}"); + Console.WriteLine($"[Update] Speed: {messagesPerSecond:F2} msg/s | Total: {messageCount:N0} | Value Count: {values.Length}"); + // Console.WriteLine($"Values: {string.Join(", ", values)}"); messagesLastInterval = 0; intervalStopwatch.Restart(); } } - // Display final statistics double totalTime = totalStopwatch.Elapsed.TotalSeconds; double averageMessagesPerSecond = TOTAL_MESSAGES / totalTime; Console.WriteLine($"[Complete] Runtime: {totalTime:F2}s | Avg Speed: {averageMessagesPerSecond:F2} msg/s | Total Messages: {TOTAL_MESSAGES:N0}"); diff --git a/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/Properties/AssemblyInfo.cs b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Properties/AssemblyInfo.cs similarity index 92% rename from hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/Properties/AssemblyInfo.cs rename to hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Properties/AssemblyInfo.cs index 83f7ca5b01..893dd4d66c 100644 --- a/hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/Properties/AssemblyInfo.cs +++ b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Properties/AssemblyInfo.cs @@ -4,11 +4,11 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("VeriStandController")] +[assembly: AssemblyTitle("VeriStandZeroMQBridge")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("VeriStandController")] +[assembly: AssemblyProduct("VeriStandZeroMQBridge")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Protos/signals.proto b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Protos/signals.proto new file mode 100644 index 0000000000..2add124012 --- /dev/null +++ b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/Protos/signals.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +option csharp_namespace = "VeriStandZeroMQBridge"; + +message Signals { + int64 timestamp = 1; + repeated Signal signals = 2; +} + +message Signal { + string alias = 1; + double value = 2; +} diff --git a/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/VeriStandZeroMQBridge.csproj b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/VeriStandZeroMQBridge.csproj new file mode 100644 index 0000000000..51bcd0d9fb --- /dev/null +++ b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/VeriStandZeroMQBridge.csproj @@ -0,0 +1,108 @@ + + + + + + Debug + AnyCPU + {D99D3F07-09BA-49F2-B4A4-D65AAB41C037} + Exe + Properties + VeriStandZeroMQBridge + VeriStandZeroMQBridge + v4.8 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\AsyncIO.0.1.69\lib\net40\AsyncIO.dll + + + ..\packages\Google.Protobuf.3.28.3\lib\net45\Google.Protobuf.dll + + + + + ..\packages\NaCl.Net.0.1.13\lib\net472\NaCl.dll + + + ..\..\..\..\..\..\Program Files\National Instruments\VeriStand 2024\nivs.lib\Reference Assemblies\NationalInstruments.VeriStand.dll + + + ..\..\..\..\..\..\Program Files\National Instruments\VeriStand 2024\nivs.lib\Reference Assemblies\NationalInstruments.VeriStand.ClientAPI.dll + + + ..\packages\NetMQ.4.0.1.13\lib\net47\NetMQ.dll + + + + ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + + + + ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + + + + + diff --git a/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/packages.config b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/packages.config new file mode 100644 index 0000000000..d889285a8f --- /dev/null +++ b/hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/packages.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file