chengsc
2024-10-30 c06382f1b619e1dc7f37be36a0cee126239abdee
Admin.NET/WCS.Application/PLC/PLCService.cs
@@ -1,5 +1,7 @@

using Dm.filter;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Drawing.Charts;
using Elastic.Clients.Elasticsearch.Tasks;
using Furion.Logging;
using IoTClient;
@@ -12,10 +14,13 @@
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 ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);
    public static void OnChangeEvent(object sender, EventArgs e)
@@ -35,8 +40,8 @@
                case PLCTypeEnum.AGV:
                    AGV(mod);                                       // AGV调度
                    break;
                case PLCTypeEnum.RobotPalletizer:
                    RobotPalletizer(mod);                             // 码垛机器人
                case PLCTypeEnum.BoxConveyorLine:
                    BoxConveyorLine(mod);                             // 码垛机器人
                    break;
                case PLCTypeEnum.StackingRobot:
                    PalletMachine(mod);
@@ -57,41 +62,67 @@
    private static void StackingMachine(WcsDeviceDto modDevice)
    {
        var plcConn = modDevice.PLCUtil;
        string ledText = "";
        switch (modDevice.Value.ToString())
        {
            case "820":
                // 跺机空闲,获取出库任务、移库任务
                {
                    // 获取任务信息
                    var modTask = _db.Queryable<WcsTask>().OrderBy(m => m.CreateTime).OrderBy(m => m.Levels, OrderByType.Desc)
                    var modTask = _db.Queryable<WcsTask>().OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime)
                        .First(s => s.Status == TaskStatusEnum.Wait && (s.TaskType == TaskTypeEnum.Out || s.TaskType == TaskTypeEnum.Move)
                        && s.StartRoadway == modDevice.StationNum);
                    if (modTask == null)
                    {
                        break;
                    }
                    // 根据目标地址和巷道获取放货工位对应的排列层
                    PlcTaskInfo taskInfo = PLCCommon.GetCTaskInfo(modTask.EndLocate, ((int)modTask.TaskType).ToString(),
                        modTask.StartRoadway, modTask.EndRoadway);
                    // 目标工位不为null,需先判断放货工位是否空闲
                    if (!string.IsNullOrEmpty(taskInfo.EndStation))
                    //判断出库锁定是否打开
                    if (PLCTaskAction.boOutLock)
                    {
                        // 打开对应的输送线连接
                        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);
                        break;//出库锁定打开则不执行出库任务
                    }
                            var (result, value) = plcConveyorConn.GetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.PlcPos);
                            if (result.IsSucceed)
                    PlcTaskInfo taskInfo = new PlcTaskInfo();
                    if (modTask.TaskType == TaskTypeEnum.Move)
                    {
                        taskInfo = PLCCommon.GetEndPai(modTask.EndRoadway.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))
                        {
                            // 打开对应的输送线连接
                            var plcConveyorConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == taskInfo.Ip);
                            if (plcConveyorConn.Connected)
                            {
                                if (value.ToString() != "720")              // 720:放货空位空闲,可放货
                                // 获取放货工位配置信息
                                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)
                                {
                                    Log.Error(string.Format("任务号:{0}:放货工位占用,稍后执行。", modTask.TaskNo));
                                    if (value.ToString() != "720")              // 720:放货空位空闲,可放货
                                    {
                                        Log.Error(string.Format("任务号:{0}:放货工位占用,稍后执行。", modTask.TaskNo));
                                        break;
                                    }
                                    else if (value.ToString() == "720")
                                    {
                                        // 若空闲提前占用此工位,同工位出入公用口 放开此程序
                                        // var ret = plcConn.SetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.WcsPos, "730");
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
@@ -99,10 +130,6 @@
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
@@ -181,8 +208,15 @@
                        _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                        //下发任务日志
                        HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                        //修改led屏信息
                        //LedDisplay(modDevice.LedIP, "工位:" + modTask.EndLocate, "出库中 " + $"储位地址:{modTask.StartLocate}", "托盘号:" + modTask.PalletNo);
                        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;
@@ -334,8 +368,6 @@
                            HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                        }
                        //修改led屏信息
                        //LedDisplay(modDevice.LedIP, "工位:" + modTask.EndLocate, "出库中 " + $"储位地址:{modTask.StartLocate}", "托盘号:" + modTask.PalletNo);
                    }
                }
                break;
