HiveMQ将 Modbus 数据转换为 MQTT 消息
本指南将引导您创建一个 .Net IoT 应用程序,该应用程序充当将 Modbus 数据转换为 MQTT 消息的桥梁。该应用程序将通过 Modbus TCP 协议从工业设备读取温度传感器数据,将该数据转换为 JSON 格式,然后使用 C# 的 HiveMQ MQTT 客户端库将数据发送到 HiveMQ Cloud MQTT代理。
设置 HiveMQ 云 MQTT 代理
首先,您必须设置 HiveMQ Cloud MQTT 代理来管理 C# IoT 应用程序的消息。前往 HiveMQ 网站,从菜单中选择Platform ,然后从左侧菜单中选择HiveMQ Cloud 。
当您登陆HiveMQ Cloud 页面时,选择“免费注册”选项。HiveMQ Cloud Serverless的免费版本允许您配置两个 MQTT 代理集群并链接最多 100 个设备。
对于首次用户,您需要输入电子邮件地址和密码。按照后续步骤验证您的电子邮件并设置您的帐户。
完成此过程后,将自动创建 MQTT 代理集群。要让设备连接到您的 MQTT 代理,请提供用户名和密码,然后单击 来设置您的连接凭据ADD
。
通过选择Overview
,您可以访问将 C# 应用程序链接到 HiveMQ Cloud MQTT 代理集群所需的连接设置。确保记录集群 URL、端口号和登录详细信息以供以后使用。
如果您需要修改连接详细信息,只需登录您的帐户,选择MANAGE CLUSTER
,然后选择ACCESS MANAGEMENT
。
在此阶段,您的 MQTT 代理已准备好处理 IoT 应用程序的消息传递。
现在,您可以开始构建 C# 应用程序以充当 MQTT 客户端,将 Modbus 消息从边缘发布到 HiveMQ Cloud MQTT 代理。
创建 C# .Net 控制台应用程序
在开始编码之前,您需要一个合适的开发环境。我推荐使用 Visual Studio IDE 进行此演示,尽管 Visual Studio Code 也是一个可行的选择。如果尚未安装,请从其网站下载 Visual Studio 的免费社区版并安装。
安装后,启动 Visual Studio IDE 并选择控制台应用程序来创建新项目。在项目类型列表下,选择 C# Console App。
为您的项目命名并点击“下一步”。然后,您可以继续选择默认的 .Net 6.0 框架。通过这些步骤,您已经创建了一个空的 C# 控制台应用程序。
下一个目标是让该应用程序能够收集 Modbus 数据并使用 MQTT 将其传输到基于云的应用程序。这是通过集成 HiveMQ C# MQTT 客户端库和 Modbus 库来实现的。
安装 HiveMQtt C# MQTT 客户端库
适用于 C# 的 HiveMQ MQTT 客户端是 GitHub 上提供的开源项目,并附带灵活的 Apache 2.0 许可证。该客户端具有完整的 MQTT 5.0 支持,并且与所有主要 MQTT 代理兼容。
额外的优势是它在 NuGet.org 上可用,允许通过 .Net NuGet 包管理器轻松安装。该包管理器简化了 .Net 项目中依赖项的管理,确保将 HiveMQ MQTT 客户端库轻松集成到您的应用程序中。
要将 HiveMQ MQTT 客户端添加到您的应用程序,请在解决方案资源管理器中右键单击您的项目,然后选择“管理 NuGet 包”。
导航到“浏览”选项卡,搜索 HiveMQtt,从搜索结果中选择客户端,然后完成安装。
安装 Modbus C# MQTT 客户端库
要从 Modbus 设备检索数据,您还需要合并 C# 的 Modbus 客户端库。使用“管理 NuGet 包”窗口,查找 NModubus 包并安装它。
发布和订阅 MQTT 消息
现在,让我们重点关注读取 Modbus TCP 数据并使用 HiveMQtt MQTT 客户端库将其作为 MQTT 消息传输到 HiveMQ Cloud MQTT 代理的 C# 代码。
首先合并必要的程序集引用,将 HiveMQtt 客户端库集成到您的代码中。
using HiveMQtt.Client;
using HiveMQtt.Client.Options;
using HiveMQtt.MQTT5.ReasonCodes;
using HiveMQtt.MQTT5.Types;
using NModbus;
using NModbus.Device;
using System.Net;
using System.Net.Sockets;
using System.Text.Json;
接下来,初始化 Modbus 客户端,提供所需的连接详细信息,并指定变量来存储返回值。
const string ipAddress = "192.168.0.229";
const int port = 502; // Default Modbus TCP port
const byte slaveId = 21;
const ushort startAddress = 0;
const ushort numRegisters = 2;
TcpClient modbus_client = new TcpClient(ipAddress, port);
Single modbus_value;
UInt16[] modbus_data = new UInt16[2];
随后,通过提供 HiveMQ Cloud MQTT 代理的连接详细信息来创建 MQTT 客户端实例。
var options = new HiveMQClientOptions
{
Host = "81b8283f2a154f549a4337bd921c5da4.s2.eu.hivemq.cloud",
Port = 8883,
UseTLS = true,
UserName = "username",
Password = "password",
};
var client = new HiveMQClient(options);
完成后,您可以建立与 MQTT 代理的连接并查看控制台上显示的连接状态。
Console.WriteLine($"Connecting to {options.Host} on port {options.Port} ...");
// Connect
HiveMQtt.Client.Results.ConnectResult connectResult;
try
{
connectResult = await client.ConnectAsync().ConfigureAwait(false);
if (connectResult.ReasonCode == ConnAckReasonCode.Success)
{
Console.WriteLine($"Connect successful: {connectResult}");
}
else
{
// FIXME: Add ToString
Console.WriteLine($"Connect failed: {connectResult}");
Environment.Exit(-1);
}
}
catch (System.Net.Sockets.SocketException e)
{
Console.WriteLine($"Error connecting to the MQTT Broker with the following socket error: {e.Message}");
Environment.Exit(-1);
}
catch (Exception e)
{
Console.WriteLine($"Error connecting to the MQTT Broker with the following message: {e.Message}");
Environment.Exit(-1);
}
下一步是创建主程序循环。在此循环中,执行以下任务:
- 实例化 Modbus 主站。
- 从我们之前创建的 Modbus 客户端读取温度数据。
- 将生成的 Modbus 数组转换为浮点数。
- 为温度数据和其他上下文信息创建 JSON 对象。
- 将 JSON 对象作为 MQTT 消息发布到 HiveMQ Cloud MQTT 代理。
Console.WriteLine("Publishing message...");
while (true)
{
var factory = new ModbusFactory();
IModbusMaster master = factory.CreateMaster(modbus_client);
// Read holding registers
ushort[] registers = master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
modbus_data[0] = registers[0];
modbus_data[1] = registers[1];
modbus_value = ModbusWordArrayToFloat(modbus_data);
var msg = JsonSerializer.Serialize(
new
{
temperature = modbus_value,
device_type = "modbus",
});
//Publish MQTT messages
var result = await client.PublishAsync("hivemqdemo/telemetry", msg, QualityOfService.AtLeastOnceDelivery).ConfigureAwait(false);
}
最后,我们有一个方法可以帮助将 Modbus 数组转换为浮点型。
/************ ROUTINE TO CONVERT MODBUS 2 BYTES BIG ENDIAN DATA TO SWAPPED FLOAT **********/
Single ModbusWordArrayToFloat(UInt16[] data)
{
if (data.Length != 2)
throw new ArgumentException("2 words of data required for a float");
byte[] bData = new byte[4];
byte[] w1 = BitConverter.GetBytes(data[0]);
byte[] w2 = BitConverter.GetBytes(data[1]);
//reverse words
Array.Copy(w2, 0, bData, 0, 2);
Array.Copy(w1, 0, bData, 2, 2);
return BitConverter.ToSingle(bData, 0);
}
执行 C# 控制台应用程序时,应成功建立与 MQTT 代理的连接。
要验证您的应用程序是否正在主动将消息传输到 HiveMQ Cloud MQTT 代理,您可以使用 MQTT 测试工具(例如 MQTT.fx)。订阅 HiveMQ Cloud MQTT 代理将允许您查看正在发布的数据。
结论
总之,我们已经成功创建了一个使用 C# 将 Modbus 数据转换为 MQTT 的网关应用程序。我们邀请您下载并进一步探索HiveMQ C# MQTT 客户端。