change-完善2楼小包产出叫料逻辑

dev
liuwf 3 months ago
parent 833bae6d08
commit 64a04dce5f

@ -1,4 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SlnMesnac.Business.@base;
using SlnMesnac.Common;
@ -21,32 +21,32 @@ using System.Threading.Tasks;
using TouchSocket.Core;
using static System.Net.Mime.MediaTypeNames;
#region << 版 本 注 释 >>
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* LAPTOP-E0N2L34V
* SlnMesnac.Business
* f79d6d97-d9b0-4b0b-a442-e6bb1c1c79e6
* (c) 2024 WenJY
* CLR4.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
*
* WenJY
* wenjy@mesnac.com
* 2024-04-10 16:36:01
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
*
*
*
* V1.0.0
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Business
{
/// <summary>
/// 设备产出业务逻辑
/// 设备产出业务逻辑
/// </summary>
public class ProdCompletionBusiness : BaseBusiness
{
@ -61,7 +61,7 @@ namespace SlnMesnac.Business
private ISqlSugarClient sqlSugarClient;
public ProdCompletionBusiness(ISqlSugarClient _sqlSugarClient,ILogger<BaseBusiness> logger, AppConfig appConfig, List<PlcAbsractFactory> plcFactories, List<RfidAbsractFactory> rfidFactories, IMesProductPlanService mesProductPlanService, IMesPrdBarCodeService barCodeTaskService, IServiceProvider serviceProvider) : base(logger, appConfig, plcFactories, rfidFactories, serviceProvider)
public ProdCompletionBusiness(ISqlSugarClient _sqlSugarClient, ILogger<BaseBusiness> logger, AppConfig appConfig, List<PlcAbsractFactory> plcFactories, List<RfidAbsractFactory> rfidFactories, IMesProductPlanService mesProductPlanService, IMesPrdBarCodeService barCodeTaskService, IServiceProvider serviceProvider) : base(logger, appConfig, plcFactories, rfidFactories, serviceProvider)
{
sqlSugarClient = _sqlSugarClient;
_mesProductPlanService = mesProductPlanService;
@ -72,10 +72,10 @@ namespace SlnMesnac.Business
_mesProductOrderService = serviceProvider.GetRequiredService<IMesProductOrderService>();
_baseMaterialInfoService = serviceProvider.GetRequiredService<IBaseMaterialInfoService>();
Init();
}
private void test()
private void test()
{
string epc = "A123456";
@ -85,28 +85,31 @@ namespace SlnMesnac.Business
}
private static bool isEmptyPalletHandleRunning = false;
public void Init()
{
Task.Run(() =>
{
EmptyPalletHandle();
});
Task.Run(async () =>
{
await EmptyPalletHandle();
});
Task.Run(() =>
{
DeviceOutPutHandle();
});
}
/// <summary>
/// 设备产出逻辑处理
/// 设备产出逻辑处理
/// </summary>
private async void DeviceOutPutHandle()
{
// 读取RFID失败重试次数超过5次推送报警
// 读取RFID失败重试次数超过5次推送报警
int readRfidAmount = 0;
while(true)
while (true)
{
try
{
@ -114,24 +117,32 @@ namespace SlnMesnac.Business
if (plc == null)
{
_logger.LogInformation("读取小包出口信号,PLC连接信息为空......");
_logger.LogInformation("读取小包出口信号,PLC连接信息为空......");
Thread.Sleep(3000);
continue;
}
if (plc.readByteByAddress(GetPlcAddressByConfigKey("2楼小包出口到位信号"))!=1)
if (plc.readByteByAddress(GetPlcAddressByConfigKey("2楼小包出口到位信号")) != 1)
{
_logger.LogInformation("等待小包出口信号触发......");
Thread.Sleep(5000);
continue;
}
string rfid = plc.readStringByAddress(GetPlcAddressByConfigKey("2楼码垛出口RFID条码地址"),12).Replace("\0","");
if (!string.IsNullOrWhiteSpace(rfid))
{
_logger.LogInformation("等待小包出口信号触发......");
_logger.LogInformation("小包出口已经有RFID了无需再读");
Thread.Sleep(5000);
continue;
}
string epcStr = await ReadEpcStrByRfidKeyAsync("secondFloorOut");
if (string.IsNullOrEmpty(epcStr))
{
_logger.LogError("小包出口到位信号触发,读取RFID失败......");
//判断前一位置是否有托盘缓存
RealPalletTask realPalletTask = _realPalletTaskService.Query().FirstOrDefault();
_logger.LogError("小包出口到位信号触发,读取RFID失败......");
//判断前一位置是否有托盘缓存
RealPalletTask realPalletTask = _realPalletTaskService.Query().FirstOrDefault();
if (realPalletTask != null)
{
epcStr = realPalletTask.PalletCode;
@ -139,15 +150,15 @@ namespace SlnMesnac.Business
else
{
readRfidAmount++;
if(readRfidAmount == 5)
if (readRfidAmount == 5)
{
string virtualEpc = NoReadRFIDAlarm();
_logger.LogError("小包出口到位信号触发,读取RFID失败超过5次......");
_logger.LogError("小包出口到位信号触发,读取RFID失败超过5次......");
if (!string.IsNullOrEmpty(virtualEpc))
{
epcStr = virtualEpc;
_logger.LogError("小包出口到位信号触发,读取RFID失败超过5次,生成虚拟托盘号:"+virtualEpc);
_logger.LogError("小包出口到位信号触发,读取RFID失败超过5次,生成虚拟托盘号:" + virtualEpc);
}
}
else
@ -155,52 +166,52 @@ namespace SlnMesnac.Business
Thread.Sleep(1000 * 5);
continue;
}
}
}
}
RefreshMessage($"小包出口读取到RFID条码{epcStr},开始绑定流程:");
RefreshMessage($"小包出口读取到RFID条码{epcStr},开始绑定流程:");
_mesProductPlanService.GetStartedProdPlan(out MesProductPlanDto productPlanDto);
if (productPlanDto == null)
{
//TODO:没有计划的话,处理方式待定
throw new ArgumentException($"未获取到正在执行的生产计划");
//TODO:没有计划的话,处理方式待定
throw new ArgumentException($"未获取到正在执行的生产计划");
}
#region 开启事务
#region 开启事务
sqlSugarClient.AsTenant().BeginTran();
//1.生成大条码插入mes_barcode_info
string bigCode =GenerateBigBarcode(productPlanDto, epcStr);
//2.40个小条码及大条码绑定托盘号,小条码绑定大条码
BindingBarCode(bigCode,epcStr);
//3.更新mes_product_plan及mes_product_order表更新已生产数量
//1.生成大条码插入mes_barcode_info
string bigCode = GenerateBigBarcode(productPlanDto, epcStr);
//2.40个小条码及大条码绑定托盘号,小条码绑定大条码
BindingBarCode(bigCode, epcStr);
//3.更新mes_product_plan及mes_product_order表更新已生产数量
UpdatePlanInfoAndOrder(productPlanDto);
// 删除正在使用的数据库托盘号
// 删除正在使用的数据库托盘号
RealPalletTask realPallet = _realPalletTaskService.Query(x => x.PalletCode == epcStr).FirstOrDefault();
if (realPallet != null)
{
sqlSugarClient.AsTenant().GetConnection("mes").Deleteable(realPallet).ExecuteCommand();
}
// 写入PLC RFID号供调度使用
plc.writeStringByAddress(GetPlcAddressByConfigKey("2楼码垛出口RFID条码地址"), epcStr);
plc.writeByteByAddress(GetPlcAddressByConfigKey("2楼小包出口到位信号"),2);
readRfidAmount = 0;
// 写入PLC RFID号供调度使用
plc.writeStringByAddress(GetPlcAddressByConfigKey("2楼码垛出口RFID条码地址"), epcStr);
// plc.writeByteByAddress(GetPlcAddressByConfigKey("2楼小包出口到位信号"), 2);
readRfidAmount = 0;
sqlSugarClient.AsTenant().CommitTran();
#endregion
}
catch (Exception ex)
{
sqlSugarClient.AsTenant().RollbackTran();
_logger.LogError($"DeviceOutPutHandle异常:{ex.Message}");
_logger.LogError($"DeviceOutPutHandle异常:{ex.Message}");
}
Thread.Sleep(1000 * 5);
}
}
/// <summary>
/// 推送报警,并生成虚拟托盘号暂时使用,虚拟托盘号储存到报警信息,人工处理可以将虚拟托盘号替换为正常托盘号
/// <return> 返回生产的虚拟托盘号
/// 推送报警,并生成虚拟托盘号暂时使用,虚拟托盘号储存到报警信息,人工处理可以将虚拟托盘号替换为正常托盘号
/// <return> 返回生产的虚拟托盘号
/// </summary>
private string NoReadRFIDAlarm()
{
@ -210,13 +221,13 @@ namespace SlnMesnac.Business
epcStr = "TEMP" + DateTime.Now.ToString("MMddHHmm");
sqlSugarClient.AsTenant().BeginTran();
// 有报警,找出该设备的报警记录,如果没有报警记录或者报警记录已结束,则新增报警记录
int warnRuleId = int.Parse(WarnStatusEnum.RFID5.GetDescription());
DmsRecordAlarmTime? dmsRecordAlarmTime = sqlSugarClient.AsTenant().GetConnection("mes").Queryable<DmsRecordAlarmTime>().First(x => x.AlarmRuleId == warnRuleId);
// 有报警,找出该设备的报警记录,如果没有报警记录或者报警记录已结束,则新增报警记录
int warnRuleId = int.Parse(WarnStatusEnum.RFID5.GetDescription());
DmsRecordAlarmTime? dmsRecordAlarmTime = sqlSugarClient.AsTenant().GetConnection("mes").Queryable<DmsRecordAlarmTime>().First(x => x.AlarmRuleId == warnRuleId);
if (dmsRecordAlarmTime == null)
{
DmsBaseAlarmRule dmsBaseAlarmRule = sqlSugarClient.AsTenant().GetConnection("mes").Queryable<DmsBaseAlarmRule>().First(x => x.AlarmRuleId == warnRuleId);
dmsRecordAlarmTime = new DmsRecordAlarmTime();
dmsRecordAlarmTime.DeviceId = dmsBaseAlarmRule.DeviceId;
dmsRecordAlarmTime.AlarmRuleId = warnRuleId;
@ -224,8 +235,8 @@ namespace SlnMesnac.Business
dmsRecordAlarmTime.ContinueTime = dmsBaseAlarmRule.ContinueTime;
dmsRecordAlarmTime.AlarmReason = dmsBaseAlarmRule.AlarmReason;
dmsRecordAlarmTime.AlarmReason = dmsBaseAlarmRule.AlarmReason;
dmsRecordAlarmTime.AlarmData = WarnStatusEnum.RFID5.ToString();
dmsRecordAlarmTime.HandleSuggest = dmsBaseAlarmRule.HandleSuggest+";;虚拟托盘号为:"+epcStr;
dmsRecordAlarmTime.AlarmData = WarnStatusEnum.RFID5.ToString();
dmsRecordAlarmTime.HandleSuggest = dmsBaseAlarmRule.HandleSuggest + ";;虚拟托盘号为:" + epcStr;
dmsRecordAlarmTime.CreateBy = "SlnMesnac";
dmsRecordAlarmTime.CreateTime = DateTime.Now;
@ -238,20 +249,20 @@ namespace SlnMesnac.Business
dmsRecordAlarmInfo.ContinueTime = dmsBaseAlarmRule.ContinueTime;
dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason;
dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason;
dmsRecordAlarmInfo.AlarmData = WarnStatusEnum.RFID5.ToString();
dmsRecordAlarmInfo.HandleSuggest = dmsBaseAlarmRule.HandleSuggest + ";;虚拟托盘号为:" + epcStr;
dmsRecordAlarmInfo.AlarmData = WarnStatusEnum.RFID5.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();
sqlSugarClient.AsTenant().GetConnection("mes").Insertable(dmsRecordAlarmInfo).ExecuteCommand();
}
else
{
dmsRecordAlarmTime.UpdateTime = DateTime.Now;
dmsRecordAlarmTime.UpdateBy = "SlnMesnac";
DmsRecordAlarmInfo dmsRecordAlarmInfo = sqlSugarClient.AsTenant().GetConnection("mes").Queryable<DmsRecordAlarmInfo>().First(x=>x.AlarmRuleId==warnRuleId);
DmsRecordAlarmInfo dmsRecordAlarmInfo = sqlSugarClient.AsTenant().GetConnection("mes").Queryable<DmsRecordAlarmInfo>().First(x => x.AlarmRuleId == warnRuleId);
if (dmsRecordAlarmInfo != null)
{
dmsRecordAlarmInfo.UpdateTime = DateTime.Now;
@ -259,15 +270,16 @@ namespace SlnMesnac.Business
}
sqlSugarClient.AsTenant().GetConnection("mes").Updateable(dmsRecordAlarmTime).ExecuteCommand();
sqlSugarClient.AsTenant().GetConnection("mes").Updateable(dmsRecordAlarmInfo).ExecuteCommand();
}
sqlSugarClient.AsTenant().CommitTran();
return epcStr;
}catch(Exception ex)
}
catch (Exception ex)
{
sqlSugarClient.AsTenant().RollbackTran();
_logger.LogError($"NoReadRFIDAlarm异常:{ex.Message}");
_logger.LogError($"NoReadRFIDAlarm异常:{ex.Message}");
return "";
}
@ -275,15 +287,15 @@ namespace SlnMesnac.Business
/// <summary>
/// 生成大条码插入mes_barcode_info
/// 生成大条码插入mes_barcode_info
/// </summary>
/// <param name="productPlanDto"></param>
/// <param name="epcStr"></param>
/// <returns></returns>
private string GenerateBigBarcode(MesProductPlanDto productPlanDto,string epcStr)
private string GenerateBigBarcode(MesProductPlanDto productPlanDto, string epcStr)
{
string bigBarcode = productPlanDto.PlanCode+DateTime.Now.ToString("_MMddHHmmss");
string bigBarcode = productPlanDto.PlanCode + DateTime.Now.ToString("_MMddHHmmss");
MesBaseBarcodeInfo mesBaseBarcodeInfo = new MesBaseBarcodeInfo();
mesBaseBarcodeInfo.printTime = DateTime.Now;
mesBaseBarcodeInfo.printPerson = "SlnMesnac";
@ -299,40 +311,40 @@ namespace SlnMesnac.Business
mesBaseBarcodeInfo.productionDate = DateTime.Now;
mesBaseBarcodeInfo.acceptedDate = DateTime.Now;
mesBaseBarcodeInfo.planCode = productPlanDto.PlanCode;
mesBaseBarcodeInfo.safeFlag = productPlanDto.SaleOrderId ==0 ?"1" : "0";
mesBaseBarcodeInfo.safeFlag = productPlanDto.SaleOrderId == 0 ? "1" : "0";
mesBaseBarcodeInfo.saleOrderId = productPlanDto.SaleOrderId;
mesBaseBarcodeInfo.saleorderCode = productPlanDto.SaleorderCode;
mesBaseBarcodeInfo.bindStatus = "1";
mesBaseBarcodeInfo.bindTime = DateTime.Now;
mesBaseBarcodeInfo.bindTime = DateTime.Now;
mesBaseBarcodeInfo.updateBy = "SlnMesnac";
mesBaseBarcodeInfo.updateTime = DateTime.Now;
mesBaseBarcodeInfo.completeFlag = "1";
mesBaseBarcodeInfo.singleFlag = "0";
mesBaseBarcodeInfo.updateTime = DateTime.Now;
mesBaseBarcodeInfo.completeFlag = "1";
mesBaseBarcodeInfo.singleFlag = "0";
var materialInfo = _baseMaterialInfoService.Query(x => x.MaterialId == productPlanDto.MaterialId).FirstOrDefault();
if(materialInfo != null)
if (materialInfo != null)
{
mesBaseBarcodeInfo.barcodeSpec = materialInfo.MaterialSpec;
}
}
sqlSugarClient.AsTenant().GetConnection("mes").Insertable(mesBaseBarcodeInfo).ExecuteCommand();
return bigBarcode;
}
/// <summary>
/// 40个小条码及大条码绑定托盘号小条码绑定大条码
/// 40个小条码及大条码绑定托盘号小条码绑定大条码
/// </summary>
/// <param name="bigBarcode"></param>
/// <param name="epcStr"></param>
private void BindingBarCode(string bigBarcode,string epcStr)
private void BindingBarCode(string bigBarcode, string epcStr)
{
List<MesPrdBarcodeInfo> list = _mesPrdBarCodeService.GetUseBarCodeList();
if(list==null || list.Count == 0)
if (list == null || list.Count == 0)
{
throw new InvalidOperationException("托盘未找到可以绑定的小条码");
throw new InvalidOperationException("托盘未找到可以绑定的小条码");
}
if (list.Where(x => x.PrintFlag == "1").ToList().Count < 40)
{
// TODO推送低级别报警
// TODO推送低级别报警
PrintLessThan40Alarm();
}
foreach (var item in list)
@ -347,44 +359,44 @@ namespace SlnMesnac.Business
private void UpdatePlanInfoAndOrder(MesProductPlanDto productPlanDto)
{
MesProductPlan productPlan = _mesProductPlanService.Query(x => x.PlanCode == productPlanDto.PlanCode).FirstOrDefault();
if(productPlan == null)
MesProductPlan productPlan = _mesProductPlanService.Query(x => x.PlanCode == productPlanDto.PlanCode).FirstOrDefault();
if (productPlan == null)
{
throw new InvalidOperationException("未找到该生产计划!");
throw new InvalidOperationException("未找到该生产计划!");
}
MesProductOrder productOrder = _mesProductOrderService.Query(x => x.ProductOrderId == productPlan.ProductOrderId).FirstOrDefault();
if (productPlan == null)
{
throw new InvalidOperationException("未找到该生产计划对应的生产工单!");
throw new InvalidOperationException("未找到该生产计划对应的生产工单!");
}
#region 更新生产计划
#region 更新生产计划
if (productPlan.CompleteAmount == 0)
{
productPlan.RealBeginTime = DateTime.Now;
}
productPlan.CompleteAmount++;
if(productPlan.CompleteAmount == productPlan.PlanAmount)
if (productPlan.CompleteAmount == productPlan.PlanAmount)
{
productPlan.RealEndTime = DateTime.Now;
productPlan.PlanStatus = Model.enums.PlanStatusEnum.;
productPlan.PlanStatus = Model.enums.PlanStatusEnum.;
}
productPlan.UpdateTime = DateTime.Now;
productPlan.UpdateBy = "SlnMesnac";
sqlSugarClient.AsTenant().GetConnection("mes").Updateable(productPlan).ExecuteCommand();
#endregion
#region 更新生产工单
#region 更新生产工单
if (productOrder.CompleteAmount == 0)
{
productOrder.RealBeginTime = DateTime.Now;
}
productOrder.CompleteAmount++;
if(productOrder.CompleteAmount== productOrder.PlanAmount)
if (productOrder.CompleteAmount == productOrder.PlanAmount)
{
productOrder.RealEndTime = DateTime.Now;
productOrder.OrderStatus = "2";
}
@ -396,8 +408,8 @@ namespace SlnMesnac.Business
}
/// <summary>
/// 小包产出绑定托盘小包喷码数量小于40低级别报警
/// <return> 返回生产的虚拟托盘号
/// 小包产出绑定托盘小包喷码数量小于40低级别报警
/// <return> 返回生产的虚拟托盘号
/// </summary>
private void PrintLessThan40Alarm()
{
@ -405,8 +417,8 @@ namespace SlnMesnac.Business
{
sqlSugarClient.AsTenant().BeginTran();
// 有报警,找出该设备的报警记录,如果没有报警记录或者报警记录已结束,则新增报警记录
int warnRuleId = int.Parse(WarnStatusEnum.40.GetDescription());
// 有报警,找出该设备的报警记录,如果没有报警记录或者报警记录已结束,则新增报警记录
int warnRuleId = int.Parse(WarnStatusEnum.40.GetDescription());
DmsRecordAlarmTime? dmsRecordAlarmTime = sqlSugarClient.AsTenant().GetConnection("mes").Queryable<DmsRecordAlarmTime>().First(x => x.AlarmRuleId == warnRuleId);
if (dmsRecordAlarmTime == null)
{
@ -419,7 +431,7 @@ namespace SlnMesnac.Business
dmsRecordAlarmTime.ContinueTime = dmsBaseAlarmRule.ContinueTime;
dmsRecordAlarmTime.AlarmReason = dmsBaseAlarmRule.AlarmReason;
dmsRecordAlarmTime.AlarmReason = dmsBaseAlarmRule.AlarmReason;
dmsRecordAlarmTime.AlarmData = WarnStatusEnum.40.ToString();
dmsRecordAlarmTime.AlarmData = WarnStatusEnum.40.ToString();
dmsRecordAlarmTime.HandleSuggest = dmsBaseAlarmRule.HandleSuggest;
dmsRecordAlarmTime.CreateBy = "SlnMesnac";
dmsRecordAlarmTime.CreateTime = DateTime.Now;
@ -433,7 +445,7 @@ namespace SlnMesnac.Business
dmsRecordAlarmInfo.ContinueTime = dmsBaseAlarmRule.ContinueTime;
dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason;
dmsRecordAlarmInfo.AlarmReason = dmsBaseAlarmRule.AlarmReason;
dmsRecordAlarmInfo.AlarmData = WarnStatusEnum.40.ToString();
dmsRecordAlarmInfo.AlarmData = WarnStatusEnum.40.ToString();
dmsRecordAlarmInfo.HandleSuggest = dmsBaseAlarmRule.HandleSuggest;
dmsRecordAlarmInfo.CreateBy = "SlnMesnac";
dmsRecordAlarmInfo.CreateTime = DateTime.Now;
@ -458,23 +470,23 @@ namespace SlnMesnac.Business
}
sqlSugarClient.AsTenant().CommitTran();
}
catch (Exception ex)
{
sqlSugarClient.AsTenant().RollbackTran();
_logger.LogError($"PrintLessThan40Alarm异常:{ex.Message}");
_logger.LogError($"PrintLessThan40Alarm异常:{ex.Message}");
}
}
/// <summary>
/// 空托盘进入码垛位,读取RFID备用
/// 空托盘进入码垛位,读取RFID备用
/// </summary>
private async void EmptyPalletHandle()
private async Task EmptyPalletHandle()
{
//读取PLC空托盘流转信号
//读取PLC空托盘流转信号
while (true)
{
try
@ -482,71 +494,75 @@ namespace SlnMesnac.Business
var plc = base.GetPlcByKey("plc");
if (plc == null)
{
_logger.LogInformation("读取PLC空托盘码垛到位信号,PLC连接信息为空......");
_logger.LogInformation("读取PLC空托盘码垛到位信号,PLC连接信息为空......");
Thread.Sleep(5000);
continue;
}
if (!plc.readBoolByAddress(GetPlcAddressByConfigKey("2楼码垛到位信号")))
{
_logger.LogInformation("等待空托盘到位信号触发......");
Thread.Sleep(5000);
continue;
}
if (!plc.readBoolByAddress(GetPlcAddressByConfigKey("2楼码垛到位信号")))
RealPalletTask realPalletTask = _realPalletTaskService.Query().FirstOrDefault();
if (realPalletTask != null)
{
_logger.LogInformation("等待空托盘到位信号触发......");
_logger.LogInformation("空托盘到位信号触发,已经有读取托盘,不再读取......");
Thread.Sleep(5000);
continue;
}
//读取RFID、获取当前正在执行的计划、将当前计划、工单等信息与托盘绑定
RefreshMessage("空托盘到位信号触发成功,读取托盘RFID信息");
//读取RFID、获取当前正在执行的计划、将当前计划、工单等信息与托盘绑定
RefreshMessage("空托盘到位信号触发成功,读取托盘RFID信息");
string epcStr = await ReadEpcStrByRfidKeyAsync("secondFloorPallet");
if (string.IsNullOrEmpty(epcStr))
{
_logger.LogError("空托盘到位信号触发,读取RFID失败......");
Thread.Sleep(1000*10);
_logger.LogError("空托盘到位信号触发,读取RFID失败......");
Thread.Sleep(1000 * 10);
continue;
}
RefreshMessage($"空托盘RFID信息读取成功标签信息{epcStr}");
RefreshMessage($"空托盘RFID信息读取成功标签信息{epcStr}");
// 插入一条托盘记录
RealPalletTask realPalletTask = new RealPalletTask()
// 插入一条托盘记录
realPalletTask = new RealPalletTask()
{
PalletCode = epcStr,
RecordTime = DateTime.Now,
};
bool result = _realPalletTaskService.Insert(realPalletTask);
if (result)
{
plc.writeBoolByAddress(GetPlcAddressByConfigKey("2楼码垛到位信号"), false);
}
_realPalletTaskService.Insert(realPalletTask);
}
catch (Exception e)
{
RefreshMessage($"空托盘进入码垛位处理异常:{e.Message}");
RefreshMessage($"空托盘进入码垛位处理异常:{e.Message}");
}
Thread.Sleep(1000*5);
Thread.Sleep(1000 * 10);
}
}
/// <summary>
/// 根据条码提取序列
/// 根据条码提取序列
/// </summary>
/// <param name="barCode"></param>
/// <param name="result"></param>
/// <exception cref="InvalidOperationException"></exception>
private void ExtractNumber(string barCode,out int result)
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;
result = Convert.ToInt32(match.Groups[1].Value) + 1;
}
else
{
throw new InvalidOperationException($"通过条码:{barCode}提取当前序列异常:未找到匹配的数字");
throw new InvalidOperationException($"通过条码:{barCode}提取当前序列异常:未找到匹配的数字");
}
}