@@ -349,7 +381,7 @@
                    {
                        string tasknoVal = val.ToString();
                        var modTask = _db.Queryable<WcsTask>().First(m => m.Status == TaskStatusEnum.Doing && m.TaskNo == tasknoVal && m.IsDelete == false);
                        if (modTask == null)
                        if (modTask == null)
                        {
                            Log.Error(string.Format("跺机控制字860:未找到对应的任务。"));
                            break;
@@ -400,7 +432,7 @@
                                        }
                                        else
                                        {
                                            Log.Error(string.Format("任务反馈失败:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg));
                                            Log.Error(string.Format("c:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg));
                                        }
                                    }
                                    // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。
@@ -412,8 +444,16 @@
                                    HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                    // led显示内容
                                    LedDisplay(modDevice.LedIP, "工位:" + modTask.StartLocate, "入库完成 " + $"任务完成:{modTask.TaskNo}", "托盘号:" + modTask.PalletNo);
                                    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;
@@ -479,13 +519,6 @@
                                                    //下发任务日志
                                                    HubUtil.PublicTaskMonitor(modcTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                                    // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。
                                                    var taskModel = _db.Queryable<WcsTask>().First(w => w.TaskNo == modTask.TaskNo);
                                                    modDevice.LedIP = _db.Queryable<WcsDevice>().Where(w => w.StationNum == taskModel.StartLocate).Select(s => s.LedIP).First();
                                                    // led显示内容
                                                    LedDisplay(modDevice.LedIP, "工位:" + modDevice.StationNum, "出库中 ", "托盘号:" + modTask.PalletNo);
                                                    break;
                                                }
                                            }
@@ -497,21 +530,22 @@
                            case TaskTypeEnum.Move:       // 移库任务
                                {
                                    var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号");
                                    var result = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo);
                                    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, "30");
                                    result = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "870");
                                    if (!result.IsSucceed)
                                    {
                                        Log.Error($"{modDevice.Text}控制字写入30失败");
                                        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<WcsTaskOutput>());
@@ -533,8 +567,8 @@
                                        {
                                            TaskNo = modTask.TaskNo,
                                            PalletNo = modTask.PalletNo,
                                            TaskType = TaskTypeEnum.Move.ToString(),
                                            TaskStatus = TaskStatusEnum.Complete.ToString()
                                            TaskType = ((int)TaskTypeEnum.Move).ToString(),
                                            TaskStatus = ((int)TaskStatusEnum.Complete).ToString()
                                        };
                                        HttpService httpService = new HttpService();
                                        var modResponseTask = httpService.RequestTask(requestMode).Result;
@@ -542,7 +576,10 @@
                                        {
                                            modcTaskMonitor.InteractiveMsg = "任务完成,返回给WMS任务完成";
                                            //修改储位信息 任务类型 执行状态 起始位置 目标位置
                                        }
                                        else
                                        {
                                            Log.Error(string.Format("任务反馈失败:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg));
                                        }
                                    }
                                    // 插入交互日志
@@ -694,7 +731,7 @@
        }
    }
    /// <summary>
    /// 堆垛机不空跑
    /// 不空跑
    /// </summary>
    /// <param name="modTask">操作完成的任务</param>
    /// <param name="plcConn">plc连接</param>
