using Dm.filter; using DocumentFormat.OpenXml.Bibliography; using DocumentFormat.OpenXml.Drawing.Charts; using Elastic.Clients.Elasticsearch.Tasks; using Furion.Logging; using IoTClient; using Microsoft.AspNetCore.SignalR; using Qiniu.Storage; using RazorEngine.Compilation.ImpromptuInterface.Dynamic; using SKIT.FlurlHttpClient.Wechat.TenpayV3.ExtendedSDK.Global.Models; using System; using System.Data; using System.Reflection.Emit; using WCS.Application.Entity; using WCS.Application.Util; using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinExpressIntracityUpdateStoreRequest.Types; using static SKIT.FlurlHttpClient.Wechat.Api.Models.NontaxInsertBillRequest.Types.CardExtra.Types.BillCard.Types; namespace WCS.Application; public static class PLCService { private static readonly object OLock = new object(); private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); public static void OnChangeEvent(object sender, EventArgs e) { try { var mod = sender as WcsDeviceDto; Console.WriteLine("PLC值为" + mod.Value); switch (mod.Type) { case PLCTypeEnum.StackingMachine: StackingMachine(mod); // 跺机 break; case PLCTypeEnum.ConveyorLine: ConveyorLine(mod); // 托盘输送线 break; case PLCTypeEnum.AGV: AGV(mod); // AGV调度 break; case PLCTypeEnum.BoxConveyorLine: BoxConveyorLine(mod); // 码垛机器人 break; case PLCTypeEnum.StackingRobot: PalletMachine(mod); break; default: break; } } catch (Exception ex) { Log.Error(ex.Message, ex); } } /// /// 跺机业务处理 /// /// private static void StackingMachine(WcsDeviceDto modDevice) { var plcConn = modDevice.PLCUtil; string ledText = ""; switch (modDevice.Value.ToString()) { case "820": // 跺机空闲,获取出库任务、移库任务 { // 获取任务信息 var modTask = _db.Queryable().OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime, OrderByType.Asc) .First(s => s.Status == TaskStatusEnum.Wait && (s.TaskType == TaskTypeEnum.Out || s.TaskType == TaskTypeEnum.Move) && s.StartRoadway == modDevice.StationNum); if (modTask == null) { break; } //判断出库锁定是否打开 if (PLCTaskAction.boOutLock) { break;//出库锁定打开则不执行出库任务 } PlcTaskInfo taskInfo = new PlcTaskInfo(); if (modTask.TaskType == TaskTypeEnum.Move) { // 移库目标地址 taskInfo = PLCCommon.GetEndPai(modTask.EndLocate.Substring(1, 2), modTask.EndLocate.Substring(2, 2), modTask.EndLocate.Substring(0, 2), modTask.EndLocate.Substring(4, 2), modTask.EndLocate.Substring(6, 2)); } else { // 根据目标地址和巷道获取出库口对应的放货工位对应的排列层 taskInfo = PLCCommon.GetCTaskInfo(modTask.EndLocate, ((int)modTask.TaskType).ToString(), modTask.StartRoadway, modTask.EndRoadway); // 目标工位不为null,需先判断放货工位是否空闲 if (!string.IsNullOrEmpty(taskInfo.EndStation)) { #region 跨跺机任务处理 ########### // 判断目标位置是否是跨跺机出库工位 if (modTask.EndLocate == "266" && modTask.StartRoadway != "R05") { // 判断入库工位是否存在未完成的入库任务 var modInTask = _db.Queryable().OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime, OrderByType.Asc) .First(s => (s.Status == TaskStatusEnum.Wait || s.Status == TaskStatusEnum.Doing) && s.TaskType == TaskTypeEnum.In && s.StartLocate == modTask.EndLocate); if (modInTask != null) { // 目标出库口有对应的入库任务跳出循环,等待入库任务完成。 break; } // 根据目标工位号获取输送线链接 var plcCconn = PLCCommon.GetPlcIp(modTask.EndLocate); // 读取目标工位当前状态 var ConveyorMod = PLCTaskAction.plcDevices.First(m => m.StationNum == modTask.EndLocate && m.DeviceType == DeviceTypeEnum.Business); var (result, value) = plcCconn.GetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.PlcPos); if (result.IsSucceed) { if (value.ToString() != "120") { // 目标工位被占用跳出循环,等待工位释放。 break; } } string aaa = PLCCommon.RoadwayToOutStationNum(modTask.StartRoadway, "1"); // 获取1楼中专工位号 taskInfo.Ip = PLCCommon.GetPlcIp(aaa).PlcIP; taskInfo.EndPai = "2"; taskInfo.EndLie = "60"; taskInfo.EndCeng = "1"; taskInfo.EndStation = aaa; } if (modTask.EndLocate == "265" && modTask.StartRoadway != "R05" && modTask.StartRoadway != "R06") { // 判断入库工位是否存在未完成的入库任务 var modInTask = _db.Queryable().OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime, OrderByType.Asc) .First(s => (s.Status == TaskStatusEnum.Wait || s.Status == TaskStatusEnum.Doing) && s.TaskType == TaskTypeEnum.In && s.StartLocate == modTask.EndLocate); if (modInTask != null) { // 目标出库口有对应的入库任务跳出循环,等待入库任务完成。 break; } // 根据目标工位号获取输送线链接 var plcCconn = PLCCommon.GetPlcIp(modTask.EndLocate); // 读取目标工位当前状态 var ConveyorMod = PLCTaskAction.plcDevices.First(m => m.StationNum == modTask.EndLocate && m.DeviceType == DeviceTypeEnum.Business); var (result, value) = plcCconn.GetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.PlcPos); if (result.IsSucceed) { if (value.ToString() != "120") { // 目标工位被占用跳出循环,等待工位释放。 break; } } string aaa = PLCCommon.RoadwayToOutStationNum(modTask.StartRoadway, "1"); // 获取1楼中专工位号 taskInfo.Ip = PLCCommon.GetPlcIp(aaa).PlcIP; taskInfo.EndPai = "2"; taskInfo.EndLie = "60"; taskInfo.EndCeng = "1"; taskInfo.EndStation = aaa; } // 写入放货工位固定地址 #endregion // 打开对应的输送线连接 var plcConveyorConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == taskInfo.Ip); if (plcConveyorConn.Connected) { // 获取放货工位配置信息 var ConveyorMod = PLCTaskAction.plcDevices.First(m => m.StationNum == taskInfo.EndStation && m.DeviceType == DeviceTypeEnum.Business); var (result, value) = plcConveyorConn.GetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.PlcPos); if (result.IsSucceed) { if (value.ToString() != "720") // 720:放货空位空闲,可放货 liudl 程序调试完成后放开 { Log.Error(string.Format("任务号:{0}:放货工位占用,稍后执行。", modTask.TaskNo)); break; } else if (value.ToString() == "720") { // 若空闲提前占用此工位,同工位出入公用口 放开此程序 var ret = plcConveyorConn.SetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.WcsPos, "730"); if (!ret.IsSucceed) { break; } } } else { break; } } else { break; } } } // 获取转换后的起始排列层 06010101 // 移库时起始排列层 PlcTaskInfo startTaskInfo = PLCCommon.GetEndPai(modTask.StartRoadway.Substring(1, 2), modTask.StartLocate.Substring(2, 2), modTask.StartLocate.Substring(0, 2), modTask.StartLocate.Substring(4, 2), modTask.StartLocate.Substring(6, 2)); // 给PLC写入任务数据 var listResult = new List(); // 任务号托盘号 var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "托盘码"); listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); // 起始排列层 var modPosRow = modDevice.listStation.FirstOrDefault(s => s.Text == "取货排"); listResult.Add(plcConn.SetPlcDBValue(modPosRow.PosType, modDevice.DbNumber, modPosRow.PlcPos, startTaskInfo.EndPai)); var modPosColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "取货列"); listResult.Add(plcConn.SetPlcDBValue(modPosColumn.PosType, modDevice.DbNumber, modPosColumn.PlcPos, startTaskInfo.EndLie)); var modPosStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "取货层"); listResult.Add(plcConn.SetPlcDBValue(modPosStorey.PosType, modDevice.DbNumber, modPosStorey.PlcPos, startTaskInfo.EndCeng)); if (modTask.TaskType == TaskTypeEnum.Out) { var modEndNo = modDevice.listStation.FirstOrDefault(s => s.Text == "目的工位"); listResult.Add(plcConn.SetPlcDBValue(modEndNo.PosType, modDevice.DbNumber, modEndNo.PlcPos, taskInfo.EndStation)); } // 目标放货工位(固定排列层) var modPosEndRow = modDevice.listStation.FirstOrDefault(s => s.Text == "放货排"); listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType, modDevice.DbNumber, modPosEndRow.PlcPos, taskInfo.EndPai)); var modPosEndColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "放货列"); listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType, modDevice.DbNumber, modPosEndColumn.PlcPos, taskInfo.EndLie)); var modPosEndStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "放货层"); listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType, modDevice.DbNumber, modPosEndStorey.PlcPos, taskInfo.EndCeng)); // 是否写入成功 if (listResult.All(s => s.IsSucceed)) { // 写入跺机任务下发完成 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "830"); // 将移库任务待执行改为正在执行 _db.Updateable() .SetColumns(s => s.Status == TaskStatusEnum.Doing) .Where(s => s.Id == modTask.Id) .ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); WcsTaskMonitor modInsertTaskMonitor; if (string.IsNullOrEmpty(taskInfo.EndStation)) { // 同巷道移库 modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令:{modTask.StartLocate}储位====》{modTask.EndLocate}储位。", PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, }; } else { // 出库任务 跨巷道移库 modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令:{modTask.StartLocate}储位====》{taskInfo.EndStation}工位。", PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, }; } // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); //修改led屏信息 var ledDevice = PLCTaskAction.plcDevices.First(m => m.StationNum == taskInfo.EndStation && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business); ledText += $"任务类型:{modTask.TaskType.GetDescription()}\n\n"; ledText += $"任务号:{modTask.TaskNo}\n"; ledText += $"托盘号:{modTask.PalletNo}\n\n"; ledText += $"起始位:{modTask.StartRoadway + " " + modTask.StartLocate}\n"; ledText += $"目标位:{modTask.EndRoadway + " " + modTask.EndLocate}"; LedDisplay(ledDevice.LedIP, ledText); } } break; case "840": // 取货完成 { // 获取跺机点位配置 var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (res, val) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos); if (res.IsSucceed) { // 获取任务信息 string tasknoVal = val.ToString(); var modTask = _db.Queryable().First(m => m.Status == TaskStatusEnum.Doing && m.TaskNo == tasknoVal && m.IsDelete == false); if (modTask == null) { Log.Error(string.Format($"PLC控制字840:未找到对应的任务。任务号:{tasknoVal}")); break; } // 记录任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, }; var modPosEndStation = modDevice.listStation.FirstOrDefault(m => m.Text == "目的工位"); var (endRes, endStation) = plcConn.GetPlcDBValue(modPosEndStation.PosType, modDevice.DbNumber, modPosEndStation.PlcPos); var modPosStartStation = modDevice.listStation.FirstOrDefault(m => m.Text == "起始工位"); var (startStationRes, startStationVal) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Short, modDevice.DbNumber, modPosStartStation.PlcPos); if (modTask.TaskType == TaskTypeEnum.In) { // 获取跺机起始工位点位配置,读取起始工位 if (startStationRes.IsSucceed) { // 根据工位号获取对应的输送线IP PLCUtil plcConveyorConn = PLCCommon.GetPlcIp(startStationVal.ToString().PadLeft(3, '0')); if (plcConveyorConn.Connected) { // 向取货工位写入流程字640 取货已完成 var ConveyorMod = PLCTaskAction.plcDevices.First(m => m.StationNum == startStationVal.ToString().PadLeft(3, '0') && m.DeviceType == DeviceTypeEnum.Business && m.IsDelete == false); var modcTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = ConveyorMod.Id, PlcName = ConveyorMod.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = startStationVal.ToString(), EndLocat = modTask.EndLocate // 目标储位地址 }; // 读取wcs控制字 var (ress, va1s) = plcConveyorConn.GetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.WcsPos); if (va1s.ToString() == "630") { var retc = plcConveyorConn.SetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.WcsPos, "640"); if (retc.IsSucceed) { modcTaskMonitor.InteractiveMsg = string.Format("工位:{0},写入取货完成:640", startStationVal); // 插入交互日志 _db.Insertable(modcTaskMonitor).ExecuteCommand(); } else { modcTaskMonitor.InteractiveMsg = string.Format("工位:{0},写入取货完成640失败", startStationVal); // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); break; } //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); // 读取wcs控制字 var (resss, va1ss) = plcConn.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos); if (va1ss.ToString() == "830") { modInsertTaskMonitor.InteractiveMsg = string.Format("工位:{0}跺机取货完成写入850", startStationVal); modInsertTaskMonitor.EndLocat = modTask.EndLocate; // 目标储位地址 // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); } // 写入流程控制字 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "850"); if (!ret.IsSucceed) { modInsertTaskMonitor.InteractiveMsg = string.Format("工位:{0}跺机取货完成写入850失败,等待再次写入。", startStationVal); modInsertTaskMonitor.EndLocat = modTask.EndLocate; // 目标储位地址 // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); break; // 写入失败跳出等待再次写入 } //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } } } } else if (modTask.TaskType == TaskTypeEnum.Out) { #region 跺机转运任务处理 if (modTask.StartRoadway != modDevice.StationNum) {// 转运任务 // 写入起始工位640 string stationFrom = startStationVal.ToString(); var plcItemconn = PLCCommon.GetPlcIp(stationFrom); if (plcItemconn.Connected) { // 写入起始工位640 var modFrom = PLCTaskAction.plcDevices.First(m => m.IsDelete == false && m.StationNum == stationFrom); var retFrom = plcItemconn.SetPlcDBValue(modFrom.PosType, modFrom.DbNumber, modFrom.WcsPos, "640"); if (retFrom.IsSucceed) { Log.Error(stationFrom + "中转工位写入640"); } else { break; } // 读取wcs控制字 var (resss, va1ss) = plcConn.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos); if (va1ss.ToString() == "830") { // 记录任务明细 modInsertTaskMonitor.InteractiveMsg = string.Format("储位地址:{0}取货完成写入850", modTask.StartLocate); modInsertTaskMonitor.EndLocat = endStation.ToString(); // 放货工位 } // 写入流程控制字 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "850"); if (!ret.IsSucceed) { modInsertTaskMonitor.InteractiveMsg = string.Format("储位地址:{0}取货完成写入850失败,等待再次写入。", modTask.StartLocate); modInsertTaskMonitor.EndLocat = modTask.EndLocate; // 目标储位地址 // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); break; // 写入失败跳出等待再次写入 } //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } } else { //if (modTask.EndLocate == "266" && modTask.StartRoadway == "R06") //{ // // R06巷道单独转运任务。 // // 写入起始工位640 // string stationFrom = startStationVal.ToString(); // var plcItemconn = PLCCommon.GetPlcIp(stationFrom); // var modFrom = PLCTaskAction.plcDevices.First(m => m.IsDelete == false && m.StationNum == stationFrom); // var retFrom = plcItemconn.SetPlcDBValue(modFrom.PosType, modFrom.DbNumber, modFrom.WcsPos, "640"); // if (retFrom.IsSucceed) // { // Log.Error(stationFrom + "中转工位写入640"); // } // else // { // break; // } // // 读取wcs控制字 // var (resss, va1ss) = plcConn.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos); // if (va1ss.ToString() == "830") // { // // 记录任务明细 // modInsertTaskMonitor.InteractiveMsg = string.Format("储位地址:{0}取货完成写入850", modTask.StartLocate); // modInsertTaskMonitor.EndLocat = endStation.ToString(); // 放货工位 // } // // 写入流程控制字 // var ret11 = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "850"); // if (!ret11.IsSucceed) // { // modInsertTaskMonitor.InteractiveMsg = string.Format("储位地址:{0}取货完成写入850失败,等待再次写入。", modTask.StartLocate); // modInsertTaskMonitor.EndLocat = modTask.EndLocate; // 目标储位地址 // // 插入交互日志 // _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // break; // 写入失败跳出等待再次写入 // } // //下发任务日志 // HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); // break; //} // 写入流程控制字 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "850"); if (!ret.IsSucceed) { break; // 写入失败跳出等待再次写入 } modInsertTaskMonitor.InteractiveMsg = string.Format("储位地址:{0}取货完成", modTask.StartLocate); modInsertTaskMonitor.EndLocat = endStation; // 目标储位 // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } #endregion } else { // 写入流程控制字 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "850"); if (!ret.IsSucceed) { break; // 写入失败跳出等待再次写入 } modInsertTaskMonitor.InteractiveMsg = string.Format("储位地址:{0}取货完成", modTask.StartLocate); modInsertTaskMonitor.EndLocat = endStation; // 目标储位 // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } } } break; case "860": //跺机放货完成 { // 获取跺机点位配置 var modPos860Task = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (res, val) = plcConn.GetPlcDBValue(modPos860Task.PosType, modDevice.DbNumber, modPos860Task.PlcPos); // 根据任务号获取任务信息 if (res.IsSucceed) { string tasknoVal = val.ToString(); var modTask = _db.Queryable().First(m => m.Status == TaskStatusEnum.Doing && m.TaskNo == tasknoVal && m.IsDelete == false); if (modTask == null) { Log.Error(string.Format("跺机控制字860:未找到对应的任务。")); break; } switch (modTask.TaskType) { case TaskTypeEnum.In: { #region 跨跺机转运任务处理##### // 判断是否跨跺机转运任务 var modPos860endAddre = modDevice.listStation.FirstOrDefault(m => m.Text == "目的工位"); var (ress, endVal) = plcConn.GetPlcDBValue(modPos860endAddre.PosType, modDevice.DbNumber, modPos860endAddre.PlcPos); string endValStr = endVal.ToString().PadLeft(3, '0'); // 根据巷道、层数获取入库放货工位 var inVal = PLCCommon.RoadwayToStationNum(modTask.EndRoadway, "1"); var inVal1 = PLCCommon.RoadwayToStationNum(modTask.EndRoadway, "2", modTask.StartLocate.ToString()); // 根据当前跺机放货工位对比目标巷道入库取货工位做对比确认是否转运任务。 if (endValStr != inVal && endValStr != inVal1) { // 根据工位号获取输送线链接 var plcCconn = PLCCommon.GetPlcIp(endValStr); if (plcCconn.Connected) { // 写入转运信息 // 给PLC写入任务数据 var listResult = new List(); // 根据工位号获取工位信息 var wcsDevice = PLCTaskAction.plcDevices.First(s => s.PlcId == plcCconn.PlcId && s.Level == DeviceLevelEnum.Station && s.StationNum == endValStr); // 读取当前工位各偏移量值 var listPos = PLCTaskAction.plcPositions.Where(s => s.DeviceId == wcsDevice.Id).ToList(); //任务号 var modPosTask = listPos.FirstOrDefault(s => s.Text == "任务号"); listResult.Add(plcCconn.SetPlcDBValue(modPosTask.PosType, wcsDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); //任务类型 var modPosTaskType = listPos.FirstOrDefault(s => s.Text == "任务类型"); listResult.Add(plcCconn.SetPlcDBValue(modPosTaskType.PosType, wcsDevice.DbNumber, modPosTaskType.PlcPos, ((int)modTask.TaskType).ToString())); //托盘号 var modPosPalletNo = listPos.FirstOrDefault(s => s.Text == "托盘码"); listResult.Add(plcCconn.SetPlcDBValue(modPosPalletNo.PosType, wcsDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); //起始工位 var modPosLocatNo = listPos.FirstOrDefault(s => s.Text == "起始工位"); listResult.Add(plcCconn.SetPlcDBValue(modPosLocatNo.PosType, wcsDevice.DbNumber, modPosLocatNo.PlcPos, endValStr)); // 目标工位 var modPosEndLocatNo = listPos.FirstOrDefault(s => s.Text == "目的工位"); listResult.Add(plcCconn.SetPlcDBValue(modPosEndLocatNo.PosType, wcsDevice.DbNumber, modPosEndLocatNo.PlcPos, inVal)); // 是否写入成功 if (listResult.All(s => s.IsSucceed)) { var result = plcCconn.SetPlcDBValue(wcsDevice.PosType, wcsDevice.DbNumber, wcsDevice.WcsPos, "740"); if (result.IsSucceed) { // 写入跺机wcs控制字 返回垛机执行完成 result = modDevice.PLCUtil.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "870"); if (result.IsSucceed) { var modcTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = wcsDevice.Id, PlcName = wcsDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = "", EndLocat = modTask.EndRoadway, InteractiveMsg = $"写入指令:收到跺机放货完成;放货{endValStr}工位===》{inVal}工位" }; // 插入交互日志 _db.Insertable(modcTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modcTaskMonitor.Adapt()); break; } } } } } // 向工位写入,当前工位到目标巷道入库取货工位流程。写入流程控制字"740" #endregion var res870 = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "870"); if (!res870.IsSucceed) { Log.Error(string.Format("跺机控制字860写入870失败!")); break; } // 改变任务状态 modTask.Status = TaskStatusEnum.Complete; modTask.FinishDate = DateTime.Now; _db.Updateable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); var modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, InteractiveMsg = $"任务完成" }; if (modTask.Origin == "WMS") { // 反馈WMS var requestMode = new TaskRequestWMS() { TaskNo = modTask.TaskNo, PalletNo = modTask.PalletNo, TaskType = ((int)TaskTypeEnum.In).ToString(), TaskStatus = ((int)TaskStatusEnum.Complete).ToString() }; HttpService httpService = new HttpService(); var modResponseTask = httpService.RequestTask(requestMode).Result; if (modResponseTask.StatusCode == 0) { modTaskMonitor.InteractiveMsg = "任务完成,返回给WMS任务完成"; } else { Log.Error(string.Format("c:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg)); } } // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。 modDevice.LedIP = _db.Queryable().Where(w => w.StationNum == modTask.StartLocate).Select(s => s.LedIP).First(); // 插入交互日志 _db.Insertable(modTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); // led显示内容 var ledDevice = PLCTaskAction.plcDevices.First(m => m.StationNum == modTask.StartLocate && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business); ledText += $"入库完成\n\n"; ledText += $"任务号:{modTask.TaskNo}\n"; ledText += $"托盘号:{modTask.PalletNo}\n\n"; ledText += $"起始位:{modTask.StartRoadway + " " + modTask.StartLocate}\n"; ledText += $"目标位:{modTask.EndRoadway + " " + modTask.EndLocate}"; LedDisplay(ledDevice.LedIP, ledText); // 此处添加不空跑业务 } break; case TaskTypeEnum.Out: // 出库任务 { string roadway = modTask.StartRoadway; // 从出库任务获取放货工位 string outCode = modTask.EndLocate; #region 跨跺机转运任务 ########## var modPosStation = modDevice.listStation.FirstOrDefault(m => m.Text == "目的工位"); var (ress, stationNum) = plcConn.GetPlcDBValue(modPosStation.PosType, modDevice.DbNumber, modPosStation.PlcPos); if (!ress.IsSucceed) { // 获取当前托盘所在工位失败 break; } // 根据目标地址和巷道获取放货工位对应的排列层 PlcTaskInfo taskInfo = PLCCommon.GetCTaskInfo(modTask.EndLocate, ((int)modTask.TaskType).ToString(), modTask.StartRoadway, modTask.EndRoadway); string stationNumstr = stationNum.ToString(); if (!taskInfo.EndStation.Contains(stationNumstr) && stationNumstr != "0") { // 是跺机中专工位 //taskInfo.EndStation = stationNumstr; string roadwayto = "R05"; // 根据出库口放货工位获取对应的中转巷道 if (taskInfo.EndStation.Contains("277")) { roadwayto = "R05"; } else if (taskInfo.EndStation.Contains("250")) { roadwayto = "R06"; } // 根据层数和巷道数确定中专工位 outCode = PLCCommon.RoadwayToStationNum(roadwayto, "1"); } #endregion // 根据工位号获取对应的输送线IP var plcConveyorConn = PLCCommon.GetPlcIp(stationNumstr); if (plcConveyorConn.Connected) { stationNumstr = stationNumstr.PadLeft(3, '0'); // 根据工位号获取工位信息 var wcsDevice = PLCTaskAction.plcDevices.First(s => s.PlcId == plcConveyorConn.PlcId && s.Level == DeviceLevelEnum.Station && s.StationNum == stationNumstr); // 读取当前工位各偏移量值 var listPos = PLCTaskAction.plcPositions.Where(s => s.DeviceId == wcsDevice.Id).ToList(); // 给PLC写入任务数据 var listResult = new List(); //任务号 var modPosTask = listPos.FirstOrDefault(s => s.Text == "任务号"); listResult.Add(plcConveyorConn.SetPlcDBValue(modPosTask.PosType, wcsDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); //任务类型 var modPosTaskType = listPos.FirstOrDefault(s => s.Text == "任务类型"); listResult.Add(plcConveyorConn.SetPlcDBValue(modPosTaskType.PosType, wcsDevice.DbNumber, modPosTaskType.PlcPos, ((int)modTask.TaskType).ToString())); //托盘号 var modPosPalletNo = listPos.FirstOrDefault(s => s.Text == "托盘码"); listResult.Add(plcConveyorConn.SetPlcDBValue(modPosPalletNo.PosType, wcsDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); //起始工位 var modPosLocatNo = listPos.FirstOrDefault(s => s.Text == "起始工位"); listResult.Add(plcConveyorConn.SetPlcDBValue(modPosLocatNo.PosType, wcsDevice.DbNumber, modPosLocatNo.PlcPos, stationNumstr)); // 目标工位 var modPosEndLocatNo = listPos.FirstOrDefault(s => s.Text == "目的工位"); listResult.Add(plcConveyorConn.SetPlcDBValue(modPosEndLocatNo.PosType, wcsDevice.DbNumber, modPosEndLocatNo.PlcPos, outCode)); // 是否写入成功 if (listResult.All(s => s.IsSucceed)) { var result = plcConveyorConn.SetPlcDBValue(wcsDevice.PosType, wcsDevice.DbNumber, wcsDevice.WcsPos, "740"); if (result.IsSucceed) { // 写入跺机wcs控制字 返回垛机执行完成 result = modDevice.PLCUtil.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "870"); if (result.IsSucceed) { var modcTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = wcsDevice.Id, PlcName = wcsDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = taskInfo.EndStation, EndLocat = outCode, InteractiveMsg = $"写入指令:收到跺机放货完成;放货{taskInfo.EndStation}工位===》{outCode}工位" }; // 插入交互日志 _db.Insertable(modcTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modcTaskMonitor.Adapt()); break; } } } //此处添加不空跑业务 } } break; case TaskTypeEnum.Move: // 移库任务 { var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); var result = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo); if (!result.IsSucceed) { Log.Error($"{modDevice.Text}写入任务号失败"); break; } result = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "870"); if (!result.IsSucceed) { Log.Error($"{modDevice.Text}控制字写入870失败"); break; } // 改变任务状态 modTask.Status = TaskStatusEnum.Complete; modTask.FinishDate = DateTime.Now; modTask.Levels = 999; _db.Updateable(modTask).ExecuteCommand(); //下发任务日志 HubUtil.PublicTask(modTask.Adapt()); var modcTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, InteractiveMsg = $"任务完成" }; if (modTask.Origin == "WMS") { // 反馈WMS var requestMode = new TaskRequestWMS() { TaskNo = modTask.TaskNo, PalletNo = modTask.PalletNo, TaskType = ((int)TaskTypeEnum.Move).ToString(), TaskStatus = ((int)TaskStatusEnum.Complete).ToString() }; HttpService httpService = new HttpService(); var modResponseTask = httpService.RequestTask(requestMode).Result; if (modResponseTask.StatusCode == 0) { modcTaskMonitor.InteractiveMsg = "任务完成,返回给WMS任务完成"; //修改储位信息 任务类型 执行状态 起始位置 目标位置 } else { Log.Error(string.Format("任务反馈失败:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg)); } } // 插入交互日志 _db.Insertable(modcTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modcTaskMonitor.Adapt()); // 此处添加不空跑业务 } break; default: break; } } } break; case "841": { } break; case "843": { //空取货异常 var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); var (result, TaskNo) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos); if (!result.IsSucceed) break; string taskNo = Convert.ToString(TaskNo); var modTask = _db.Queryable().First(s => s.TaskNo == taskNo && s.Status == TaskStatusEnum.Doing); if (modTask == null) { Log.Error($"【堆垛机】当前任务号不存在对应的任务,任务号:{modTask.TaskNo}"); break; } var res = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "844"); if (!res.IsSucceed) break; modTask.Status = TaskStatusEnum.Exception; _db.Updateable(modTask).UpdateColumns(s => s.Status).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); Log.Information($"【堆垛机】wcs任务变更空取异常,任务号:{modTask.TaskNo}"); var modTaskRequest = modTask.Adapt(); HttpService httpService = new HttpService(); var modResponseTask = httpService.RequestEmptyException(modTaskRequest).Result; if (modResponseTask.StatusCode == "0") { //请求成功 modTask.IsSuccess = TaskSuccessEnum.Success; _db.Updateable(modTask).UpdateColumns(s => s.IsSuccess).ExecuteCommand(); //下发任务日志 HubUtil.PublicTask(modTask.Adapt()); } else { //请求失败 modTask.IsSuccess = TaskSuccessEnum.Fail; modTask.Information = modResponseTask.Message; _db.Updateable(modTask).UpdateColumns(s => new { s.IsSuccess, s.Information }).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); } } break; case "861": { //满放货异常 var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "托盘号"); var (result, TaskNo) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos); if (!result.IsSucceed) break; string taskNo = Convert.ToString(TaskNo); var modTask = _db.Queryable().First(s => s.TaskNo == taskNo && s.Status == TaskStatusEnum.Doing); if (modTask == null) { Log.Error($"【堆垛机】当前任务号不存在对应的任务,任务号:{modTask.TaskNo}"); break; } modTask.Status = TaskStatusEnum.Exception; _db.Updateable(modTask).UpdateColumns(s => s.Status).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); Log.Information($"【堆垛机】wcs任务变更满取异常,任务号:{modTask.TaskNo}"); var modTaskRequest = modTask.Adapt(); HttpService httpService = new HttpService(); var modResponseTask = httpService.RequestFullException(modTaskRequest).Result; if (modResponseTask.StatusCode == "0") { //修改任务为正在执行 modTask.Status = TaskStatusEnum.Doing; _db.Updateable(modTask).UpdateColumns(s => s.Status).ExecuteCommand(); // 起始排列层 var modPosRow = modDevice.listStation.FirstOrDefault(s => s.Text == "取货排"); var modPosColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "取货列"); var modPosStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "取货层"); // 目标放货工位 var modPosEndRow = modDevice.listStation.FirstOrDefault(s => s.Text == "放货排"); var modPosEndColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "放货列"); var modPosEndStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "放货层"); string endLocat = modResponseTask.TaskList.EndLocate; string row = int.Parse(endLocat.Substring(0, 2)).ToString(); string column = int.Parse(endLocat.Substring(2, 2)).ToString(); string storey = int.Parse(endLocat.Substring(4, 2)).ToString(); // 给PLC写入任务数据 var listResult = new List(); // 任务号托盘号 listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); // 起始排列层 listResult.Add(plcConn.SetPlcDBValue(modPosRow.PosType, modDevice.DbNumber, modPosRow.PlcPos, "2")); listResult.Add(plcConn.SetPlcDBValue(modPosColumn.PosType, modDevice.DbNumber, modPosColumn.PlcPos, "100")); listResult.Add(plcConn.SetPlcDBValue(modPosStorey.PosType, modDevice.DbNumber, modPosStorey.PlcPos, "1")); listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType, modDevice.DbNumber, modPosEndRow.PlcPos, row)); listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType, modDevice.DbNumber, modPosEndColumn.PlcPos, column)); listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType, modDevice.DbNumber, modPosEndStorey.PlcPos, storey)); // 是否写入成功 if (listResult.All(s => s.IsSucceed)) { // 向跺机写入控制流程字 var res = modDevice.PLCUtil.SetPlcDBValue(modDevice.PosType, modDevice.WcsPos, "862"); var modcTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = endLocat, InteractiveMsg = $"写入指令:{modDevice.StationNum}工位====》" + endLocat + "储位地址!" }; // 插入交互日志 _db.Insertable(modcTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modcTaskMonitor.Adapt()); } } //else //{ // //请求失败 // modTask.IsSuccess = TaskSuccessEnum.Fail; // modTask.Information = modResponseTask.Message; // _db.Updateable(modTask).UpdateColumns(s => new { s.IsSuccess, s.Information }).ExecuteCommand(); //} } break; default: break; } } /// /// 不空跑 /// /// 操作完成的任务 /// plc连接 /// 设备信息 private static void ContinuousOperation(WcsTask modTask, PLCUtil plcConn, WcsDeviceDto modDevice) { // 查询所有待执行的任务 var listTask = _db.Queryable().Where(s => s.Status == TaskStatusEnum.Wait).ToList(); WcsTask modNextTask = null; switch (modTask.TaskType) { case TaskTypeEnum.In: { // 先找出对应排列层的入库任务 var listInTask = listTask.Where(s => s.TaskType == TaskTypeEnum.In) .Select(s => s.EndLocate.Substring(0, 6)) .ToHashSet(); // 找出库任务,对应巷道的任务 var listNextTask = listTask.Where(s => s.TaskType == TaskTypeEnum.Out && s.StartRoadway == modTask.EndRoadway).ToList(); foreach (var modNext in listNextTask) { // 如果有对应排列层的入库任务,那就不能优先执行 if (listInTask.Contains(modNext.EndLocate.Substring(0, 6))) { continue; } // todo: 写入modNext任务信息给plc Console.WriteLine($"入库任务{modTask.TaskNo}执行完成后,不空跑逻辑检测下一任务为{modNext.TaskNo}"); modNextTask = modNext; break; } } break; case TaskTypeEnum.Out: { // 先找出对应排列层的出库任务 var listInTask = listTask.Where(s => s.TaskType == TaskTypeEnum.Out) .Select(s => s.EndLocate.Substring(0, 6)) .ToHashSet(); // 找入库任务,对应巷道的任务 var listNextTask = listTask.Where(s => s.TaskType == TaskTypeEnum.In && s.StartRoadway == modTask.EndRoadway).ToList(); foreach (var modNext in listNextTask) { // 如果有对应排列层的出库任务,那就不能优先执行 if (listInTask.Contains(modNext.EndLocate.Substring(0, 6))) { continue; } // todo: 写入modNext任务信息给plc Console.WriteLine($"出库任务{modTask.TaskNo}执行完成后,不空跑逻辑检测下一任务为{modNext.TaskNo}"); modNextTask = modNext; break; } } break; case TaskTypeEnum.Move: { var modDevicePos = _db.Queryable().Where(s => s.PlcId == plcConn.PlcId && s.DeviceType == DeviceTypeEnum.Show).First(); var (result, value) = plcConn.GetPlcDBValue(modDevicePos.PosType, modDevicePos.DbNumber, modDevicePos.PlcPos); //当前堆垛机所在位置 var height = Math.Round(value / 790000d * 200).ToInt(); //todo:这里看能不能找到堆垛机所在位置在哪个排列层,优先寻找附近的任务? } break; } if (modNextTask != null) { // 获取转换后的起始排列层 06010101 PlcTaskInfo startTaskInfo = PLCCommon.GetEndPai(modTask.StartRoadway.Substring(1, 2), modTask.StartLocate.Substring(2, 2), modTask.StartLocate.Substring(0, 2), modTask.StartLocate.Substring(4, 2), modTask.StartLocate.Substring(6, 2)); // 给PLC写入任务数据 var listResult = new List(); // 任务号托盘号 var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "托盘码"); listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); // 起始排列层 var modPosRow = modDevice.listStation.FirstOrDefault(s => s.Text == "取货排"); listResult.Add(plcConn.SetPlcDBValue(modPosRow.PosType, modDevice.DbNumber, modPosRow.PlcPos, startTaskInfo.EndPai)); var modPosColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "取货列"); listResult.Add(plcConn.SetPlcDBValue(modPosColumn.PosType, modDevice.DbNumber, modPosColumn.PlcPos, startTaskInfo.EndLie)); var modPosStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "取货层"); listResult.Add(plcConn.SetPlcDBValue(modPosStorey.PosType, modDevice.DbNumber, modPosStorey.PlcPos, startTaskInfo.EndCeng)); // 目标放货工位(固定排列层) PlcTaskInfo taskInfo = PLCCommon.GetCTaskInfo(modTask.EndLocate, ((int)modTask.TaskType).ToString(), modTask.StartRoadway, modTask.EndRoadway); var modPosEndRow = modDevice.listStation.FirstOrDefault(s => s.Text == "放货排"); listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType, modDevice.DbNumber, modPosEndRow.PlcPos, taskInfo.EndPai)); var modPosEndColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "放货列"); listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType, modDevice.DbNumber, modPosEndColumn.PlcPos, taskInfo.EndLie)); var modPosEndStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "放货层"); listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType, modDevice.DbNumber, modPosEndStorey.PlcPos, taskInfo.EndCeng)); // 是否写入成功 if (listResult.All(s => s.IsSucceed)) { // 写入跺机任务下发完成 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "830"); // 将移库任务待执行改为正在执行 _db.Updateable() .SetColumns(s => s.Status == TaskStatusEnum.Doing) .Where(s => s.Id == modTask.Id) .ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); WcsTaskMonitor modInsertTaskMonitor; if (string.IsNullOrEmpty(taskInfo.EndStation)) { // 同巷道移库 modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令:{modTask.StartLocate}储位====》{modTask.EndLocate}储位。", PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, }; } else { // 出库任务 跨巷道移库 modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令:{modTask.StartLocate}储位====》{taskInfo.EndStation}工位。", PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, }; } // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); //修改led屏信息 //LedDisplay(modDevice.LedIP, "工位:" + modTask.EndLocate, "出库中 " + $"储位地址:{modTask.StartLocate}", "托盘号:" + modTask.PalletNo); } } } /// /// 输送线业务处理 /// /// private static void ConveyorLine(WcsDeviceDto modDevice) { var plcConn = modDevice.PLCUtil; // 获取楼层数ceshi var louCeng = PLCCommon.GetRoadwayByStationNew(modDevice.StationNum); if (louCeng == "") { return; } var ledText = ""; switch (modDevice.Value.ToString()) { case "120": { // 120:空闲; wcs调度小车写130请求放(占住工位) } break; case "140": { // 140:可放;写入任务号等交互信息最后写入150正在放; wcs接受wms发送的小车任务完成信号后变更为:160: var http = new HttpService(); var modResponseTask = http.IssuedAgvTask(modDevice.StationNum).Result; if (modResponseTask.StatusCode == 0) { plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "150"); } } break; case "230": { // 230:托盘输送到位,请求小车; WCS向WMS申请小车输送WMS返回成功;写入240 ; } break; case "310": //入库申请PLC出现异常(托盘超宽、超高等) { plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "311"); string dbStr = ""; switch (modDevice.StationNum) { case "094": dbStr = "2381"; break; case "160": dbStr = "2385"; break; case "155": dbStr = "2383"; break; } string errorStr = "异常信息:"; //将异常信息显示到LED屏幕上 var (errorRes0, errorVal0) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{dbStr}.0", ""); if (errorRes0.IsSucceed && errorVal0 == true) { errorStr += " 扫码失败"; } var (errorRes1, errorVal1) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{dbStr}.1", ""); if (errorRes1.IsSucceed && errorVal1 == true) { errorStr += " 称重失败"; } var (errorRes2, errorVal2) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{dbStr}.2", ""); if (errorRes2.IsSucceed && errorVal2 == true) { errorStr += " 垛型左超宽"; } var (errorRes3, errorVal3) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{dbStr}.3", ""); if (errorRes3.IsSucceed && errorVal3 == true) { errorStr += " 垛型右超宽"; } var (errorRes4, errorVal4) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{dbStr}.4", ""); if (errorRes4.IsSucceed && errorVal4 == true) { errorStr += " 垛型前超长"; } var (errorRes5, errorVal5) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{dbStr}.5", ""); if (errorRes5.IsSucceed && errorVal5 == true) { errorStr += " 垛型后超长"; } var (errorRes6, errorVal6) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{dbStr}.6", ""); if (errorRes6.IsSucceed && errorVal6 == true) { errorStr += " 垛型后超高"; } var (errorRes7, errorVal7) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{dbStr}.7", ""); if (errorRes7.IsSucceed && errorVal7 == true) { errorStr += " 高低位异常报警"; } var (errorRes9, errorVal9) = plcConn.GetPlcDBValue(PLCDataTypeEnum.Bit, $"M{Convert.ToUInt32(dbStr)-1}.1", ""); if (errorRes9.IsSucceed && errorVal9 == true) { errorStr += " 扫码仪通讯报警"; } ledText += $"申请入库失败\n\n"; ledText += $"{errorStr}"; LedDisplay(modDevice.LedIP, ledText); } break; case "320": { //防止重复申请 var (res0, Val0) = plcConn.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos); if (res0.IsSucceed && Val0 != 0) { break; } // 申请巷道 string strMsg = ""; string taskModel = ""; // 获取工位托盘码信息 var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码"); var (res, palletVal) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); if (!res.IsSucceed) { break; } string palletStr = Convert.ToString(palletVal); var modPosEndLocat = modDevice.listStation.FirstOrDefault(s => s.Text == "目的工位"); //获取托盘高度 var modPosPalletHeight = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘高度"); var (resPalletHeight, palletHeightVal) = plcConn.GetPlcDBValue(modPosPalletHeight.PosType, modDevice.DbNumber, modPosPalletHeight.PlcPos); if (!resPalletHeight.IsSucceed) { break; } //获取托盘实际重量 var modPosPalletWeight = modDevice.listStation.FirstOrDefault(m => m.Text == "实际重量"); var (resPalletWeight, palletWeightVal) = plcConn.GetPlcDBValue(modPosPalletWeight.PosType, modDevice.DbNumber, modPosPalletWeight.PlcPos); //判断入库锁定是否打开 if (PLCTaskAction.boEnterLock) { var (res350, palletVal350) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); if (res350.IsSucceed && palletVal350 != "350") { ledText += $"申请入库失败\n\n"; ledText += $"托盘号:{palletVal}\n"; ledText += $"入库任务已锁定,请解锁后重试!\n"; LedDisplay(modDevice.LedIP, ledText); } // 写入输送线退回指令 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modPosEndLocat.PlcPos, modDevice.StationNum); if (ret.IsSucceed) { plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "350"); } break; } if (palletVal == null) { var (res350, palletVal350) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); if (res350.IsSucceed && palletVal350 != "350") { ledText += $"申请入库失败\n\n"; ledText += $"托盘号:{palletVal}\n"; ledText += $"扫描托盘号失败!\n"; LedDisplay(modDevice.LedIP, ledText); } // 写入输送线退回指令 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modPosEndLocat.PlcPos, modDevice.StationNum); if (ret.IsSucceed) { plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "350"); } break; } var http = new HttpService(); string TaskNo = "", EndLocate = ""; strMsg = http.RequestRoadWay(palletVal, modDevice.StationNum, taskModel, louCeng, ref EndLocate, ref TaskNo, (int)palletHeightVal); if (!strMsg.Contains("-1")) { // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。 var taskInfo = _db.Queryable().First(w => w.TaskNo == TaskNo); modDevice.LedIP = _db.Queryable().Where(w => w.StationNum == taskInfo.StartLocate).Select(s => s.LedIP).First(); // 写入330 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "330"); if (ret.IsSucceed) { // 插入任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令330:{modDevice.StationNum}工位申请巷道", PalletNo = palletVal, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = EndLocate, }; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // 通知任务界面任务已存在更新 请更新界面 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); // led显示内容 try { ledText += $"任务类型:{taskInfo.TaskType.GetDescription()}\n\n"; ledText += $"任务号:{taskInfo.TaskNo}\n"; ledText += $"托盘号:{taskInfo.PalletNo}\n"; ledText += $"起始位:{taskInfo.StartRoadway + " " + taskInfo.StartLocate}\n"; ledText += $"目标位:{taskInfo.EndRoadway + " " + taskInfo.EndLocate}\n"; ledText += $"重量(KG):{Convert.ToDecimal(palletWeightVal)}"; LedDisplay(modDevice.LedIP, ledText); } catch (Exception ex) { Log.Error(ex.Message); } } } else { var (res350, palletVal350) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); if (res350.IsSucceed && palletVal350 != "350") { ledText += $"申请入库失败\n\n"; ledText += $"托盘号:{palletVal}\n"; ledText += $"{strMsg}\n"; LedDisplay(modDevice.LedIP, ledText); } // 写入输送线退回指令 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modPosEndLocat.PlcPos, modDevice.StationNum); if (ret.IsSucceed) { plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "350"); } } } break; case "330": { // 写入任务 托盘移动 340 // 获取工位托盘码信息 var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码"); var (res, palletVal) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); if (!res.IsSucceed) { break; } string pallet = palletVal.ToString(); // 获取任务信息 var modTask = _db.Queryable().First(s => s.IsDelete == false && s.PalletNo == pallet && (s.Status == TaskStatusEnum.Wait || s.Status == TaskStatusEnum.Doing) && s.TaskType == TaskTypeEnum.In); if (modTask == null) { // 此托盘没有对应的转移任务 led显示 break; } //判断入库锁定是否打开 if (PLCTaskAction.boEnterLock) { break;//入库锁定打开则不执行入库任务 } // 获取巷道口入库工位 string endLocatVlue = PLCCommon.RoadwayToStationNum(modTask.EndRoadway, louCeng, modDevice.StationNum); #region 跺机转运任务处理 ########## // 判断是否四楼输送线 if (modDevice.StationNum == "265") { // 是 if (modTask.EndRoadway != "R05" && modTask.EndRoadway != "R06") { // 根据巷道获取中转跺机IP ### R05巷道 var sInfo = PLCCommon.GetStokePlc("R05", louCeng); var plcStackeConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == sInfo.Ip); if (plcStackeConn.Connected) { var djmodel = _db.Queryable().First(m => m.IP == sInfo.Ip); var djMod = PLCTaskAction.plcDevices.First(m => m.PlcId == djmodel.Id && m.DeviceType == DeviceTypeEnum.Business && m.IsDelete == false); var (djRes, djVal) = plcStackeConn.GetPlcDBValue(djMod.PosType, djMod.DbNumber, djMod.PlcPos); // 判断R05跺机是否空闲 if (djRes.IsSucceed && djVal.ToString() == "820") { endLocatVlue = "253"; } } // 根据巷道获取中转跺机IP ### R06巷道 var sInfoR06 = PLCCommon.GetStokePlc("R06", louCeng); var plcStackeConnR06 = PLCTaskAction.listPlcConn.First(m => m.PlcIP == sInfoR06.Ip); if (plcStackeConnR06.Connected) { var djmodel = _db.Queryable().First(m => m.IP == sInfoR06.Ip); var djMod = PLCTaskAction.plcDevices.First(m => m.PlcId == djmodel.Id && m.DeviceType == DeviceTypeEnum.Business && m.IsDelete == false); var (djRes, djVal) = plcStackeConnR06.GetPlcDBValue(djMod.PosType, djMod.DbNumber, djMod.PlcPos); // 判断R05跺机是否空闲 if (djRes.IsSucceed && djVal.ToString() == "820") { endLocatVlue = "250"; } } } } if (modDevice.StationNum == "266") { // 是 if (modTask.EndRoadway != "R05") { endLocatVlue = "277"; } } #endregion // 给PLC写入任务数据 var listResult = new List(); // 任务号、任务类型、托盘号 var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); var modPosTaskType = modDevice.listStation.FirstOrDefault(s => s.Text == "任务类型"); var taskTypeStr = (int)modTask.TaskType; listResult.Add(plcConn.SetPlcDBValue(modPosTaskType.PosType, modDevice.DbNumber, modPosTaskType.PlcPos, taskTypeStr.ToString())); var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "托盘码"); listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); // 起始工位、目的工位 var modPosStrLocat = modDevice.listStation.FirstOrDefault(s => s.Text == "起始工位"); listResult.Add(plcConn.SetPlcDBValue(modPosStrLocat.PosType, modDevice.DbNumber, modPosStrLocat.PlcPos, modDevice.StationNum)); var modPosEndLocat = modDevice.listStation.FirstOrDefault(s => s.Text == "目的工位"); listResult.Add(plcConn.SetPlcDBValue(modPosEndLocat.PosType, modDevice.DbNumber, modPosEndLocat.PlcPos, endLocatVlue)); if (listResult.All(s => s.IsSucceed)) { // 将任务状态变更为正在执行 _db.Updateable() .SetColumns(s => s.Status == TaskStatusEnum.Doing) .Where(s => s.Id == modTask.Id) .ExecuteCommand(); // 写入流程字 330 340 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "340"); // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。 modDevice.LedIP = _db.Queryable().Where(w => w.StationNum == modTask.StartLocate).Select(s => s.LedIP).First(); if (ret.IsSucceed) { // 插入任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令340:{modDevice.StationNum}储位====》{endLocatVlue}工位", PalletNo = palletVal, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = endLocatVlue, }; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // 通知任务界面任务已存在更新 请更新界面 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } } } break; case "620": { // 申请储位 更新入库任务(储位地址) 630 var strMsg = ""; var taskModel = ""; // 判断是否演示模式 if (PLCTaskAction.boDemo) { // 演示模式 taskModel = "1"; } // 根据工位号获取巷道号 var roadway = PLCCommon.GetRoadwayByStation(modDevice.StationNum); if (roadway == "") { break; } // 获取工位托盘码信息 var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码"); var (res, palletVal) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); if (!res.IsSucceed) { break; } #region 跺机转运任务处理 ########### // 根据任务目标巷道号获取工位号 var modPosEndStation = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (ress, endTaskNoVal) = plcConn.GetPlcDBValue(modPosEndStation.PosType, modDevice.DbNumber, modPosEndStation.PlcPos); if (!ress.IsSucceed) { break; } string taskno = endTaskNoVal; var taskInfo2 = _db.Queryable().First(w => w.TaskNo == taskno); // 根据任务号获取当前任务目标巷道 if (taskInfo2 == null) { break; } string roadwayNo = PLCCommon.GetRoadwayByStation(modDevice.StationNum); // 当前工位对应的巷道号 // 判断是否入库转运任务 if (roadwayNo != taskInfo2.EndRoadway && taskInfo2.TaskType == TaskTypeEnum.In) {// 是 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "630"); if (ret.IsSucceed) { var modPosTaskNo = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (resss, taskNoVal) = plcConn.GetPlcDBValue(modPosEndStation.PosType, modDevice.DbNumber, modPosEndStation.PlcPos); if (!resss.IsSucceed) { break; } string taskNo = taskNoVal.ToString(); var taskInfos = _db.Queryable().First(w => w.TaskNo == taskNo); modDevice.LedIP = _db.Queryable().Where(w => w.StationNum == taskInfos.StartLocate).Select(s => s.LedIP).First(); // 插入任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = taskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令630:开启跺机转运任务", PalletNo = palletVal, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = strMsg, }; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // 通知任务界面任务已存在更新 请更新界面 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); var ledDevice = PLCTaskAction.plcDevices.First(m => m.StationNum == modDevice.StationNum && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business); ledText += $"任务类型:{taskInfos.TaskType.GetDescription()}\n\n"; ledText += $"任务号:{taskInfos.TaskNo}\n"; ledText += $"托盘号:{taskInfos.PalletNo}\n\n"; ledText += $"起始位:{taskInfos.StartRoadway + " " + taskInfos.StartLocate}\n"; ledText += $"目标位:{taskInfos.EndRoadway + " " + taskInfos.EndLocate}"; LedDisplay(modDevice.LedIP, ledText); } break; } // 判断是否出库转运任务 var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (res1, taskVal) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos); if (res1.IsSucceed) { string taskNo = taskVal.ToString(); var taskInfos = _db.Queryable().First(w => w.TaskNo == taskNo); if (taskInfos.TaskType == TaskTypeEnum.Out) { var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "630"); if (!ret.IsSucceed) { break; } modDevice.LedIP = _db.Queryable().Where(w => w.StationNum == taskInfos.EndLocate).Select(s => s.LedIP).First(); // 插入任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = taskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令630:开启跺机转运任务", PalletNo = palletVal, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = strMsg, }; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // 通知任务界面任务已存在更新 请更新界面 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); var ledDevice = PLCTaskAction.plcDevices.First(m => m.StationNum == modDevice.StationNum && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business); ledText += $"任务类型:{taskInfos.TaskType.GetDescription()}\n\n"; ledText += $"任务号:{taskInfos.TaskNo}\n"; ledText += $"托盘号:{taskInfos.PalletNo}\n\n"; ledText += $"起始位:{taskInfos.StartRoadway + " " + taskInfos.StartLocate}\n"; ledText += $"目标位:{taskInfos.EndRoadway + " " + taskInfos.EndLocate}"; LedDisplay(modDevice.LedIP, ledText); break; } } else { break; } #endregion var http = new HttpService(); string TaskNo = ""; // 向WMS申请储位信息 strMsg = http.RequestLocate(palletVal, modDevice.StationNum, taskModel, roadway, ref TaskNo, (int)taskInfo2.PalletQty); // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。 var taskInfo = _db.Queryable().First(w => w.TaskNo == TaskNo); modDevice.LedIP = _db.Queryable().Where(w => w.StationNum == taskInfo.StartLocate).Select(s => s.LedIP).First(); if (!strMsg.Contains("-1")) { // 写入流程字 630 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "630"); if (ret.IsSucceed) { // 插入任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令340:{modDevice.StationNum}工位申请储位", PalletNo = palletVal, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = strMsg, }; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // 通知任务界面任务已存在更新 请更新界面 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); var ledDevice = PLCTaskAction.plcDevices.First(m => m.StationNum == modDevice.StationNum && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business); ledText += $"任务类型:{taskInfo.TaskType.GetDescription()}\n\n"; ledText += $"任务号:{taskInfo.TaskNo}\n"; ledText += $"托盘号:{taskInfo.PalletNo}\n\n"; ledText += $"起始位:{taskInfo.StartRoadway + " " + taskInfo.StartLocate}\n"; ledText += $"目标位:{taskInfo.EndRoadway + " " + taskInfo.EndLocate}"; LedDisplay(modDevice.LedIP, ledText); } } else { // 申请储位失败!LED显示 Log.Error(string.Format($"申请储位失败:{strMsg},读写plc错误")); // led显示内容 var ledDevice = PLCTaskAction.plcDevices.First(m => m.StationNum == modDevice.StationNum && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business); ledText += $"申请入库失败\n\n"; ledText += $"{strMsg}\n"; LedDisplay(modDevice.LedIP, ledText); } } break; case "630": { #region 写入跺机取货任务 不用写入640垛取货完成后会写 // 获取工位托盘码信息 var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码"); var (res, palletVal) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); // 获取工位任务号信息 var modPosTaskNo = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (taskRes, taskNoVal) = plcConn.GetPlcDBValue(modPosTaskNo.PosType, modDevice.DbNumber, modPosTaskNo.PlcPos); if (!res.IsSucceed || !taskRes.IsSucceed) { break; } string pallet = palletVal.ToString(); string taskNo = taskNoVal.ToString(); // 获取任务信息 var modTask = _db.Queryable().First(s => s.IsDelete == false && s.PalletNo == pallet && s.Status == TaskStatusEnum.Doing && s.TaskNo == taskNo); if (modTask == null) { // 此托盘没有对应的转移任务 led显示 break; } #region 跺机转运任务处理 ########### string taskno = taskNoVal; string roadwayNo = PLCCommon.GetRoadwayByStation(modDevice.StationNum); // 当前工位对应的巷道号 // 获取当前工位目标地址 var modPosEndStation = modDevice.listStation.FirstOrDefault(m => m.Text == "目的工位"); var (ress, endStationVal) = plcConn.GetPlcDBValue(modPosEndStation.PosType, modDevice.DbNumber, modPosEndStation.PlcPos); if (!ress.IsSucceed) { break; } if (modTask.EndRoadway == null) { modTask.EndRoadway = ""; } var sInfo = PLCCommon.GetStokePlc(roadwayNo, louCeng, modDevice.StationNum); // 根据当前巷道获取跺机信息 // 判断是否入库转运任务 // 判断是否入库转运任务 if (roadwayNo != modTask.EndRoadway && modTask.TaskType == TaskTypeEnum.In) {// 是 // 根据当前工位号,获取对应的取货排列层 sInfo = PLCCommon.GetStokePlc(roadwayNo, louCeng, modDevice.StationNum); // 判断1层放货工位状态是否空闲 var endStationNum = PLCCommon.RoadwayToOutStationNum(roadwayNo, "1"); var ConveyorMod = PLCTaskAction.plcDevices.First(m => m.StationNum == endStationNum && m.DeviceType == DeviceTypeEnum.Business && m.IsDelete == false); var plcConveyorConn = PLCCommon.GetPlcIp(endStationNum); if (plcConveyorConn.Connected) { // 读取1楼放货工位状态 var (reouts, plcVal) = plcConveyorConn.GetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.PlcPos); if (reouts.IsSucceed) { //if (plcVal.ToString() != "720") //{ // // 1层放货工位占用,等待放货工位释放 // break; //} // 判断跺机是否空闲 var plcSConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == sInfo.Ip); if (plcSConn.Connected) { var djmodel = _db.Queryable().First(m => m.IP == sInfo.Ip); var djMod = PLCTaskAction.plcDevices.First(m => m.PlcId == djmodel.Id && m.DeviceType == DeviceTypeEnum.Business && m.IsDelete == false); var djInfos = PLCTaskAction.plcPositions.Where(m => m.IsDelete == false && m.DeviceId == djMod.Id).ToList(); var djInfo = djInfos.First(m => m.Text == "PLC流程字"); // 获取跺机当前状态 var (djRess, djVal) = plcSConn.GetPlcDBValue(djMod.PosType, djMod.DbNumber, djMod.PlcPos); if (!djRess.IsSucceed || djVal.ToString() != "820") { // 跺机非空闲等待 break; } var listResult = new List(); // 任务号、任务类型、托盘号 var modPosTask = djInfos.FirstOrDefault(s => s.Text == "任务号"); listResult.Add(plcSConn.SetPlcDBValue(modPosTask.PosType, djMod.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); var modPosTaskType = djInfos.FirstOrDefault(s => s.Text == "任务类型"); var taskTypeStr = (int)modTask.TaskType; listResult.Add(plcSConn.SetPlcDBValue(modPosTaskType.PosType, djMod.DbNumber, modPosTaskType.PlcPos, taskTypeStr.ToString())); var modPosPalletNo = djInfos.FirstOrDefault(s => s.Text == "托盘码"); listResult.Add(plcSConn.SetPlcDBValue(modPosPalletNo.PosType, djMod.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); //起始工位 var modPosStrStationNum = djInfos.FirstOrDefault(s => s.Text == "起始工位"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrStationNum.PosType, djMod.DbNumber, modPosStrStationNum.PlcPos, modDevice.StationNum)); // 目的工位 var modPosendStationNum = djInfos.FirstOrDefault(s => s.Text == "目的工位"); listResult.Add(plcSConn.SetPlcDBValue(modPosendStationNum.PosType, djMod.DbNumber, modPosendStationNum.PlcPos, endStationNum)); //取货排、列、层 var modPosStrPai = djInfos.FirstOrDefault(s => s.Text == "取货排"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrPai.PosType, djMod.DbNumber, modPosStrPai.PlcPos, sInfo.Pai)); var modPosStrLie = djInfos.FirstOrDefault(s => s.Text == "取货列"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrLie.PosType, djMod.DbNumber, modPosStrLie.PlcPos, sInfo.Lie)); var modPosStrCeng = djInfos.FirstOrDefault(s => s.Text == "取货层"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrCeng.PosType, djMod.DbNumber, modPosStrCeng.PlcPos, sInfo.Ceng)); //放货排、列、层 var modPosEndPai = djInfos.FirstOrDefault(s => s.Text == "放货排"); listResult.Add(plcSConn.SetPlcDBValue(modPosEndPai.PosType, djMod.DbNumber, modPosEndPai.PlcPos, "2")); var modPosEndLie = djInfos.FirstOrDefault(s => s.Text == "放货列"); listResult.Add(plcSConn.SetPlcDBValue(modPosEndLie.PosType, djMod.DbNumber, modPosEndLie.PlcPos, "60")); var modPosEndCeng = djInfos.FirstOrDefault(s => s.Text == "放货层"); listResult.Add(plcSConn.SetPlcDBValue(modPosEndCeng.PosType, djMod.DbNumber, modPosEndCeng.PlcPos, "1")); if (listResult.All(s => s.IsSucceed)) { // 写入跺机 830 var retc2 = plcSConn.SetPlcDBValue(djMod.PosType, djMod.DbNumber, djMod.WcsPos, "830"); // 插入任务明细 任务明细实体类 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = modTask.EndLocate // 目标储位地址 }; if (!retc2.IsSucceed) { modInsertTaskMonitor.InteractiveMsg = $"输送线取货工位:{modDevice.StationNum},写入垛机取货任务830失败等待再次写入"; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); break; } // 写入目标工位 730 : 逻辑上此处不用占用地址。 var retc3 = plcConveyorConn.SetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.WcsPos, "730"); modInsertTaskMonitor.InteractiveMsg = $"跺机写入指令830:{modDevice.StationNum}工位====》" + modTask.EndLocate + "储位地址!"; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); if (PLCTaskAction.boRefresh) { //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } } } } } break; } // 判断是否出库转运任务 if (modTask.TaskType == TaskTypeEnum.Out) { var roadWay1 = "R06"; if (modTask.EndLocate == "266") { roadWay1 = "R05"; } var sInfo1 = PLCCommon.GetStokePlc(roadWay1, "2"); // 放货排列层信息 var plcSConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == sInfo1.Ip); if (plcSConn.Connected) { var djmodel = _db.Queryable().First(m => m.IP == sInfo1.Ip); var djMod = PLCTaskAction.plcDevices.First(m => m.PlcId == djmodel.Id && m.DeviceType == DeviceTypeEnum.Business && m.IsDelete == false); var djInfos = PLCTaskAction.plcPositions.Where(m => m.IsDelete == false && m.DeviceId == djMod.Id).ToList(); var djInfo = djInfos.First(m => m.Text == "PLC流程字"); // 获取跺机当前状态 var (djRess, djVal) = plcSConn.GetPlcDBValue(djMod.PosType, djMod.DbNumber, djMod.PlcPos); if (!djRess.IsSucceed || djVal.ToString() != "820") { // 跺机非空闲等待 break; } var listResult = new List(); // 任务号、任务类型、托盘号 var modPosTask = djInfos.FirstOrDefault(s => s.Text == "任务号"); listResult.Add(plcSConn.SetPlcDBValue(modPosTask.PosType, djMod.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); var modPosTaskType = djInfos.FirstOrDefault(s => s.Text == "任务类型"); var taskTypeStr = (int)modTask.TaskType; listResult.Add(plcSConn.SetPlcDBValue(modPosTaskType.PosType, djMod.DbNumber, modPosTaskType.PlcPos, taskTypeStr.ToString())); var modPosPalletNo = djInfos.FirstOrDefault(s => s.Text == "托盘码"); listResult.Add(plcSConn.SetPlcDBValue(modPosPalletNo.PosType, djMod.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); //起始工位 var modPosStrStationNum = djInfos.FirstOrDefault(s => s.Text == "起始工位"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrStationNum.PosType, djMod.DbNumber, modPosStrStationNum.PlcPos, modDevice.StationNum)); //目的工位 if (modTask.EndLocate == "266") { modTask.EndLocate = "277"; } if (modTask.EndLocate == "265") { modTask.EndLocate = "250"; } var modPosStrend = djInfos.FirstOrDefault(s => s.Text == "目的工位"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrend.PosType, djMod.DbNumber, modPosStrend.PlcPos, modTask.EndLocate)); // 此处现在存的是出库口266。 //取货排、列、层 var modPosStrPai = djInfos.FirstOrDefault(s => s.Text == "取货排"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrPai.PosType, djMod.DbNumber, modPosStrPai.PlcPos, "3")); var modPosStrLie = djInfos.FirstOrDefault(s => s.Text == "取货列"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrLie.PosType, djMod.DbNumber, modPosStrLie.PlcPos, "60")); var modPosStrCeng = djInfos.FirstOrDefault(s => s.Text == "取货层"); listResult.Add(plcSConn.SetPlcDBValue(modPosStrCeng.PosType, djMod.DbNumber, modPosStrCeng.PlcPos, "1")); //放货排、列、层 var modPosEndPai = djInfos.FirstOrDefault(s => s.Text == "放货排"); listResult.Add(plcSConn.SetPlcDBValue(modPosEndPai.PosType, djMod.DbNumber, modPosEndPai.PlcPos, sInfo1.Pai)); var modPosEndLie = djInfos.FirstOrDefault(s => s.Text == "放货列"); listResult.Add(plcSConn.SetPlcDBValue(modPosEndLie.PosType, djMod.DbNumber, modPosEndLie.PlcPos, sInfo1.Lie)); var modPosEndCeng = djInfos.FirstOrDefault(s => s.Text == "放货层"); listResult.Add(plcSConn.SetPlcDBValue(modPosEndCeng.PosType, djMod.DbNumber, modPosEndCeng.PlcPos, sInfo1.Ceng)); if (listResult.All(s => s.IsSucceed)) { // 写入跺机 830 var retc2 = plcSConn.SetPlcDBValue(djMod.PosType, djMod.DbNumber, djMod.WcsPos, "830"); // 插入任务明细 任务明细实体类 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate // 目标储位地址 }; if (!retc2.IsSucceed) { modInsertTaskMonitor.InteractiveMsg = $"输送线取货工位:{modDevice.StationNum},写入垛机取货任务830失败等待再次写入"; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); break; } modInsertTaskMonitor.InteractiveMsg = $"跺机写入指令830:{modDevice.StationNum}工位====》" + modTask.EndLocate + "储位地址!"; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); if (PLCTaskAction.boRefresh) { //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } } } break; } #endregion // 非正常入库任务不往下执行 if (modTask.TaskType != TaskTypeEnum.In) { break; } if (string.IsNullOrWhiteSpace(sInfo.Ip)) { //需加上LED显示 Log.Error(string.Format($"根据巷道获取跺机IP失败,请联系管理员")); break; } // 跺机连接 var plcStackeConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == sInfo.Ip); if (plcStackeConn.Connected) { // 目标排列层 var endLocate = modTask.EndLocate; if (string.IsNullOrWhiteSpace(modTask.EndLocate)) { Log.Error(string.Format($"目标位置为空,请人工处理,读写plc错误")); break; } // 转换目标工位排列层 03010301 var paiVal = PLCCommon.GetDjAdress(modTask.EndRoadway.Substring(1, 2), endLocate.Substring(0, 2), endLocate.Substring(6, 2)); string pai = paiVal.ToString(); string lie = int.Parse(endLocate.Substring(2, 2)).ToString(); string ceng = int.Parse(endLocate.Substring(4, 2)).ToString(); var djmodel = _db.Queryable().First(m => m.IP == sInfo.Ip); var djMod = PLCTaskAction.plcDevices.First(m => m.PlcId == djmodel.Id && m.DeviceType == DeviceTypeEnum.Business && m.IsDelete == false); var djInfos = PLCTaskAction.plcPositions.Where(m => m.IsDelete == false && m.DeviceId == djMod.Id).ToList(); var djInfo = djInfos.First(m => m.Text == "PLC流程字"); // 获取跺机当前状态 var (djRes, djVal) = plcStackeConn.GetPlcDBValue(djMod.PosType, djMod.DbNumber, djMod.PlcPos); if (!djRes.IsSucceed || djVal.ToString() != "820") { // 跺机非空闲等待 break; } // 给PLC写入任务数据 var listResult = new List(); // 任务号、任务类型、托盘号 var modPosTask = djInfos.FirstOrDefault(s => s.Text == "任务号"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosTask.PosType, djMod.DbNumber, modPosTask.PlcPos, modTask.TaskNo)); var modPosTaskType = djInfos.FirstOrDefault(s => s.Text == "任务类型"); var taskTypeStr = (int)modTask.TaskType; listResult.Add(plcStackeConn.SetPlcDBValue(modPosTaskType.PosType, djMod.DbNumber, modPosTaskType.PlcPos, taskTypeStr.ToString())); var modPosPalletNo = djInfos.FirstOrDefault(s => s.Text == "托盘码"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosPalletNo.PosType, djMod.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo)); //起始工位 var modPosStrStationNum = djInfos.FirstOrDefault(s => s.Text == "起始工位"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosStrStationNum.PosType, djMod.DbNumber, modPosStrStationNum.PlcPos, modDevice.StationNum)); //目的工位 var modPosendStationNum = djInfos.FirstOrDefault(s => s.Text == "目的工位"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosStrStationNum.PosType, djMod.DbNumber, modPosendStationNum.PlcPos, modDevice.StationNum)); // 此处现在是139 应该为0 //取货排、列、层 var modPosStrPai = djInfos.FirstOrDefault(s => s.Text == "取货排"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosStrPai.PosType, djMod.DbNumber, modPosStrPai.PlcPos, sInfo.Pai)); var modPosStrLie = djInfos.FirstOrDefault(s => s.Text == "取货列"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosStrLie.PosType, djMod.DbNumber, modPosStrLie.PlcPos, sInfo.Lie)); var modPosStrCeng = djInfos.FirstOrDefault(s => s.Text == "取货层"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosStrCeng.PosType, djMod.DbNumber, modPosStrCeng.PlcPos, sInfo.Ceng)); //放货排、列、层 var modPosEndPai = djInfos.FirstOrDefault(s => s.Text == "放货排"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosEndPai.PosType, djMod.DbNumber, modPosEndPai.PlcPos, pai)); var modPosEndLie = djInfos.FirstOrDefault(s => s.Text == "放货列"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosEndLie.PosType, djMod.DbNumber, modPosEndLie.PlcPos, lie)); var modPosEndCeng = djInfos.FirstOrDefault(s => s.Text == "放货层"); listResult.Add(plcStackeConn.SetPlcDBValue(modPosEndCeng.PosType, djMod.DbNumber, modPosEndCeng.PlcPos, ceng)); if (listResult.All(s => s.IsSucceed)) { // 写入跺机 830 var retc2 = plcStackeConn.SetPlcDBValue(djMod.PosType, djMod.DbNumber, djMod.WcsPos, "830"); // 插入任务明细 任务明细实体类 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = modTask.EndLocate // 目标储位地址 }; if (!retc2.IsSucceed) { modInsertTaskMonitor.InteractiveMsg = $"输送线取货工位:{modDevice.StationNum},写入垛机取货任务830失败等待再次写入"; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); break; } modInsertTaskMonitor.InteractiveMsg = $"跺机写入指令830:{modDevice.StationNum}工位====》" + modTask.EndLocate + "储位地址!"; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); if (PLCTaskAction.boRefresh) { //下发任务日志 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } } } #endregion } break; #region 出库交互 case "420": { string plcValue = "430"; #region 托盘到达拣选工位/出库口 var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (res, taskVal) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos); var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码"); var (res2, palletVal) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); var modPosStarStationNum = modDevice.listStation.FirstOrDefault(m => m.Text == "起始工位"); var (res3, starVal) = plcConn.GetPlcDBValue(modPosStarStationNum.PosType, modDevice.DbNumber, modPosStarStationNum.PlcPos); //判断是否四楼出库口 //if (modDevice.StationNum == "265" || modDevice.StationNum == "266") //{ // var http = new HttpService(); // //根据出库任务号获取出库单类型 // var modResponseTask = http.GetSoOrderTypeByTaskNo(taskVal).Result; // if (modResponseTask.StatusCode == 0 && modResponseTask.Msg == "1")//1:领料出库单 // { // plcValue = "230"; // } //} var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, plcValue); if (ret.IsSucceed) { // 插入任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = taskVal, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令{plcValue}:托盘到达{modDevice.StationNum}工位", PalletNo = palletVal, Status = TaskStatusEnum.Complete, StartLocat = starVal, EndLocat = modDevice.StationNum, }; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // 通知任务界面任务已存在更新 请更新界面 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。 var taskInfo = _db.Queryable().First(w => w.TaskNo == modInsertTaskMonitor.TaskNo); modDevice.LedIP = _db.Queryable().Where(w => w.StationNum == taskInfo.EndLocate).Select(s => s.LedIP).First(); // led显示内容 // 根据目标工位号获取对应的LEDIP地址 var ledDevice = PLCTaskAction.plcDevices.First(m => m.StationNum == modDevice.StationNum && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business && m.PlcId == modDevice.PlcId); ledText += $"出库完成\n\n"; ledText += $"任务号:{taskInfo.TaskNo}\n"; ledText += $"托盘号:{taskInfo.PalletNo}\n\n"; ledText += $"起始位:{taskInfo.StartRoadway + " " + taskInfo.StartLocate}\n"; ledText += $"目标位:{taskInfo.EndRoadway + " " + taskInfo.EndLocate}"; LedDisplay(ledDevice.LedIP, ledText); } // 反馈WMS出库完成 //TaskReques taskReques = new TaskReques(); //taskReques.taskNo = TaskNo; //taskReques.TaskType = "1"; //taskReques.TaskStatus = "2"; //bool bl = wcsMySql.RequestTasks(taskReques); #endregion } break; case "440": { #region 拣选完成,托盘离开工位 // 写入450 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "450"); if (ret.IsSucceed) { var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (res, taskVal) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos); var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码"); var (res2, palletVal) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos); var modPosStarStationNum = modDevice.listStation.FirstOrDefault(m => m.Text == "起始工位"); var (res3, starVal) = plcConn.GetPlcDBValue(modPosStarStationNum.PosType, modDevice.DbNumber, modPosStarStationNum.PlcPos); string tasknoVal = taskVal.ToString(); var modTask = _db.Queryable().First(m => m.Status == TaskStatusEnum.Doing && m.TaskNo == tasknoVal && m.IsDelete == false); if (modTask == null) { Log.Error(string.Format("输送线440:未找到对应的任务。")); break; } // 改变任务状态 modTask.Status = TaskStatusEnum.Complete; modTask.FinishDate = DateTime.Now; modTask.Levels = 999; _db.Updateable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); // 插入任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令450:{modDevice.StationNum}拣选完成,托盘离开工位", PalletNo = palletVal, Status = TaskStatusEnum.Complete, StartLocat = starVal.ToString(), EndLocat = modDevice.StationNum, }; if (modTask.Origin == "WMS") { // 反馈WMS var requestMode = new TaskRequestWMS() { TaskNo = modTask.TaskNo, PalletNo = modTask.PalletNo, TaskType = ((int)TaskTypeEnum.Out).ToString(), TaskStatus = ((int)TaskStatusEnum.Complete).ToString() }; HttpService httpService = new HttpService(); var modResponseTask = httpService.RequestTask(requestMode).Result; if (modResponseTask.StatusCode == 0) { modInsertTaskMonitor.InteractiveMsg += ",返回给WMS任务完成"; } else { Log.Error(string.Format("任务反馈失败:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg)); } } // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // 通知任务界面任务已存在更新 请更新界面 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); // led显示内容 var ledDevice = PLCTaskAction.plcDevices.First(m => m.StationNum == modDevice.StationNum && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business && m.PlcId == modDevice.PlcId); ledText += $"拣选完成,托盘离开工位\n\n"; ledText += $"任务号:{modTask.TaskNo}\n"; ledText += $"托盘号:{modTask.PalletNo}\n\n"; ledText += $"起始位:{modTask.StartRoadway + " " + modTask.StartLocate}\n"; ledText += $"目标位:{modTask.EndRoadway + " " + modTask.EndLocate}"; LedDisplay(ledDevice.LedIP, ledText); } #endregion } break; #endregion #region 叫空托盘跺 case "50": // plc申请空托 { lock (OLock) { // 判断是否已有向叫空托工位的出库任务 var modTask = _db.Queryable().First(m => (m.Status == TaskStatusEnum.Doing || m.Status == TaskStatusEnum.Wait) && m.EndLocate == modDevice.StationNum && m.IsDelete == false); if (modTask != null) { Log.Error("已存在向" + modDevice.StationNum + "工位的任务。任务号:" + modTask.TaskNo); break; } // 防止重复叫空托跺 var (res, palletVal) = plcConn.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos); if (palletVal != 0) { break; } // 调用WMS空托出库接口,返回出库任务存入出库表 var strMsg = ""; var http = new HttpService(); strMsg = http.IssuePlnOutHouseWcs("1", modDevice.StationNum); if (!strMsg.Contains("-1")) { // 写入plc流程字60 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "60"); } else { // 申请巷道失败!LED显示 Log.Error(string.Format($"工位号:{modDevice.StationNum}申请空托跺失败:{strMsg};")); } } } break; case "80": // 空托盘跺已到位 { // 调用wms任务出库任务完成 // 获取跺机点位配置 var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号"); var (res, val) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos); // 根据任务号获取任务信息 if (res.IsSucceed) { string tasknoVal = val.ToString(); var modTask = _db.Queryable().First(m => m.Status == TaskStatusEnum.Doing && m.TaskNo == tasknoVal && m.IsDelete == false); if (modTask == null) { //Log.Error(string.Format($"工位号:{modDevice.StationNum}空托盘到达,未找到对应的任务!任务号{tasknoVal};")); break; } // 写入plc流程字90 var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "90"); if (ret.IsSucceed) { // 改变任务状态 modTask.Status = TaskStatusEnum.Complete; modTask.FinishDate = DateTime.Now; modTask.Levels = 999; _db.Updateable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); var modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, InteractiveMsg = $"任务完成" }; if (modTask.Origin == "WMS") { // 反馈WMS var requestMode = new TaskRequestWMS() { TaskNo = modTask.TaskNo, PalletNo = modTask.PalletNo, TaskType = ((int)TaskTypeEnum.Out).ToString(), TaskStatus = ((int)TaskStatusEnum.Complete).ToString() }; HttpService httpService = new HttpService(); var modResponseTask = httpService.RequestTask(requestMode).Result; if (modResponseTask.StatusCode == 0) { modTaskMonitor.InteractiveMsg = "任务完成,返回给WMS任务完成"; } else { Log.Error(string.Format("任务反馈失败:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg)); } } // 插入交互日志 _db.Insertable(modTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); } } } break; #endregion #region 拆垛业务 case "520": //托盘达到拆垛工位,WCS写入品种号并写入530 { // 获取托盘条码配置 var modPalletNo = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘条码" && m.IsDelete == false); // 读取PLC托盘条码号 var (res, palletVal) = plcConn.GetPlcDBValue(modPalletNo.PosType, modDevice.DbNumber, modPalletNo.PlcPos); string palletNo = palletVal.ToString(); if (string.IsNullOrEmpty(palletNo)) { Log.Error(string.Format("{0},读取的托盘号为null", modDevice.Text)); break; } string pzNo = string.Empty; //调用WMS接口获取托盘上物料品种信息 var http = new HttpService(); pzNo = http.GetPalletPzNo(palletNo); if (!string.IsNullOrEmpty(pzNo)) { var modAddCode = modDevice.listStation.FirstOrDefault(m => m.Text == "品种" && m.IsDelete == false); // 写入拆垛品种 var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, pzNo); if (retVal.IsSucceed) { plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "530"); } } } break; case "540": //拆垛完成即出库完成任务结束,WCS写入550,PLC清0 { // 获取托盘条码配置 var modPalletNo = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘条码" && m.IsDelete == false); // 读取PLC托盘条码号 var (res, palletVal) = plcConn.GetPlcDBValue(modPalletNo.PosType, modDevice.DbNumber, modPalletNo.PlcPos); string palletNo = palletVal.ToString(); if (string.IsNullOrEmpty(palletNo)) { Log.Error(string.Format("{0},读取的托盘号为null", modDevice.Text)); break; } //调用WMS接口进行成品箱码拣货 var http = new HttpService(); var strMsg = http.BoxUnstackd(palletNo); if (!strMsg.Contains("-1")) { plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "550"); } } break; #endregion default: break; } } /// /// AGV业务处理 /// /// private static void AGV(WcsDeviceDto modDevice) { } /// /// 叠托机业务处理 /// /// private static void PalletMachine(WcsDeviceDto modDevice) { var plcConn = modDevice.PLCUtil; switch (modDevice.Value.ToString()) { case "220": // 注释1 { } break; case "230": // 注释2 { } break; case "240": { } break; default: break; } } /// /// 件箱输送和码垛机器人业务处理 配置的是件箱输送 /// /// private static void BoxConveyorLine(WcsDeviceDto modDevice) { var plcConn = modDevice.PLCUtil; if (modDevice.DbNumber == "DB101" || modDevice.DbNumber == "DB102" || modDevice.DbNumber == "DB103" || modDevice.DbNumber == "DB104" || modDevice.DbNumber == "DB105") { // 主扫交互流程 switch (modDevice.Value.ToString()) { case "1": // 主扫申请分道 wcs写入2 { var modPosReadBox = modDevice.listStation.FirstOrDefault(m => m.Text == "读取箱码" && m.IsDelete == false); var (res, boxNo) = plcConn.GetPlcDBValue(modPosReadBox.PosType, modDevice.DbNumber, modPosReadBox.PlcPos); if (string.IsNullOrWhiteSpace(boxNo.ToString())) { // 写入流程控制字 2 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2"); if (retVal.IsSucceed) { Log.Error("箱码为null进行剔除"); break; } } // 根据箱码获取箱内信息 string boxNoVal = boxNo.ToString(); var boxInfo = _db.Queryable().First(w => w.IsDelete == false && w.BoxNo == boxNoVal && string.IsNullOrEmpty(w.PalletNo)); if (boxInfo == null) { // 写入流程控制字 2 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2"); if (retVal.IsSucceed) { Log.Error($"箱码为null或已绑定托盘,进行剔除。箱码:{boxNoVal}"); break; } } // 根据箱内品种号获取码躲绑定工位及对应的分道号 var checkTaskInfo = _db.Queryable().First(w => w.SkuNo == boxInfo.SkuNo && w.SkuName == boxInfo.SkuName && w.LotNo == boxInfo.LotNo); if (checkTaskInfo == null) { Log.Error($"测试--。箱码:{boxNoVal},箱ID:{boxInfo.Id},物料编码:{boxInfo.SkuNo},物料名称:{boxInfo.SkuName},批次:{boxInfo.LotNo}"); // 写入流程控制字 2 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2"); if (retVal.IsSucceed) { Log.Error($"箱码未绑定分拣任务,进行剔除。箱码:{boxNoVal}"); break; } } else { // 给PLC写入任务数据 var listResult = new List(); //批次号 var modPosLotNo = modDevice.listStation.FirstOrDefault(m => m.Text == "批次号" && m.IsDelete == false); listResult.Add(plcConn.SetPlcDBValue(modPosLotNo.PosType, modDevice.DbNumber, modPosLotNo.PlcPos, boxInfo.LotNo)); //品种 var modPosPZ = modDevice.listStation.FirstOrDefault(m => m.Text == "品种" && m.IsDelete == false); listResult.Add(plcConn.SetPlcDBValue(modPosPZ.PosType, modDevice.DbNumber, modPosPZ.PlcPos, checkTaskInfo.PZNo)); //是否尾箱 var modPosIsEndBox = modDevice.listStation.FirstOrDefault(m => m.Text == "是否尾箱" && m.IsDelete == false); listResult.Add(plcConn.SetPlcDBValue(modPosIsEndBox.PosType, modDevice.DbNumber, modPosIsEndBox.PlcPos, boxInfo.EndLotFlag)); //写入箱码 var modPosBox = modDevice.listStation.FirstOrDefault(m => m.Text == "写入箱码" && m.IsDelete == false); listResult.Add(plcConn.SetPlcDBValue(modPosBox.PosType, modDevice.DbNumber, modPosBox.PlcPos, boxInfo.BoxNo)); // 是否写入成功 if (listResult.All(s => s.IsSucceed)) { // 写入流程控制字 2 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2"); if (retVal.IsSucceed) { break; } } } } break; default: break; } } else { // 插码交互 switch (modDevice.Value.ToString()) { case "1": // 托盘条码可读 { // 获取托盘条码配置 var modPalletNo = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘条码" && m.IsDelete == false); // 读取PLC托盘条码号 var (res, palletVal) = plcConn.GetPlcDBValue(modPalletNo.PosType, modDevice.DbNumber, modPalletNo.PlcPos); string palletNo = palletVal.ToString(); if (string.IsNullOrEmpty(palletNo)) { Log.Error(string.Format("{0},读取的托盘号为null", modDevice.Text)); break; } // 根据工位号将托盘号保存在分道表 var checkTaskMedel = _db.Queryable().First(m => m.Port == modDevice.StationNum && m.IsDelete == false); if (checkTaskMedel == null) { Log.Error(string.Format("根据码垛工位{0},获取分道失败!", modDevice.StationNum)); break; } checkTaskMedel.PalletNo = palletNo; checkTaskMedel.BoxCount = 0; var rowCount = _db.Updateable(checkTaskMedel).ExecuteCommand(); if (rowCount > 0) { // plc写入读取成功表示 2 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2"); if (retVal.IsSucceed) { // liudl 此处需添加 // 通知分拣码垛页更新 } } } break; case "20": // 申请插码 { // 获取托盘条码配置 var modAddCode = modDevice.listStation.FirstOrDefault(m => m.Text == "插码结果" && m.IsDelete == false); //获取插码箱数 var modAddBoxNum = modDevice.listStation.FirstOrDefault(m => m.Text == "插码箱数" && m.IsDelete == false); var (boxNumRes, boxNumVal) = plcConn.GetPlcDBValue(modAddBoxNum.PosType, modDevice.DbNumber, modAddBoxNum.PlcPos); int boxNum = Convert.ToInt32(boxNumVal); if (boxNum != 1 && boxNum != 2) { Log.Error(string.Format($"码垛工位{0},请求插码箱数不正确! boxNum:{boxNum}", modDevice.StationNum)); // 写入插入结果 2:插码失败 var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2"); break; } // 获取当前分道托盘号 var checkTaskMedel = _db.Queryable().First(m => m.Port == modDevice.StationNum && m.IsDelete == false); if (checkTaskMedel == null) { Log.Error(string.Format("根据码垛工位{0},获取分道失败!", modDevice.StationNum)); // 写入插入结果 2:插码失败 var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2"); break; } string palletNo = checkTaskMedel.PalletNo; if (string.IsNullOrEmpty(palletNo)) { Log.Error(string.Format("获取码垛工位{0}上的托盘号失败!", modDevice.StationNum)); // 写入插入结果 2:插码失败 var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2"); break; } for (int i = 1; i <= boxNum; i++) { // 获取箱条码 // 获取箱条码配置 var modBoxNo = modDevice.listStation.FirstOrDefault(m => m.Text == $"读取箱码{i}"); var (res, boxVal) = plcConn.GetPlcDBValue(modBoxNo.PosType, modDevice.DbNumber, modBoxNo.PlcPos); string boxNo = boxVal.ToString(); if (string.IsNullOrEmpty(boxNo)) { Log.Error(string.Format("码垛工位{0},箱码为null插码失败!请人工强制结批。", modDevice.StationNum)); break; } // 验证箱码表是否存在此箱码 var boxInfo = _db.Queryable().Where(w => w.IsDelete == false && w.BoxNo == boxNo).ToList(); if (boxInfo.Count == 0) { Log.Error(string.Format("码垛工位{0},箱码{1}不存在!请人工强制结批。", modDevice.StationNum, boxNo)); // 写入插入结果 2:插码失败 plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2"); break; } // 修改插码表 foreach (WcsBoxInfo item in boxInfo) { item.PalletNo = palletNo; item.UpdateTime = DateTime.Now; } var resultCount = _db.Updateable(boxInfo).ExecuteCommand(); if (resultCount <= 0) { // 插码失败 Log.Error(string.Format("箱码{0};码垛工位{1},绑定托盘{2}失败,请强制结批", boxNo, modDevice.StationNum, palletNo)); // 写入插入结果 2:插码失败 plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2"); break; } } // 插码成功 var retVal2 = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "1"); if (retVal2.IsSucceed) { //更新已插码数量 checkTaskMedel.BoxCount += boxNum; _db.Updateable(checkTaskMedel).ExecuteCommand(); } else { // 写入失败 Log.Error(string.Format("写入PLC插码结果失败,码垛工位{1},托盘号{2}", modDevice.StationNum, palletNo)); } } break; case "40": // 请求组托,申请入库 { lock (OLock) { // 根据工位号,获取托盘号 var checkTaskMedel = _db.Queryable().First(m => m.Port == modDevice.StationNum && m.IsDelete == false); // 根据工位号获取 托盘线该工位号的配置信息 var numModel = PLCTaskAction.plcDevices.First(m => m.StationNum == modDevice.StationNum && m.IsDelete == false && m.DeviceType == DeviceTypeEnum.Business && m.PlcId != modDevice.PlcId); //var posModel = PLCTaskAction.plcPositions.First(m => m.DeviceId == numModel.Id && m.Text == "目的工位" && m.IsDelete == false); if (checkTaskMedel == null) { Log.Error(string.Format("组托失败根据码垛工位{0},获取托盘号失败!", modDevice.StationNum)); // 写入组托回复流程字 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "60"); break; } //获取托盘高度 //var posPalletHeightModel = PLCTaskAction.plcPositions.First(m => m.DeviceId == numModel.Id && m.Text == "托盘高度" && m.IsDelete == false); //var (resPalletHeight, palletHeightVal) = plcConn.GetPlcDBValue(posPalletHeightModel.PosType, modDevice.DbNumber, posPalletHeightModel.PlcPos); //if (!resPalletHeight.IsSucceed) //{ // break; //} // 码垛工位托盘号 string palletNo = checkTaskMedel.PalletNo; //判断该托盘是否有正在执行的任务,防止重复申请 var taskIng = _db.Queryable().First(w => w.PalletNo == palletNo && (w.Status == TaskStatusEnum.Wait || w.Status == TaskStatusEnum.Doing) && w.IsDelete == false); if (taskIng != null) { break; } // 根据托盘号,将组托信息插入boxinfolog表 并删除boxinfo表数据 var boxInfoList = _db.Queryable().Where(w => w.IsDelete == false && w.PalletNo == palletNo).ToList(); if (boxInfoList.Count <= 0) { Log.Error(string.Format("申请巷道失败,码垛工位{0},箱码信息不存在", modDevice.StationNum)); // 写入组托回复流程字 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "60"); break; } // 向WMS申请巷道 var http = new HttpService(); string TaskNo = "", EndLocate = ""; string strMsg = http.BindRequestRoadWay(checkTaskMedel.OrderNo, palletNo, checkTaskMedel.BoxCount.ToDecimal(), "0", checkTaskMedel.SkuNo, checkTaskMedel.LotNo, "", "", boxInfoList, modDevice.StationNum, "1", "1", ref EndLocate, ref TaskNo, (int)1351); if (strMsg.Contains("-1")) { Log.Error(string.Format("申请巷道失败,码垛工位{0};原因{1}", modDevice.StationNum, strMsg)); // 写入组托回复流程字 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "60"); break; } else { // 获取入库任务信息 var taskModel = _db.Queryable().First(m => m.TaskNo == TaskNo && m.IsDelete == false && m.Status == TaskStatusEnum.Wait); if (taskModel != null) { // 写入组托回复流程字 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "50"); if (retVal.IsSucceed) { // 将入库任务由正在执行改为正在执行 taskModel.Status = TaskStatusEnum.Doing; _db.Updateable(taskModel).ExecuteCommand(); string sqlStr = $"insert into WCSBoxInfoLog select * from WCSBoxInfo where IsDelete=0 and PalletNo='{palletNo}'"; int insertCount = _db.Ado.ExecuteCommand(sqlStr); if (insertCount > 0) { string sqlStr2 = $"delete from WCSBoxInfo where IsDelete=0 and PalletNo='{palletNo}'"; _db.Ado.ExecuteCommand(sqlStr2); } // 插入任务明细 var modInsertTaskMonitor = new WcsTaskMonitor() { TaskNo = TaskNo, PlcId = modDevice.Id, PlcName = modDevice.Text, InteractiveMsg = $"写入指令50:申请巷道成功", PalletNo = palletNo, Status = TaskStatusEnum.Complete, StartLocat = modDevice.StationNum, EndLocat = strMsg, }; // 插入交互日志 _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); // 通知任务界面任务已存在更新 请更新界面 HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt()); } } } } } break; case "100": //自动结批 { // 获取当前分道托盘号 var checkTaskMedel = _db.Queryable().First(m => m.Port == modDevice.StationNum && m.IsDelete == false); if (checkTaskMedel == null) { Log.Error(string.Format("码垛工位{0},批次{1},自动结批失败!请人工强制结批!", modDevice.StationNum, checkTaskMedel.LotNo)); break; } // 触发结批 解绑分道 AutoEndLot(checkTaskMedel.LotNo, plcConn, "0", modDevice); } break; default: break; } } } /// /// 拆垛机器人业务处理 /// /// private static void StackingRobot(WcsDeviceDto modDevice) { var plcConn = modDevice.PLCUtil; switch (modDevice.Value.ToString()) { case "0": { // 若拆垛工位为空闲,查询任务表是否有未绑定的出库任务,做绑定操作 } break; default: break; } } private static void LedDisplay(string ip,string text) { try { LedDll Led = new LedDll(); Led.ConsoleLeds(ip, text); // 设置实例 //Led.ConsoleLeds("10.18.51.238", $"任务类型:{TaskTypeEnum.Move.GetDescription()}\n\n任务号:TK2024102100001\n托盘号:LN000145\n\n起始位:033\n目标位:R01-02010102"); } catch (Exception ex) { Log.Error(ex.Message); } } /// /// 自动结批 并 解绑分道 /// /// 批次号 /// Plc连接 /// 是否解绑分道 0:解绑 1:绑定 private static void AutoEndLot(string lotNo, PLCUtil plcConn, string status, WcsDeviceDto modDevice) { try { if (string.IsNullOrWhiteSpace(lotNo)) { Console.WriteLine("批次号为null"); } var checkTaskList = _db.Queryable().Where(w => w.LotNo == lotNo && w.Status == "1").ToList(); if (checkTaskList.Count <= 0) { Console.WriteLine("未找到分道绑定信息"); } var taskInfo = _db.Queryable().First(w => w.OrderNo == checkTaskList[0].OrderNo); if (taskInfo != null) { taskInfo.Status= TaskStatusEnum.Complete;//已结束 //更新任务状态 _db.Updateable(taskInfo).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } foreach (var item in checkTaskList) { #region#给PLC写入结批批次号 var listResult = new List(); listResult.Add(plcConn.SetPlcDBValue(item.PosType, item.DbNumber, item.PlcPos, "0"));//品种号 listResult.Add(plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PosLot, ""));//批次号 listResult.Add(plcConn.SetPlcDBValue(item.PosTypeStatus, item.DbNumber, item.PosStatus, "0"));//绑定状态 0:未绑定 1:已绑定 if (listResult.All(s => s.IsSucceed)) { // 写入组托回复流程字 var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "110"); if (retVal.IsSucceed) { //写入流程字成功后更新分拣任务 item.OrderNo = ""; item.TaskNo = ""; item.LotNo = ""; item.SkuNo = ""; item.SkuName = ""; item.BoxType = ""; item.Qty = 0; item.BoxCount = 0; item.PZNo = ""; item.PalletNo = ""; item.Status = status; // 绑定分道 0:解绑 1:绑定 //更新绑定信息 _db.Updateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } } else { throw Oops.Bah("与PCL交互失败,结批失败!"); } #endregion } } catch (Exception ex) { Log.Error(ex.Message); throw; } } private static void Test(WcsDeviceDto modDevice) { //写死测试读string var (res, val) = modDevice.PLCUtil.GetPlcDBValue(PLCDataTypeEnum.String, "DB100", "64"); Console.WriteLine("DB100.64----" + val); //测试批量读取 Dictionary listaddress = new Dictionary(); foreach (var modStation in modDevice.listStation) { listaddress.Add(modStation.PlcPos, modStation.PosType); } var result = modDevice.PLCUtil.GetPlcBatchDBValue(listaddress); if (result.Value.Count > 0) { foreach (var value in result.Value) { Console.WriteLine("地址" + value.Key + "----值" + value, value); } } if (!result.IsSucceed) { foreach (var err in result.ErrList) { Console.WriteLine(err); } if (result.Value.Count > 0)//有错误的也有成功的 { } } if (modDevice.Value == 820) { //测试写入830 //var result = mod.PLCUtil.SetPlcDBValue(mod.PosType.Value, mod.DbNumber, mod.PlcPos, "830"); ////写入是否成功 //if (result.IsSucceed) //{ //} } else if (modDevice.Value == 840) { } else if (modDevice.Value == 860) { } } }