@ -84,9 +84,11 @@ namespace SlnMesnac.Business
_mesPrdBarCodeService = serviceProvider.GetRequiredService<IMesPrdBarCodeService>();
_configInfoBusiness = configInfoBusiness;
//testRFID();
}
public void TestTran()
{
try
@ -127,7 +129,6 @@ namespace SlnMesnac.Business
Console.WriteLine(aaa);
//RefreshMessage($"投料校验RFID标签读取成功标签信息{epcStr}");
}
#region 委托事件
@ -392,13 +393,16 @@ namespace SlnMesnac.Business
//2.生成小包条码
GenerateBarcode(40);
//BaseConfigInfo configInfo = _configInfoBusiness.GetConfigInfos().Where(x => x.ConfigKey == "系统运行时长").FirstOrDefault();
//configInfo.ConfigValue = "0";
//sqlSugarClient.AsTenant().GetConnection("local").Updateable(configInfo).ExecuteCommand();
//_configInfoBusiness.RefreshConfigInfo();
sqlSugarClient.AsTenant().CommitTran();
//3.清空投料系统运行时间
BaseConfigInfo configInfo = _configInfoBusiness.GetConfigInfos().Where(x => x.ConfigKey == "系统运行时长").FirstOrDefault();
configInfo.ConfigValue = "0";
sqlSugarClient.AsTenant().GetConnection("local").Updateable(configInfo).ExecuteCommand();
_configInfoBusiness.RefreshConfigInfo();
sqlSugarClient.AsTenant().CommitTran();
_configInfoBusiness.UpdateConfigInfo(configInfo);
}
}

