feat - 添加二次验证超时逻辑,整理代码结构,添加json注释

master
SoulStar 2 months ago
parent 4d215c0ac3
commit a826bb745e

@ -69,9 +69,14 @@ namespace SlnMesnac.Config
public int? WriteCount { get; set; }
/// <summary>
/// 盘点间隔时间(秒)
/// 盘点间隔时间(秒)
/// </summary>
public int? InventoryIntervalSeconds { get; set; }
/// <summary>
/// 二次验证超时时间(毫秒)
/// </summary>
public int? VerifyTimeoutMilliseconds { get; set; }
}
}

@ -187,8 +187,8 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
Console.WriteLine("调用MES获取订单接口");
//调用MES接口获取生产订单信息
//MessageBox.Show("MES订单获取成功!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
string response = "{\"code\":200,\"msg\":\"success\",\"data\":[{\"OrderNo\":\"SS042\",\"ProductCode\":\"4030502500100006\",\"ProductType\":\"钢丝带-ST-井下阻燃钢丝带\",\"ProductName\":\"输送带-井下阻燃钢丝带-ST\",\"ProductSpec\":\"1400mmST/S2500*18+8MT/MTD7.2P15N89\",\"PlanQty\":130.00,\"NextProductNo\":2}]}\r\n";
//string response = await _httpclient.GetMesOrderInfo(lineno, BeginDate.ToString("yyyy-MM-dd"));
//string response = "{\"code\":200,\"msg\":\"success\",\"data\":[{\"OrderNo\":\"SS042\",\"ProductCode\":\"4030502500100006\",\"ProductType\":\"钢丝带-ST-井下阻燃钢丝带\",\"ProductName\":\"输送带-井下阻燃钢丝带-ST\",\"ProductSpec\":\"1400mmST/S2500*18+8MT/MTD7.2P15N89\",\"PlanQty\":130.00,\"NextProductNo\":2}]}\r\n";
string response = await _httpclient.GetMesOrderInfo(lineno, BeginDate.ToString("yyyy-MM-dd"));
Console.WriteLine("接收MES接口返回:" + response);
// 反序列化
try

