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.

593 lines
22 KiB
C#

using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
4 weeks ago
using Microsoft.Extensions.DependencyInjection;
2 weeks ago
using Serilog;
using SlnMesnac.Common;
4 weeks ago
using SlnMesnac.Config;
using SlnMesnac.Model.domain;
using SlnMesnac.Model.dto;
using SlnMesnac.Model.Enum;
using SlnMesnac.Repository;
4 weeks ago
using SlnMesnac.Repository.service;
using SlnMesnac.Rfid;
using SlnMesnac.Rfid.Enum;
4 weeks ago
using SlnMesnac.Serilog;
using SlnMesnac.WPF.Attribute;
using SlnMesnac.WPF.Model;
using SlnMesnac.WPF.Page.IndexPage;
4 weeks ago
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;
4 weeks ago
using System.Windows.Threading;
using TouchSocket.Core;
using TouchSocket.Sockets;
4 weeks ago
using static Microsoft.WindowsAPICodePack.Shell.PropertySystem.SystemProperties.System;
using Task = System.Threading.Tasks.Task;
namespace SlnMesnac.WPF.ViewModel.IndexPage
{
[RegisterAsSingletonAttribute]
public class ProductionLineViewModel : ObservableObject
4 weeks ago
{
private static StringChange _StringChange;
private String SerialNo = "";
4 weeks ago
private SerilogHelper _logger;
//容器里面的读写器集合
public List<RfidAbsractFactory> rfidList;
private AppConfig appConfig;
private DispatcherTimer _timer;
private RealReadDataService dataService = RealReadDataService.Instance;
#region 关联属性
/// <summary>
/// 历史遗留的达芬
/// </summary>
private ObservableCollection<Real_DataInfo> _Deviceinfo = new ObservableCollection<Real_DataInfo>();
public ObservableCollection<Real_DataInfo> Deviceinfo
{
get { return _Deviceinfo; }
set
{
if (_Deviceinfo != value)
{
SetProperty(ref _Deviceinfo, value);
}
}
}
/// <summary>
/// 准备写入的列表
/// </summary>
private ObservableCollection<real_readdata> _preparedWriteList = new ObservableCollection<real_readdata>();
public ObservableCollection<real_readdata> PreparedWriteList
4 weeks ago
{
get { return _preparedWriteList; }
4 weeks ago
set
{
if (_preparedWriteList != value)
{
SetProperty(ref _preparedWriteList, value);
}
}
}
/// <summary>
/// 写入记录
/// </summary>
private ObservableCollection<real_readdata> _tempRecordList = new ObservableCollection<real_readdata>();
public ObservableCollection<real_readdata> TempRecordList
{
get { return _tempRecordList; }
set
{
if (_tempRecordList != value)
{
SetProperty(ref _tempRecordList, value);
}
4 weeks ago
}
}
4 weeks ago
/// <summary>
/// 日期时间
/// </summary>
private DateTime _currentDateTime;
public DateTime CurrentDateTime
{
get => _currentDateTime;
set
{
if (_currentDateTime != value)
{
SetProperty(ref _currentDateTime, value);
4 weeks ago
}
}
}
/// <summary>
/// 上一次写入状态
/// </summary>
private string _lastWriteState;
public string LastWriteState
{
get => _lastWriteState;
set
{
if (_lastWriteState != value)
{
SetProperty(ref _lastWriteState, value);
}
}
}
/// <summary>
/// RFID连接状态
/// </summary>
private string _rfidConnectState;
public string RFIDConnectState
{
get => _rfidConnectState;
set
{
if (_rfidConnectState != value)
{
SetProperty(ref _rfidConnectState, value);
}
}
}
/// <summary>
/// 订单号
/// </summary>
private string _orderNo;
public string OrderNo
{
get => _orderNo;
set
{
if (_orderNo != value)
{
SetProperty(ref _orderNo, value);
}
}
}
/// <summary>
/// 产线号
/// </summary>
private string _lineNo;
public string LineNo
{
get => _lineNo;
set
{
if (_lineNo != value)
{
SetProperty(ref _lineNo, value);
}
}
}
/// <summary>
/// 带号
/// </summary>
private string _bindNo;
public string BindNo
{
get => _bindNo;
set
{
if (_bindNo != value)
{
SetProperty(ref _bindNo, value);
}
}
}
/// <summary>
/// 写入数量
/// </summary>
private string _writeCount;
public string WriteCount
{
get => _writeCount;
set
{
if (_writeCount != value)
{
SetProperty(ref _writeCount, value);
}
}
}
public RelayCommand<object> GenerateCodeCommand { get; set; }
public RelayCommand<object> ListClearCommand { get; set; }
public RelayCommand<object> HistoryClearCommand { get; set; }
public RelayCommand<object> HistoryPageCommand { get; set; }
public RelayCommand<object> AutoWriteCommand { get; set; }
public RelayCommand<object> RFIDWriteCommand { get; set; }
#endregion
4 weeks ago
public ProductionLineViewModel()
{
GenerateCodeCommand = new RelayCommand<object>(t => GenerateCode(t));
ListClearCommand = new RelayCommand<object>(t => ListClear(t));
HistoryClearCommand = new RelayCommand<object>(t => HistoryClear(t));
HistoryPageCommand = new RelayCommand<object>(t => HistoryPage(t));
AutoWriteCommand = new RelayCommand<object>(t => AutoWrite(t));
RFIDWriteCommand = new RelayCommand<object>(t => RFIDWrite(t));
// 构造函数里注册
_StringChange = App.ServiceProvider.GetService<StringChange>();
4 weeks ago
_logger = App.ServiceProvider.GetService<SerilogHelper>();
appConfig = App.ServiceProvider.GetService<AppConfig>();
rfidList = App.ServiceProvider.GetRequiredService<List<RfidAbsractFactory>>();
rfidList.ForEach(rfid =>
{
4 weeks ago
rfid._Action += RecvIdentifyData_Instance;
//rfid._RefreshLogMessageAction += RefreshLogMessage;
});
StartCheckStatus();
//GetRFIDHistoryRecords();
_currentDateTime = DateTime.Now;
_timer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(1) // 每秒更新一次
};
_timer.Tick += (s, e) =>
{
CurrentDateTime = DateTime.Now;
};
_timer.Start();
2 weeks ago
Log.Information("RFID输送带系统启动");
4 weeks ago
}
/// <summary>
/// 编码生成
/// </summary>
/// <param name="obj"></param>
private void GenerateCode(object obj)
{
PreparedWriteList.Clear();
if(!int.TryParse(WriteCount, out int count))
{
MessageBox.Show("请输入有效的写入数量!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
for(int i = 1; i <= count; i++)
{
string writeString = OrderNo + LineNo + DateTime.Now.ToString("yy") + BindNo + i.ToString("D2");
PreparedWriteList.Add(new real_readdata()
{
objid = Guid.NewGuid().ToString(),
orderno = OrderNo,
lineno = LineNo,
bindno = BindNo,
serialno = i.ToString("D2"),
rfidascii = writeString,
writestatus = "等待"
});
}
}
/// <summary>
/// 清除生成编码数据
/// </summary>
/// <param name="obj"></param>
private void ListClear(object obj)
{
if(MessageBox.Show("确认", "确定要清除已生成的数据吗?(该操作不可还原)", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
PreparedWriteList.Clear();
}
}
/// <summary>
/// 清除历史数据
/// </summary>
/// <param name="obj"></param>
private void HistoryClear(object obj)
4 weeks ago
{
if (MessageBox.Show("确认", "确定要清除本次写入的数据吗?(可在查看历史中查询以往写入的标签)", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
TempRecordList.Clear();
}
4 weeks ago
}
/// <summary>
/// 历史记录页面
/// </summary>
/// <param name="obj"></param>
private void HistoryPage(object obj)
4 weeks ago
{
HistorySearch window = new HistorySearch();
window.Show();
}
/// <summary>
/// 自动写入
/// </summary>
/// <param name="obj"></param>
private void AutoWrite(object obj)
{
}
/// <summary>
/// 手动写入
/// </summary>
/// <param name="obj"></param>
private void RFIDWrite(object obj)
{
real_readdata? data;
if (obj is real_readdata)
{
data = obj as real_readdata;
}
else
{
return;
}
4 weeks ago
//rfidList.FirstOrDefault(x => x.deviceid == iCombineId)
4 weeks ago
}
/// <summary>
/// 接收到连续盘点标签返回
/// </summary>
/// <param name="iCombineId"></param>
/// <param name="tagInfos"></param>
private async void RecvIdentifyData_Instance(string iCombineId, List<TagInfo> tagInfos)
{
string info = "";
try
{
if (string.IsNullOrEmpty(Deviceinfo.FirstOrDefault(x => x.Deviceid == iCombineId).OrderNo))
4 weeks ago
{
MessageBox.Show("请先获取MES订单号", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
4 weeks ago
}
//读到停止连续盘点
bool stopflag = await rfidList.FirstOrDefault(x => x.deviceid == iCombineId).Set_StopIdentify();
4 weeks ago
//查询数据库是否已存在记录
bool iflag = false;
string epcascii = Encoding.ASCII.GetString(tagInfos[0].EPC);
epcascii = epcascii.Replace("\0", "");
List<real_readdata> real_Readdatas = dataService.Helper.Query(x => x.rfidascii == epcascii);
//如果不存在则写入
if (real_Readdatas.Count <= 0)
//if (true)
4 weeks ago
{
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");
4 weeks ago
//拼接订单号写入标签
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 = dataService.Helper.Insert(real_Readdata);
//刷新界面
//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);
4 weeks ago
}
await Task.Run(async () =>
{
await Task.Delay(1000);
await rfidList.FirstOrDefault(x => x.deviceid == iCombineId)!.Set_BeginIdentify();
});
4 weeks ago
}
catch (Exception e)
{
Log.Error($"读结果准备写入时异常:{e.Message}");
}
finally
{
4 weeks ago
}
}
/// <summary>
/// 添加数据的方法(核心:添加前/后判断行数)
/// </summary>
/// <param name="iCombineId"></param>
/// <param name="tagInfos"></param>
public void AddRFIDData(string iCombineId, List<TagInfo> tagInfos)
4 weeks ago
{
//// 1. 判断当前行数是否>10是则清空
//if (RFIDHistoryRecords.Count >= 10)
//{
// RFIDHistoryRecords.Clear();
//}
4 weeks ago
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();
4 weeks ago
});
}
#region 心跳检测
4 weeks ago
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)
{
2 weeks ago
Log.Information($"监听设备状态异常:{ex.Message}");
4 weeks ago
}
await Task.Delay(1000 * 20);
4 weeks ago
}
});
}
private List<List<RfidAbsractFactory>> SplitListIntoBatches(List<RfidAbsractFactory> sourceList, int batchSize)
{
var batches = new List<List<RfidAbsractFactory>>();
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<RfidAbsractFactory> 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))
4 weeks ago
{
if (value.AddSeconds(15) < DateTime.Now)
4 weeks ago
{
await Reconnect(device);
RFIDConnectState = "已连接";
4 weeks ago
}
else
{
RFIDConnectState = "已连接";
}
4 weeks ago
}
else
{
await Reconnect(device);
RFIDConnectState = "已连接";
var res = false;
//无限获取心跳返回报文
Log.Information($"准备第一次获取心跳");
res = await device.Set_HeartBeat(5);
4 weeks ago
}
}
catch (Exception ex)
{
2 weeks ago
Log.Information($"更新RFID状态异常:{ex.Message}", ex);
4 weeks ago
}
}
/// <summary>
/// 无限重连
/// </summary>
/// <param name="device"></param>
/// <returns></returns>
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);
}
#endregion
4 weeks ago
}
}