using Admin.NET.Core.Service; using COSXML.Network; using DocumentFormat.OpenXml.Bibliography; using DocumentFormat.OpenXml.Drawing; using DocumentFormat.OpenXml.Spreadsheet; using Furion.Logging; using IoTClient; using WCS.Application.Util; namespace WCS.Application; public static class PLCService { private static readonly object OLock = new object(); public static bool AGVStatus = false; private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); private static readonly WcsTaskService _taskService = App.GetService(); private static readonly SysCacheService sysCacheService = App.GetRequiredService(); private static readonly SysConfigService _sysConfigService = App.GetRequiredService(); private static Dictionary dicTaskNo = new Dictionary(); public static void OnChangeEvent(object sender, EventArgs e) { try { var mod = sender as WcsDeviceDto; //Console.WriteLine($"{mod.Text}值为" + mod.Value); switch (mod.Type) { case PLCTypeEnum.ConveyorLine: ConveyorLine(mod); // 托盘输送线 break; case PLCTypeEnum.AGV: AGV(mod); // AGV调度 break; case PLCTypeEnum.ShuttleCar: //穿梭车 ShuttleCar(mod); break; case PLCTypeEnum.RobotPalletizer: RobotPalletizer(mod);//码垛机器人 break; case PLCTypeEnum.PalletMachine: PalletMachine(mod); break; default: break; } } catch (Exception ex) { Log.Error(ex.Message, ex); } } /// /// 拆托机 /// /// private static void PalletMachine(WcsDeviceDto modDevice) { if (modDevice.Value) { if (!_db.Queryable() .Where(s => s.Type == PLCTypeEnum.AGV && s.Status <= TaskStatusEnum.Doing && s.EndLocate == AGVStaionEnum.D1.ToString()).Any()) { WcsTask modTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.AGV, StartLocate = AGVStorageUtil.GetPalletOutStorage(), EndLocate = AGVStaionEnum.D1.ToString(), PalletNo = "", Status = TaskStatusEnum.Wait, Levels = 3, Origin = "WCS" }; if (modTask.StartLocate.IsNullOrEmpty()) return; _db.Insertable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); } } } /// /// 码垛机器人业务处理 /// private static void RobotPalletizer(WcsDeviceDto modDevice) { var plcConn = modDevice.modbusUtil; string station = "B" + modDevice.StationNum; string value = Convert.ToString(modDevice.Value); if (value == "1") { if (modDevice.Level == DeviceLevelEnum.DB) { //缺托盘信号,叫小车去拉空托盘 if (!_db.Queryable().Where(s => s.Type == PLCTypeEnum.AGV && s.Status <= TaskStatusEnum.Doing && s.StartLocate == AGVStaionEnum.D1.ToString() && s.EndLocate == station.ToString()).Any()) { WcsTask modTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.AGV, StartLocate = AGVStaionEnum.D1.ToString(), EndLocate = station, PalletNo = "", Status = TaskStatusEnum.Wait, Levels = 4, Origin = "WCS" }; _db.Insertable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); } } else if (modDevice.Level == DeviceLevelEnum.Station) { //如果读到信号通知AGV小车拉货(满跺) //todo:点位和值还没定,对接时候改一下 var endLocate = "C" + modDevice.StationNum; if (!_db.Queryable().Where(s => s.Type == PLCTypeEnum.AGV && s.Status <= TaskStatusEnum.Doing && s.StartLocate == station.ToString()).Any()) { WcsTask modTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.AGV, StartLocate = station.ToString(), EndLocate = endLocate, PalletNo = "", Status = TaskStatusEnum.Wait, Levels = 2, Origin = "WCS" }; _db.Insertable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); } } } } //穿梭车业务处理 private static void ShuttleCar(WcsDeviceDto modDevice) { var plcConn = modDevice.modbusUtil; switch (modDevice.Value.ToString()) { case "0": sysCacheService.HashAddOrUpdate("AlarmInfo_Car", plcConn.PlcIP, -1); break; case "1": { sysCacheService.HashAddOrUpdate("AlarmInfo_Car", plcConn.PlcIP, -1); var modPosTaskStatus = modDevice.listStation.FirstOrDefault(s => s.Text == "任务状态"); var (resultTaskStatus, valueTaskStatus) = plcConn.GetDBValue(modPosTaskStatus.PosType, modPosTaskStatus.PlcPos); if (resultTaskStatus.IsSucceed && valueTaskStatus == 1) { var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); var (resultTask, valueTask) = plcConn.GetDBValue(modPosTask.PosType, modPosTask.PlcPos); string valueTaskStr = Convert.ToString(valueTask); string strNo = ""; var boNo = dicTaskNo.TryGetValue(modDevice.Id.ToString(), out strNo); if (valueTaskStr != "0" && strNo != valueTaskStr) { var modFinshTask = _db.Queryable().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.Id.ToString().EndsWith(valueTaskStr)); if (modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete) { //12.4出库改成调用WMS完成任务接口;WMS操控PDA托盘下架后,WCS任务状态才完成(避免小车继续跑) if (modFinshTask.TaskType == TaskTypeEnum.In) { modFinshTask.Status = TaskStatusEnum.Complete; modFinshTask.FinishDate = DateTime.Now; _db.Updateable(modFinshTask).ExecuteCommand(); var taskMonitor = new WcsTaskMonitor() { TaskNo = modFinshTask.TaskNo, PlcName = modDevice.Text, InteractiveMsg = $"穿梭车反馈任务完成" }; _db.Insertable(taskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTask(modFinshTask.Adapt()); HubUtil.PublicTaskMonitor(taskMonitor.Adapt()); } HttpService httpService = new HttpService(); var requestMode = new TaskRequestWMS() { TaskNo = modFinshTask.TaskNo, PalletNo = modFinshTask.PalletNo, TaskType = ((int)modFinshTask.TaskType).ToString(), TaskStatus = ((int)TaskStatusEnum.Complete).ToString() }; var modResponseTask = httpService.RequestTask(requestMode).Result; modFinshTask.IsSuccess = TaskSuccessEnum.Success; _db.Updateable(modFinshTask).ExecuteCommand(); if (dicTaskNo.ContainsKey(modDevice.Id.ToString())) dicTaskNo.Remove(modDevice.Id.ToString()); dicTaskNo.Add(modDevice.Id.ToString(), valueTaskStr); } } } var modStationX = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(X)"); var (resultx, valuex) = plcConn.GetDBValue(modStationX.PosType, modStationX.PlcPos); var modStationY = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(Y)"); var (resulty, valuey) = plcConn.GetDBValue(modStationY.PosType, modStationY.PlcPos); var modStationZ = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(Z)"); var (resultz, valuez) = plcConn.GetDBValue(modStationZ.PosType, modStationZ.PlcPos); // 获取任务信息 var stationStart = ((int)valuex).ToString().PadLeft(2, '0'); var stationEnd = ((int)valuez).ToString().PadLeft(2, '0') + "01"; var listTask = _db.Queryable().OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime) .Where(s => s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.StartLocate.StartsWith(stationStart) && s.StartLocate.EndsWith(stationEnd)).ToList(); var modTask = listTask.FirstOrDefault(); //return; if (modTask == null) return; if (modTask.StartLocate == modTask.EndLocate) { modTask.Status = TaskStatusEnum.Doing; _db.Updateable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt()); return; } if (modTask.Status == TaskStatusEnum.Doing) { Thread.Sleep(3000); return; } //先复位 var modRest = modDevice.listStation.FirstOrDefault(s => s.Text == "复位"); plcConn.SetDBValue(modRest.PosType, modRest.PlcPos, "1"); List listResult = new List(); //写入任务号Id的末4位,2个小车一起跑有极低概率重复 var modWriteTask = modDevice.listStation.FirstOrDefault(s => s.Text == "写入任务号"); listResult.Add(plcConn.SetDBValue(modWriteTask.PosType, modWriteTask.PlcPos, modTask.Id.ToString().Substring(modTask.Id.ToString().Length - 4))); var modNodeX = modDevice.listStation.FirstOrDefault(s => s.Text == "节点坐标X"); var modNodeY = modDevice.listStation.FirstOrDefault(s => s.Text == "节点坐标Y"); var modNodeZ = modDevice.listStation.FirstOrDefault(s => s.Text == "节点坐标Z"); var modNodeStatus = modDevice.listStation.FirstOrDefault(s => s.Text == "节点举升状态"); int posX = Convert.ToInt32(modNodeX.PlcPos); int posY = Convert.ToInt32(modNodeY.PlcPos); int posZ = Convert.ToInt32(modNodeZ.PlcPos); int posStatus = Convert.ToInt32(modNodeStatus.PlcPos); if (Convert.ToInt32(valuey) != Convert.ToInt32(modTask.StartLocate.Substring(2, 2))) { //写入小车当前位置 listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), Convert.ToString(valuex))); listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), Convert.ToString(valuey))); listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), Convert.ToString(valuez))); listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "3")); } //写入起始位置取货 listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), modTask.StartLocate.Substring(0, 2))); listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), modTask.StartLocate.Substring(2, 2))); listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), modTask.StartLocate.Substring(4, 2))); listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "2")); //写入目标位置放货 listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), modTask.EndLocate.Substring(0, 2))); listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), modTask.EndLocate.Substring(2, 2))); listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), modTask.EndLocate.Substring(4, 2))); listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "3")); string endPos = ""; if (modTask.StartLocate.Substring(0, 2).ToInt() >= 14) endPos = "01"; else endPos = "21"; if (listTask.Count == 1 && modTask.EndLocate.Substring(2, 2) != endPos) { //如果后续没有任务,就让小车回到原位 listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), modTask.EndLocate.Substring(0, 2))); listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), endPos));//todo:这里位置待定 listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), modTask.EndLocate.Substring(4, 2))); listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "3")); } while (posX <= 43097) { listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), "0")); listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), "0")); listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), "0")); listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), "0")); } if (listResult.All(s => s.IsSucceed)) { var modStart = modDevice.listStation.FirstOrDefault(s => s.Text == "启动命令"); var result = plcConn.SetDBValue(modStart.PosType, modStart.PlcPos, "1"); if (result.IsSucceed) { modTask.Status = TaskStatusEnum.Doing; _db.Updateable(modTask).ExecuteCommand(); var taskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcName = modDevice.Text, InteractiveMsg = $"向穿梭车下发任务{modTask.TaskNo}" }; _db.Insertable(taskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTask(modTask.Adapt()); HubUtil.PublicTaskMonitor(taskMonitor.Adapt()); } } } break; case "2": { var modPosTaskStatus = modDevice.listStation.FirstOrDefault(s => s.Text == "任务状态"); var (resultTaskStatus, valueTaskStatus) = plcConn.GetDBValue(modPosTaskStatus.PosType, modPosTaskStatus.PlcPos); { if (resultTaskStatus.IsSucceed && valueTaskStatus == 1) { var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); var (resultTask, valueTask) = plcConn.GetDBValue(modPosTask.PosType, modPosTask.PlcPos); string valueTaskStr = Convert.ToString(valueTask); string strNo = ""; var boNo = dicTaskNo.TryGetValue(modDevice.Id.ToString(), out strNo); if (valueTaskStr != "0" && strNo != valueTaskStr) { var modFinshTask = _db.Queryable().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.Id.ToString().EndsWith(valueTaskStr)); if (modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete) { //modFinshTask.Status = TaskStatusEnum.Complete; //modFinshTask.FinishDate = DateTime.Now; //_db.Updateable(modFinshTask).ExecuteCommand(); //var taskMonitor = new WcsTaskMonitor() //{ // TaskNo = modFinshTask.TaskNo, // PlcName = modDevice.Text, // InteractiveMsg = $"穿梭车反馈任务完成" //}; //_db.Insertable(taskMonitor).ExecuteCommand(); HttpService httpService = new HttpService(); var requestMode = new TaskRequestWMS() { TaskNo = modFinshTask.TaskNo, PalletNo = modFinshTask.PalletNo, TaskType = ((int)modFinshTask.TaskType).ToString(), TaskStatus = ((int)TaskStatusEnum.Complete).ToString() }; var modResponseTask = httpService.RequestTask(requestMode).Result; modFinshTask.IsSuccess = TaskSuccessEnum.Success; _db.Updateable(modFinshTask).ExecuteCommand(); //下发任务日志 //HubUtil.PublicTask(modFinshTask.Adapt()); //HubUtil.PublicTaskMonitor(taskMonitor.Adapt()); if (dicTaskNo.ContainsKey(modDevice.Id.ToString())) dicTaskNo.Remove(modDevice.Id.ToString()); dicTaskNo.Add(modDevice.Id.ToString(), valueTaskStr); } } } } Console.WriteLine($"穿梭车{modDevice.PlcIdIP}异常"); var modPosError = modDevice.listStation.FirstOrDefault(s => s.Text == "错误码"); var (result, valueError) = plcConn.GetDBValue(modPosError.PosType, modPosError.PlcPos); if (result.IsSucceed) { sysCacheService.HashAddOrUpdate("AlarmInfo_Car", plcConn.PlcIP, Convert.ToInt32(valueError)); } } break; default: break; } } /// /// 输送线业务处理 /// /// private static void ConveyorLine(WcsDeviceDto modDevice) { var plcConn = modDevice.PLCUtil; switch (modDevice.Value.ToString()) { case "20": { string Devicelndex = ""; if (modDevice.Text == "2号卷帘门") Devicelndex = "222"; else if (modDevice.Text == "3号卷帘门") Devicelndex = "111"; var modCallBack = sysCacheService.Get("OpenDoor" + Devicelndex); if (modCallBack != null) { var modAgvDevice = PLCTaskAction.plcs.FirstOrDefault(s => s.Text == "AGV"); AgvNotifyInput input = new AgvNotifyInput() { ActionStatus = "1", DeviceIndex = Devicelndex, UUID = modCallBack.UUID, }; var response = new HttpService().NotifyExcuteResultInfo(input).Result; if (response.code == 0) { sysCacheService.Remove("OpenDoor" + Devicelndex); } } } break; case "100": { string stationNum = ""; if (modDevice.StationNum == "1" || modDevice.StationNum == "4") { stationNum = "10"; //判断有没有小车到C口的任务,如果有就写120 var countTask = _db.Queryable().Where(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.AGV && s.EndLocate == "A1").Count(); if (countTask != 0) { var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "120"); Log.Information($"向plc{modDevice.PlcIdIP}写入120,结果:{ret.ToJson()}"); return; } } string strPalletNo = ""; if (modDevice.StationNum == "10" || modDevice.StationNum == "4") { var modPosPallet = modDevice.listStation.First(s => s.Text == "托盘条码"); //todo:先写死 plcConn.SetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos, "T2400001"); var (res, palletNo) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos, modPosPallet.StringLength); if (!res.IsSucceed || palletNo == "") { var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "120"); Log.Information($"向plc{modDevice.PlcIdIP}写入120,结果:{ret.ToJson()}"); return; } strPalletNo = Convert.ToString(palletNo); } if (modDevice.StationNum == "10") { if (strPalletNo.Substring(0, 1) == "T") stationNum = "4"; else stationNum = "1"; //调WMS接口决定目的工位 参数托盘条码、起始工位 //ResponseStationModel response = new HttpService().RequestStationNum(new RequestStation() { PalletNo = strPalletNo, StatrtStationNum = modDevice.StationNum }).Result; //if (response.Success == 0) //{ // stationNum = response.TaskList.EndLocate; //} //else //{ // Log.Error("调用WMS接口申请工位,失败原因" + response.Message); // return; //} } // 写入托盘输送线码垛工位 var listResult = new List(); // 写入托盘输送线码垛工位 目的工位、任务号,写入交互流程组托成功 var posModel = modDevice.listStation.First(m => m.Text == "起始工位"); listResult.Add(plcConn.SetPlcDBValue(posModel.PosType, modDevice.DbNumber, posModel.PlcPos, modDevice.StationNum)); var posModel2 = modDevice.listStation.First(m => m.Text == "目标工位"); listResult.Add(plcConn.SetPlcDBValue(posModel2.PosType, modDevice.DbNumber, posModel2.PlcPos, stationNum)); string taskNo = _taskService.GetTaskCode("WCS"); var modPosTask = modDevice.listStation.First(s => s.Text == "任务号"); listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, taskNo)); if (listResult.All(s => s.IsSucceed)) { var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "130"); Log.Information($"向plc{modDevice.PlcIdIP}写入130,结果:{ret.ToJson()}"); if (ret.IsSucceed) { AddWcsTaskInput modTask = new AddWcsTaskInput() { TaskNo = taskNo, TaskType = TaskTypeEnum.In, PalletNo = strPalletNo, Status = TaskStatusEnum.Doing, IsSuccess = TaskSuccessEnum.Fail, StartLocate = modDevice.StationNum, EndLocate = stationNum, Type = PLCTypeEnum.ConveyorLine, }; _taskService.Add(modTask); WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modDevice.Text, StartLocat = modDevice.StationNum, EndLocat = stationNum, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入指令130,结果{ret.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTask(modTask.Adapt()); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); } } } break; case "140": { var modPosTask = modDevice.listStation.First(m => m.Text == "任务号"); var (result, taskNo) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modPosTask.StringLength); var modPosPallet = modDevice.listStation.First(m => m.Text == "托盘条码"); var (res, palletNo) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos, modPosPallet.StringLength); WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor(); WcsTask modTask = new WcsTask(); if (!result.IsSucceed) { Log.Error($"{plcConn.PlcIP}读取任务号失败"); return; } //if (modDevice.StationNum == "1") //{ // var response = new HttpService().EditLogPalletTask(new RequestStation() { PalletNo = palletNo, StatrtStationNum = modDevice.StationNum }).Result; // if (response.Success != 0) // { // Log.Error(response.Message); // } //} if (modDevice.StationNum == "10") { var posModel = modDevice.listStation.First(m => m.Text == "起始工位"); var (resultS, station) = plcConn.GetPlcDBValue(posModel.PosType, modDevice.DbNumber, posModel.PlcPos); if (resultS.IsSucceed) { if (station == 1) { WcsTask modInsertTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.AGV, StartLocate = AGVStaionEnum.A2.ToString(), EndLocate = AGVStaionEnum.F1.ToString(), PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Wait, Levels = 5, Origin = "WCS" }; _db.Insertable(modInsertTask).ExecuteCommand(); HubUtil.PublicTask(modInsertTask.Adapt()); } else if (station == 4) { WcsTask modInsertTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.AGV, StartLocate = AGVStaionEnum.A2.ToString(), EndLocate = AGVStorageUtil.GetPalletInStorage(), PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Wait, Levels = 5, Origin = "WCS" }; _db.Insertable(modInsertTask).ExecuteCommand(); HubUtil.PublicTask(modInsertTask.Adapt()); } } else { Log.Error("获取起始工位失败,失败原因" + resultS.Err); return; } } var ledText = ""; if (modDevice.StationNum == "4") { //todo:led ledText += "任务类型:入库\n\n"; ledText += $"任务号:{taskNo}\n"; ledText += $"托盘号:{palletNo}\n\n"; //ledText += $"起始位:10\n"; //ledText += $"目标位:4"; LedDisplay(modDevice.LedIP, ledText); } var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "150"); Log.Information($"向plc{modDevice.PlcIdIP}写入150,结果:{ret.ToJson()}"); if (ret.IsSucceed) { string strTaskNo = taskNo; modTask = _db.Queryable().First(s => s.TaskNo == strTaskNo); if (modTask != null) { modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modDevice.Text, StartLocat = modTask.StationNum, EndLocat = modTask.EndLocate, InteractiveMsg = $"向{modDevice.Text}写入指令150,结果{ret.IsSucceed}", }; modTaskMonitor.Status = TaskStatusEnum.Complete; _db.Insertable(modTaskMonitor).ExecuteCommand(); modTask.FinishDate = DateTime.Now; modTask.Status = TaskStatusEnum.Complete; _db.Updateable(modTask).ExecuteCommand(); //下发任务日志 HubUtil.PublicTask(modTask.Adapt()); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); } } } break; default: break; } } /// /// AGV业务处理 /// /// private static void AGV(WcsDeviceDto modDevice) { if (AGVStatus) { return; } var listTask = _db.Queryable() .Where(s => (s.Status == TaskStatusEnum.Doing || s.Status == TaskStatusEnum.Wait) && s.Type == PLCTypeEnum.AGV) .OrderBy(s => s.Levels).ToList(); if (listTask.Count == 0) return; if (listTask.Any(s => s.Status == TaskStatusEnum.Doing)) { //有任务执行中 暂不下发任务 return; } //WcsTask modTask = listTask.FirstOrDefault(); foreach (var modTask in listTask) { //入缓存区时,检验一下缓存区位置 if (modTask.EndLocate.Substring(0, 1) == "Z") { if (modTask.EndLocate.Substring(1, 1) == "5") { string end = AGVStorageUtil.GetPalletInStorage(modTask.TaskNo); if (end.IsNullOrEmpty()) continue; if (modTask.EndLocate != end) { modTask.EndLocate = end; } } else { string end = AGVStorageUtil.GetProductInStorage(modTask.TaskNo); if (end.IsNullOrEmpty()) continue; if (modTask.EndLocate != end) { modTask.EndLocate = end; } } } //出缓存区时,检验一下缓存区位置 if (modTask.StartLocate.Substring(0, 1) == "Z") { if (modTask.StartLocate.Substring(1, 1) == "5") { string start = AGVStorageUtil.GetPalletOutStorage(); if (start.IsNullOrEmpty()) continue; if (modTask.StartLocate != start) { modTask.StartLocate = start; } } else { string start = AGVStorageUtil.GetProductOutStorage(); if (start.IsNullOrEmpty()) continue; if (modTask.StartLocate != start) { modTask.StartLocate = start; } } } //把托盘拉到缓存位 先判断这里有没有 if (modTask.EndLocate.Substring(0, 1) == "C") { var bo = _sysConfigService.GetConfigValue("cache_" + modTask.EndLocate).Result; if (bo) continue; } //如果拉托盘去成品工位,先检查有没有缺托 if (modTask.StartLocate.Substring(0, 1) == "D" && modTask.EndLocate.Substring(0, 1) == "B") { if (listTask.Any(s => s.EndLocate.Substring(0, 1) == "D")) continue; } if (modTask.EndLocate == AGVStaionEnum.F1.ToString()) { if (_sysConfigService.GetConfigValue("cache_Materal").Result) continue; } //if (modTask.StartLocate == AGVStaionEnum.F1.ToString()) //{ // if (!_sysConfigService.GetConfigValue("cache_Materal").Result) // continue; //} if (modTask.StartLocate == AGVStaionEnum.D1.ToString()) { var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.PalletMachine); var modDevice2 = PLCTaskAction.plcDevices.FirstOrDefault(s => s.PlcId == modPlc.Id && s.Text == "拆托机"); var modConn = new PLCUtil(modPlc); //是否缺托信号 var modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice2.Id && s.Text == "允许取托"); var (result, value) = modConn.GetPlcDBValue(modPos.PosType, modDevice2.DbNumber, modPos.PlcPos); if (result.IsSucceed) { if (value) { //如果未完成就判断下取托信号有没有写,完成就叫小车取托盘 modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice2.Id && s.Text == "取托信号"); (result, value) = modConn.GetPlcDBValue(modPos.PosType, modDevice2.DbNumber, modPos.PlcPos); //如果没写入取托信号,就写入 if (result.IsSucceed && !value) { result = modConn.SetPlcDBValue(modPos.PosType, modDevice2.DbNumber, modPos.PlcPos, "1"); WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice2.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice2.Text}写入取托信号1,结果{result.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); Thread.Sleep(5000); } break; } else { modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice2.Id && s.Text == "准备完成"); (result, value) = modConn.GetPlcDBValue(modPos.PosType, modDevice2.DbNumber, modPos.PlcPos); if (!value) { continue; } } } else { Console.WriteLine("连接拆托机信号失败"); continue; } } if (modTask.EndLocate == AGVStaionEnum.A1.ToString()) { if (_db.Queryable().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.Status == TaskStatusEnum.Doing).Any()) continue; } AgvTaskInput input = new AgvTaskInput() { ReqCode = modTask.Id.ToString(), TaskCode = modTask.TaskNo, CtnrCode = modTask.PalletNo, PositionCodePath = new List() { new PositionCodePathItem(){ PositionCode = modTask.StartLocate }, new PositionCodePathItem(){ PositionCode = modTask.EndLocate } } }; input.TaskTyp = "1" + modTask.StartLocate.Substring(0, 1) + modTask.EndLocate.Substring(0, 1); var response = new HttpService().GenAgvSchedulingTask(input).Result; if (response.code == "0") { AGVStatus = true; modTask.Status = TaskStatusEnum.Doing; _db.Updateable(modTask).ExecuteCommand(); var modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.modPlc.Id, PlcName = modDevice.modPlc.IP, InteractiveMsg = "向AGV小车下发任务" }; _db.Insertable(modTaskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTask(modTask.Adapt()); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); } Console.WriteLine(response.ToJson()); return; } Thread.Sleep(3000); } /// /// Led屏展示信息 /// /// 地址 /// 上方区域 /// 中间区域 /// 底部区域 private static void LedDisplay(string ip, string top, string content, string foot) { try { LedDll Led = new LedDll(); Led.LEDstr(ip, top, content, foot); } catch (Exception ex) { Log.Error(ex.Message); } } /// /// LED信息展示 /// /// /// 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); } } private static void Test(WcsDeviceDto modDevice) { //卷帘门2申请打开 //var result = modDevice.PLCUtil.SetPlcDBValue(PLCDataTypeEnum.Short, "DB1000", "1152", "10"); //卷帘门2申请关闭 //var result = modDevice.PLCUtil.SetPlcDBValue(PLCDataTypeEnum.Short, "DB1000", "1152", "30"); //卷帘门3申请打开 //var result = modDevice.PLCUtil.SetPlcDBValue(PLCDataTypeEnum.Short, "DB1000", "1154", "10"); //卷帘门3申请关闭 //var result = modDevice.PLCUtil.SetPlcDBValue(PLCDataTypeEnum.Short, "DB1000", "1154", "30"); //C口AGV放托盘完成申请入库 var result = modDevice.PLCUtil.SetPlcDBValue(PLCDataTypeEnum.Short, "DB1000", "1156", "100"); ////写死测试读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) //{ //} } }