@ -43,6 +43,8 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
[RegisterAsSingletonAttribute]
public class ProductionLineViewModel : ViewModelBase
{
#region 参数定义
private static StringChange _StringChange;
private String SerialNo = "";
private SerilogHelper _logger;
@ -61,6 +63,11 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
private bool IsVerify = false;
private string LastWrite;
private string LastRFIDEPC;
private CancellationTokenSource? _verifyCts;
#endregion
#region 关联属性
public ObservableCollection<RFIDRecord> RFIDHistoryRecords
{
@ -85,7 +92,7 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
RaisePropertyChanged(() => Deviceinfo);
}
}
/// <summary>
/// 日期时间
/// </summary>
@ -137,6 +144,10 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
}
}
#endregion
#region 构造函数
public ProductionLineViewModel()
{
GetOrderInfoCommand = new RelayCommand<object>(t => RefreshData(t));
@ -173,6 +184,219 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
Log.Information("RFID输送带系统启动");
}
#endregion
#region 核心写入算法
/// <summary>
/// 接收到连续盘点标签返回
/// </summary>
/// <param name="iCombineId"></param>
/// <param name="tagInfos"></param>
private async void RecvIdentifyData_Instance(string iCombineId, List<TagInfo> tagInfos)
{
try
{
//初次写入
if (!IsVerify)
{
//写入前等待标签稳定
if (!IsVerify)
{
await Task.Delay(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteDelaySet ?? 2000);
}
//验证是否已获取订单信息
if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo))
{
MessageBox.Show("请先获取MES订单号", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//查询数据库是否已存在记录
string epcascii = Encoding.ASCII.GetString(tagInfos[0].EPC);
epcascii = epcascii.Replace("\0", "");
List<real_readdata> real_Readdatas = databaseService._helper.Query(x => x.rfidascii == epcascii);
//如果不存在则写入
if (real_Readdatas.Count <= 0)
//if (true)
{
//验证是否已获取序列号
if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo))
{
return;
}
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
//拼接订单号写入标签
string WriteData = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo
+ Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo
+ DateTime.Now.ToString("yy")
+ Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).NextProductNo
+ Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo;
CurrentState = "写入中";
LastRFIDEPC = tagInfos[0].EPCstring;
//写入 三次重写
lock (_lockObj) //锁住写入过程,防止写入的时候开始定时盘点
{
var deviceConfig = appConfig.deviceInfoConfig.FirstOrDefault(x => x.Deviceid == iCombineId);
for (int i = 0; i < deviceConfig.WriteCount; i++)
{
bool writeflag = rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData).GetAwaiter().GetResult();
if (writeflag)
{
LastWrite = WriteData;
IsVerify = true;
// 启动验证超时检测
_verifyCts?.Cancel();
_verifyCts = new CancellationTokenSource();
var token = _verifyCts.Token;
var capturedTagInfos = tagInfos;
var timeoutMs = deviceConfig.VerifyTimeoutMilliseconds ?? 20000;
_ = Task.Run(async () =>
{
try
{
await Task.Delay(timeoutMs, token);
if (IsVerify)
{
Log.Error($"二次验证超时未读到标签,标签已离开,记为写入失败");
DataAdd(iCombineId, capturedTagInfos, false);
}
}
catch (TaskCanceledException) { }
}, token);
rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
return;
}
else
{
Log.Error($"第{i + 1}次写入失败,重试中...");
continue;
}
}
Log.Error($"写入失败,[{tagInfos[0].EPCstring}] 记为失败写入");
//插入失败记录
DataAdd(iCombineId, tagInfos, false);
return;
}
}
else
{
await Task.Run(async () =>
{
await Task.Delay(1000);
await rfidList.FirstOrDefault(x => x.deviceid == iCombineId)!.Set_BeginIdentify();
CurrentState = "盘点中";
});
}
}
else //二次验证流程
{
var judgeString = Encoding.ASCII.GetString(tagInfos[0].EPC);
judgeString = judgeString.Replace("\0", "");
//二次验证如果不通过 重新开始盘点
if (judgeString != LastWrite)
{
// 读到标签但数据不匹配,重置超时(标签仍在天线范围内)
_verifyCts?.Cancel();
_verifyCts = new CancellationTokenSource();
var token = _verifyCts.Token;
var capturedTagInfos = tagInfos;
var deviceConfig = appConfig.deviceInfoConfig.FirstOrDefault(x => x.Deviceid == iCombineId);
var timeoutMs = deviceConfig?.VerifyTimeoutMilliseconds ?? 20000;
_ = Task.Run(async () =>
{
try
{
await Task.Delay(timeoutMs, token);
if (IsVerify)
{
Log.Error($"二次验证超时写入标签超时,标签已离开,记为写入失败");
DataAdd(iCombineId, capturedTagInfos, false);
}
}
catch (TaskCanceledException) { }
}, token);
var tempEPC = LastRFIDEPC;
rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
LastRFIDEPC = tempEPC;
CurrentState = "盘点中";
return;
}
else //二次验证通过
{
_verifyCts?.Cancel();
Log.Information($"验证成功");
//插入成功记录
DataAdd(iCombineId, tagInfos, true);
return;
}
}
}
catch (Exception e)
{
Log.Error($"读结果准备写入时异常:{e.Message}");
CurrentState = "空闲";
}
}
/// <summary>
/// 插入记录
/// </summary>
/// <param name="iCombineId"></param>
/// <param name="tagInfos"></param>
/// <param name="isSuccess"></param>
private void DataAdd(string iCombineId, List<TagInfo> tagInfos, bool isSuccess)
{
IsVerify = false;
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus = isSuccess ? "成功" : "失败";
LastWriteState = isSuccess ? "成功" : "失败";
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = LastWrite;
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC = LastRFIDEPC;
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo = (Convert.ToInt32(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo) + 1).ToString("D2");
//保存写入记录
real_readdata real_Readdata = new real_readdata()
{
objid = Guid.NewGuid().ToString(),
serialno = (Convert.ToInt32(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo) - 1).ToString("D2"),
orderno = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo,
lineno = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo,
producttype = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ProductType,
rfidepc = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC,
rfidascii = LastWrite,
readtime = Convert.ToDateTime(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime),
writetime = Convert.ToDateTime(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime),
writestatus = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus
};
//插入到数据库历史记录中
var a = databaseService._helper.Insert(real_Readdata);
//插入记录到首页临时数据显示
AddRFIDData(iCombineId, tagInfos);
LastRFIDEPC = "";
LastWrite = "";
rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
CurrentState = "盘点中";
return;
}
#endregion
#region 数据流相关
/// <summary>
/// 测试按钮
/// </summary>
/// <param name="t"></param>
private void RefreshData(object? t)
{
Random random = new Random();
@ -196,7 +420,11 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
public RelayCommand<object> GetOrderInfoCommand { get; set; }
/// <summary>
/// 开始订单初次流程
/// </summary>
/// <param name="recipient"></param>
/// <param name="real_Data"></param>
private void RefreshOrderNo(object recipient, Real_DataInfo real_Data)
{
//查询当前订单产线最大序列号
@ -239,6 +467,9 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
CurrentState = "空闲";
}
/// <summary>
/// 初次加载设备信息
/// </summary>
private void LoadDeviceInfo()
{
List<DeviceInfoConfig> DeviceInfos = appConfig.deviceInfoConfig.Where(x => x.Collectid == appConfig.StationCode && x.Deleteflag == 0).ToList();
@ -299,194 +530,16 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
Deviceinfo.Add(real_DataInfo);
}
});
}
/// <summary>
/// 接收到连续盘点标签返回
/// 添加数据的方法
/// </summary>
/// <param name="iCombineId"></param>
/// <param name="tagInfos"></param>
private async void RecvIdentifyData_Instance(string iCombineId, List<TagInfo> tagInfos)
{
try
{
//二次验证
if (IsVerify)
{
var judgeString = Encoding.ASCII.GetString(tagInfos[0].EPC);
judgeString = judgeString.Replace("\0", "");
//二次验证如果不通过 重新开始盘点
if (judgeString != LastWrite)
{
var tempEPC = LastRFIDEPC;
rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
LastRFIDEPC = tempEPC;
CurrentState = "盘点中";
//IsVerify = true;
return;
}
else //二次验证通过
{
Log.Information($"验证成功");
//插入成功记录
DataAdd(iCombineId, tagInfos, true);
return;
}
}
else //正常写入
{
//写入前等待标签稳定
if (!IsVerify)
{
await Task.Delay(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteDelaySet ?? 2000);
}
//验证是否已获取订单信息
if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo))
{
MessageBox.Show("请先获取MES订单号", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//查询数据库是否已存在记录
string epcascii = Encoding.ASCII.GetString(tagInfos[0].EPC);
epcascii = epcascii.Replace("\0", "");
List<real_readdata> real_Readdatas = databaseService._helper.Query(x => x.rfidascii == epcascii);
//如果不存在则写入
if (real_Readdatas.Count <= 0)
//if (true)
{
//验证是否已获取序列号
if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo))
{
return;
}
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
//拼接订单号写入标签
string WriteData = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo
+ Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo
+ DateTime.Now.ToString("yy")
+ Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).NextProductNo
+ Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo;
CurrentState = "写入中";
LastRFIDEPC = tagInfos[0].EPCstring;
//写入 三次重写
lock (_lockObj)
{
var deviceConfig = appConfig.deviceInfoConfig.FirstOrDefault(x => x.Deviceid == iCombineId);
for (int i = 0; i < deviceConfig.WriteCount; i++)
{
bool writeflag = rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData).GetAwaiter().GetResult();
if (writeflag)
{
LastWrite = WriteData;
IsVerify = true;
rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
return;
}
else
{
Log.Error($"第{i + 1}次写入失败,重试中...");
continue;
}
}
Log.Error($"写入失败,[{tagInfos[0].EPCstring}] 记为失败写入");
//插入失败记录
DataAdd(iCombineId, tagInfos, false);
return;
}
}
else
{
await Task.Run(async () =>
{
await Task.Delay(1000);
await rfidList.FirstOrDefault(x => x.deviceid == iCombineId)!.Set_BeginIdentify();
CurrentState = "盘点中";
});
}
}
}
catch (Exception e)
{
Log.Error($"读结果准备写入时异常:{e.Message}");
CurrentState = "空闲";
}
}
/// <summary>
/// 插入记录
/// </summary>
/// <param name="iCombineId"></param>
/// <param name="tagInfos"></param>
/// <param name="isSuccess"></param>
private void DataAdd(string iCombineId, List<TagInfo> tagInfos, bool isSuccess)
{
IsVerify = false;
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus = isSuccess ? "成功" : "失败";
LastWriteState = isSuccess ? "成功" : "失败";
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = LastWrite;
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC = LastRFIDEPC;
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo = (Convert.ToInt32(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo) + 1).ToString("D2");
//保存写入记录
real_readdata real_Readdata = new real_readdata()
{
objid = Guid.NewGuid().ToString(),
serialno = (Convert.ToInt32(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo) - 1).ToString("D2"),
orderno = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo,
lineno = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo,
producttype = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ProductType,
rfidepc = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC,
rfidascii = LastWrite,
readtime = Convert.ToDateTime(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime),
writetime = Convert.ToDateTime(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime),
writestatus = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus
};
//插入到数据库历史记录中
var a = databaseService._helper.Insert(real_Readdata);
//插入记录到首页临时数据显示
AddRFIDData(iCombineId, tagInfos);
LastRFIDEPC = "";
LastWrite = "";
rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
CurrentState = "盘点中";
return;
}
public void RefreshEventArgs(string iCombineId, List<TagInfo> tagInfos)
{
try
{
App.Current.Dispatcher.BeginInvoke((Action)(() =>
{
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC = tagInfos[0].EPCstring;
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = Encoding.ASCII.GetString(tagInfos[0].EPC);
Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}));
}
catch (Exception ex)
{
Log.Information($"异常:{ex.Message}");
}
}
// 添加数据的方法(核心:添加前/后判断行数)
public void AddRFIDData(string iCombineId, List<TagInfo> tagInfos)
{
//// 1. 判断当前行数是否>10是则清空
//if (RFIDHistoryRecords.Count >= 10)
//{
// RFIDHistoryRecords.Clear();
//}
Task.Run(() =>
Task.Run(() =>
{
App.Current.Dispatcher.Invoke(() =>
{
@ -503,8 +556,12 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
});
});
});
}
#endregion
#region 设备状态检测
private void StartCheckStatus()
{
Task.Run(async () =>
@ -590,6 +647,28 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
}
}
/// <summary>
/// 无限重连
/// </summary>
/// <param name="device"></param>
/// <returns></returns>
private async Task Reconnect(RfidAbsractFactory device)
{
var res = false;
do
{
await Task.Delay(1000);
Deviceinfo.FirstOrDefault(x => x.Deviceid == device.deviceid).IsOnline = "未连接";
Log.Information($"[{device.deviceid}]:[{device.ip}:{device.port}]连接中...");
res = await device.ConnectAsync(device.ip, device.port, device.deviceid);
}
while (!res);
}
#endregion
#region 定时盘点
/// <summary>
/// 启动定时盘点
/// </summary>
@ -626,7 +705,7 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
{
try
{
lock(_lockObj)
lock (_lockObj)
{
var rfid = rfidList.FirstOrDefault(x => x.deviceid == deviceId);
if (rfid != null)
@ -644,23 +723,6 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
}
}
/// <summary>
/// 无限重连
/// </summary>
/// <param name="device"></param>
/// <returns></returns>
private async Task Reconnect(RfidAbsractFactory device)
{
var res = false;
do
{
await Task.Delay(1000);
Deviceinfo.FirstOrDefault(x => x.Deviceid == device.deviceid).IsOnline = "未连接";
Log.Information($"[{device.deviceid}]:[{device.ip}:{device.port}]连接中...");
res = await device.ConnectAsync(device.ip, device.port, device.deviceid);
}
while (!res);
}
#endregion
}
}

@ -74,17 +74,30 @@
"deviceInfoConfig": [
{
//ID
"DeviceId": "10001",
//
"Name": "Line1",
//IP:Port
"ConnectStr": "192.168.0.7:20108",
//
"Connectmode": "1",
// RFly_I160RFly_I160
"Devicetype": "RFly_I160",
//
"Collectid": "102",
//线
"Addr": "VM006",
//01
"Deleteflag": "0",
//
"WriteDelaySet": 1000,
//
"WriteCount": 3,
"InventoryIntervalSeconds": 5000
//
"InventoryIntervalSeconds": 5000,
//
"VerifyTimeoutMilliseconds": 20000
},
{
"DeviceId": "10002",
@ -97,7 +110,8 @@
"Deleteflag": "1",
"WriteDelaySet": 1000,
"WriteCount": 3,
"InventoryIntervalSeconds": 5000
"InventoryIntervalSeconds": 5000,
"VerifyTimeoutMilliseconds": 20000
}
],

Loading…
Cancel
Save