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#

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();
}
}
}
}
}