序言:
在线束行业工作的朋友一定会熟悉KOMAX的开线设备Alpha 550 ,此设备功能强大质量可靠深受大家的喜爱。随着工业4.0的发展,Alpha 550的HMI系统也走在了科技的前沿,
提供了很多数据接口,如MQTT,MIKO等,MQTT更是一个开放的接口,为大家采集数据提供了很多方便!我所在的公司是行业内颇有影响力的大公司,公司领导非常重视科技
的发展,许多新技术和好的解决方案都应用到了生产中,这样既提高了产量又保证了产品的质量,使公司的产品在行业内更具有竞争力!在公司领导和同事的帮助下我在日常的
工作中不断学习总结,积累了一些经验,写出来和大家分享,希望我的作品能起到抛砖引玉的作用,期待大牛们更多佳作!
引入MQTT库
既然Alpha 550 HMI的MQTT接口是开放的,那么我们就利用此协议做一个客户端进行数据采集。
首先新建工程,添加MQTTnet库,库的版本为4.2.1.781,此版本为最新版,相比以前的3.0版本做了很多改进,更加好用。
MQTT客户端工作流程
//声明一个私有的IMqttClient变量
private IMqttClient mqttClient;
//创建一个新的MqttFactory实例
var mqttFactory = new MqttFactory();
//使用MqttFactory实例创建一个新的MQTT客户端
mqttClient = mqttFactory.CreateMqttClient();
分别实现客户端不同的功能
//断开连接时
mqttClient.DisconnectedAsync += MqttClient_DisconnectedAsync;
//连接时
mqttClient.ConnectedAsync += MqttClient_ConnectedAsync;
//收到订阅的消息时
mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;
//订阅消息
mqttClient.SubscribeAsync(topicFilter);
主要代码
以下为实现功能的主要代码
public partial class Form1 : Form
{
//订阅状态
public static int substat = 0;
public Form1()
{
InitializeComponent();
}
//定义MQTT实例
private IMqttClient mqttClient;
//MQTT连接状态
bool mqttIsConnected = false;
//连接服务器
private void BTN_connect_Click(object sender, EventArgs e)
{
//检查已连接就返回
if (mqttIsConnected)
return;
//检查网络地址
// 定义正则表达式,用于匹配网络地址
string pattern = @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$";
// 使用正则表达式进行匹配
bool isAddress = Regex.IsMatch(IP.Text, pattern);
if (!isAddress)
{
// 文本框中的内容不符合网络地址格式
MessageBox.Show("请输入正确的地址!");
return;
}
//检查端口号
int number;
bool isInteger = int.TryParse(PORT.Text, out number);
if (!isInteger)
{
// 文本框中的内容不是整数
MessageBox.Show("请输入正确的端口号!");
return;
}
try
{
mqttIsConnected = false;
var mqttFactory = new MqttFactory();
//安全设置
var tlsOptions = new MqttClientTlsOptions
{
UseTls = false,
IgnoreCertificateChainErrors = true,
IgnoreCertificateRevocationErrors = true,
AllowUntrustedCertificates = true
};
//客户端配置
var options = new MqttClientOptions
{
ClientId = ID.Text,
ProtocolVersion = MqttProtocolVersion.V311,
ChannelOptions = new MqttClientTcpOptions
{
Server = IP.Text.Trim(),
Port = int.Parse(this.PORT.Text.Trim()),
TlsOptions = tlsOptions
}
};
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
//判断是否需要密码
if (!string.IsNullOrWhiteSpace(TEXT_USER.Text) && !string.IsNullOrWhiteSpace(TEXT_Password.Text))
{
options.Credentials = new MqttClientCredentials(TEXT_USER.Text, Encoding.UTF8.GetBytes(TEXT_Password.Text));
}
options.CleanSession = true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(500);
mqttClient = mqttFactory.CreateMqttClient();
//事件订阅
mqttClient.DisconnectedAsync += MqttClient_DisconnectedAsync;
mqttClient.ConnectedAsync += MqttClient_ConnectedAsync;
mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;
Task task = mqttClient.ConnectAsync(options, CancellationToken.None);
task.Wait();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error Occurs", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
//连接断开时
private Task MqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
{
//Console.WriteLine($"Mqtt客户端连接断开!");
//重连
//MqttClientTask();
mqttIsConnected = false;
this.BeginInvoke((MethodInvoker)delegate { this.textBox6.AppendText($"时间: {DateTime.Now}"+" Mqtt客户端连接断开!" + Environment.NewLine); });
return Task.CompletedTask;
}
//接收到信息时
private Task MqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
{
//消息
//var msg = System.Text.Encoding.Default.GetString(arg.ApplicationMessage.PayloadSegment.ToArray());
string msg = arg.ApplicationMessage.ConvertPayloadToString();
this.BeginInvoke((MethodInvoker)delegate
{
this.textBox6.AppendText($"时间: {DateTime.Now}" + Environment.NewLine);
this.textBox6.AppendText($"订阅主题: {arg.ApplicationMessage.Topic}" + Environment.NewLine);
this.textBox6.AppendText("接收到的内容:" + Environment.NewLine);
this.textBox6.AppendText(msg + Environment.NewLine);
});
return Task.CompletedTask;
}
//连接成功时
private Task MqttClient_ConnectedAsync(MqttClientConnectedEventArgs arg)
{
this.BeginInvoke((MethodInvoker)delegate { this.textBox6.AppendText($"时间: {DateTime.Now}"+" Mqtt客户端连接成功!" + Environment.NewLine); });
mqttIsConnected = true;
return Task.CompletedTask;
}
//断开连接
private async void BTN_disconnect_Click(object sender, EventArgs e)
{
mqttIsConnected = false;
await mqttClient.DisconnectAsync();
}
/// <summary>
/// The method that handles the button click to start the subscriber.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
/// 订阅话题
private async void BTN_sub_Click(object sender, EventArgs e)
{
if (mqttIsConnected)
{
var Topic = this.TOPIC.Text.Trim();
var qos = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce;
var topicFilter = new MqttTopicFilterBuilder().WithTopic(Topic).WithQualityOfServiceLevel(qos).Build();
await mqttClient.SubscribeAsync(topicFilter);
this.BeginInvoke((MethodInvoker)delegate { this.textBox6.AppendText($"时间: {DateTime.Now}" + " Topic:" + Topic + " 订阅成功!" + Environment.NewLine); });
substat = 1;
}
else
{
this.BeginInvoke((MethodInvoker)delegate { this.textBox6.AppendText("请先连接服务器!" + Environment.NewLine); });
substat = 0;
}
}
//取消订阅话题
private async void BTN_unsub_Click(object sender, EventArgs e)
{
if (mqttIsConnected)
{
string Topic = this.TOPIC.Text.Trim();
await mqttClient.UnsubscribeAsync(Topic);
substat = 0;
this.BeginInvoke((MethodInvoker)delegate { this.textBox6.AppendText($"时间: {DateTime.Now}" + " Topic:" + Topic + " 取消订阅成功!" + Environment.NewLine); });
}
}
private async void BTN_push_Click(object sender, EventArgs e)
{
if (!mqttIsConnected)
{
MessageBox.Show("请连接服务器!");
return;
}
string Topic = this.TOPIC.Text.Trim();
//var qos = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce;
var qos = comboBox1.SelectedIndex;
string conent = Text_push.Text.Trim();
if (string.IsNullOrWhiteSpace(Topic))
{
MessageBox.Show("请输入消息发布的主题!");
return;
}
if (string.IsNullOrWhiteSpace(conent))
{
MessageBox.Show("请输入消息发布的的内容!");
return;
}
try
{
var payload = Encoding.UTF8.GetBytes(conent);
var message = new MqttApplicationMessageBuilder().WithTopic(Topic).WithPayload(payload).WithQualityOfServiceLevel((MqttQualityOfServiceLevel)qos).WithRetainFlag().Build();
await this.mqttClient.PublishAsync(message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error Occurs", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
//((Button)sender).Enabled = true;
}
private void button1_Click(object sender, EventArgs e)
{
using (Form messageBox = new Form())
{
messageBox.Text = "Komax Topic";
messageBox.FormBorderStyle = FormBorderStyle.FixedDialog;
messageBox.StartPosition = FormStartPosition.CenterParent;
messageBox.ClientSize = new System.Drawing.Size(600, 380);
TextBox textBox = new TextBox();
textBox.Multiline = true;
textBox.ReadOnly = true;
textBox.BorderStyle = BorderStyle.None;
textBox.BackColor = this.BackColor;
textBox.Font = this.Font;
textBox.Text = "status/device/material/load" + Environment.NewLine +
"status/scan/material" + Environment.NewLine +
"status/device/material/change" + Environment.NewLine +
"application/production/job/report/counter" + Environment.NewLine +
"application/production/job/quality/acd" + Environment.NewLine +
"application/barcode/request" + Environment.NewLine +
"application/production/job/quality/cfaplus" + Environment.NewLine +
"application/production/job/quality/cfa" + Environment.NewLine +
"application/production/job/verification/crimpheight" + Environment.NewLine +
"application/production/job/verification/crimpwidth" + Environment.NewLine +
"data/change" + Environment.NewLine +
"status/device/production/mode" + Environment.NewLine +
"status/device/state" + Environment.NewLine +
"status/error" + Environment.NewLine +
"application/production/job/quality/genericprocess" + Environment.NewLine +
"application/production/job/verification/insulationcrimpheight" + Environment.NewLine +
"application/production/job/update/progress" + Environment.NewLine +
"application/production/job/state" + Environment.NewLine +
"application/production/job/workflow/step" + Environment.NewLine +
"application/production/job/workflow/task/report" + Environment.NewLine +
"status/network" + Environment.NewLine +
"permission/change" + Environment.NewLine +
"application/production/job/verification/pulloutforce" + Environment.NewLine +
"application/production/job/quality/seal" + Environment.NewLine +
"application/production/job/quality/sleeve" + Environment.NewLine +
"user" + Environment.NewLine +
"application/production/job/quality/vision" + Environment.NewLine +
"application/production/job/verification/wirelength";
textBox.Dock = DockStyle.Fill;
textBox.ContextMenuStrip = new ContextMenuStrip();
textBox.ContextMenuStrip.Items.Add("Copy", null, (s, ea) => { Clipboard.SetText(textBox.SelectedText); });
messageBox.Controls.Add(textBox);
messageBox.ShowDialog();
}
}
}