286 lines
9.3 KiB
C#
286 lines
9.3 KiB
C#
|
|
using LolaiService.Global;
|
|||
|
|
using Rovinj.Device;
|
|||
|
|
using Rovinj.Log;
|
|||
|
|
using Rovinj.Reader;
|
|||
|
|
using Rovinj.Reader.Silion;
|
|||
|
|
using Rovinj.Tunnel;
|
|||
|
|
using Rovinj.Tunnel.Plc;
|
|||
|
|
|
|||
|
|
namespace LolaiService.Devices.Tunnel
|
|||
|
|
{
|
|||
|
|
/// <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;
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <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 (GlobalData.tunnel == null)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (GlobalData.tunnel.Reader.IsStarted)
|
|||
|
|
{
|
|||
|
|
GlobalData.tunnel.StopReader();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
StopTunnel();
|
|||
|
|
GlobalData.tunnel.Close();
|
|||
|
|
GlobalData.tunnel = null;
|
|||
|
|
GlobalData.isTunnelConnected = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 停止隧道
|
|||
|
|
/// </summary>
|
|||
|
|
private void StopTunnel()
|
|||
|
|
{
|
|||
|
|
if (GlobalData.tunnel.IsStarted)
|
|||
|
|
GlobalData.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 (!GlobalData.isTunnelConnected)
|
|||
|
|
{
|
|||
|
|
//创建并打开隧道
|
|||
|
|
GlobalData.tunnel = TunnelFactory.CreateTunnel(TunnelType.SC201, tunnelConfig);//根据实际的设备选择对应的类型,这里假设是SC201
|
|||
|
|
GlobalData.tunnel.TagsReported += Tunnel_TagsReported; //读到标签时触发;
|
|||
|
|
GlobalData.tunnel.ReaderStateChanged += Tunnel_ReaderStateChanged; //读写器状态变化
|
|||
|
|
GlobalData.tunnel.PlcStateChanged += Tunnel_PlcStateChanged; //PLC 状态变化
|
|||
|
|
GlobalData.tunnel.ErrorReceived += Tunnel_ErrorReceived; //收到错误时触发
|
|||
|
|
if (GlobalData.tunnel.Open())
|
|||
|
|
{
|
|||
|
|
LogHelper.Info("连接成功");
|
|||
|
|
|
|||
|
|
GlobalData.isTunnelConnected = true;
|
|||
|
|
|
|||
|
|
//获取读写器能力(支持的发射功率列表)
|
|||
|
|
silionReader = GlobalData.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 (GlobalData.tunnel.Initialize())//复位
|
|||
|
|
{
|
|||
|
|
LogHelper.Info("复位成功");
|
|||
|
|
//语音提示
|
|||
|
|
//SoundPlayer player = new SoundPlayer();
|
|||
|
|
//player.Play();
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
LogHelper.Error("连接失败");
|
|||
|
|
GlobalData.tunnel.Close();
|
|||
|
|
GlobalData.isTunnelConnected = false;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
CloseTunnel();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 隧道关门
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public string CloseDoor()
|
|||
|
|
{
|
|||
|
|
if (GlobalData.tunnel == null)
|
|||
|
|
{
|
|||
|
|
return "隧道机未连接";
|
|||
|
|
}
|
|||
|
|
if (GlobalData.tunnel.CloseDoor())
|
|||
|
|
{
|
|||
|
|
return "已关门";
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return "关门失败";
|
|||
|
|
}
|
|||
|
|
//MessageBox.Show(string.Format(crm.GetString("ExecuteCommandFailed"), btn_CloseDoor.Text));
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 隧道开门
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public string OpenDoor()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
if (GlobalData.tunnel == null)
|
|||
|
|
{
|
|||
|
|
return "隧道机未连接";
|
|||
|
|
}
|
|||
|
|
if (GlobalData.tunnel.OpenDoor())
|
|||
|
|
{
|
|||
|
|
return "已开门";
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return "开门失败";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|