@ -0,0 +1,57 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Security.Principal;
using System.Text;
namespace SlnMesnac.Model.domain
{
/// <summary>
/// 设备状态信息
/// </summary>
[SugarTable("dms_realtime_status")]
public class DmsRealtimeStatus
{
/// <summary>
/// 状态ID
/// </summary>
[SugarColumn(ColumnName = "status_id", IsPrimaryKey = true, IsIdentity = true)]
public long StatusId { get; set; }
/// <summary>
/// 设备状态编号
/// </summary>
[SugarColumn(ColumnName = "status_code")]
public string StatusCode { get; set; }
/// <summary>
/// 设备状态名称
/// </summary>
[SugarColumn(ColumnName = "status_name")]
public string StatusName { get; set; }
/// <summary>
/// 设备状态值
/// </summary>
[SugarColumn(ColumnName = "status_value")]
public string StatusValue { get; set; }
/// <summary>
/// 所属设备id
/// </summary>
[SugarColumn(ColumnName = "device_id")]
public long? DeviceId { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnName = "creat_time")]
public DateTime? CreatTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnName = "update_time")]
public DateTime? UpdateTime { get; set; }
}
}

@ -0,0 +1,69 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Security.Principal;
using System.Text;
namespace SlnMesnac.Model.domain
{
/// <summary>
/// 设备状态历史记录
/// </summary>
[SugarTable("dms_realtime_status_history")]
public class DmsRealtimeStatusHistory
{
/// <summary>
/// 历史记录ID
/// </summary>
[SugarColumn(ColumnName = "history_id", IsPrimaryKey = true, IsIdentity = true)]
public long HistoryId { get; set; }
/// <summary>
/// 状态ID
/// </summary>
[SugarColumn(ColumnName = "status_id")]
public long StatusId { get; set; }
/// <summary>
/// 设备状态编号
/// </summary>
[SugarColumn(ColumnName = "status_code")]
public string StatusCode { get; set; }
/// <summary>
/// 设备状态名称
/// </summary>
[SugarColumn(ColumnName = "status_name")]
public string StatusName { get; set; }
/// <summary>
/// 设备状态值
/// </summary>
[SugarColumn(ColumnName = "status_value")]
public string StatusValue { get; set; }
/// <summary>
/// 所属设备id
/// </summary>
[SugarColumn(ColumnName = "device_id")]
public long? DeviceId { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnName = "creat_time")]
public DateTime? CreatTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnName = "update_time")]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 同步时间
/// </summary>
[SugarColumn(ColumnName = "sync_time")]
public DateTime SyncTime { get; set; }
}
}