@@ -860,6 +897,11 @@
        var plcConn = modDevice.PLCUtil;
        // 获取楼层数ceshi
        var louCeng = PLCCommon.GetRoadwayByStationNew(modDevice.StationNum);
        if (louCeng == "")
        {
            return;
        }
        var ledText = "";
        switch (modDevice.Value.ToString())
        {
            case "320":
@@ -867,11 +909,7 @@
                    // 申请巷道
                    string strMsg = "";
                    string taskModel = "";
                    // 判断是否演示模式
                    if (PLCTaskAction.boDemo)
                    {
                        taskModel = "1";// 演示模式
                    }
                    // 获取工位托盘码信息
                    var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码");
                    var (res, palletVal) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modPosPallet.PlcPos);
@@ -879,6 +917,52 @@
                    {
                        break;
                    }
                    var modPosEndLocat = modDevice.listStation.FirstOrDefault(s => s.Text == "目的工位");
                    //判断入库锁定是否打开
                    if (PLCTaskAction.boEnterLock)
                    {
                        var (res350, palletVal350) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, 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(PLCDataTypeEnum.String, 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);
@@ -913,20 +997,48 @@
                            // 通知任务界面任务已存在更新 请更新界面
                            HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                            // led显示内容
                            LedDisplay(modDevice.LedIP, "工位:" + modDevice.StationNum, "申请入库 " + $"目标巷道:{EndLocate}", "托盘号:" + palletVal);
                            try
                            {
                                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);
                            }
                            catch (Exception ex)
                            {
                                Log.Error(ex.Message);
                            }
                        }
                    }
                    else
                    {
                        // 申请巷道失败!LED显示
                        Log.Error(string.Format($"申请巷道失败:{strMsg},读写plc错误"));
                        var (res350, palletVal350) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, 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
                    // 获取工位托盘码信息
@@ -943,6 +1055,11 @@
                    {
                        // 此托盘没有对应的转移任务 led显示
                        break;
                    }
                    //判断入库锁定是否打开
                    if (PLCTaskAction.boEnterLock)
                    {
                        break;//入库锁定打开则不执行入库任务
                    }
                    // 获取巷道口入库工位
@@ -999,8 +1116,6 @@
                            // 通知任务界面任务已存在更新 请更新界面
                            HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                            // led显示内容
                            LedDisplay(modDevice.LedIP, "工位:" + modDevice.StationNum, "入库中 " + $"目标巷道:{endLocatVlue}", "托盘号:" + palletVal);
                        }
                    }
@@ -1065,14 +1180,25 @@
                            // 通知任务界面任务已存在更新 请更新界面
                            HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                            // led显示内容
                            LedDisplay(modDevice.LedIP, "工位:" + modDevice.StationNum, "入库中 " + $"申请储位地址:{strMsg}", "托盘号:" + palletVal);
                            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);
                    }
                }
@@ -1120,6 +1246,7 @@
                            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();
@@ -1216,8 +1343,8 @@
                    #endregion
                }
                break;
            #region 出库交互
            #region 出库交互
            case "420":
                {
                    #region 托盘到达拣选工位/出库口
@@ -1255,10 +1382,18 @@
                        // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。
                        var taskInfo = _db.Queryable<WcsTask>().First(w => w.TaskNo == modInsertTaskMonitor.TaskNo);
                        modDevice.LedIP = _db.Queryable<WcsDevice>().Where(w => w.StationNum == taskInfo.StartLocate).Select(s => s.LedIP).First();
                        modDevice.LedIP = _db.Queryable<WcsDevice>().Where(w => w.StationNum == taskInfo.EndLocate).Select(s => s.LedIP).First();
                        // led显示内容
                        LedDisplay(modDevice.LedIP, "到达工位:" + modDevice.StationNum, "出库完成 " + $"储位地址:{modInsertTaskMonitor.StartLocat}", "托盘号:" + palletVal);
                        // 根据目标工位号获取对应的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();
@@ -1293,6 +1428,7 @@
                        // 改变任务状态
                        modTask.Status = TaskStatusEnum.Complete;
                        modTask.FinishDate = DateTime.Now;
                        modTask.Levels = 999;
                        _db.Updateable(modTask).ExecuteCommand();
                        HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>());
                        // 插入任务明细 
