using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using SlnMesnac.Business.@base; using SlnMesnac.Common; using SlnMesnac.Config; using SlnMesnac.Model.domain; using SlnMesnac.Model.dto; using SlnMesnac.Model.enums; using SlnMesnac.Plc; using SlnMesnac.Repository.service; using SlnMesnac.Rfid; using SlnMesnac.TouchSocket; using SqlSugar; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using TouchSocket.Core; using static System.Net.Mime.MediaTypeNames; #region << 版 本 注 释 >> /*-------------------------------------------------------------------- * 版权所有 (c) 2024 WenJY 保留所有权利。 * CLR版本:4.0.30319.42000 * 机器名称:LAPTOP-E0N2L34V * 命名空间:SlnMesnac.Business * 唯一标识:f79d6d97-d9b0-4b0b-a442-e6bb1c1c79e6 * * 创建者:WenJY * 电子邮箱:wenjy@mesnac.com * 创建时间:2024-04-10 16:36:01 * 版本:V1.0.0 * 描述: * *-------------------------------------------------------------------- * 修改人: * 时间: * 修改说明: * * 版本:V1.0.0 *--------------------------------------------------------------------*/ #endregion << 版 本 注 释 >> namespace SlnMesnac.Business { /// /// 设备产出业务逻辑 /// public class ProdCompletionBusiness : BaseBusiness { private FJ500Comm.FJ500SP fj500s = new FJ500Comm.FJ500SP(); //喷码机喷码失败或者设备状态检查重试次数,0代表状态正常 public static int PmTryAmount = 0; //喷码机心跳,每次收到回复刷新时间,如果超过1分钟,则认为喷码机断开连接,添加一条报警 private DateTime PmHeartTime = DateTime.Now; private readonly IMesProductPlanService _mesProductPlanService; private readonly IMesProductOrderService _mesProductOrderService; private readonly IMesPrdBarCodeService _barCodeTaskService; private readonly IBaseMaterialInfoService _baseMaterialInfoService; private readonly IMesBaseBarcodeInfoService _mesBaseBarcodeInfoService; public readonly IMesPrdBarCodeService _mesPrdBarCodeService; private readonly IRealPalletTaskService _realPalletTaskService; private readonly UdpServer udpServer; private DebugConfig debugConfig = DebugConfig.Instance; private ISqlSugarClient sqlSugarClient; public ProdCompletionBusiness(ISqlSugarClient _sqlSugarClient, ILogger logger, AppConfig appConfig, List plcFactories, List rfidFactories, IMesProductPlanService mesProductPlanService, IMesPrdBarCodeService barCodeTaskService, IServiceProvider serviceProvider) : base(logger, appConfig, plcFactories, rfidFactories, serviceProvider) { udpServer = serviceProvider.GetRequiredService(); UdpServer.ReceivedPMCodeEvent += PmCodeHandler; sqlSugarClient = _sqlSugarClient; _mesProductPlanService = mesProductPlanService; _barCodeTaskService = barCodeTaskService; _realPalletTaskService = serviceProvider.GetRequiredService(); _mesBaseBarcodeInfoService = serviceProvider.GetRequiredService(); _mesPrdBarCodeService = serviceProvider.GetRequiredService(); _mesProductOrderService = serviceProvider.GetRequiredService(); _baseMaterialInfoService = serviceProvider.GetRequiredService(); Init(); } private void test() { try { sqlSugarClient.AsTenant().BeginTran(); string palletCode1 = ""; WmsBaseLocation source = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().Where(x => x.LocationCode == "3114").First(); WmsBaseLocation target = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().Where(x => x.LocationCode == "3314").First(); // palletCode1 = source.ContainerCode; // source.ContainerCode = target.ContainerCode; target.ContainerCode = source.ContainerCode; sqlSugarClient.AsTenant().GetConnection("mes").Updateable(source).ExecuteCommand(); sqlSugarClient.AsTenant().GetConnection("mes").Updateable(target).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); }catch(Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); } // MesProductPlanDetail? mesProductPlanDetail = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.PlanCode == "20240724144533JL001"); //sqlSugarClient.AsTenant().BeginTran(); //string epc = "JYHB01010102"; //_mesProductPlanService.GetStartedProdPlan(out MesProductPlanDto productPlanDto); //string bigCode = GenerateBigBarcode(productPlanDto, epc); //BindingBarCode(bigCode, epc, productPlanDto); //sqlSugarClient.AsTenant().BeginTran(); } // 3114 private static bool isEmptyPalletHandleRunning = false; public void Init() { Task.Run(async () => { await EmptyPalletHandle(); }); Task.Run(() => { DeviceOutPutHandle(); }); //喷码机设备状态检查 checkPmStatus(); } #region 喷码机设备相关通讯 /// /// 喷码机状态检查 /// public void checkPmStatus() { PmTryAmount++; Task.Run(() => { while (true) { try { //发送检查状态指令 // udpServer.SendMessage(fj500s.CheckState()); // Thread.Sleep(1000 * 5); // 重新发送带喷印条码,保证始终有条码 SendFirstPmCode(); } catch (Exception ex) { _logger.LogError("checkStatus异常:" + ex.Message); } Thread.Sleep(1000 * 30); if (DateTime.Now - PmHeartTime > TimeSpan.FromMinutes(2)) { //报警 _logger.LogError("====================喷码机通讯心跳失败预警,推送报警"); AddAlarm(WarnStatusEnum.喷码机设备状态检查故障或者喷印失败预警超过30次); PmTryAmount++; } } }); } /// /// 喷码机返回信息解析处理 /// 1.传输完成及喷码完成 /// 2.喷码机状态检查 /// /// private void PmCodeHandler(string str) { PmHeartTime = DateTime.Now; try { int LastTryAmount = PmTryAmount; var result = fj500s.GetAck(str); if (result == "00") { // 发送数据成功 _logger.LogInformation("====================收到喷码机发送数据成功"); PmTryAmount = 0; } else if (result == "0E") { // 喷码机设备故障 _logger.LogError($"====================收到喷码机设备状态检查故障或者喷印失败预警,喷码机重试次数:{PmTryAmount}"); PmTryAmount++; if (PmTryAmount <= 30) { //重新发送 Task.Run(() => { Thread.Sleep(1000 * 5); SendFirstPmCode(); }); } else { _logger.LogError("====================超过30次,推送报警"); AddAlarm(WarnStatusEnum.喷码机设备状态检查故障或者喷印失败预警超过30次); } } else if (result == "0F") { _logger.LogInformation("====================收到喷码机打印完成,推送下一条待打印条码"); updatePrdBarcodeInfo(); SendFirstPmCode(); _logger.LogInformation("====================推送下一条待打印条码成功"); PmTryAmount = 0; } if (LastTryAmount>0 && PmTryAmount==0) { // 报警消除 _logger.LogInformation("喷码机报警消除"); deleteAlarm(WarnStatusEnum.喷码机设备状态检查故障或者喷印失败预警超过30次); } } catch (Exception ex) { _logger.LogError("PmCodeHandler喷码机回复信息解析处理异常:" + ex.Message); } } /// /// 获取数据库最早未喷印未绑定条码 /// private void SendFirstPmCode() { try { MesPrdBarcodeInfo mesPrdBarcodeInfo = _barCodeTaskService.Query(x => x.PrintFlag == "0" && x.BindStatus == 0).OrderBy(x => x.PrdBarcodeId).FirstOrDefault(); if (mesPrdBarcodeInfo != null) { udpServer.SendMessage(mesPrdBarcodeInfo.PrdBarcodeInfo); } else { _logger.LogError("可喷码数不足,请检查原因"); } }catch (Exception ex) { _logger.LogError("SendFirstPmCode获取数据库最早未喷印未绑定条码异常:" + ex.Message); } } /// /// 喷印完成更新条码 /// private void updatePrdBarcodeInfo() { MesPrdBarcodeInfo mesPrdBarcodeInfo = _barCodeTaskService.Query(x => x.PrintFlag == "0" && x.BindStatus == 0).OrderBy(x => x.PrdBarcodeId).FirstOrDefault(); mesPrdBarcodeInfo.PrintFlag = "1"; mesPrdBarcodeInfo.PrintTime = DateTime.Now; _barCodeTaskService.Update(mesPrdBarcodeInfo); } #endregion /// /// 设备产出逻辑处理 /// private async void DeviceOutPutHandle() { // 读取RFID失败重试次数,超过5次推送报警 int readRfidAmount = 0; while (true) { try { var plc = base.GetPlcByKey("plc"); if (plc == null || plc.IsConnected== false) { _logger.LogInformation("2F读取小包出口信号,PLC连接信息为空......"); Thread.Sleep(3000); continue; } if (!plc.readBoolByAddress(GetPlcAddressByConfigKey("2楼小包出口到位信号"))) { plc.writeStringByAddress(GetPlcAddressByConfigKey("2楼码垛出口RFID条码地址"), "", 12); Thread.Sleep(5000); continue; } string rfid = plc.readStringByAddress(GetPlcAddressByConfigKey("2楼码垛出口RFID条码地址"), 12).Replace("\0", ""); if (!string.IsNullOrWhiteSpace(rfid)) { //_logger.LogInformation("小包出口已经有RFID了,无需再读"); Thread.Sleep(5000); continue; } string epcStr = await ReadEpcStrByRfidKeyAsync("secondFloorOut"); if (string.IsNullOrEmpty(epcStr)) { _logger.LogError("小包出口到位信号触发,读取RFID失败......"); //判断前一位置是否有托盘缓存 RealPalletTask realPalletTask = _realPalletTaskService.Query().FirstOrDefault(); if (realPalletTask != null) { epcStr = realPalletTask.PalletCode; } else { readRfidAmount++; if (readRfidAmount == 5) { string virtualEpc = NoReadRFIDAlarm(); _logger.LogError("小包出口到位信号触发,读取RFID失败超过5次......"); //if (!string.IsNullOrEmpty(virtualEpc)) //{ // //TODU 虚拟托盘号需要在系统存储 // epcStr = virtualEpc; // _logger.LogError("小包出口到位信号触发,读取RFID失败超过5次,生成虚拟托盘号:" + virtualEpc); //} Thread.Sleep(1000 * 5); continue; } else { Thread.Sleep(1000 * 5); continue; } } } // 校验该epc是否已经存在库存里,有的话重新读 var hasLocation = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().Where(x => x.ContainerCode == epcStr).First(); if (hasLocation != null) { _logger.LogError("小包出口到位信号触发,读取RFID失败,该epc已经存在库存里:" + epcStr); Thread.Sleep(5000); continue; } RefreshMessage($"2F小包出口读取到RFID条码{epcStr},开始入库:"); _mesProductPlanService.GetStartedProdPlan(out MesProductPlanDto productPlanDto); if (productPlanDto == null) { //throw new ArgumentException($"未获取到正在执行的生产计划"); //无计划时,按照无计划订单处理,MaterialId可修改,在配置文件 productPlanDto = new MesProductPlanDto(); productPlanDto.PlanCode = "0"; productPlanDto.MaterialId = long.Parse(debugConfig.MaterialId); productPlanDto.SaleOrderId = 0; productPlanDto.SaleorderCode = "0"; } #region 开启事务 sqlSugarClient.AsTenant().BeginTran(); //1.生成大条码插入mes_barcode_info; string bigCode = GenerateBigBarcode(productPlanDto, epcStr); //2.40个小条码及大条码绑定托盘号,小条码绑定大条码,,托盘绑定大条码 BindingBarCode(bigCode, epcStr, productPlanDto); //3.更新mes_product_plan及mes_product_order表,更新已生产数量 UpdatePlanInfoAndOrder(productPlanDto); // 删除所有数据库托盘号 List realPalletList = _realPalletTaskService.Query(); if (realPalletList != null && realPalletList.Count > 0) { sqlSugarClient.AsTenant().GetConnection("mes").Deleteable(realPalletList).ExecuteCommand(); } // 写入PLC RFID号供调度使用 plc.writeStringByAddress(GetPlcAddressByConfigKey("2楼码垛出口RFID条码地址"), epcStr, 12); // plc.writeByteByAddress(GetPlcAddressByConfigKey("2楼小包出口到位信号"), 2); readRfidAmount = 0; sqlSugarClient.AsTenant().CommitTran(); #endregion } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.LogError($"DeviceOutPutHandle异常:{ex.Message}"); } Thread.Sleep(1000 * 5); } } /// /// 生成大条码插入mes_barcode_info; /// /// /// /// private string GenerateBigBarcode(MesProductPlanDto productPlanDto, string epcStr) { string bigBarcode = productPlanDto.PlanCode + DateTime.Now.ToString("_MMddHHmmss"); MesBaseBarcodeInfo mesBaseBarcodeInfo = new MesBaseBarcodeInfo(); mesBaseBarcodeInfo.printTime = DateTime.Now; mesBaseBarcodeInfo.printPerson = "SlnMesnac"; mesBaseBarcodeInfo.printFlag = "1"; mesBaseBarcodeInfo.batchFlag = "0"; mesBaseBarcodeInfo.barcodeType = "3"; mesBaseBarcodeInfo.barcodeInfo = bigBarcode; mesBaseBarcodeInfo.batchCode = bigBarcode; mesBaseBarcodeInfo.palletInfoCode = epcStr; mesBaseBarcodeInfo.materialId = productPlanDto.MaterialId; mesBaseBarcodeInfo.amount = 1; mesBaseBarcodeInfo.printNumber = 1; mesBaseBarcodeInfo.productionDate = DateTime.Now; mesBaseBarcodeInfo.acceptedDate = DateTime.Now; mesBaseBarcodeInfo.planCode = productPlanDto.PlanCode; MesProductPlanDetail? mesProductPlanDetail = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.PlanCode == productPlanDto.PlanCode); if (mesProductPlanDetail != null) { mesBaseBarcodeInfo.planDetailCode = mesProductPlanDetail.PlanDetailCode; } mesBaseBarcodeInfo.safeFlag = productPlanDto.SaleOrderId == 0 ? "1" : "0"; mesBaseBarcodeInfo.saleOrderId = productPlanDto.SaleOrderId; mesBaseBarcodeInfo.saleorderCode = productPlanDto.SaleorderCode; mesBaseBarcodeInfo.bindStatus = "1"; mesBaseBarcodeInfo.bindTime = DateTime.Now; mesBaseBarcodeInfo.updateBy = "SlnMesnac"; mesBaseBarcodeInfo.updateTime = DateTime.Now; mesBaseBarcodeInfo.completeFlag = "1"; mesBaseBarcodeInfo.singleFlag = "0"; var materialInfo = _baseMaterialInfoService.Query(x => x.MaterialId == productPlanDto.MaterialId).FirstOrDefault(); if (materialInfo != null) { mesBaseBarcodeInfo.barcodeSpec = materialInfo.MaterialSpec; } sqlSugarClient.AsTenant().GetConnection("mes").Insertable(mesBaseBarcodeInfo).ExecuteCommand(); return bigBarcode; } /// /// 40个小条码及大条码绑定托盘号,小条码绑定大条码 /// /// /// private void BindingBarCode(string bigBarcode, string epcStr, MesProductPlanDto productPlanDto) { List list = _mesPrdBarCodeService.GetUseBarCodeList(); if (list == null || list.Count == 0) { throw new InvalidOperationException("托盘未找到可以绑定的小条码"); } if (list.Where(x => x.PrintFlag == "1").ToList().Count < 40) { // 推送低级别报警 AddAlarm(WarnStatusEnum.托盘绑定时已喷码数不足40); } foreach (var item in list) { item.PalletInfoCode = epcStr; item.MesBarcodeInfo = bigBarcode; item.BindTime = DateTime.Now; item.BindStatus = 1; } sqlSugarClient.AsTenant().GetConnection("mes").Updateable(list).ExecuteCommand(); //托盘绑定大条码信息 BasePalletInfo palletInfo = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().Where(x => x.PalletInfoCode == epcStr).First(); if (palletInfo != null) { palletInfo.MaterialBarcode = bigBarcode; palletInfo.MaterialId = productPlanDto.MaterialId; } sqlSugarClient.AsTenant().GetConnection("mes").Updateable(palletInfo).ExecuteCommand(); } private void UpdatePlanInfoAndOrder(MesProductPlanDto productPlanDto) { MesProductPlan productPlan = _mesProductPlanService.Query(x => x.PlanCode == productPlanDto.PlanCode).FirstOrDefault(); if (productPlan == null) { _logger.LogInformation("未找到该生产计划对应的生产工单!,按照无工单处理,无需更新计划"); return; } MesProductOrder productOrder = _mesProductOrderService.Query(x => x.ProductOrderId == productPlan.ProductOrderId).FirstOrDefault(); if (productPlan == null) { _logger.LogInformation("未找到该生产计划对应的生产工单!,按照无工单处理,无需更新计划"); return; } #region 更新生产计划 if (productPlan.CompleteAmount == 0) { productPlan.RealBeginTime = DateTime.Now; } productPlan.CompleteAmount++; if (productPlan.CompleteAmount == productPlan.PlanAmount) { productPlan.RealEndTime = DateTime.Now; productPlan.PlanStatus = Model.enums.PlanStatusEnum.已完成; } productPlan.UpdateTime = DateTime.Now; productPlan.UpdateBy = "SlnMesnac"; sqlSugarClient.AsTenant().GetConnection("mes").Updateable(productPlan).ExecuteCommand(); #endregion #region 更新生产工单 if (productOrder.CompleteAmount == 0) { productOrder.RealBeginTime = DateTime.Now; } productOrder.CompleteAmount++; if (productOrder.CompleteAmount == productOrder.PlanAmount) { productOrder.RealEndTime = DateTime.Now; productOrder.OrderStatus = "2"; } productOrder.UpdateTime = DateTime.Now; productOrder.UpdateBy = "SlnMesnac"; sqlSugarClient.AsTenant().GetConnection("mes").Updateable(productOrder).ExecuteCommand(); #endregion } #region 报警 /// /// /// 插入报警 /// private void AddAlarm(WarnStatusEnum warnStatusEnum) { try { sqlSugarClient.AsTenant().BeginTran(); // 有报警,找出该设备的报警记录,如果没有报警记录或者报警记录已结束,则新增报警记录 int warnRuleId = int.Parse(warnStatusEnum.GetDescription()); DmsRecordAlarmTime? dmsRecordAlarmTime = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == warnRuleId); if (dmsRecordAlarmTime == null) { DmsBaseAlarmRule dmsBaseAlarmRule = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == warnRuleId); dmsRecordAlarmTime = new DmsRecordAlarmTime(); dmsRecordAlarmTime.DeviceId = dmsBaseAlarmRule.DeviceId; dmsRecordAlarmTime.AlarmRuleId = warnRuleId; dmsRecordAlarmTime.AlarmBeginTime = DateTime.Now; dmsRecordAlarmTime.ContinueTime = dmsBaseAlarmRule.ContinueTime; dmsRecordAlarmTime.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmTime.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmTime.AlarmData = warnStatusEnum.ToString(); dmsRecordAlarmTime.HandleSuggest = dmsBaseAlarmRule.HandleSuggest; dmsRecordAlarmTime.CreateBy = "SlnMesnac"; dmsRecordAlarmTime.CreateTime = DateTime.Now; DmsRecordAlarmInfo dmsRecordAlarmInfo = new DmsRecordAlarmInfo(); dmsRecordAlarmInfo.DeviceId = dmsBaseAlarmRule.DeviceId; dmsRecordAlarmInfo.AlarmRuleId = warnRuleId; dmsRecordAlarmInfo.AlarmBeginTime = DateTime.Now; dmsRecordAlarmInfo.AlarmStatus = "0"; dmsRecordAlarmInfo.NoticeStatus = "0"; dmsRecordAlarmInfo.ContinueTime = dmsBaseAlarmRule.ContinueTime; dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmInfo.AlarmData = warnStatusEnum.ToString(); dmsRecordAlarmInfo.HandleSuggest = dmsBaseAlarmRule.HandleSuggest; dmsRecordAlarmInfo.CreateBy = "SlnMesnac"; dmsRecordAlarmInfo.CreateTime = DateTime.Now; sqlSugarClient.AsTenant().GetConnection("mes").Insertable(dmsRecordAlarmTime).ExecuteCommand(); sqlSugarClient.AsTenant().GetConnection("mes").Insertable(dmsRecordAlarmInfo).ExecuteCommand(); } else { dmsRecordAlarmTime.UpdateTime = DateTime.Now; dmsRecordAlarmTime.UpdateBy = "SlnMesnac"; DmsRecordAlarmInfo dmsRecordAlarmInfo = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == warnRuleId); if (dmsRecordAlarmInfo != null) { dmsRecordAlarmInfo.UpdateTime = DateTime.Now; dmsRecordAlarmInfo.UpdateBy = "SlnMesnac"; sqlSugarClient.AsTenant().GetConnection("mes").Updateable(dmsRecordAlarmInfo).ExecuteCommand(); } else { DmsBaseAlarmRule dmsBaseAlarmRule = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == warnRuleId); dmsRecordAlarmInfo = new DmsRecordAlarmInfo(); dmsRecordAlarmInfo.DeviceId = dmsRecordAlarmTime.DeviceId; dmsRecordAlarmInfo.AlarmRuleId = warnRuleId; dmsRecordAlarmInfo.AlarmBeginTime = DateTime.Now; dmsRecordAlarmInfo.AlarmStatus = "0"; dmsRecordAlarmInfo.NoticeStatus = "0"; dmsRecordAlarmInfo.ContinueTime = dmsBaseAlarmRule.ContinueTime; dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmInfo.AlarmData = warnStatusEnum.ToString(); dmsRecordAlarmInfo.HandleSuggest = dmsBaseAlarmRule.HandleSuggest; dmsRecordAlarmInfo.CreateBy = "SlnMesnac"; dmsRecordAlarmInfo.CreateTime = DateTime.Now; sqlSugarClient.AsTenant().GetConnection("mes").Insertable(dmsRecordAlarmInfo).ExecuteCommand(); } sqlSugarClient.AsTenant().GetConnection("mes").Updateable(dmsRecordAlarmTime).ExecuteCommand(); } sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.LogError($"插入或者更新报错信息异常{warnStatusEnum.ToString()} ==>:{ex.Message}"); } } /// /// 消除报警 /// /// private void deleteAlarm(WarnStatusEnum warnStatusEnum) { DmsRecordAlarmTime? dmsRecordAlarmTime = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == long.Parse(warnStatusEnum.GetDescription())); if (dmsRecordAlarmTime != null) { sqlSugarClient.AsTenant().BeginTran(); DmsRecordAlarmInfo dmsRecordAlarmInfo = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == dmsRecordAlarmTime.AlarmRuleId && x.AlarmStatus == "0"); if (dmsRecordAlarmInfo != null) { dmsRecordAlarmInfo.AlarmEndTime = DateTime.Now; dmsRecordAlarmInfo.AlarmStatus = "2"; dmsRecordAlarmInfo.UpdateTime = DateTime.Now; sqlSugarClient.AsTenant().GetConnection("mes").Updateable(dmsRecordAlarmInfo).ExecuteCommand(); } sqlSugarClient.AsTenant().GetConnection("mes").Deleteable(dmsRecordAlarmTime).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } } /// /// 推送报警,并生成虚拟托盘号暂时使用,虚拟托盘号储存到报警信息,人工处理可以将虚拟托盘号替换为正常托盘号 /// 返回生产的虚拟托盘号 /// private string NoReadRFIDAlarm() { string epcStr; try { epcStr = "TEMP" + DateTime.Now.ToString("MMddHHmm"); sqlSugarClient.AsTenant().BeginTran(); // 有报警,找出该设备的报警记录,如果没有报警记录或者报警记录已结束,则新增报警记录 int warnRuleId = int.Parse(WarnStatusEnum.小包出口读取RFID失败5次.GetDescription()); DmsRecordAlarmTime? dmsRecordAlarmTime = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == warnRuleId); if (dmsRecordAlarmTime == null) { DmsBaseAlarmRule dmsBaseAlarmRule = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == warnRuleId); dmsRecordAlarmTime = new DmsRecordAlarmTime(); dmsRecordAlarmTime.DeviceId = dmsBaseAlarmRule.DeviceId; dmsRecordAlarmTime.AlarmRuleId = warnRuleId; dmsRecordAlarmTime.AlarmBeginTime = DateTime.Now; dmsRecordAlarmTime.ContinueTime = dmsBaseAlarmRule.ContinueTime; dmsRecordAlarmTime.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmTime.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmTime.AlarmData = WarnStatusEnum.小包出口读取RFID失败5次.ToString(); dmsRecordAlarmTime.HandleSuggest = dmsBaseAlarmRule.HandleSuggest + ";;虚拟托盘号为:" + epcStr; dmsRecordAlarmTime.CreateBy = "SlnMesnac"; dmsRecordAlarmTime.CreateTime = DateTime.Now; DmsRecordAlarmInfo dmsRecordAlarmInfo = new DmsRecordAlarmInfo(); dmsRecordAlarmInfo.DeviceId = dmsBaseAlarmRule.DeviceId; dmsRecordAlarmInfo.AlarmRuleId = warnRuleId; dmsRecordAlarmInfo.AlarmBeginTime = DateTime.Now; dmsRecordAlarmInfo.AlarmStatus = "0"; dmsRecordAlarmInfo.NoticeStatus = "0"; dmsRecordAlarmInfo.ContinueTime = dmsBaseAlarmRule.ContinueTime; dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason; dmsRecordAlarmInfo.AlarmData = WarnStatusEnum.小包出口读取RFID失败5次.ToString(); dmsRecordAlarmInfo.HandleSuggest = dmsBaseAlarmRule.HandleSuggest + ";;虚拟托盘号为:" + epcStr; dmsRecordAlarmInfo.CreateBy = "SlnMesnac"; dmsRecordAlarmInfo.CreateTime = DateTime.Now; sqlSugarClient.AsTenant().GetConnection("mes").Insertable(dmsRecordAlarmTime).ExecuteCommand(); sqlSugarClient.AsTenant().GetConnection("mes").Insertable(dmsRecordAlarmInfo).ExecuteCommand(); } else { dmsRecordAlarmTime.UpdateTime = DateTime.Now; dmsRecordAlarmTime.UpdateBy = "SlnMesnac"; DmsRecordAlarmInfo dmsRecordAlarmInfo = sqlSugarClient.AsTenant().GetConnection("mes").Queryable().First(x => x.AlarmRuleId == warnRuleId); if (dmsRecordAlarmInfo != null) { dmsRecordAlarmInfo.UpdateTime = DateTime.Now; dmsRecordAlarmInfo.UpdateBy = "SlnMesnac"; } sqlSugarClient.AsTenant().GetConnection("mes").Updateable(dmsRecordAlarmTime).ExecuteCommand(); sqlSugarClient.AsTenant().GetConnection("mes").Updateable(dmsRecordAlarmInfo).ExecuteCommand(); } sqlSugarClient.AsTenant().CommitTran(); return epcStr; } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.LogError($"NoReadRFIDAlarm异常:{ex.Message}"); return ""; } } #endregion /// /// 空托盘进入码垛位,读取RFID备用 /// private async Task EmptyPalletHandle() { //读取PLC空托盘流转信号 while (true) { try { var plc = base.GetPlcByKey("plc"); if (plc == null) { _logger.LogInformation("读取PLC空托盘码垛到位信号,PLC连接信息为空......"); Thread.Sleep(5000); continue; } if (!plc.readBoolByAddress(GetPlcAddressByConfigKey("2楼码垛到位信号"))) { _logger.LogInformation("等待空托盘到位信号触发......"); Thread.Sleep(5000); continue; } RealPalletTask realPalletTask = _realPalletTaskService.Query().FirstOrDefault(); if (realPalletTask != null) { _logger.LogInformation("空托盘到位信号触发,已经有读取托盘,不再读取......"); Thread.Sleep(5000); continue; } //读取RFID、获取当前正在执行的计划、将当前计划、工单等信息与托盘绑定 RefreshMessage("空托盘到位信号触发成功,读取托盘RFID信息"); string epcStr = await ReadEpcStrByRfidKeyAsync("secondFloorPallet"); if (string.IsNullOrEmpty(epcStr)) { _logger.LogError("空托盘到位信号触发,读取RFID失败......"); Thread.Sleep(1000 * 10); continue; } RefreshMessage($"空托盘RFID信息读取成功,标签信息:{epcStr}"); // 插入一条托盘记录 realPalletTask = new RealPalletTask() { PalletCode = epcStr, RecordTime = DateTime.Now, }; _realPalletTaskService.Insert(realPalletTask); } catch (Exception e) { RefreshMessage($"空托盘进入码垛位处理异常:{e.Message}"); } Thread.Sleep(1000 * 10); } } /// /// 根据条码提取序列 /// /// /// /// private void ExtractNumber(string barCode, out int result) { string pattern = @"\b0*(\d{1,6})\b$"; Match match = Regex.Match(barCode, pattern); if (match.Success) { result = Convert.ToInt32(match.Groups[1].Value) + 1; } else { throw new InvalidOperationException($"通过条码:{barCode}提取当前序列异常:未找到匹配的数字"); } } } }