@ -0,0 +1,34 @@
using System;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* LAPTOP-E0N2L34V
* SlnMesnac.Model.dto
* 496f8d2b-70e3-4a05-ae18-a9b0fcd06b82
*
* WenJY
* wenjy@mesnac.com
* 2024-03-27 21:58:35
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Model.dto
{
/// <summary>
/// 采集设备状态
/// </summary>
public class DmsRealTimeDto
{
}
}

@ -121,7 +121,9 @@ namespace SlnMesnac.Repository.service.Impl
}
catch (Exception e)
{
throw new InvalidOperationException($"获取已开始的第一条生产计划异常:{e.Message}");
productPlanDto = null;
return null;
//throw new InvalidOperationException($"获取已开始的第一条生产计划异常:{e.Message}");
}
}

@ -17,9 +17,11 @@ namespace SlnMesnac.WPF.Dto
//设备运行状态
public bool status { get; set; }
//报警类型
public WarnStatusEnum warnStatus { get; set; } = WarnStatusEnum.;
//设备实时状态采集点
// public List<> realTimeList { get; set; }
}

@ -18,12 +18,17 @@
<Grid >
<StackPanel VerticalAlignment="Center" Orientation="Horizontal" >
<TextBlock Text="包装袋余量:" FontSize="25" VerticalAlignment="Center" Width="140" Margin="0,0,20,0" Foreground="White" HorizontalAlignment="Left"/>
<TextBlock x:Name="BagsAmountTxt" Text="0" Width="80" FontSize="25" VerticalAlignment="Center" Margin="0,0,20,0" Foreground="White"/>
<Button x:Name="AmountChangeButton" Style="{StaticResource BUTTON_AGREE}" Content="数量调整" FontSize="30" Background="Blue" Width="180" Height="60" Margin="0 0 20 0" HorizontalAlignment="Left" Click="AmountChangeButton_Click"/>
<TextBlock Text="缓存区重量:" FontSize="25" VerticalAlignment="Center" Width="140" Margin="0,0,20,0" Foreground="White" HorizontalAlignment="Left"/>
<TextBlock x:Name="BufferWeightTxt" Text="0" Width="80" FontSize="25" VerticalAlignment="Center" Margin="0,0,20,0" Foreground="White"/>
<Button x:Name="SetStopWeightButton" Style="{StaticResource BUTTON_AGREE}" Content="设置重量阈值" FontSize="30" Background="CadetBlue" Width="200" Height="60" Margin="0 0 20 0" HorizontalAlignment="Left" Click="SetStopWeightButton_Click" />
<Button x:Name="StartButton" Style="{StaticResource BUTTON_AGREE}" Content="一键启动" FontSize="30" Background="LimeGreen" Width="180" Height="60" Margin="180 0 20 0" Click="StartButton_Click"/>
<Button x:Name="StopButton" Style="{StaticResource BUTTON_AGREE}" Content="一键停止" FontSize="30" Background="OrangeRed" Width="180" Height="60" Margin="0,0,20,0" Click="StopButton_Click"/>
<Button x:Name="StopUrgentButton" Style="{StaticResource BUTTON_AGREE}" Content="急停" FontSize="30" Background="#E4B74C" Width="150" Height="60" Margin="0,0,0,0" Click="StopUrgentButton_Click"/>
<TextBlock Text="包装袋余量:" FontSize="25" VerticalAlignment="Center" Width="140" Margin="200,0,20,0" Foreground="White" HorizontalAlignment="Left"/>
<TextBlock x:Name="BagsAmountTxt" Text="0" Width="80" FontSize="25" VerticalAlignment="Center" Margin="0,0,20,0" Foreground="White"/>
<Button x:Name="AmountChangeButton" Style="{StaticResource BUTTON_AGREE}" Content="数量调整" FontSize="30" Background="CadetBlue" Width="180" Height="60" Margin="0 0 20 0" HorizontalAlignment="Left" Click="AmountChangeButton_Click"/>
</StackPanel>
</Grid>
</Border>

