using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using GalaSoft.MvvmLight; using HslCommunication.Enthernet; using Microsoft.Extensions.DependencyInjection; using Models; using Serilog; using SlnMesnac.Common; using SlnMesnac.Config; using SlnMesnac.Model.domain; using SlnMesnac.Model.dto; using SlnMesnac.Model.Enum; using SlnMesnac.Repository; using SlnMesnac.Repository.service; using SlnMesnac.Rfid; using SlnMesnac.Rfid.Enum; using SlnMesnac.Serilog; using SlnMesnac.TouchSocket; using SlnMesnac.WPF.Attribute; using SlnMesnac.WPF.Model; using SqlSugar; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Threading; using TouchSocket.Core; using static Microsoft.WindowsAPICodePack.Shell.PropertySystem.SystemProperties.System; using Task = System.Threading.Tasks.Task; namespace SlnMesnac.WPF.ViewModel.IndexPage { [RegisterAsSingletonAttribute] public class ProductionLineViewModel : ViewModelBase { private static StringChange _StringChange; private String SerialNo = ""; private SerilogHelper _logger; private ISqlSugarClient? sqlSugarClient; //容器里面的读写器集合 public List rfidList; private AppConfig appConfig; public TcpServer _TcpServer; private DispatcherTimer _timer; private ObservableCollection _rfidHistoryRecords = new ObservableCollection(); public ObservableCollection RFIDHistoryRecords { get { return _rfidHistoryRecords; } set { _rfidHistoryRecords = value; RaisePropertyChanged(() => RFIDHistoryRecords); } } ChangeTypeViewModel ChangeTypeView; /// /// 日期时间 /// private DateTime _currentDateTime; public DateTime CurrentDateTime { get => _currentDateTime; set { if (_currentDateTime != value) { _currentDateTime = value; RaisePropertyChanged(() => CurrentDateTime); } } } /// /// 上一次写入状态 /// private string _lastWriteState; public string LastWriteState { get => _lastWriteState; set { if (_lastWriteState != value) { _lastWriteState = value; RaisePropertyChanged(() => LastWriteState); } } } /// /// RFID连接状态 /// private string _rfidConnectState; public string RFIDConnectState { get => _rfidConnectState; set { if (_rfidConnectState != value) { _rfidConnectState = value; RaisePropertyChanged(() => RFIDConnectState); } } } public ProductionLineViewModel() { GetOrderInfoCommand = new RelayCommand(t => RefreshData(t)); ChangeTypeView = App.ServiceProvider.GetService(); // 构造函数里注册 WeakReferenceMessenger.Default.Register(this, RefreshOrderNo); _StringChange = App.ServiceProvider.GetService(); _logger = App.ServiceProvider.GetService(); appConfig = App.ServiceProvider.GetService(); sqlSugarClient = App.ServiceProvider.GetService(); _TcpServer = App.ServiceProvider.GetRequiredService(); rfidList = App.ServiceProvider.GetRequiredService>(); rfidList.ForEach(rfid => { rfid._Action += RecvIdentifyData_Instance; //rfid._RefreshLogMessageAction += RefreshLogMessage; }); LoadDeviceInfo(); StartCheckStatus(); //GetRFIDHistoryRecords(); _currentDateTime = DateTime.Now; _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) // 每秒更新一次 }; _timer.Tick += (s, e) => { CurrentDateTime = DateTime.Now; }; _timer.Start(); Log.Information("RFID输送带系统启动"); } private void RefreshData(object? t) { Random random = new Random(); string ss = random.Next(10, 99).ToString(); string EPCstring = "JSSD" + ss; List tagInfos = new List(); TagInfo tagInfo = new TagInfo() { EPCstring = "JSSD" + ss, EPC = Encoding.ASCII.GetBytes(EPCstring), }; tagInfos.Add(tagInfo); Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").RfidEPC = _StringChange.bytesToHexStr(tagInfos[0].EPC, tagInfos[0].EPC.Length); Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").RfidASCII = EPCstring; Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").WriteStatus = "成功"; Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Deviceinfo.FirstOrDefault(x => x.Deviceid == "10001").WriteTime = DateTime.Now.AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss"); RecvIdentifyData_Instance("10001", tagInfos); } public RelayCommand GetOrderInfoCommand { get; set; } private void RefreshOrderNo(object recipient, Real_DataInfo real_Data) { //查询当前订单产线最大序列号 List real_Readdatas = sqlSugarClient.Queryable().Where(expression: x => x.orderno == real_Data.OrderNo && x.lineno == real_Data.LineNo).ToList(); string SNo = ""; if (real_Readdatas.Count > 0) { SNo = real_Readdatas.Max(x => x.serialno); SNo = (Convert.ToInt32(SNo) + 1).ToString("D2"); } else { SNo = "1"; } Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).SerialNo = Convert.ToInt32(SNo).ToString("D2"); Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).OrderNo = real_Data.OrderNo; Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).ProductType = real_Data.ProductType; Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).LineNo = real_Data.LineNo; Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).RfidCount = real_Data.RfidCount; Deviceinfo.FirstOrDefault(x => x.Deviceid == real_Data.Deviceid).NextProductNo = real_Data.NextProductNo; rfidList.FirstOrDefault(x => x.deviceid == real_Data.Deviceid).Set_BeginIdentify().GetAwaiter().GetResult(); } private void LoadDeviceInfo() { List DeviceInfos = appConfig.deviceInfoConfig.Where(x => x.Collectid == appConfig.StationCode && x.Deleteflag == 0).ToList(); List real_DataInfos = new List(); foreach (var item in DeviceInfos) { Real_DataInfo real_DataInfo = new Real_DataInfo() { Name = item.Name, Deviceid = item.Deviceid, Connectstr = item.Connectstr, LineName = item.Name, LineNo = item.Addr, OrderNo = "", ProductType = "", WriteCount = "", RfidCount = "", IsOnline = "未连接", RfidASCII = "", RfidEPC = "", ReadTime = "", WriteTime = "", ProductStatus = "", WriteStatus = "", }; real_DataInfos.Add(real_DataInfo); } //Real_DataInfo real_DataInfo = new Real_DataInfo() //{ // Name = "1", // Deviceid = "10001", // Connectstr = "192.168.0.1:20108", // LineNo = "6#", // OrderNo = "123456", // ProductType = "整芯带", // WriteCount = "0", // RfidCount = "20", // IsOnline = "未连接", // RfidASCII = "0", // RfidEPC = "0", // ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), // WriteTime = DateTime.Now.AddSeconds(10).ToString("yyyy-MM-dd HH:mm:ss"), // ProductStatus = "生产中", // WriteStatus = "写入成功", //}; //Real_DataInfo real_DataInfo2 = new Real_DataInfo() //{ // Name = "2", // Deviceid = "10002", // Connectstr = "127.0.0.1:20108", // LineNo = "7#", // OrderNo = "123456", // ProductType = "整芯带", // WriteCount = "0", // RfidCount = "20", // IsOnline = "未连接", // RfidASCII = "0", // RfidEPC = "0", // ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), // WriteTime = DateTime.Now.AddSeconds(10).ToString("yyyy-MM-dd HH:mm:ss"), // ProductStatus = "生产中", // WriteStatus = "写入成功", //}; //real_DataInfos.Add(real_DataInfo); //real_DataInfos.Add(real_DataInfo2); App.Current.Dispatcher.Invoke(() => { Deviceinfo.Clear(); foreach (var item in real_DataInfos) { Real_DataInfo real_DataInfo = new Real_DataInfo() { Name = item.Name, Deviceid = item.Deviceid, Connectstr = item.Connectstr, LineName = item.Name, LineNo = item.LineNo, OrderNo = item.OrderNo, ProductType = item.ProductType, WriteCount = item.WriteCount, RfidCount = item.RfidCount, IsOnline = item.IsOnline, RfidASCII = item.RfidASCII, ReadTime = item.ReadTime, WriteTime = item.WriteTime, ProductStatus = item.ProductStatus, WriteStatus = item.WriteStatus, RfidEPC = item.RfidEPC, }; Deviceinfo.Add(real_DataInfo); } }); } /// /// 接收到连续盘点标签返回 /// /// /// private async void RecvIdentifyData_Instance(string iCombineId, List tagInfos) { string info = ""; try { if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo)) { MessageBox.Show("请先获取MES订单号!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //读到停止连续盘点 //bool stopflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_StopIdentify(); //查询数据库是否已存在记录 bool iflag = false; string epcascii = Encoding.ASCII.GetString(tagInfos[0].EPC); epcascii = epcascii.Replace("\0", ""); List real_Readdatas = sqlSugarClient.Queryable().Where(expression: x => x.rfidascii == epcascii).ToList(); //如果不存在则写入 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; //写入 三次重写 bool writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData); if (!writeflag) { Log.Error($"第一次写入失败,重试中..."); writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData); if (!writeflag) { Log.Error($"第二次写入失败,重试中..."); writeflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_Write(tagInfos[0].EPC, WriteData); if (!writeflag) { Log.Error($"第三次写入失败,立即开始重新盘点"); LastWriteState = "失败"; rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_BeginIdentify().GetAwaiter().GetResult(); return; } } } Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus = "成功"; LastWriteState = "成功"; Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII = WriteData; Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC = tagInfos[0].EPCstring; 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() { 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 = WriteData, 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 = sqlSugarClient.Ado.Context.CopyNew().Insertable(real_Readdata).ExecuteCommand(); //刷新界面 //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"); //RefreshEventArgs(iCombineId, tagInfos); AddRFIDData(iCombineId, tagInfos); } await Task.Run(async () => { await Task.Delay(1000); await rfidList.FirstOrDefault(x => x.deviceid == iCombineId)!.Set_BeginIdentify(); }); } catch (Exception e) { Log.Error($"读结果准备写入时异常:{e.Message}"); } finally { } } public void RefreshEventArgs(string iCombineId, List 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 tagInfos) { //// 1. 判断当前行数是否>10,是则清空 //if (RFIDHistoryRecords.Count >= 10) //{ // RFIDHistoryRecords.Clear(); //} App.Current.Dispatcher.Invoke(() => { RFIDHistoryRecords.Insert(0, new RFIDRecord { OrderNumber = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo, LineNumber = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).LineNo, ProductType = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ProductType, OriginalEPC = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidEPC, RFIDCode = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).RfidASCII, ReadTime = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime, WriteTime = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).ReadTime, WriteStatus = Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).WriteStatus // 模拟1条失败数据 }); //RFIDHistoryRecords.OrderByDescending(x => x.ReadTime).ToList(); }); } private ObservableCollection _Deviceinfo = new ObservableCollection(); public ObservableCollection Deviceinfo { get { return _Deviceinfo; } set { _Deviceinfo = value; RaisePropertyChanged(() => Deviceinfo); } } private void StartCheckStatus() { Task.Run(async () => { while (true) { try { #region RFID状态 //RefreshLogMessage("检测设备状态"); var batches = SplitListIntoBatches(rfidList, 10); for (int i = 0; i < batches.Count; i++) { var currentBatch = batches[i]; // 显示当前批次信息(UI线程) Console.WriteLine($"{DateTime.Now}开始检测第{i + 1}批(共{currentBatch.Count}个设备)\r\n"); // 异步检测当前批次的设备状态(不阻塞UI) await DetectDeviceBatchAsync(currentBatch); // 批次之间的间隔(最后一批无需等待) if (i < batches.Count - 1) { Console.WriteLine($"{DateTime.Now}第{i + 1}批检测完成,共{batches.Count}批,等待{1000 / 1000}秒后检测下一批\r\n"); await Task.Delay(10); } } #endregion RFID状态 } catch (Exception ex) { Log.Information($"监听设备状态异常:{ex.Message}"); } await Task.Delay(1000 * 20); } }); } private List> SplitListIntoBatches(List sourceList, int batchSize) { var batches = new List>(); for (int i = 0; i < sourceList.Count; i += batchSize) { // 截取每批的设备(最后一批可能不足10个) var batch = sourceList.Skip(i).Take(batchSize).ToList(); batches.Add(batch); } return batches; } private async Task DetectDeviceBatchAsync(List batch) { // 并行检测当前批次的设备(可选,根据接口性能调整) var detectionTasks = batch.Select(device => DetectSingleDeviceAsync(device)); // 等待当前批次所有设备检测完成 await Task.WhenAll(detectionTasks); } private async Task DetectSingleDeviceAsync(RfidAbsractFactory device) { try { //基于心跳检测的断线重连机制 if (GloalVar.HeartBeatRecoard.TryGetValue(device.deviceid, out var value)) { if (value.AddSeconds(15) < DateTime.Now) { await Reconnect(device); RFIDConnectState = "已连接"; } } else { await Reconnect(device); RFIDConnectState = "已连接"; var res = false; //无限获取心跳返回报文 Log.Information($"准备第一次获取心跳"); res = await device.Set_HeartBeat(5); } } catch (Exception ex) { Log.Information($"更新RFID状态异常:{ex.Message}", ex); } } /// /// 无限重连 /// /// /// private async Task Reconnect(RfidAbsractFactory device) { var res = false; do { RFIDConnectState = "未连接"; Log.Information($"[{device.deviceid}]:[{device.ip}:{device.port}]连接中..."); res = await device.ConnectAsync(device.ip, device.port, device.deviceid); } while (!res); } } }