diff --git a/SlnMesnac.Rfid/Factory/RflyFactory.cs b/SlnMesnac.Rfid/Factory/RflyFactory.cs
index 2058412..f58095d 100644
--- a/SlnMesnac.Rfid/Factory/RflyFactory.cs
+++ b/SlnMesnac.Rfid/Factory/RflyFactory.cs
@@ -96,33 +96,35 @@ namespace SlnMesnac.Rfid.Factory
{
try
{
- lock (GloalVar.TCPLocker)
- {
+ //lock (GloalVar.TCPLocker)
+ //{
m_deviceID = deviceid;
m_strIP = ip;
_tcpClient.SetupAsync(new TouchSocketConfig().SetRemoteIPHost($"{ip}:{port}"));
_tcpClient.ConnectAsync(1500).GetAwaiter().GetResult();
- }
+ //}
_tcpClient.Received = (client, e) =>
{
//从客户端收到信息
//var mes = Encoding.UTF8.GetString(e.Memory.Span.ToArray(), 0, e.Memory.Span.Length);//注意:数据长度是byteBlock.Len
-
+ //只要收到消息,就算心跳
+ if (GloalVar.HeartBeatRecoard.TryGetValue(deviceid, out var value))
+ {
+ GloalVar.HeartBeatRecoard[deviceid] = DateTime.Now;
+ }
+ else
+ {
+ GloalVar.HeartBeatRecoard.Add(deviceid, DateTime.Now);
+ }
byte[] receivedBuffer = new byte[e.Memory.Span.Length];
Array.Copy(e.Memory.Span.ToArray(), 0, receivedBuffer, 0, e.Memory.Span.Length);
if (receivedBuffer.Length > 3)
{
+
//心跳
if (e.Memory.Span.ToArray()[3] == 0xBF)
{
- if (GloalVar.HeartBeatRecoard.TryGetValue(deviceid, out var value))
- {
- GloalVar.HeartBeatRecoard[deviceid] = DateTime.Now;
- }
- else
- {
- GloalVar.HeartBeatRecoard.Add(deviceid, DateTime.Now);
- }
+ //Log.Information($"{m_deviceID},IP:{m_strIP}接收心跳{_stringChange.bytesToHexStr(receivedBuffer, receivedBuffer.Length)}");
}
//连续盘点返回
if (e.Memory.Span.ToArray()[3] == 0x01)
@@ -189,8 +191,9 @@ namespace SlnMesnac.Rfid.Factory
///
public override async Task Set_HeartBeat(byte second)
{
- lock (GloalVar.TCPLocker)
- {
+ //lock (GloalVar.TCPLocker)
+ //{
+ Log.Information($"设置心跳:【{second}】秒");
byte[] data = new byte[3];
data[0] = 0x00;
data[1] = second;
@@ -234,7 +237,7 @@ namespace SlnMesnac.Rfid.Factory
return false;
}
}
- }
+ //}
}
///
@@ -551,8 +554,8 @@ namespace SlnMesnac.Rfid.Factory
byte[] bCRC = new byte[4];
try
{
- lock (GloalVar.TCPLocker)
- {
+ //lock (GloalVar.TCPLocker)
+ //{
#region 指令封装
MessagePack pMessagePack = new MessagePack();
pMessagePack.m_pData = new byte[8];
@@ -594,7 +597,7 @@ namespace SlnMesnac.Rfid.Factory
//}
//return false;
return true;
- }
+ //}
}
catch (Exception e)
{
@@ -613,8 +616,8 @@ namespace SlnMesnac.Rfid.Factory
byte[] bCRC = new byte[4];
try
{
- lock (GloalVar.TCPLocker)
- {
+ //lock (GloalVar.TCPLocker)
+ //{
#region 指令封装
MessagePack pMessagePack = new MessagePack();
@@ -656,7 +659,7 @@ namespace SlnMesnac.Rfid.Factory
// }
//}
return true;
- }
+ //}
}
catch (Exception e)
{
@@ -708,8 +711,8 @@ namespace SlnMesnac.Rfid.Factory
try
{
- lock (GloalVar.TCPLocker)
- {
+ //lock (GloalVar.TCPLocker)
+ //{
#region 指令封装
//自动根据写入数据封装
Base03HENtity rawData = new Base03HENtity()
@@ -788,6 +791,15 @@ namespace SlnMesnac.Rfid.Factory
{
var reciveBuffer = responsedData.Memory.ToArray();
Log.Information($"{m_deviceID}接收写入指令{_stringChange.bytesToHexStr(reciveBuffer, reciveBuffer.Length)}");
+ //只要收到消息,就算心跳
+ if (GloalVar.HeartBeatRecoard.TryGetValue(deviceid, out var value))
+ {
+ GloalVar.HeartBeatRecoard[deviceid] = DateTime.Now;
+ }
+ else
+ {
+ GloalVar.HeartBeatRecoard.Add(deviceid, DateTime.Now);
+ }
if (reciveBuffer[3] == 0x03 && reciveBuffer[4] == 0x00)
{
Log.Information($"写入成功,写入数值{pWriteData}");
@@ -795,7 +807,7 @@ namespace SlnMesnac.Rfid.Factory
}
}
return false;
- }
+ //}
}
catch (Exception e)
diff --git a/SlnMesnac.Rfid/GloalVar.cs b/SlnMesnac.Rfid/GloalVar.cs
index 0532738..cfbebd8 100644
--- a/SlnMesnac.Rfid/GloalVar.cs
+++ b/SlnMesnac.Rfid/GloalVar.cs
@@ -9,8 +9,11 @@ namespace SlnMesnac.Rfid
///
public class GloalVar
{
+ ///
+ /// deviceid,心跳时间
+ ///
public static Dictionary HeartBeatRecoard { get; set; } = new Dictionary();
- public static readonly object TCPLocker = new object();
+ //public static readonly object TCPLocker = new object();
}
}
diff --git a/SlnMesnac.WPF/App.xaml.cs b/SlnMesnac.WPF/App.xaml.cs
index 447482d..0044757 100644
--- a/SlnMesnac.WPF/App.xaml.cs
+++ b/SlnMesnac.WPF/App.xaml.cs
@@ -15,6 +15,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using TouchSocket.Sockets;
@@ -26,6 +27,18 @@ namespace SlnMesnac.WPF
///
public partial class App : Application
{
+ [DllImport("kernel32.dll")]
+ private static extern IntPtr GetConsoleWindow();
+
+ [DllImport("user32.dll")]
+ private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
+
+ [DllImport("kernel32.dll")]
+ private static extern bool AllocConsole();
+
+ private const int SW_HIDE = 0;
+ private const int SW_SHOW = 5;
+
private Mutex _instanceMutex = null;
private LierdaCracker cracker = new LierdaCracker();
public static IServiceProvider ServiceProvider { get; private set; }
@@ -50,6 +63,7 @@ namespace SlnMesnac.WPF
{
try
{
+ HideConsoleIfConfigured();
this.DispatcherUnhandledException += App_DispatcherUnhandledException; //全局异常处理
#region 多实例初始化
// 从命令行参数获取实例ID(如果指定了)
@@ -132,6 +146,34 @@ namespace SlnMesnac.WPF
}
}
+ private void HideConsoleIfConfigured()
+ {
+ try
+ {
+ var config = new ConfigurationBuilder()
+ .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
+ .AddJsonFile("appsettings.json", optional: true)
+ .Build();
+
+ var showConsole = config.GetSection("AppConfig:ShowConsole").Get();
+ var consoleWindow = GetConsoleWindow();
+
+ if (consoleWindow != IntPtr.Zero)
+ {
+ if (showConsole == true)
+ {
+ ShowWindow(consoleWindow, SW_SHOW);
+ }
+ else if (showConsole == false)
+ {
+ ShowWindow(consoleWindow, SW_HIDE);
+ }
+ }
+ }
+ catch
+ {
+ }
+ }
///
/// 从命令行参数获取实例ID
diff --git a/SlnMesnac.WPF/ViewModel/IndexPage/ProductionLineViewModel.cs b/SlnMesnac.WPF/ViewModel/IndexPage/ProductionLineViewModel.cs
index 8f77098..601003a 100644
--- a/SlnMesnac.WPF/ViewModel/IndexPage/ProductionLineViewModel.cs
+++ b/SlnMesnac.WPF/ViewModel/IndexPage/ProductionLineViewModel.cs
@@ -58,7 +58,6 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
private Dictionary _inventoryTimers = new Dictionary();
private ObservableCollection _rfidHistoryRecords = new ObservableCollection();
private RealReadDataImpl databaseService = RealReadDataImpl.Instance;
- private static readonly object _lockObj = new object();
private System.Threading.Timer ReReadTimer;
private bool IsVerify = false;
private string LastWrite;
@@ -197,17 +196,19 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
{
try
{
+ var rfidInfo = rfidList.FirstOrDefault(x => x.deviceid == iCombineId);
+ var deviceInfo = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId);
//初次写入
if (!IsVerify)
{
//写入前等待标签稳定
if (!IsVerify)
{
- await Task.Delay(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteDelaySet ?? 2000);
+ await Task.Delay(deviceInfo.WriteDelaySet ?? 2000);
}
//验证是否已获取订单信息
- if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo))
+ if (string.IsNullOrEmpty(deviceInfo.OrderNo))
{
MessageBox.Show("请先获取MES订单号!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
@@ -223,72 +224,79 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
//if (true)
{
//验证是否已获取序列号
- if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo))
+ if (string.IsNullOrEmpty(deviceInfo.SerialNo))
{
return;
}
- Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ deviceInfo.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
+ string WriteData = deviceInfo.OrderNo
+ + deviceInfo.LineNo
+ DateTime.Now.ToString("yy")
- + Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).NextProductNo
- + Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).SerialNo;
+ + deviceInfo.NextProductNo
+ + deviceInfo.SerialNo;
CurrentState = "写入中";
LastRFIDEPC = tagInfos[0].EPCstring;
- //写入 三次重写
- lock (_lockObj) //锁住写入过程,防止写入的时候开始定时盘点
+ //写入
+ StopInventoryTimer(iCombineId);
+ await rfidInfo.Set_HeartBeat(0);
+ Task.Delay(100).Wait();
+ var deviceConfig = appConfig.deviceInfoConfig.FirstOrDefault(x => x.Deviceid == iCombineId);
+ for (int i = 0; i < deviceConfig.WriteCount; i++)
{
- var deviceConfig = appConfig.deviceInfoConfig.FirstOrDefault(x => x.Deviceid == iCombineId);
- for (int i = 0; i < deviceConfig.WriteCount; i++)
+ bool writeflag = rfidInfo.Set_Write(tagInfos[0].EPC, WriteData).GetAwaiter().GetResult();
+ if (writeflag)
{
- bool writeflag = rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData).GetAwaiter().GetResult();
- if (writeflag)
- {
- LastWrite = WriteData;
- IsVerify = true;
+ LastWrite = WriteData;
+ IsVerify = true;
- // 启动验证超时检测
- _verifyCts?.Cancel();
- _verifyCts = new CancellationTokenSource();
- var token = _verifyCts.Token;
- var capturedTagInfos = tagInfos;
- var timeoutMs = deviceConfig.VerifyTimeoutMilliseconds ?? 20000;
- _ = Task.Run(async () =>
+ rfidInfo.Set_BeginIdentify().GetAwaiter().GetResult();
+
+ // 启动验证超时检测
+ _verifyCts?.Cancel();
+ _verifyCts = new CancellationTokenSource();
+ var token = _verifyCts.Token;
+ var capturedTagInfos = tagInfos;
+ var timeoutMs = deviceConfig.VerifyTimeoutMilliseconds ?? 20000;
+ _ = Task.Run(async () =>
+ {
+ try
{
- try
+ await Task.Delay(timeoutMs, token);
+ if (IsVerify)
{
- await Task.Delay(timeoutMs, token);
- if (IsVerify)
- {
- Log.Error($"二次验证超时未读到标签,标签已离开,记为写入失败");
- DataAdd(iCombineId, capturedTagInfos, false);
- }
+ Log.Error($"二次验证超时未读到标签,标签已离开,记为写入失败");
+ DataAdd(iCombineId, capturedTagInfos, false);
}
- catch (TaskCanceledException) { }
- }, token);
+ }
+ catch (TaskCanceledException) { }
+ }, token);
- rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
- return;
- }
- else
- {
- Log.Error($"第{i + 1}次写入失败,重试中...");
- continue;
- }
+ StartInventoryTimer(iCombineId, deviceConfig.InventoryIntervalSeconds.Value);
+ await rfidInfo.Set_HeartBeat(5);
+ return;
+ }
+ else
+ {
+ Log.Error($"第{i + 1}次写入失败,重试中...");
+ Task.Delay(100).Wait();
+ continue;
}
- Log.Error($"写入失败,[{tagInfos[0].EPCstring}] 记为失败写入");
- //插入失败记录
- DataAdd(iCombineId, tagInfos, false);
- return;
}
+ Log.Error($"写入失败,[{tagInfos[0].EPCstring}] 记为失败写入");
+ //插入失败记录
+ DataAdd(iCombineId, tagInfos, false);
+ StartInventoryTimer(iCombineId, deviceConfig.InventoryIntervalSeconds.Value);
+ await rfidInfo.Set_HeartBeat(5);
+ return;
+
}
else
{
await Task.Run(async () =>
{
await Task.Delay(1000);
- await rfidList.FirstOrDefault(x => x.deviceid == iCombineId)!.Set_BeginIdentify();
+ await rfidInfo!.Set_BeginIdentify();
CurrentState = "盘点中";
});
}
@@ -312,17 +320,15 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
try
{
await Task.Delay(timeoutMs, token);
- if (IsVerify)
- {
- Log.Error($"二次验证超时写入标签超时,标签已离开,记为写入失败");
- DataAdd(iCombineId, capturedTagInfos, false);
- }
+ Log.Error($"二次验证超时写入标签超时,标签已离开,记为写入失败");
+ DataAdd(iCombineId, capturedTagInfos, false);
}
catch (TaskCanceledException) { }
}, token);
+ IsVerify = false;
var tempEPC = LastRFIDEPC;
- rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
+ rfidInfo.Set_BeginIdentify().GetAwaiter().GetResult();
LastRFIDEPC = tempEPC;
CurrentState = "盘点中";
return;
@@ -352,26 +358,30 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
///
private void DataAdd(string iCombineId, List tagInfos, bool isSuccess)
{
+ var deviceInfo = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId);
+ var rfidInfo = rfidList.FirstOrDefault(x => x.deviceid == iCombineId);
+
+ var deviceConfig = appConfig.deviceInfoConfig.FirstOrDefault(x => x.Deviceid == iCombineId);
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 ? "成功" : "失败";
+ deviceInfo.WriteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ deviceInfo.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");
+ deviceInfo.RfidASCII = LastWrite;
+ deviceInfo.RfidEPC = LastRFIDEPC;
+ deviceInfo.SerialNo = (Convert.ToInt32(deviceInfo.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,
+ serialno = (Convert.ToInt32(deviceInfo.SerialNo) - 1).ToString("D2"),
+ orderno = deviceInfo.OrderNo,
+ lineno = deviceInfo.LineNo,
+ producttype = deviceInfo.ProductType,
+ rfidepc = deviceInfo.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
+ readtime = Convert.ToDateTime(deviceInfo.ReadTime),
+ writetime = Convert.ToDateTime(deviceInfo.WriteTime),
+ writestatus = deviceInfo.WriteStatus
};
//插入到数据库历史记录中
@@ -383,7 +393,8 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
LastRFIDEPC = "";
LastWrite = "";
- rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult();
+ rfidInfo.Set_BeginIdentify().GetAwaiter().GetResult();
+ StartInventoryTimer(iCombineId, deviceConfig.InventoryIntervalSeconds.Value);
CurrentState = "盘点中";
return;
}
@@ -681,6 +692,7 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
};
timer.Tick += (s, e) => OnInventoryTimerTick(deviceId);
timer.Start();
+ //OnInventoryTimerTick(deviceId);
_inventoryTimers[deviceId] = timer;
Log.Information($"设备 {deviceId} 启动定时盘点,间隔 {intervalSeconds} ms");
}
@@ -705,16 +717,13 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
{
try
{
- lock (_lockObj)
+ var rfid = rfidList.FirstOrDefault(x => x.deviceid == deviceId);
+ if (rfid != null)
{
- var rfid = rfidList.FirstOrDefault(x => x.deviceid == deviceId);
- if (rfid != null)
- {
- //Log.Information($"设备 {deviceId} 执行定时盘点");
- //await rfid.Set_StopIdentify();
- //await Task.Delay(100);
- rfid.Set_BeginIdentify().GetAwaiter().GetResult();
- }
+ //Log.Information($"设备 {deviceId} 执行定时盘点");
+ //await rfid.Set_StopIdentify();
+ //await Task.Delay(100);
+ rfid.Set_BeginIdentify().GetAwaiter().GetResult();
}
}
catch (Exception ex)
diff --git a/SlnMesnac.WPF/appsettings.json b/SlnMesnac.WPF/appsettings.json
index 723f600..efd94f3 100644
--- a/SlnMesnac.WPF/appsettings.json
+++ b/SlnMesnac.WPF/appsettings.json
@@ -8,6 +8,8 @@
},
"AllowedHosts": "*",
"AppConfig": {
+ //是否显示控制台
+ "ShowConsole": false,
"logPath": "D:\\net6.0-windows\\log",
"InstanceDataPath": "D:\\net6.0-windows\\log",
"SqlConfig": [
@@ -93,7 +95,7 @@
//初次读到数据后写入数据延迟设置,单位毫秒
"WriteDelaySet": 1000,
//写入失败重试次数(每次写入设置为五秒超时时间)
- "WriteCount": 3,
+ "WriteCount": 30,
//定时重置盘点间隔时间,单位毫秒
"InventoryIntervalSeconds": 5000,
//二次验证超时时间,单位毫秒