@ -151,6 +151,13 @@ namespace SlnMesnac.WPF.Page
RefreshHot(machineStatusDtos);
RefreshUnPack(machineStatusDtos);
App.Current.Dispatcher.BeginInvoke((Action)(() =>
{
BagsAmountTxt.Text = _configInfoBusiness.GetConfigInfos().FirstOrDefault(x => x.ConfigKey == "包装袋余量").ConfigValue;
BufferWeightTxt.Text = recipeManageCache.BufferWeight.ToString("F2");
}));
//开关机时间采集
machineStatusDtos.ForEach(x => OeeCollection(x));
//报警采集
@ -164,10 +171,7 @@ namespace SlnMesnac.WPF.Page
Thread.Sleep(1000 * 30);
}
App.Current.Dispatcher.BeginInvoke((Action)(() =>
{
BagsAmountTxt.Text = _configInfoBusiness.GetConfigInfos().FirstOrDefault(x => x.ConfigKey == "包装袋余量").ConfigValue;
}));
}
catch (Exception ex)
{
@ -370,6 +374,9 @@ namespace SlnMesnac.WPF.Page
if (warnStatusEnum == WarnStatusEnum.)
{
return 0;
}else if(warnStatusEnum == WarnStatusEnum. || warnStatusEnum == WarnStatusEnum.)
{ // 不停
return -1;
}
else if (warnStatusEnum.ToString().Contains("烘干机"))
{
@ -615,15 +622,14 @@ namespace SlnMesnac.WPF.Page
}
else
{
return false;
recipeManageCache.useRecipeManage.RecipeName = targetRecipet.RecipeName;
recipeManageCache.RecipeMode = "手动模式";
return true;
}
}
#endregion
#region 设备启动、停止
/// <summary>
@ -790,14 +796,15 @@ namespace SlnMesnac.WPF.Page
MessageBox.Show("拆包机未成功停止,请先检查");
return result;
}
#region 烘干机
SendPulseSignal("烘干机螺旋停止");
if(stopLevel < 2) return result;
Thread.Sleep(MachineSleep);
#region 烘干机
SendPulseSignal("烘干机燃烧停止");
if (stopLevel < 3) return result;
Thread.Sleep(MachineSleep);
SendPulseSignal("烘干机螺旋停止");
if (stopLevel < 2) return result;
Thread.Sleep(MachineSleep);
SendPulseSignal("烘干机风机停止");
@ -1528,7 +1535,7 @@ namespace SlnMesnac.WPF.Page
bool unPackStatus3 = plc.readBoolByAddress(baseBusiness.GetPlcAddressByConfigKey("物料到位"));
bool unPackStatus4 = plc.readBoolByAddress(baseBusiness.GetPlcAddressByConfigKey("设备投料"));
bool unPackStatus5 = plc.readBoolByAddress(baseBusiness.GetPlcAddressByConfigKey("拆包机请求移走空托盘"));
bool unPackStatus7 = plc.readBoolByAddress(baseBusiness.GetPlcAddressByConfigKey("拆包机连接状态"));
bool unPackStatus8 = plc.readBoolByAddress(baseBusiness.GetPlcAddressByConfigKey("拆包机堵料停螺旋"));
@ -1537,7 +1544,7 @@ namespace SlnMesnac.WPF.Page
float unPackStatus11 = plc.readFloatByAddress(baseBusiness.GetPlcAddressByConfigKey("拆包机螺旋1频率反馈"));
float unPackStatus12 = plc.readFloatByAddress(baseBusiness.GetPlcAddressByConfigKey("拆包机螺旋2频率反馈"));
float unPackStatus13 = plc.readFloatByAddress(baseBusiness.GetPlcAddressByConfigKey("拆包机废袋机频率反馈"));
App.Current.Dispatcher.BeginInvoke((Action)(() =>
{
@ -1560,6 +1567,8 @@ namespace SlnMesnac.WPF.Page
}));
//数据采集部分
MachineStatusDto machineStatusDto = new MachineStatusDto();
machineStatusDto.deviceId = 1016;
machineStatusDto.status = unPackStatus1;
@ -1875,6 +1884,8 @@ namespace SlnMesnac.WPF.Page
#region 设备管理界面螺旋频率设定--暂未启用
///// <summary>
@ -2067,7 +2078,10 @@ namespace SlnMesnac.WPF.Page
//}
#endregion
private void SetStopWeightButton_Click(object sender, RoutedEventArgs e)
{
InputDialogWindow window = new InputDialogWindow();
window.ShowDialog();
}
}
}

