chengsc
2025-04-28 25f52fdb9a195ab651bff2ebb318119ce7f1f633
Admin.NET/WCS.Application/PLC/PLCService.cs
@@ -146,6 +146,7 @@
    private static void ShuttleCar(WcsDeviceDto modDevice)
    {
        var plcConn = modDevice.modbusUtil;
        // 四向车状态 0:未空闲,1:空闲,2:异常  3:充电中
        switch (modDevice.Value.ToString())
        {
            case "0":
@@ -156,9 +157,10 @@
                    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任务
                    //判断读取任务状态是否成功 并且任务状态是1 0:无任务,1:任务完成,2:任务取消,3:任务暂停,4:任务异常 5:任务执行中
                    WcsCarTasks carTaskNext = null;//null 新任务  not null 当前小车&&当前任务 下一节任务
                    if (resultTaskStatus.IsSucceed && valueTaskStatus == 1)
                    {
                        var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号");
@@ -169,16 +171,18 @@
                        var carTask = _db.Queryable<WcsCarTasks>().First(m=>m.IsDelete == false && m.Status == TaskStatusEnum.Doing && m.CarTaskNo == valueTaskStr && m.CarNo == modDevice.PlcIdIP);
                        if (carTask == null)
                        {
                            return;//没有找到任务
                            var modRests = modDevice.listStation.FirstOrDefault(s => s.Text == "复位");
                            plcConn.SetDBValue(modRests.PosType, modRests.PlcPos, "1");//没有找到任务  复位
                            return;
                        }
                         
                        var modFinshTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar && s.TaskNo == carTask.TaskNo);
                        if (modFinshTask == null)
                        {
                            return;//没有查询到总任务
                            break;//没有查询到总任务
                        }
                        //获取路径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();
                        carTaskNext = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == carTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.Status <= TaskStatusEnum.Doing).OrderBy(m=>m.CreateTime).First();
                        
                        if (carTask != null && carTask.Status != TaskStatusEnum.Complete)
                        {
@@ -197,8 +201,8 @@
                            
                            HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>());
                        }
                        //没有路径2的任务 变更总任务信息
                        if (carTask2 == null && modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete)
                        //总任务下没有其他未执行小车的任务 变更总任务信息
                        if (carTaskNext == null && modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete)
                        {
                            modFinshTask.Status = TaskStatusEnum.Complete;
                            modFinshTask.FinishDate = DateTime.Now;
@@ -221,7 +225,7 @@
                        }
                        
                    }
                    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)");
@@ -229,30 +233,40 @@
                    var modStationZ = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(Z)");
                    var (resultz, valuez) = plcConn.GetDBValue(modStationZ.PosType, modStationZ.PlcPos);
                    // 获取任务信息
                    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();
                    WcsTask modTask;
                    //要下发路径2任务
                    if (carTask2 == null)
                    if (carTaskNext != null)
                    {
                        modTask = _db.Queryable<WcsTask>().First(s => s.IsDelete == false && s.TaskNo == carTask2.TaskNo && s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar);
                        modTask = _db.Queryable<WcsTask>().First(s => s.IsDelete == false && s.TaskNo == carTaskNext.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();
                        carTaskNext = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.Status == TaskStatusEnum.Wait).OrderBy(m => m.CreateTime).First();
                    }
                    else
                    {
                        // 获取任务信息
                        modTask = _db.Queryable<WcsTask>().Where(s => s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar).OrderBy(m => m.Levels).OrderBy(m => m.CreateTime).First();
                        if (modTask == null)
                        {
                            return;
                        }
                        carTaskNext = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.Status == TaskStatusEnum.Wait).OrderBy(m => m.CreateTime).First();
                    }
                    //return;
                    if (modTask == null || carTask2 == null)
                    if (modTask == null || carTaskNext == null)
                    {
                        //判断小车是否有空闲时间记录 没有:添加  有:判断当前时间与记录时间是否满足5分钟 满足:添加让小车去充电任务
                        return;
                    }
                    
                    if (carTask2.Status == TaskStatusEnum.Doing)
                    if (carTaskNext.Status == TaskStatusEnum.Doing)
                    {
                        Thread.Sleep(3000);
                        return;
                    }
                    //判断当前任务是否还有前置任务未完成
                    var preStrs = carTask2.PreId.Split(';');
                    var preStrs = carTaskNext.PreId.Split(';');
                    foreach (var preStr in preStrs)
                    {
                        if (string.IsNullOrWhiteSpace(preStr))
@@ -285,27 +299,34 @@
                    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"));
                    }
                    //交互路径
                    var execuPath = carTask2.ExecutionPath.Split(';');
                    var execuPath = carTaskNext.ExecutionPath.Split(';');
                    if (Convert.ToInt32(valuex) != Convert.ToInt32(execuPath[0].Substring(0, 2)) || Convert.ToInt32(valuey) != Convert.ToInt32(execuPath[0].Substring(2, 2)) || Convert.ToInt32(valuez) != Convert.ToInt32(execuPath[0].Substring(4, 2)))
                    {
                        return; //小车位置与路径起始位置不同
                        ////写入小车当前位置
                        //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"));
                    }
                    foreach (var ePath in execuPath)
                    {
                        if (string.IsNullOrWhiteSpace(ePath))
                        {
                            continue;
                        }
                        var epathx = ePath.Substring(0, 2);
                        var epathy = ePath.Substring(2, 2);
                        var epathz = ePath.Substring(4, 2);
                        var epathn = ePath.Substring(6, 1);
                        //写入交互位置
                        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)));
                        listResult.Add(plcConn.SetDBValue(modNodeX.PosType, posX++.ToString(), epathx));
                        listResult.Add(plcConn.SetDBValue(modNodeY.PosType, posY++.ToString(), epathy));
                        listResult.Add(plcConn.SetDBValue(modNodeZ.PosType, posZ++.ToString(), epathz));
                        listResult.Add(plcConn.SetDBValue(modNodeStatus.PosType, posStatus++.ToString(), epathn));
                    }
                    
                    //这里是把后面的坐标全写0(为了防止上次任务坐标没被覆盖)
@@ -322,14 +343,15 @@
                        var result = plcConn.SetDBValue(modStart.PosType, modStart.PlcPos, "1");
                        if (result.IsSucceed)
                        {
                            carTask2.Status = TaskStatusEnum.Doing;
                            carTask2.CarTaskNo = carTaskNo;
                            _db.Updateable(carTask2).ExecuteCommand();
                            carTaskNext.Status = TaskStatusEnum.Doing;
                            carTaskNext.CarTaskNo = carTaskNo;
                            _db.Updateable(carTaskNext).ExecuteCommand();
                            //清除小车空闲时间
                            var taskMonitor = new WcsTaskMonitor()
                            {
                                TaskNo = carTask2.TaskNo,
                                TaskNo = carTaskNext.TaskNo,
                                PlcName = modDevice.Text,
                                InteractiveMsg = $"向穿梭车下发任务{carTask2.TaskNo}"
                                InteractiveMsg = $"向穿梭车下发任务{carTaskNext.TaskNo}"
                            };
                            _db.Insertable(taskMonitor).ExecuteCommand();
                            //下发任务日志