chengsc
2025-04-25 5883a139074dd7493d9f0d776540f196d55d1034
Admin.NET/WCS.Application/PLC/PLCService.cs
@@ -5,6 +5,8 @@
using DocumentFormat.OpenXml.Spreadsheet;
using Furion.Logging;
using IoTClient;
using NewLife.Reflection;
using WCS.Application.Entity;
using WCS.Application.Util;
namespace WCS.Application;
@@ -154,52 +156,70 @@
                    sysCacheService.HashAddOrUpdate("AlarmInfo_Car", plcConn.PlcIP, -1);
                    var modPosTaskStatus = modDevice.listStation.FirstOrDefault(s => s.Text == "任务状态");
                    var (resultTaskStatus, valueTaskStatus) = plcConn.GetDBValue(modPosTaskStatus.PosType, modPosTaskStatus.PlcPos);
                    //判断读取任务状态是否成功 并且任务状态是1  0:未空闲,1:空闲,2:异常  3:充电中
                    WcsCarTasks carTask2 = null;//null 新任务  not null 路径2任务
                    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)
                        //读取任务号
                        int valueTaskStr = Convert.ToInt32(valueTask);
                        //获取任务信息 根据  任务号、小车编号
                        var carTask = _db.Queryable<WcsCarTasks>().First(m=>m.IsDelete == false && m.Status == TaskStatusEnum.Doing && m.CarTaskNo == valueTaskStr && m.CarNo == modDevice.PlcIdIP);
                        if (carTask == null)
                        {
                            var modFinshTask = _db.Queryable<WcsTask>().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<WcsTaskOutput>());
                                    HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>());
                                }
                                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);
                            }
                            return;//没有找到任务
                        }
                        var modFinshTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.TaskNo == carTask.TaskNo);
                        if (modFinshTask == null)
                        {
                            return;//没有查询到总任务
                        }
                        //获取路径2的任务 下发
                        carTask2 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == carTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.PreId.Contains(carTask.Id.ToString())).OrderBy(m=>m.CreateTime).First();
                        if (carTask != null && carTask.Status != TaskStatusEnum.Complete)
                        {
                            carTask.Status = TaskStatusEnum.Complete;
                            carTask.UpdateTime = DateTime.Now;
                            _db.Updateable(carTask).ExecuteCommand();
                            //添加任务明细
                            var taskMonitor = new WcsTaskMonitor()
                            {
                                TaskNo = carTask.TaskNo,
                                PlcName = modDevice.Text,
                                InteractiveMsg = $"穿梭车反馈任务完成"
                            };
                            _db.Insertable(taskMonitor).ExecuteCommand();
                            //下发任务日志
                            HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>());
                        }
                        //没有路径2的任务 变更总任务信息
                        if (carTask2 == null && modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete)
                        {
                            modFinshTask.Status = TaskStatusEnum.Complete;
                            modFinshTask.FinishDate = DateTime.Now;
                            _db.Updateable(modFinshTask).ExecuteCommand();
                            //反馈WMS系统 任务完成
                            //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<WcsTaskOutput>());
                        }
                    }
                    var modStationX = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(X)");
@@ -210,35 +230,52 @@
                    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<WcsTask>().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)
                    var modTask = _db.Queryable<WcsTask>().Where(s => s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar).OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime).First();
                    //要下发路径2任务
                    if (carTask2 == null)
                    {
                        modTask.Status = TaskStatusEnum.Doing;
                        _db.Updateable(modTask).ExecuteCommand();
                        HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>());
                        modTask = _db.Queryable<WcsTask>().First(s => s.IsDelete == false && s.TaskNo == carTask2.TaskNo && s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar);
                        carTask2= _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP).OrderBy(m => m.CreateTime).First();
                    }
                    //return;
                    if (modTask == null || carTask2 == null)
                    {
                        return;
                    }
                    if (modTask.Status == TaskStatusEnum.Doing)
                    if (carTask2.Status == TaskStatusEnum.Doing)
                    {
                        Thread.Sleep(3000);
                        return;
                    }
                    //判断当前任务是否还有前置任务未完成
                    var preStrs = carTask2.PreId.Split(';');
                    foreach (var preStr in preStrs)
                    {
                        if (string.IsNullOrWhiteSpace(preStr))
                        {
                            continue;
                        }
                        var preId = long.Parse(preStr);
                        var CarTaskPre = _db.Queryable<WcsCarTasks>().First(m => m.Id == preId);
                        if (CarTaskPre.Status <= TaskStatusEnum.Doing)
                        {
                            return;//前置任务未完成
                        }
                    }
                    //先复位
                    var modRest = modDevice.listStation.FirstOrDefault(s => s.Text == "复位");
                    plcConn.SetDBValue(modRest.PosType, modRest.PlcPos, "1");
                    List<Result> listResult = new List<Result>();
                    //写入任务号Id的末4位,2个小车一起跑有极低概率重复
                    //获取小车任务号
                    var carTaskNo = FourWayCarUtil.GetTaskNo();
                    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)));
                    listResult.Add(plcConn.SetDBValue(modWriteTask.PosType, modWriteTask.PlcPos, carTaskNo.ToString()));
                    var modNodeX = modDevice.listStation.FirstOrDefault(s => s.Text == "节点坐标X");
                    var modNodeY = modDevice.listStation.FirstOrDefault(s => s.Text == "节点坐标Y");