@@ -1301,7 +1437,7 @@
                            TaskNo = modTask.TaskNo,
                            PlcId = modDevice.Id,
                            PlcName = modDevice.Text,
                            InteractiveMsg = $"写入指令450:{modDevice.StationNum}拣选完成,托盘离开工位",
                            InteractiveMsg = $"写入指令450:{modDevice.StationNum}出库完成",
                            PalletNo = palletVal,
                            Status = TaskStatusEnum.Complete,
                            StartLocat = starVal.ToString(),
@@ -1335,13 +1471,116 @@
                        // 通知任务界面任务已存在更新 请更新界面
                        HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                        // led显示内容
                        modDevice.LedIP = _db.Queryable<WcsDevice>().Where(w => w.StationNum == modTask.StartLocate).Select(s => s.LedIP).First();
                        LedDisplay(modDevice.LedIP, "工位:" + modTask.StartLocate, $"拣选完成,托盘离开工位", "托盘号:" + modTask.PalletNo);
                        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申请空托
                {
                    // 防止重复叫空托跺
                    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", "205");
                    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<WcsTask>().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<WcsTaskOutput>());
                            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<WcsTaskMonitorOutput>());
                        }
                    }
                }
                break;
            #endregion
            default: break;
@@ -1387,58 +1626,51 @@
    }
    /// <summary>
    /// 码垛机器人业务处理
    /// 件箱输送和码垛机器人业务处理  配置的是件箱输送
    /// </summary>
    /// <param name="modDevice"></param>
    private static void RobotPalletizer(WcsDeviceDto modDevice)
    private static async void BoxConveyorLine(WcsDeviceDto modDevice)
    {
        var plcConn = modDevice.PLCUtil;
        switch (modDevice.Value.ToString())
        if (modDevice.DbNumber == "DB101")
        {
            case "1":
                // 主扫申请分道 wcs写入2
                {
                    var taskModel = "";
                    // 判断是否演示模式
                    if (PLCTaskAction.boDemo)
            // 主扫交互流程
            switch (modDevice.Value.ToString())
            {
                case "1":
                    // 主扫申请分道 wcs写入2
                    {
                        // 演示模式
                        taskModel = "1";
                        // 直接
                    }
                    else
                    {
                        // 通道号
                        var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "通道号");
                        // 读取plc箱码
                        var modBoxNo = modDevice.listStation.FirstOrDefault(m => m.Text == "箱码");
                        var (res, boxNo) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modBoxNo.PlcPos);
                        if (string.IsNullOrWhiteSpace(boxNo.ToString()))
                        // 判断是否演示模式 true:演示模式   false:生产模式
                        if (PLCTaskAction.boDemo)
                        {
                            // 箱码为null写入剔除通道号
                            var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, "0");
                            // 通道号
                            var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "通道号");
                            // 演示模式直接写入1分道
                            var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, "1");
                            if (ret.IsSucceed)
                            {
                                // 写入流程控制字 2
                                var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                if (retVal.IsSucceed)
                                if (!retVal.IsSucceed)
                                {
                                    Log.Error("箱码为null进行剔除");
                                    Log.Error("演示模式写入分道号失败!");
                                    break;
                                }
                            }
                        }
                        else
                        else
                        {
                            // 根据箱码获取箱内信息
                            string boxNoVal = boxNo.ToString();
                            var boxInfo = _db.Queryable<WcsBoxInfo>().First(w => w.IsDelete == false && w.BoxNo == boxNoVal && string.IsNullOrEmpty(w.PalletNo));
                            if (boxInfo == null)
                            // 通道号
                            var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "通道号");
                            // 读取plc箱码
                            var modBoxNo = modDevice.listStation.FirstOrDefault(m => m.Text == "箱码");
                            var (res, boxNo) = plcConn.GetPlcDBValue(modBoxNo.PosType, modDevice.DbNumber, modBoxNo.PlcPos);
                            if (string.IsNullOrWhiteSpace(boxNo.ToString()))
                            {
                                // 箱信息为null写入剔除通道号
                                // 箱码为null写入剔除通道号
                                var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, "0");
                                if (ret.IsSucceed)
                                {
@@ -1446,59 +1678,380 @@
                                    var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                    if (retVal.IsSucceed)
                                    {
                                        Log.Error("箱码为null或已绑定托盘,进行剔除。");
                                        break;
                                    }
                                }
                            }
                            // 根据箱内品种号获取码躲绑定工位及对应的分道号
                            var checkTaskInfo = _db.Queryable<WcsCheckTask>().First(w => w.SkuNo == boxInfo.SkuNo && w.SkuName == boxInfo.SkuName && w.LotNo == boxInfo.LotNo);
                            if (checkTaskInfo == null)
                            {
                                // 绑定信息为null写入剔除通道号
                                var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, "0");
                                if (ret.IsSucceed)
                                {
                                    // 写入流程控制字 2
                                    var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                    if (retVal.IsSucceed)
                                    {
                                        Log.Error("箱码未绑定分拣任务,进行剔除。");
                                        Log.Error("箱码为null进行剔除");
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                // 与plc交互写入分道号和流程控制字
                                var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, checkTaskInfo.RoboatNo);
                                if (ret.IsSucceed)
                                // 根据箱码获取箱内信息
                                string boxNoVal = boxNo.ToString();
                                var boxInfo = _db.Queryable<WcsBoxInfo>().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)
                                    // 箱信息为null写入剔除通道号
                                    var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, "0");
                                    if (ret.IsSucceed)
                                    {
                                        break;
                                        // 写入流程控制字 2
                                        var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                        if (retVal.IsSucceed)
                                        {
                                            Log.Error("箱码为null或已绑定托盘,进行剔除。");
                                            break;
                                        }
                                    }
                                }
                            }
                                // 根据箱内品种号获取码躲绑定工位及对应的分道号
                                var checkTaskInfo = _db.Queryable<WcsCheckTask>().First(w => w.SkuNo == boxInfo.SkuNo && w.SkuName == boxInfo.SkuName && w.LotNo == boxInfo.LotNo);
                                if (checkTaskInfo == null)
                                {
                                    // 绑定信息为null写入剔除通道号
                                    var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, "0");
                                    if (ret.IsSucceed)
                                    {
                                        // 写入流程控制字 2
                                        var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                        if (retVal.IsSucceed)
                                        {
                                            Log.Error("箱码未绑定分拣任务,进行剔除。");
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    // 与plc交互写入分道号和流程控制字
                                    var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, checkTaskInfo.LineNo);
                                    if (ret.IsSucceed)
                                    {
                                        // 写入流程控制字 2
                                        var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                        if (retVal.IsSucceed)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                break;
            case "230":
                // 注释2
                {
                    break;
                default: break;
            }
        }
        else
        {
            // 插码交互
            switch (modDevice.Value.ToString())
            {
                case "1":
                    // 托盘条码可读
                    {
                        // 获取托盘条码配置
                        var modPalletNo = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘条码");
                        // 读取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;
                        }
                }
                break;
            case "240":
                {
                        // 根据工位号将托盘号保存在分道表
                        var checkTaskMedel = _db.Queryable<WcsCheckTask>().First(m => m.Port == modDevice.StationNum && m.IsDelete == false);
                        if (checkTaskMedel == null)
                        {
                            Log.Error(string.Format("根据码垛工位{0},获取分道失败!", modDevice.StationNum));
                            break;
                        }
                        checkTaskMedel.PalletNo = palletNo;
                        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 == "插码结果");
                        // 判断是否演示模式 true:演示模式   false:生产模式
                        if (PLCTaskAction.boDemo)
                        {
                            // 演示模式直接写入插码结果 1:成功
                            var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "1");
                            break;
                        }
                        else
                        {
                            // 获取箱条码
                            // 获取箱条码配置
                            var modBoxNo = modDevice.listStation.FirstOrDefault(m => m.Text == "箱条码");
                            var (res, boxVal) = plcConn.GetPlcDBValue(modBoxNo.PosType, modDevice.DbNumber, modBoxNo.PlcPos);
                            string boxNo = boxVal.ToString();
                            if (string.IsNullOrEmpty(boxNo))
                            {
                                Log.Error($"码垛工位{modDevice.StationNum},箱码为null插码失败!请人工强制结批。" );
                                // 写入插入结果 2:插码失败
                                var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2");
                                break;
                            }
                            // 验证箱码表是否存在此箱码
                            var boxInfo = _db.Queryable<WcsBoxInfo>().Where(w => w.IsDelete == false && w.BoxNo == boxNo).ToList();
                            if (boxInfo.Count == 0)
                            {
                                Log.Error($"码垛工位{modDevice.StationNum},箱码{boxNo}不存在!请人工强制结批。");
                                // 写入插入结果 2:插码失败
                                var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2");
                                break;
                            }
                            // 获取当前分道托盘号
                            var checkTaskMedel = _db.Queryable<WcsCheckTask>().First(m => m.Port == modDevice.StationNum && m.IsDelete == false);
                            if (checkTaskMedel == null)
                            {
                                Log.Error(string.Format("根据码垛工位{0},获取分道失败!", modDevice.StationNum));
                                break;
                            }
                            string palletNo = checkTaskMedel.PalletNo;
                            if (string.IsNullOrEmpty(palletNo))
                            {
                                Log.Error(string.Format("获取码垛工位{0}上的托盘号失败!",modDevice.StationNum));
                                break;
                            }
                            // 修改插码表
                            foreach (WcsBoxInfo item in boxInfo)
                            {
                                item.PalletNo = palletNo;
                                item.UpdateTime = DateTime.Now;
                            }
                }
                break;
            default: break;
        }
                            var rowCount = _db.Updateable(boxInfo).ExecuteCommand();
                            if (rowCount > 0)
                            {
                                // 插码成功
                                var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "1");
                                //是否结批箱
                                if (boxInfo[0].EndLotFlag == "1" && retVal.IsSucceed)
                                {
                                    // 触发结批 解绑分道
                                    AutoEndLot(boxInfo[0].LotNo, plcConn, "0");
                                }
                            }
                            else
                            {
                                // 插码失败
                                Log.Error($"箱码{boxNo};码垛工位{modDevice.StationNum},插码失败,请强制结批");
                                var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2");
                                if (retVal.IsSucceed)
                                {
                                    // 触发结批 不解绑分道
                                    AutoEndLot(boxInfo[0].LotNo, plcConn, "1");
                                }
                            }
                        }
                    }
                    break;
                case "40":
                    // 请求组托,申请入库
                     {
                        // 根据工位号,获取托盘号
                        var checkTaskMedel = _db.Queryable<WcsCheckTask>().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(posModel.PosType, numModel.DbNumber, posModel.PlcPos, "234");
                            if (retVal.IsSucceed)
                            {
                                // 写入组托回复流程字
                                retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "50");
                            }
                            break;
                        }
                        // 码垛工位托盘号
                        string palletNo = checkTaskMedel.PalletNo;
                        // 是否演示模式
                        if (PLCTaskAction.boDemo)
                        {
                            // 直接箱wms申请巷道
                            var http = new HttpService();
                            string TaskNo = "", EndLocate = "";
                            string strMsg = http.RequestRoadWay(palletNo, modDevice.StationNum, "1", "2", ref EndLocate, ref TaskNo);
                            if (strMsg.Contains("-1"))
                            {
                                Log.Error(string.Format("申请巷道失败,码垛工位{0};原因{1}", modDevice.StationNum, strMsg));
                                break;
                            }
                            else
                            {
                                // 获取入库任务信息
                                var taskModel = _db.Queryable<WcsTask>().First(m => m.TaskNo == TaskNo && m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing));
                                if (taskModel != null)
                                {
                                    // 获取入库取货工位
                                    string endLocatVlue = PLCCommon.RoadwayToStationNum(taskModel.EndRoadway, "2");
                                    var listResult = new List<Result>();
                                    // 写入托盘输送线码垛工位 目的工位、任务号,写入交互流程组托成功 执行入库{若需要可以写入任务号等等其他信息}
                                    listResult.Add(plcConn.SetPlcDBValue(posModel.PosType, numModel.DbNumber, posModel.PlcPos, endLocatVlue));    // 目标工位
                                    var modPosTask = PLCTaskAction.plcPositions.First(s => s.DeviceId == numModel.Id && s.Text == "任务号" && s.IsDelete == false);
                                    listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, numModel.DbNumber, modPosTask.PlcPos, TaskNo));
                                    var modPosTaskType = PLCTaskAction.plcPositions.First(s => s.DeviceId == numModel.Id && s.Text == "任务类型" && s.IsDelete == false);
                                    var taskTypeStr = (int)taskModel.TaskType;
                                    listResult.Add(plcConn.SetPlcDBValue(modPosTaskType.PosType, numModel.DbNumber, modPosTaskType.PlcPos, taskTypeStr.ToString()));
                                    if (listResult.All(s => s.IsSucceed))
                                    {
                                        // 写入组托回复流程字
                                        var retVal1 = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "50");
                                        if (retVal1.IsSucceed)
                                        {
                                            // 将入库任务由正在执行改为正在执行
                                            taskModel.Status = TaskStatusEnum.Doing;
                                            _db.Updateable(taskModel).ExecuteCommand();
                                            // 插入任务明细
                                            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<WcsTaskMonitorOutput>());
                                        }
                                    }
                                    //// 写入托盘输送线码垛工位 目的工位,写入交互流程组托成功 执行入库{若需要可以写入任务号等等其他信息}
                                    //var retVal = plcConn.SetPlcDBValue(posModel.PosType, numModel.DbNumber, posModel.PlcPos, endLocatVlue);
                                    //if (retVal.IsSucceed)
                                    //{
                                    //    // 写入码垛交互-组托回复流程字
                                    //    retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "50");
                                    //    // 将入库任务由正在执行改为正在执行
                                    //    taskModel.Status = TaskStatusEnum.Doing;
                                    //    _db.Updateable(taskModel).ExecuteCommand();
                                    //}
                                }
                            }
                        }
                        else
                        {
                            // 根据托盘号,将组托信息插入boxinfolog表 并删除boxinfo表数据
                            var boxInfoList = await _db.Queryable<WcsBoxInfo>().Where(w => w.IsDelete == false && w.PalletNo == palletNo).ToListAsync();
                            if (boxInfoList.Count <= 0)
                            {
                                Log.Error(string.Format("申请巷道失败,码垛工位{0},箱码信息不存在", modDevice.StationNum));
                                // 写入交互工位目标地址
                                var retVal = plcConn.SetPlcDBValue(posModel.PosType, numModel.DbNumber, posModel.PlcPos, "234");
                                if (retVal.IsSucceed)
                                {
                                    // 写入组托回复流程字
                                    retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "50");
                                }
                                break;
                            }
                            string sqlStr = $"insert into WCSBoxInfoLog select * from WCSBoxInfo where IsDelete=0 and PalletNo='{palletNo}'";
                            int insertCount = _db.Ado.ExecuteCommand(sqlStr);
                            if (insertCount > 0)
                            {
                                // 组托成功后将信息存到log表
                                string sqlStr2 = $"delete from WCSBoxInfoLog where  IsDelete=0 and PalletNo='{palletNo}'";
                                _db.Ado.ExecuteCommand(sqlStr2);
                            }
                            // 向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", "2", ref EndLocate, ref TaskNo);
                            if (strMsg.Contains("-1"))
                            {
                                Log.Error(string.Format("申请巷道失败,码垛工位{0};原因{1}", modDevice.StationNum, strMsg));
                                break;
                            }
                            else
                            {
                                // 获取入库任务信息
                                var taskModel = _db.Queryable<WcsTask>().First(m => m.TaskNo == TaskNo && m.IsDelete == false && m.Status == TaskStatusEnum.Wait);
                                if (taskModel != null)
                                {
                                    // 获取入库取货工位
                                    string endLocatVlue = PLCCommon.RoadwayToStationNum(taskModel.EndRoadway, "2");
                                    var listResult = new List<Result>();
                                    // 写入托盘输送线码垛工位 目的工位、任务号,写入交互流程组托成功 执行入库{若需要可以写入任务号等等其他信息}
                                    listResult.Add(plcConn.SetPlcDBValue(posModel.PosType, numModel.DbNumber, posModel.PlcPos, endLocatVlue));    // 目标工位
                                    var modPosTask = PLCTaskAction.plcPositions.First(s => s.DeviceId == numModel.Id && s.Text == "任务号" && s.IsDelete == false);
                                    listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, numModel.DbNumber, modPosTask.PlcPos, TaskNo));
                                    var modPosTaskType = PLCTaskAction.plcPositions.First(s => s.DeviceId == numModel.Id && s.Text == "任务类型" && s.IsDelete == false);
                                    var taskTypeStr = (int)taskModel.TaskType;
                                    listResult.Add(plcConn.SetPlcDBValue(modPosTaskType.PosType, numModel.DbNumber, modPosTaskType.PlcPos, taskTypeStr.ToString()));
                                    if (listResult.All(s => s.IsSucceed))
                                    {
                                        // 写入组托回复流程字
                                        var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "50");
                                        if (retVal.IsSucceed)
                                        {
                                            // 将入库任务由正在执行改为正在执行
                                            taskModel.Status = TaskStatusEnum.Doing;
                                            _db.Updateable(taskModel).ExecuteCommand();
                                            // 插入任务明细
                                            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<WcsTaskMonitorOutput>());
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                default:break;
            }
        }
    }
    /// <summary>
