第三讲:从零构建一个 SECS/GEM Host 主机端程序
关键词:最小化主机程序、建立连接、发送报文、接收事件、完整通信流程模拟
本讲目标
你将掌握如何 独立搭建一个“最小可用”的主机端,也就是:
- 不依赖 Sample 项目
- 用你自己的控制逻辑
- 能连上设备、发指令、收事件
- 能“跑通一条完整业务链”:从建链 -> 发指令 -> 收事件
一、创建项目 & 引入依赖
在 Visual Studio 2022 新建一个 Console App(.NET 6/7/8 都可)
引入 NuGet 包
Install-Package SECS4NET
或在 .csproj
里添加:
<PackageReference Include="SECS4NET" Version="x.x.x" />
二、构建主机通信核心逻辑
1. 建立连接
using SECS4NET;
var gem = new SecsGemBuilder()
.UseHsms()
.ConnectMode(HSMSConnectMode.Active) // 主机模式
.Host("192.168.1.100") // 目标设备 IP
.Port(5000) // 目标端口
.DeviceId(0)
.Build();
await gem.ConnectAsync();
Console.WriteLine("连接已建立!");
2. 接收报文(事件监听)
gem.MessageReceived += OnSecsMessageReceived;
void OnSecsMessageReceived(object sender, SecsMessage e)
{
Console.WriteLine($"收到:S{e.Stream}F{e.Function}");
if (e.Stream == 6 && e.Function == 11)
{
var ceid = e.SecsItem[0].GetValue<ushort>();
Console.WriteLine($"事件触发:CEID = {ceid}");
}
}
3. 发送 S1F13:建立通信(可选)
var msg = new SecsMessage(1, 13, true);
var reply = await gem.SendAsync(msg);
Console.WriteLine("建链回应:" + reply.Stream + "/" + reply.Function);
4. 发送 S2F41:远程命令(最实用)
var remoteCommand = new SecsMessage(2, 41, true,
Item.L(
Item.A("START_LOT"),
Item.L(Item.A("Lot123"), Item.A("Recipe_XYZ"))
)
);
var reply = await gem.SendAsync(remoteCommand);
Console.WriteLine($"远程命令回应:S{reply.Stream}F{reply.Function}");
5. 注册事件(可选但关键)
假设你知道设备有哪些 CEID 和 RPTID,可以注册:
var enableEvent = new SecsMessage(2, 33, true,
Item.L(
Item.U2(1), // CEID = 1
Item.L(Item.U2(100)) // RPTID = 100
)
);
await gem.SendAsync(enableEvent);
然后再定义 RPTID 对应哪些 VIDs:
var defineReport = new SecsMessage(2, 35, true,
Item.L(
Item.U2(100), // RPTID
Item.L(Item.U2(3001)) // VID
)
);
await gem.SendAsync(defineReport);
三、完整运行效果预期
你写完这套主机端后,在和设备连接时应该能做到:
动作 | 预期结果 |
---|---|
连接设备 | 控制台输出 “连接已建立” |
设备触发事件 | 控制台打印 S6F11 + CEID |
主机发命令 | 控制台打印 S2F42 回复 |
注册事件 | 后续设备才会上报 S6F11 |
报文调试 | 可以加上报文打印,观察内容 |
四、推荐封装方式(进阶思路)
如果你要把它嵌入你未来的工具或 EAP 子模块,建议这样封装:
public class SecsHostService
{
private readonly SecsGem _gem;
public SecsHostService(string ip, int port)
{
_gem = new SecsGemBuilder()
.UseHsms()
.ConnectMode(HSMSConnectMode.Active)
.Host(ip)
.Port(port)
.DeviceId(0)
.Build();
_gem.MessageReceived += OnMessage;
}
public Task ConnectAsync() => _gem.ConnectAsync();
private void OnMessage(object sender, SecsMessage e)
{
// 在这里写统一逻辑,比如触发事件、写日志、发送通知
}
public Task SendRemoteCommand(string cmd, params string[] args)
{
var msg = new SecsMessage(2, 41, true,
Item.L(
Item.A(cmd),
Item.L(args.Select(Item.A).ToArray())
)
);
return _gem.SendAsync(msg);
}
}
这样你以后只需要 new SecsHostService()
,就能封装整个主机控制逻辑。
第三讲 · 小结
你已经掌握了如何:
- 完整搭建一个主机端最小程序;
- 与设备建立通信、注册事件、收发指令;
- 监听 S6F11 上报、解析 CEID 内容;
- 把逻辑封装成类,集成进自己的系统或工具。
下一讲会带你进入一个面试中经常被问的区域:
第四讲:SECS 报文结构到底长什么样?怎么读懂一条复杂的 SML?
我们会讲 Item 的层级结构、SML 报文格式、VID 变量的解析逻辑,真正走到“看得懂、改得动”的程度。
只需你一句“继续”,咱们马上出发。