@@ -256,29 +293,21 @@
                        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)
                    //交互路径
                    var execuPath = carTask2.ExecutionPath.Split(';');
                    foreach (var ePath in execuPath)
                    {
                        //如果后续没有任务,就让小车回到原位
                        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"));
                        if (string.IsNullOrWhiteSpace(ePath))
                        {
                            continue;
                        }
                        //写入交互位置
                        listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), ePath.Substring(0, 2)));
                        listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), ePath.Substring(2, 2)));
                        listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), ePath.Substring(4, 2)));
                        listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), ePath.Substring(5, 1)));
                    }
                    //这里是把后面的坐标全写0(为了防止上次任务坐标没被覆盖)
                    while (posX <= 43097)
                    {
@@ -293,17 +322,17 @@
                        var result = plcConn.SetDBValue(modStart.PosType, modStart.PlcPos, "1");
                        if (result.IsSucceed)
                        {
                            modTask.Status = TaskStatusEnum.Doing;
                            _db.Updateable(modTask).ExecuteCommand();
                            carTask2.Status = TaskStatusEnum.Doing;
                            carTask2.CarTaskNo = carTaskNo;
                            _db.Updateable(carTask2).ExecuteCommand();
                            var taskMonitor = new WcsTaskMonitor()
                            {
                                TaskNo = modTask.TaskNo,
                                TaskNo = carTask2.TaskNo,
                                PlcName = modDevice.Text,
                                InteractiveMsg = $"向穿梭车下发任务{modTask.TaskNo}"
                                InteractiveMsg = $"向穿梭车下发任务{carTask2.TaskNo}"
                            };
                            _db.Insertable(taskMonitor).ExecuteCommand();
                            //下发任务日志
                            HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>());
                            HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>());
                        }
                    }
@@ -314,42 +343,42 @@
                    //小车状态异常
                    var modPosTaskStatus = modDevice.listStation.FirstOrDefault(s => s.Text == "任务状态");
                    var (resultTaskStatus, valueTaskStatus) = plcConn.GetDBValue(modPosTaskStatus.PosType, modPosTaskStatus.PlcPos);
                    if (resultTaskStatus.IsSucceed && valueTaskStatus == 1)
                    {
                        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 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<WcsTask>().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.Id.ToString().EndsWith(valueTaskStr));
                            if (modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete)
                            {
                                var modFinshTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.Id.ToString().EndsWith(valueTaskStr));
                                if (modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete)
                                HttpService httpService = new HttpService();
                                var requestMode = new TaskRequestWMS()
                                {
                                    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<WcsTaskOutput>());
                                    //HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>());
                                    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<WcsTaskOutput>());
                                //HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>());
                                    if (dicTaskNo.ContainsKey(modDevice.Id.ToString()))
                                        dicTaskNo.Remove(modDevice.Id.ToString());
                                    dicTaskNo.Add(modDevice.Id.ToString(), valueTaskStr);
                                }
                                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);
@@ -599,160 +628,22 @@
    /// <param name="modDevice"></param>
    private static void AGV(WcsDeviceDto modDevice)
    {
        if (AGVStatus)
        {
            return;
        }
        //这里找出来AGV待执行和正在执行的任务,如果有正在执行的任务就跳出,没有的话就按照优先级下发一个任务给AGV
        var listTask = _db.Queryable<WcsTask>()
                        .Where(s => (s.Status == TaskStatusEnum.Doing || s.Status == TaskStatusEnum.Wait) && s.Type == PLCTypeEnum.AGV)
                        .OrderBy(s => s.Levels).ToList();
        //这里找出来AGV待执行的任务、按照优先级下发一个任务给AGV
        var listTask = _db.Queryable<WcsTask>().Where(s => (s.Status == TaskStatusEnum.Wait || s.Status == TaskStatusEnum.Doing) && 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 (_db.Queryable<WcsTask>().Any(s => s.EndLocate == modTask.EndLocate && s.IsDelete == false && s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.AGV ))
            {
                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;
                    }
                }
                continue; // 有目的位置一致且正在执行的任务
            }
            //出缓存区时,检验一下缓存区位置
            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<bool>("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<bool>("cache_Materal").Result)
                    continue;
            }
            //if (modTask.StartLocate == AGVStaionEnum.F1.ToString())
            //{
            //    if (!_sysConfigService.GetConfigValue<bool>("cache_Materal").Result)
            //        continue;
            //}
            
            //如果起始工位是拆托机
            if (modTask.StartLocate == AGVStaionEnum.D1.ToString())
            {
                //获取叠拆托机IP
                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<WcsTaskMonitorOutput>());
                            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<WcsTask>().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.Status == TaskStatusEnum.Doing).Any())
                    continue;
            }
            //下发AGV任务
            AgvTaskInput input = new AgvTaskInput()
            {
                ReqCode = modTask.Id.ToString(),