@ -0,0 +1,26 @@
<Window x:Class="SlnMesnac.WPF.Page.InputDialogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SlnMesnac.WPF.Page"
mc:Ignorable="d"
Title="重量设置" Height="300" Width="700" WindowStartupLocation="CenterScreen" Topmost="True" Background="Transparent">
<Border Margin="5" Background="Transparent" CornerRadius="10">
<Border.Effect>
<DropShadowEffect Color="LightGoldenrodYellow" ShadowDepth="0" BlurRadius="5" Opacity="0.3" Direction="0"></DropShadowEffect>
</Border.Effect>
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal">
<TextBlock Text="最大重量阈值:" FontSize="25" VerticalAlignment="Center" Width="200" Margin="0,0,20,0" Foreground="White" HorizontalAlignment="Left"/>
<TextBlock x:Name="BagsAmountTxt" Text="1222" Width="80" FontSize="25" VerticalAlignment="Center" Margin="0,0,20,0" Foreground="White"/>
<Button x:Name="AmountChangeButton" Style="{StaticResource BUTTON_AGREE}" Content="数量调整" FontSize="30" Background="CadetBlue" Width="180" Height="60" Margin="0 0 20 0" HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Margin="80 150 0 0" VerticalAlignment="Center" >
<TextBlock Text="提示信息: 缓存区重量超过该值,设备将会停止!" FontSize="25" Width="600" Margin="0,0,20,0" Foreground="White" HorizontalAlignment="Left"/>
</StackPanel>
</Grid>
</Border>
</Window>

