246 lines
8.2 KiB
C#
246 lines
8.2 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 隧道机实现类
|
||
/// </summary>
|
||
public class RfidTunnel : IRfidTunnel
|
||
{
|
||
/// <summary>
|
||
/// 是否开始校验数量
|
||
/// </summary>
|
||
private volatile bool isStartCheckTags;
|
||
/// <summary>
|
||
/// 扫描ID的标签
|
||
/// </summary>
|
||
private string tagsScanId;
|
||
/// <summary>
|
||
/// 标签ID列表,可以是EPC或TID
|
||
/// </summary>
|
||
private List<string> tagIdList = new List<string>();
|
||
/// <summary>
|
||
/// 当前PLC的状态
|
||
/// </summary>
|
||
private PlcStatus currentPlcStatus;
|
||
/// <summary>
|
||
/// 隧道是否已连接
|
||
/// </summary>
|
||
private bool isTunnelConnected;
|
||
/// <summary>
|
||
///通道机接口
|
||
/// </summary>
|
||
private ITunnel tunnel;
|
||
/// <summary>
|
||
/// 线程退出标识
|
||
/// </summary>
|
||
private CancellationTokenSource cancellationTokenSource;
|
||
/// <summary>
|
||
/// 检查标签线程
|
||
/// </summary>
|
||
private Thread checkTagsThread;
|
||
/// <summary>
|
||
/// Silion读写器,支持R2000/E310/E710芯片,支持1、2、3、4、8、16口天线
|
||
/// </summary>
|
||
private SilionReader silionReader;
|
||
public RfidTunnel() { }
|
||
|
||
/// <summary>
|
||
/// 通道机读写器状态变化事件
|
||
/// </summary>
|
||
/// <param name="tunnel"></param>
|
||
/// <param name="e"></param>
|
||
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("其他状态");
|
||
//其他状态
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 标签报告事件
|
||
/// </summary>
|
||
/// <param name="tunnel"></param>
|
||
/// <param name="e"></param>
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 通道机PLC状态变化事件
|
||
/// </summary>
|
||
/// <param name="tunnel"></param>
|
||
/// <param name="e"></param>
|
||
public void Tunnel_PlcStateChanged(ITunnel tunnel, TunnelPlcStateChangedEventArgs e)
|
||
{
|
||
currentPlcStatus = e.PlcStatus;//记录当前PLC状态
|
||
LogHelper.Info("通道机PLC状态变化事件:" + e.PlcStatus);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通道机错误接收事件
|
||
/// </summary>
|
||
/// <param name="tunnel"></param>
|
||
/// <param name="e"></param>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
public void Tunnel_ErrorReceived(ITunnel tunnel, TunnelErrorReceivedEventArgs e)
|
||
{
|
||
// 在控制台输出错误信息,包括错误消息和异常详情
|
||
Console.WriteLine($"错误信息:{e.ErrorMessage},异常:{e.Exception}");
|
||
LogHelper.Error("通道机错误接收事件:" + $"错误信息:{e.ErrorMessage},异常:{e.Exception}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭通道机连接
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
public void CloseTunnel()
|
||
{
|
||
if (tunnel == null)
|
||
return;
|
||
|
||
if (tunnel.Reader.IsStarted)
|
||
{
|
||
tunnel.StopReader();
|
||
}
|
||
|
||
StopTunnel();
|
||
tunnel.Close();
|
||
tunnel = null;
|
||
isTunnelConnected = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 停止隧道
|
||
/// </summary>
|
||
private void StopTunnel()
|
||
{
|
||
if (tunnel.IsStarted)
|
||
tunnel.Stop();
|
||
|
||
isStartCheckTags = false;
|
||
|
||
if (cancellationTokenSource != null)
|
||
cancellationTokenSource.Cancel();
|
||
|
||
if (checkTagsThread != null)
|
||
checkTagsThread.Join();
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 连接隧道
|
||
/// </summary>
|
||
/// <param name="readerConfig">配置RFID读写器参数</param>
|
||
/// <param name="plcConnectionConfig">配置PLC连接方式</param>
|
||
/// <param name="tunnelConfig">配置读写器连接方式</param>
|
||
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<double> doubles = new List<double>();
|
||
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;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|