using Rovinj.Device; using Rovinj.Reader.Silion; using Rovinj.Tunnel; using Rovinj.Tunnel.Plc; using Rovinj.Reader; using System; using System.Collections.Generic; using System.Linq; using System.Media; using System.Text; using System.Threading; using System.Threading.Tasks; using Rovinj.Log; namespace TunnelNuget { /// /// 隧道机实现类 /// public class RfidTunnel : IRfidTunnel { /// /// 是否开始校验数量 /// private volatile bool isStartCheckTags; /// /// 扫描ID的标签 /// private string tagsScanId; /// /// 标签ID列表,可以是EPC或TID /// private List tagIdList = new List(); /// /// 当前PLC的状态 /// private PlcStatus currentPlcStatus; /// /// 隧道是否已连接 /// private bool isTunnelConnected; /// ///通道机接口 /// private ITunnel tunnel; /// /// 线程退出标识 /// private CancellationTokenSource cancellationTokenSource; /// /// 检查标签线程 /// private Thread checkTagsThread; /// /// Silion读写器,支持R2000/E310/E710芯片,支持1、2、3、4、8、16口天线 /// private SilionReader silionReader; public RfidTunnel() { } /// /// 通道机读写器状态变化事件 /// /// /// public void Tunnel_ReaderStateChanged(ITunnel tunnel, TunnelReaderStateChangedEventArgs e) { LogHelper.Error("e.RunningState:" + e.RunningState); if (e.RunningState == 0) { //停止业务 LogHelper.Info("停止业务"); } else if (e.RunningState == 1) { //启动业务 tagsScanId = e.ScanId; LogHelper.Info("启动业务"); } else { LogHelper.Info("其他状态"); //其他状态 } } /// /// 标签报告事件 /// /// /// public void Tunnel_TagsReported(ITunnel tunnel, TunnelTagsReportedEventArgs e) { LogHelper.Error("e.Tags.Count:" + e.Tags.Count); for (int i = 0; i < e.Tags.Count; i++) { Tag tag = e.Tags[i]; //过滤掉不符合扫描ID的标签 if (tag.ScanId != tagsScanId) continue; //如果配置为"TID"且TID不为空,则使用TID;否则使用EPC。检查标签ID是否已存在于 tagIdList 中,避免重复添加。 if (tunnel.TunnelConfig.TagIdFieldName == "TID" && !string.IsNullOrEmpty(tag.TID)) { if (tagIdList.Contains(tag.TID)) continue; tagIdList.Add(tag.TID); LogHelper.Info("tag.TID:" + tag.TID); } else { if (tagIdList.Contains(tag.EPC)) continue; tagIdList.Add(tag.EPC); LogHelper.Info("tag.TID:" + tag.TID); } } } /// /// 通道机PLC状态变化事件 /// /// /// public void Tunnel_PlcStateChanged(ITunnel tunnel, TunnelPlcStateChangedEventArgs e) { currentPlcStatus = e.PlcStatus;//记录当前PLC状态 LogHelper.Info("通道机PLC状态变化事件:" + e.PlcStatus); } /// /// 通道机错误接收事件 /// /// /// /// public void Tunnel_ErrorReceived(ITunnel tunnel, TunnelErrorReceivedEventArgs e) { // 在控制台输出错误信息,包括错误消息和异常详情 Console.WriteLine($"错误信息:{e.ErrorMessage},异常:{e.Exception}"); LogHelper.Error("通道机错误接收事件:" + $"错误信息:{e.ErrorMessage},异常:{e.Exception}"); } /// /// 关闭通道机连接 /// /// /// public void CloseTunnel() { if (tunnel == null) return; if (tunnel.Reader.IsStarted) { tunnel.StopReader(); } StopTunnel(); tunnel.Close(); tunnel = null; isTunnelConnected = false; } /// /// 停止隧道 /// private void StopTunnel() { if (tunnel.IsStarted) tunnel.Stop(); isStartCheckTags = false; if (cancellationTokenSource != null) cancellationTokenSource.Cancel(); if (checkTagsThread != null) checkTagsThread.Join(); } /// /// 连接隧道 /// /// 配置RFID读写器参数 /// 配置PLC连接方式 /// 配置读写器连接方式 public bool ConnectTunnel(SilionReaderConfig readerConfig, ConnectionConfig plcConnectionConfig, TunnelConfig tunnelConfig) { if (!isTunnelConnected) { //创建并打开隧道 tunnel = TunnelFactory.CreateTunnel(TunnelType.SC201, tunnelConfig);//根据实际的设备选择对应的类型,这里假设是SC201 tunnel.TagsReported += Tunnel_TagsReported; //读到标签时触发; tunnel.ReaderStateChanged += Tunnel_ReaderStateChanged; //读写器状态变化 tunnel.PlcStateChanged += Tunnel_PlcStateChanged; //PLC 状态变化 tunnel.ErrorReceived += Tunnel_ErrorReceived; //收到错误时触发 if (tunnel.Open()) { LogHelper.Info("连接成功"); isTunnelConnected = true; //获取读写器能力(支持的发射功率列表) silionReader = tunnel.Reader as SilionReader; if (silionReader.ReaderCapability != null) { //发射率列表 List doubles = new List(); for (int i = 0; i < silionReader.ReaderCapability.TxPowers.Count; i++) { doubles.Add(silionReader.ReaderCapability.TxPowers[i]); LogHelper.Info("发射率列表:" + silionReader.ReaderCapability.TxPowers[i]); } } if (tunnel.Initialize())//复位 { LogHelper.Info("复位成功"); //语音提示 SoundPlayer player = new SoundPlayer(); player.Play(); } return true; } else { LogHelper.Error("连接失败"); tunnel.Close(); isTunnelConnected = false; return false; } } else { CloseTunnel(); return false; } } } }