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