@@ -1534,7 +2087,78 @@
            LedDll Led = new LedDll();
            Led.LEDstr(ip, top, content, foot);
        }
        catch { }
        catch (Exception ex)
        {
            Log.Error(ex.Message);
        }
    }
    /// <summary>
    /// LED信息展示
    /// </summary>
    /// <param name="ip"></param>
    /// <param name="text"></param>
    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);
        }
    }
    /// <summary>
    /// 自动结批
    /// </summary>
    /// <param name="lotNo">批次号</param>
    /// <param name="plcConn">Plc连接</param>
    /// <param name="status">是否解绑分道 0:解绑  1:绑定</param>
    private static void AutoEndLot(string lotNo,PLCUtil plcConn,string status)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(lotNo))
            {
                Console.WriteLine("批次号为nul");
            }
            var checkTaskList = _db.Queryable<WcsCheckTask>().Where(w => w.LotNo == lotNo && w.Status == "1").ToList();
            if (checkTaskList.Count <= 0)
            {
                Console.WriteLine("未找到分道绑定信息");
            }
            foreach (var item in checkTaskList)
            {
                #region#给PLC写入结批批次号
                var ret = plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PosLot, "1");
                if (ret.IsSucceed)
                {
                    //写入流程字成功后更新分拣任务    liudl 最后一托盘申请完入库才可清空
                    //item.OrderNo = "";
                    //item.TaskNo = "";
                    //item.LotNo = "";
                    //item.SkuNo = "";
                    //item.SkuName = "";
                    //item.BoxType = "";
                    //item.Qty = 0;
                    //item.PZNo = "";
                    item.Status = status;      // 绑定分道 0:解绑  1:绑定
                    //更新分拣任务
                    _db.Updateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                }
                #endregion
            }
        }
        catch (Exception ex)
        {
            Log.Error(ex.Message);
            throw;
        }
    }
    private static void Test(WcsDeviceDto modDevice)