You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
6.4 KiB
C#
190 lines
6.4 KiB
C#
using HighWayIot.Log4net;
|
|
using HighWayIot.Plc.PlcHelper;
|
|
using HighWayIot.Repository.domain;
|
|
using HighWayIot.Repository.service;
|
|
using HighWayIot.Rfid;
|
|
using HighWayIot.Rfid.Entity;
|
|
using HighWayIot.TouchSocket;
|
|
using HighWayIot.Winform.Properties;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace HighWayIot.Winform.Business
|
|
{
|
|
/// <summary>
|
|
/// TCP数据工厂类
|
|
/// </summary>
|
|
public class TCPClientFactory
|
|
{
|
|
/// <summary>
|
|
/// 标签服务类
|
|
/// </summary>
|
|
private ZxTagSettingService _tagrService = ZxTagSettingService.Instance;
|
|
|
|
/// <summary>
|
|
/// 标签实体类
|
|
/// </summary>
|
|
private List<ZxTagSettingEntity> _tagSetting;
|
|
|
|
/// <summary>
|
|
/// 读写器服务类
|
|
/// </summary>
|
|
private ZxReaderSettingService _readerService = ZxReaderSettingService.Instance;
|
|
|
|
/// <summary>
|
|
/// 读写器实体类
|
|
/// </summary>
|
|
private List<ZxReaderSettingEntity> _readerSetting;
|
|
|
|
/// <summary>
|
|
/// RFID数据分析
|
|
/// </summary>
|
|
private RfidDataAnalyse _RfidDataAnalyse = new RfidDataAnalyse();
|
|
|
|
/// <summary>
|
|
/// PLC
|
|
/// </summary>
|
|
private WorkStationHelper _workStationHelper = new WorkStationHelper();
|
|
|
|
/// <summary>
|
|
/// TCP客户端
|
|
/// </summary>
|
|
private TouchSocketTcpClient _touchSocketTcpClient = TouchSocketTcpClient.Instance;
|
|
|
|
/// <summary>
|
|
/// 心跳检测
|
|
/// </summary>
|
|
private Dictionary<string, DateTime> _heartBeatRecord = new Dictionary<string, DateTime>();
|
|
|
|
/// <summary>
|
|
/// Timer
|
|
/// </summary>
|
|
private Timer _heartbeatTimer;
|
|
|
|
public TCPClientFactory()
|
|
{
|
|
_tagSetting = _tagrService.GetTagInfos();
|
|
_readerSetting = _readerService.GetReaderInfos();
|
|
_heartbeatTimer = new Timer(new TimerCallback(HeartbeatJudge), null, 0, 10000);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 对接收到的数据进行初步解析分发到各个报文类型的解析类中
|
|
/// </summary>
|
|
public void ReciveDataRoute(byte[] bytes, string ip)
|
|
{
|
|
BaseReciveDataEntity reciveData = BaseRFIDDataAnalyse.BaseReceiveAnalyse(bytes);
|
|
if(reciveData == null)
|
|
{
|
|
return;
|
|
}
|
|
switch (reciveData.Code)
|
|
{
|
|
case 0x02: //盘点结果
|
|
Receive02HEntity data02Hentity = _RfidDataAnalyse.Receive02H(reciveData.Data);
|
|
if (data02Hentity == null || data02Hentity.Data == null)
|
|
{
|
|
return;
|
|
}
|
|
ReciveRFIDSingal(data02Hentity, ip);
|
|
ReciveHeartBeatSignal(ip);
|
|
break;
|
|
case 0xBF: //心跳信号
|
|
ReciveHeartBeatSignal(ip);
|
|
break;
|
|
default:
|
|
LogHelper.Instance.Error($"接收到未知报文,识别代码[{reciveData.Code.ToString("X2")}]");
|
|
return;
|
|
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 接收信息的信号
|
|
/// </summary>
|
|
/// <param name="bytes"></param>
|
|
public void ReciveRFIDSingal(Receive02HEntity entity, string ip)
|
|
{
|
|
//找到读取次数最大的标签EPC
|
|
byte[] epcData = entity.Data.Where(x => x.Count == entity.Data.Max(y => y.Count)).First().EPC;
|
|
|
|
//标签号byte数组转换成字符串
|
|
string epcResult = string.Join(" ", epcData.Select(x => x.ToString("X2")));
|
|
|
|
//根据IP和标签EPC获取工位和对应设备号
|
|
string deviceNo = _tagSetting.Where(x => x.RfidEpc == epcResult).FirstOrDefault().DeviceNo;
|
|
string workstationNo = _readerSetting.Where(x => x.RfidIp == ip).FirstOrDefault().WorkstationNo;
|
|
|
|
if (string.IsNullOrEmpty(deviceNo))
|
|
{
|
|
LogHelper.Instance.Error($"未查询到 [{epcResult}] 标签相关的信息!");
|
|
return;
|
|
}
|
|
if (string.IsNullOrEmpty(workstationNo))
|
|
{
|
|
LogHelper.Instance.Error($"未查询到 [{ip}] 读写器相关的信息!");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
///写入对应的PLC信号
|
|
_workStationHelper.WriteStationSingal(int.Parse(workstationNo), int.Parse(deviceNo));
|
|
LogHelper.Instance.RfidLog($"{workstationNo}工位, {deviceNo}号车");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Instance.Error("数值转换发生错误", ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 心跳信号接收
|
|
/// </summary>
|
|
public void ReciveHeartBeatSignal(string ip)
|
|
{
|
|
//if(entity.Status != 0x00)
|
|
//{
|
|
// string workstationNo = _readerService.GetWorkstateNoByIp(ip);
|
|
// LogHelper.Instance.Error($"读写器编号[{workstationNo}]心跳返回异常,异常代码[{entity.Status.ToString("X2")}],系统时间[{entity.Systick}]");
|
|
//}
|
|
|
|
//初次心跳处理
|
|
if (!_heartBeatRecord.ContainsKey(ip))
|
|
{
|
|
LogHelper.Instance.RfidLog($"[{ip}] 初次心跳");
|
|
_heartBeatRecord.Add(ip, DateTime.Now);
|
|
return;
|
|
}
|
|
else //不是初次就更新
|
|
{
|
|
_heartBeatRecord[ip] = DateTime.Now;
|
|
}
|
|
|
|
//心跳异常处理
|
|
}
|
|
|
|
public void HeartbeatJudge(object o)
|
|
{
|
|
foreach (var kvp in _heartBeatRecord.ToArray())
|
|
{
|
|
DateTime lastTime = kvp.Value;
|
|
TimeSpan timeSpan = DateTime.Now - lastTime;
|
|
if (timeSpan > TimeSpan.FromSeconds(16))
|
|
{
|
|
LogHelper.Instance.RfidLog($"[{kvp.Key}] 可能掉线,准备重连");
|
|
_heartBeatRecord.Remove(kvp.Key);
|
|
_touchSocketTcpClient.DisposeClient(kvp.Key).GetAwaiter().GetResult();
|
|
_touchSocketTcpClient.CreateTcpClient(kvp.Key, "20108");
|
|
_touchSocketTcpClient.Send(kvp.Key, _RfidDataAnalyse.SendBFH(5)).GetAwaiter().GetResult();
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|