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.
246 lines
8.7 KiB
C#
246 lines
8.7 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.IO;
|
|
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;
|
|
|
|
/// <summary>
|
|
/// 锁对象
|
|
/// </summary>
|
|
private static readonly object _heartBeatLocker = new object();
|
|
|
|
/// <summary>
|
|
/// 工位识别历史记录
|
|
/// </summary>
|
|
public Dictionary<int, int> StationRecord = new Dictionary<int, int>();
|
|
|
|
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: //盘点结果
|
|
ReciveHeartBeatSignal(ip);
|
|
Receive02HEntity data02Hentity = _RfidDataAnalyse.Receive02H(reciveData.Data);
|
|
if (data02Hentity == null || data02Hentity.Data == null)
|
|
{
|
|
return;
|
|
}
|
|
ReciveRFIDSingal(data02Hentity, ip);
|
|
break;
|
|
case 0xBF: //心跳信号
|
|
ReciveHeartBeatSignal(ip);
|
|
if (reciveData.Status != 0x00)
|
|
{
|
|
LogHelper.Instance.Error($"读写器[{ip}]心跳返回异常,异常代码[{reciveData.Status}]");
|
|
}
|
|
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
|
|
{
|
|
//记录当前配方对应的小车
|
|
if (int.Parse(workstationNo) == 1)
|
|
{
|
|
RecipeSendBusiness.RecipeNeededVehicleNo = int.Parse(deviceNo);
|
|
}
|
|
//如果对应位置成功写入,记录上次该工位写入的是该小车,如果下次还是,不再写入(防止重复写入)
|
|
int stationNo = int.Parse(workstationNo);
|
|
int vehicleNo = int.Parse(deviceNo);
|
|
//if (StationRecord.ContainsKey(stationNo)) //判断上次是不是写入的该点位
|
|
//{
|
|
// //上次就写入的该车 就不继续写入了
|
|
// if (StationRecord[stationNo] == vehicleNo)
|
|
// {
|
|
// return;
|
|
// }
|
|
//}
|
|
//写入对应的PLC信号
|
|
if (_workStationHelper.WriteStationSingal(stationNo, vehicleNo))
|
|
{
|
|
////写入成功后记录,上次已写入了该点位,不继续写入
|
|
//if (StationRecord.ContainsKey(stationNo))
|
|
//{
|
|
// StationRecord[stationNo] = vehicleNo;
|
|
//}
|
|
//else
|
|
//{
|
|
// StationRecord.Add(stationNo, vehicleNo);
|
|
//}
|
|
LogHelper.Instance.RfidLog($"{workstationNo}工位, {deviceNo}号车 写入成功[{DateTime.Now.ToString("yy-MM-dd HH:mm:ss:fff")}]");
|
|
}
|
|
else
|
|
{
|
|
LogHelper.Instance.Error($"{workstationNo}工位, {deviceNo}号车 信号写入异常(测试阶段日志) [{DateTime.Now.ToString("yy-MM-dd HH:mm:ss:fff")}]");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Instance.Error("数值转换发生错误", ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 心跳信号接收
|
|
/// </summary>
|
|
public void ReciveHeartBeatSignal(string ip)
|
|
{
|
|
try
|
|
{
|
|
//初次心跳处理
|
|
if (!_heartBeatRecord.ContainsKey(ip))
|
|
{
|
|
LogHelper.Instance.RfidLog($"[{ip}] 初次心跳");
|
|
_heartBeatRecord.Add(ip, DateTime.Now);
|
|
return;
|
|
}
|
|
else //不是初次就更新
|
|
{
|
|
_heartBeatRecord[ip] = DateTime.Now;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Instance.Error($"心跳信号接收异常 {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 心跳识别
|
|
/// </summary>
|
|
/// <param name="o"></param>
|
|
public void HeartbeatJudge(object o)
|
|
{
|
|
try
|
|
{
|
|
foreach (var kvp in _heartBeatRecord.ToArray())
|
|
{
|
|
TimeSpan timeSpan = DateTime.Now - kvp.Value;
|
|
if (timeSpan.TotalSeconds > 10)
|
|
{
|
|
LogHelper.Instance.RfidLog($"[{kvp.Key}] 可能掉线,准备重连");
|
|
_heartBeatRecord.Remove(kvp.Key);
|
|
_touchSocketTcpClient.DisposeClient(kvp.Key);
|
|
_touchSocketTcpClient.CreateTcpClient(kvp.Key, "20108");
|
|
_touchSocketTcpClient.Send(kvp.Key, _RfidDataAnalyse.SendBFH(3));
|
|
_heartBeatRecord.Remove(kvp.Key);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Instance.Error($"心跳信号监测异常 {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
}
|