@ -0,0 +1,38 @@
using Microsoft.Extensions.DependencyInjection;
using Quartz.Util;
using SlnMesnac.Business;
using SlnMesnac.Model.domain;
using SlnMesnac.WPF.Model;
using SlnMesnac.WPF.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace SlnMesnac.WPF.Page
{
/// <summary>
///
/// </summary>
public partial class InputDialogWindow : Window
{
private RecipeManageCache recipeManageCache = RecipeManageCache.Instance;
public InputDialogWindow()
{
InitializeComponent();
}
}
}

@ -48,6 +48,9 @@
</ItemGroup>
<ItemGroup>
<Compile Update="Page\Window\InputDialogWindow.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Page\Window\RecipeModeSetWindow.xaml.cs">
<SubType>Code</SubType>
</Compile>

@ -192,7 +192,7 @@ namespace SlnMesnac.WPF.ViewModel
Task.Run(() =>
{
_prodCompletionBusiness.PrintMessageToListBoxEvent += PrintMessageToListBox;
_prodCompletionBusiness.Init();
// _prodCompletionBusiness.Init();
});
}

@ -38,9 +38,9 @@
{
"configId": 1,
"plcType": "SiemensPlc",
// "plcIp": "192.168.2.220",
"plcIp": "127.0.0.1",
"plcPort": 103,
"plcIp": "192.168.2.220",
// "plcIp": "127.0.0.1",
"plcPort": 102,
"plcKey": "plc",
"isFlage": true
},
@ -60,7 +60,7 @@
"equipIp": "192.168.2.27",
"equipPort": 20108,
"equipKey": "secondFloorPallet",
"isFlage": false
"isFlage": true
},
{
// RFID
@ -68,7 +68,7 @@
"equipIp": "192.168.2.28",
"equipPort": 20108,
"equipKey": "secondFloorOut",
"isFlage": false
"isFlage": true
}
]
//"redisConfig": "175.27.215.92:6379,password=redis@2023"

Loading…
Cancel
Save