liudl
2025-02-16 c58ba7324d1ca0eb0941ac2762334c19d7d92e3f
Admin.NET/WCS.Application/PLC/PLCService.cs
@@ -2,10 +2,13 @@
using Dm.filter;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Drawing.Charts;
using Elastic.Clients.Elasticsearch.Snapshot;
using Elastic.Clients.Elasticsearch.Tasks;
using Flurl.Util;
using Furion.Logging;
using IoTClient;
using Microsoft.AspNetCore.SignalR;
using NewLife.Reflection;
using Qiniu.Storage;
using RazorEngine.Compilation.ImpromptuInterface.Dynamic;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.ExtendedSDK.Global.Models;
@@ -13,6 +16,7 @@
using System.Data;
using System.Reflection.Emit;
using WCS.Application.Entity;
using WCS.Application.Service.WcsDevice.Dto;
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;
@@ -45,7 +49,7 @@
                    BoxConveyorLine(mod);                             // 码垛机器人
                    break;
                case PLCTypeEnum.StackingRobot:
                    PalletMachine(mod);
                    StackingRobot(mod);                           //拆垛机器人
                    break;
                default:
                    break;
@@ -284,22 +288,23 @@
                                        modcTaskMonitor.InteractiveMsg = string.Format("工位:{0},写入取货完成:640", startStationVal);
                                        // 插入交互日志
                                        _db.Insertable(modcTaskMonitor).ExecuteCommand();
                                    }
                                    var retc = plcConveyorConn.SetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.WcsPos, "640");
                                        var retc = plcConveyorConn.SetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.WcsPos, "640");
                                    if (!retc.IsSucceed)
                                    {
                                        modcTaskMonitor.InteractiveMsg = string.Format("工位:{0},写入取货完成640失败", startStationVal);
                                        // 插入交互日志
                                        _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                                        if (!retc.IsSucceed)
                                        {
                                            modcTaskMonitor.InteractiveMsg = string.Format("工位:{0},写入取货完成640失败", startStationVal);
                                            // 插入交互日志
                                            _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                                            //下发任务日志
                                            HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                            break;
                                        }
                                        //下发任务日志
                                        HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                        break;
                                    }
                                    //下发任务日志
                                    HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                }
                                // 读取wcs控制字
@@ -612,7 +617,7 @@
                    var modTask = _db.Queryable<WcsTask>().First(s => s.TaskNo == taskNo && s.Status == TaskStatusEnum.Doing);
                    if (modTask == null)
                    {
                        Log.Error($"【堆垛机】当前任务号不存在对应的任务,任务号:{modTask.TaskNo}");
                        Log.Error($"【堆垛机】当前任务号不存在对应的任务,任务号:{TaskNo}");
                        break;
                    }
                    var res = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "844");
@@ -647,7 +652,7 @@
                {
                    //满放货异常
                    var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号");
                    var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "托盘号");
                    var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "托盘码");
                    var (result, TaskNo) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos);
                    if (!result.IsSucceed)
                        break;
@@ -655,7 +660,7 @@
                    var modTask = _db.Queryable<WcsTask>().First(s => s.TaskNo == taskNo && s.Status == TaskStatusEnum.Doing);
                    if (modTask == null)
                    {
                        Log.Error($"【堆垛机】当前任务号不存在对应的任务,任务号:{modTask.TaskNo}");
                        Log.Error($"【堆垛机】当前任务号不存在对应的任务,任务号:{TaskNo}");
                        break;
                    }
                    modTask.Status = TaskStatusEnum.Exception;
@@ -684,17 +689,38 @@
                        string storey = int.Parse(endLocat.Substring(4, 2)).ToString();
                        // 给PLC写入任务数据
                        //var listResult = new List<Result>();
                        //// 任务号托盘号
                        //listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo));
                        //listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo));
                        //// 起始排列层
                        //listResult.Add(plcConn.SetPlcDBValue(modPosRow.PosType, modDevice.DbNumber, modPosRow.PlcPos, "2"));
                        //listResult.Add(plcConn.SetPlcDBValue(modPosColumn.PosType, modDevice.DbNumber, modPosColumn.PlcPos, "100"));
                        //listResult.Add(plcConn.SetPlcDBValue(modPosStorey.PosType, modDevice.DbNumber, modPosStorey.PlcPos, "1"));
                        //listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType, modDevice.DbNumber, modPosEndRow.PlcPos, row));
                        //listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType, modDevice.DbNumber, modPosEndColumn.PlcPos, column));
                        //listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType, modDevice.DbNumber, modPosEndStorey.PlcPos, storey));
                        PlcTaskInfo taskInfo = new PlcTaskInfo();
                        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));
                        // 给PLC写入任务数据
                        var listResult = new List<Result>();
                        // 任务号托盘号
                        modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号");
                        listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo));
                        modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "托盘码");
                        listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo));
                        // 起始排列层
                        listResult.Add(plcConn.SetPlcDBValue(modPosRow.PosType, modDevice.DbNumber, modPosRow.PlcPos, "2"));
                        listResult.Add(plcConn.SetPlcDBValue(modPosColumn.PosType, modDevice.DbNumber, modPosColumn.PlcPos, "100"));
                        listResult.Add(plcConn.SetPlcDBValue(modPosStorey.PosType, modDevice.DbNumber, modPosStorey.PlcPos, "1"));
                        listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType, modDevice.DbNumber, modPosEndRow.PlcPos, row));
                        listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType, modDevice.DbNumber, modPosEndColumn.PlcPos, column));
                        listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType, modDevice.DbNumber, modPosEndStorey.PlcPos, storey));
                        // 目标放货工位(固定排列层)
                         modPosEndRow = modDevice.listStation.FirstOrDefault(s => s.Text == "放货排");
                        listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType, modDevice.DbNumber, modPosEndRow.PlcPos, taskInfo.EndPai));
                        modPosEndColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "放货列");
                        listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType, modDevice.DbNumber, modPosEndColumn.PlcPos, taskInfo.EndLie));
                        modPosEndStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "放货层");
                        listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType, modDevice.DbNumber, modPosEndStorey.PlcPos, taskInfo.EndCeng));
                        // 是否写入成功
                        if (listResult.All(s => s.IsSucceed))
                        {
@@ -966,6 +992,35 @@
                    var http = new HttpService();
                    string TaskNo = "", EndLocate = "";
                    //根据工位判断是否为叠托机工位申请空托盘跺入库,是:向WMS申请空托盘跺组托
                    string groupMsg = "";
                    if (modDevice.StationNum == "27")
                    {
                        var Qty = plcConn.GetPlcDBValue(PLCDataTypeEnum.Int,"DB135.0").ToString();//获取叠托机叠托数量
                        groupMsg = http.BindPlnInHouseWcs(Qty, palletVal);
                        if (!groupMsg.Contains("-1"))
                        {
                            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;
                    }
                    string IsBale = "0";
                    strMsg = http.RequestRoadWay(palletVal, modDevice.StationNum, taskModel, louCeng, ref EndLocate, ref TaskNo);
                    if (!strMsg.Contains("-1"))
@@ -976,7 +1031,6 @@
                        // 写入330
                        var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "330");
                        if (ret.IsSucceed)
                        {
                            // 插入任务明细 
@@ -991,9 +1045,21 @@
                                StartLocat = modDevice.StationNum,
                                EndLocat = EndLocate,
                            };
                            // 插入交互日志
                            _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                            //判断是否裹包
                            var gbPos = modDevice.listStation.FirstOrDefault(s => s.Text == "Element_1");
                            strMsg = new HttpService().RequestPackWcs(palletVal);
                            if (strMsg == "1")
                            {
                                //写入裹包指令
                                ret = plcConn.SetPlcDBValue(gbPos.PosType, modDevice.DbNumber, gbPos.PlcPos, "2");
                            }
                            else
                            {
                                ret = plcConn.SetPlcDBValue(gbPos.PosType, modDevice.DbNumber, gbPos.PlcPos, "1");
                            }
                            // 通知任务界面任务已存在更新 请更新界面
                            HubUtil.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
@@ -1152,12 +1218,11 @@
                    // 向WMS申请储位信息
                    strMsg = http.RequestLocate(palletVal, modDevice.StationNum, taskModel, roadway, ref TaskNo);
                    // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。
                    var taskInfo = _db.Queryable<WcsTask>().First(w => w.TaskNo == TaskNo);
                    modDevice.LedIP = _db.Queryable<WcsDevice>().Where(w => w.StationNum == taskInfo.StartLocate).Select(s => s.LedIP).First();
                    if (!strMsg.Contains("-1"))
                    {
                        // 根据任务号获取起始工位地址,根据起始工位地址获取LEDIP 推送到LED屏幕。
                        var taskInfo = _db.Queryable<WcsTask>().First(w => w.TaskNo == TaskNo);
                        modDevice.LedIP = _db.Queryable<WcsDevice>().Where(w => w.StationNum == taskInfo.StartLocate).Select(s => s.LedIP).First();
                        // 写入流程字 630
                        var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "630");
@@ -1449,7 +1514,7 @@
                            // 反馈WMS
                            var requestMode = new TaskRequestWMS()
                            {
                                TaskNo = modTask.TaskNo,
                                TaskNo = modTask.TaskNo + modTask.EndLocate ,
                                PalletNo = modTask.PalletNo,
                                TaskType = ((int)TaskTypeEnum.Out).ToString(),
                                TaskStatus = ((int)TaskStatusEnum.Complete).ToString()
@@ -1558,7 +1623,7 @@
                                // 反馈WMS
                                var requestMode = new TaskRequestWMS()
                                {
                                    TaskNo = modTask.TaskNo,
                                    TaskNo = modTask.TaskNo + modTask.EndLocate ,
                                    PalletNo = modTask.PalletNo,
                                    TaskType = ((int)TaskTypeEnum.Out).ToString(),
                                    TaskStatus = ((int)TaskStatusEnum.Complete).ToString()
@@ -1580,6 +1645,123 @@
                            HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                        }
                    }                    
                }
                break;
            #endregion
            case "10":
                {
                    #region 缠膜完成
                    // 获取工位托盘码信息
                    var strMsg = "";
                    var http = new HttpService();
                    var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码");
                    var (res, palletVal) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modPosPallet.PlcPos);
                    //向WMS反馈托盘缠膜完成
                    strMsg = http.RequestPackedWcs(palletVal);
                    if (!strMsg.Contains("-1"))
                    {
                        var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "11");//收到缠膜完成11
                        if (ret.IsSucceed)
                        {
                            // 插入任务明细
                            var modInsertTaskMonitor = new WcsTaskMonitor()
                            {
                                PlcId = modDevice.Id,
                                PlcName = modDevice.Text,
                                InteractiveMsg = $"写入指令11:{modDevice.StationNum}工位缠膜完成",
                                PalletNo = palletVal,
                                Status = TaskStatusEnum.Complete,
                                StartLocat = modDevice.StationNum
                            };
                            // 插入交互日志
                            _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                        }
                    }
                    else
                    {
                    }
                    #endregion
                }
                break;
            case "20":
                {
                    #region 是否拆膜    21:否 22:是
                    // 获取工位托盘码信息
                    var strMsg = "";
                    var http = new HttpService();
                    var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码");
                    var (res, palletVal) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modPosPallet.PlcPos);
                    // 获取托盘任务号
                    var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号");
                    var (res1, val) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos);
                    // 根据任务号获取任务信息,目的工位是009的再向WMS发出拆膜申请
                    if (res1.IsSucceed)
                    {
                        string tasknoVal = val.ToString();
                        var modTask = _db.Queryable<WcsTask>().First(m => m.Status == TaskStatusEnum.Doing && m.TaskNo == tasknoVal && m.EndLocate == "009" && m.IsDelete == false);
                        if (modTask == null)
                        {
                            break;
                        }
                    }
                    strMsg = http.RequestUnPackWcs(palletVal);
                    if (!strMsg.Contains("-1"))
                    {
                        var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "22");
                        if (ret.IsSucceed)
                        {
                            // 插入任务明细
                            var modInsertTaskMonitor = new WcsTaskMonitor()
                            {
                                PlcId = modDevice.Id,
                                PlcName = modDevice.Text,
                                InteractiveMsg = $"写入指令22:{modDevice.StationNum}工位需要拆膜",
                                PalletNo = palletVal,
                                Status = TaskStatusEnum.Complete,
                                StartLocat = modDevice.StationNum
                            };
                            // 插入交互日志
                            _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                        }
                    }
                    else
                    {
                        var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "21");
                        if (ret.IsSucceed)
                        {
                            // 插入任务明细
                            var modInsertTaskMonitor = new WcsTaskMonitor()
                            {
                                PlcId = modDevice.Id,
                                PlcName = modDevice.Text,
                                InteractiveMsg = $"写入指令21:{modDevice.StationNum}工位不需要拆膜",
                                PalletNo = palletVal,
                                Status = TaskStatusEnum.Complete,
                                StartLocat = modDevice.StationNum
                            };
                            // 插入交互日志
                            _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                        }
                    }
                    #endregion
                }
                break;
            #region 小车可放信号
            case "150":
                { // 获取工位任务号信息
                    var strMsg = "";
                    var http = new HttpService();
                    var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码");
                    var (res, palletVal) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modPosPallet.PlcPos);
                    // 获取托盘任务号
                    var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号");
                    var (res1, val) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos);
                }
                break;
            #endregion
@@ -1634,7 +1816,7 @@
    {
        var plcConn = modDevice.PLCUtil;
        if (modDevice.DbNumber == "DB101")
        if (modDevice.DbNumber == "DB101")//&& modDevice.DbNumber == "DB102"&& (modDevice.DbNumber == "DB102"||modDevice.PlcIdIP == "10.18.51.110")
        {
            // 主扫交互流程
            switch (modDevice.Value.ToString())
@@ -1648,10 +1830,13 @@
                            // 通道号
                            var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "通道号");
                            // 演示模式直接写入1分道
                            var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, "1");
                            // 演示模式直接写入分道号
                            Random random = new Random();
                            int ranNumber = random.Next(2) == 0 ? 1 : 5;
                            var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, ranNumber.ToString());
                            if (ret.IsSucceed)
                            {
                                Log.Information(string.Format("分道成功,道号是:" + ranNumber));
                                // 写入流程控制字 2
                                var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                if (!retVal.IsSucceed)
@@ -1704,11 +1889,12 @@
                                        }
                                    }
                                }
                                // 根据箱内品种号获取码躲绑定工位及对应的分道号
                                var checkTaskInfo = _db.Queryable<WcsCheckTask>().First(w => w.SkuNo == boxInfo.SkuNo && w.SkuName == boxInfo.SkuName && w.LotNo == boxInfo.LotNo && w.Status == "1");
                                if (checkTaskInfo == null)
                                // 验证是否零箱
                                if (boxInfo.BitBoxMark == "1")
                                {
                                    // 绑定信息为null写入剔除通道号
                                    // 是零箱直接剔除,进行人工组托
                                    var ret = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, "0");
                                    if (ret.IsSucceed)
                                    {
@@ -1716,8 +1902,225 @@
                                        var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                        if (retVal.IsSucceed)
                                        {
                                            Log.Error("箱码未绑定分拣任务,进行剔除。");
                                            Log.Error("零箱,进行剔除。");
                                            break;
                                        }
                                    }
                                    break;
                                }
                                // 根据箱内品种号获取码躲绑定工位及对应的分道号
                                var checkTaskInfo = _db.Queryable<WcsCheckTask>().First(w => w.SkuNo == boxInfo.SkuNo && w.SkuName == boxInfo.SkuName && w.LotNo == boxInfo.LotNo && w.Status == "1");
                                if (checkTaskInfo == null)
                                {
                                    // 判断是否关联单据 wcsordertask
                                    var orderModel = _db.Queryable<WcsOderTask>()
                                        .First(m => m.SkuNo == boxInfo.SkuNo && m.Status== TaskStatusEnum.Wait && m.LotNo == boxInfo.LotNo && m.IsDelete == false);
                                    if (orderModel != null)
                                    {
                                        // 根据boxinfo表产线字段自动绑定分道(1线产品只能绑定到8道)
                                        if (boxInfo.LineNo != "1")
                                        {// 绑定到除8道外其他道
                                            // 获取未绑定道
                                            var lineNoModels = _db.Queryable<WcsCheckTask>()
                                                .Where(m => m.Status == "0" && m.LineNo != "8" && m.RoboatType == PLCTypeEnum.RobotPalletizer).ToList();
                                            if (lineNoModels.Count > 0)
                                            {
                                                // 获取当前物料品种号
                                                var skuInfo = await _db.Queryable<WcsMateialPzInfo>().Where(w => w.SkuNo == boxInfo.SkuNo).FirstAsync();
                                                if (skuInfo == 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;
                                                        }
                                                    }
                                                    break;
                                                }
                                                foreach (var lineNoModel in lineNoModels)
                                                {
                                                    // 读取设备验证是否绑定分道
                                                    var (respg, pzNo) = plcConn.GetPlcDBValue(lineNoModel.PosType, lineNoModel.DbNumber, lineNoModel.PlcPos);
                                                    if (respg.IsSucceed)
                                                    {
                                                        if (pzNo != 0)
                                                        {
                                                            // plc此分道未解绑
                                                            break;
                                                        }
                                                        else
                                                        {
                                                            // 自动绑定分道
                                                            lineNoModel.OrderNo = orderModel.OrderNo;
                                                            lineNoModel.LotNo = boxInfo.LotNo;
                                                            lineNoModel.SkuNo = boxInfo.SkuNo;
                                                            lineNoModel.SkuName = boxInfo.SkuName;
                                                            lineNoModel.Qty = orderModel.Qty;
                                                            lineNoModel.Status = "1";//已绑定
                                                            lineNoModel.PZNo = skuInfo.PZNo;
                                                            // 给PLC写入品规
                                                            var ret = plcConn.SetPlcDBValue(lineNoModel.PosType, lineNoModel.DbNumber, lineNoModel.PlcPos, skuInfo.PZNo);
                                                            if (ret.IsSucceed)
                                                            {
                                                                //写入流程字成功后更新分拣任务
                                                                _db.Updateable(lineNoModel).ExecuteCommand();
                                                                //更新WcsOderTask表
                                                                orderModel.Status = TaskStatusEnum.Doing;
                                                                _db.Updateable(orderModel).ExecuteCommand();
                                                                // Liudl 通知前端更新分拣任务
                                                                //下发分拣任务
                                                                HubUtil.PublicCheckTask(lineNoModel.Adapt<WcsDeviceTaskOrderDto>());
                                                                break;
                                                            }
                                                            else
                                                            {
                                                                throw Oops.Bah("与PCL交互失败,绑定失败!");
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        // 读取plc失败
                                                        break;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                // 若没有空闲道,进行剔除处理。防止堵塞件箱线
                                                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;
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                        else
                                        {// 绑定到8道
                                         // 获取未绑定道
                                            var lineNo8Model = _db.Queryable<WcsCheckTask>()
                                                .First(m => m.Status == "0" && m.LineNo == "8" && m.RoboatType == PLCTypeEnum.RobotPalletizer);
                                            if (lineNo8Model != null)
                                            {
                                                // 获取当前物料品种号
                                                var skuInfo = await _db.Queryable<WcsMateialPzInfo>().Where(w => w.SkuNo == boxInfo.SkuNo).FirstAsync();
                                                if (skuInfo == 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;
                                                        }
                                                    }
                                                    break;
                                                }
                                                // 读取设备验证是否绑定分道
                                                var (respg, pzNo) = plcConn.GetPlcDBValue(lineNo8Model.PosType, lineNo8Model.DbNumber, lineNo8Model.PlcPos);
                                                if (respg.IsSucceed)
                                                {
                                                    if (pzNo != 0)
                                                    {
                                                        // plc此分道未解绑
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        // 自动绑定分道
                                                        lineNo8Model.OrderNo = orderModel.OrderNo;
                                                        lineNo8Model.LotNo = boxInfo.LotNo;
                                                        lineNo8Model.SkuNo = boxInfo.SkuNo;
                                                        lineNo8Model.SkuName = boxInfo.SkuName;
                                                        lineNo8Model.Qty = orderModel.Qty;
                                                        lineNo8Model.Status = "1";//已绑定
                                                        lineNo8Model.PZNo = skuInfo.PZNo;
                                                        // 给PLC写入品规
                                                        var ret = plcConn.SetPlcDBValue(lineNo8Model.PosType, lineNo8Model.DbNumber, lineNo8Model.PlcPos, skuInfo.PZNo);
                                                        if (ret.IsSucceed)
                                                        {
                                                            //写入流程字成功后更新分拣任务
                                                            _db.Updateable(lineNo8Model).ExecuteCommand();
                                                            //更新WcsOderTask表
                                                            orderModel.Status = TaskStatusEnum.Doing;
                                                            _db.Updateable(orderModel).ExecuteCommand();
                                                            // Liudl 通知前端更新分拣任务
                                                            //下发分拣任务
                                                            HubUtil.PublicCheckTask(lineNo8Model.Adapt<WcsDeviceTaskOrderDto>());
                                                            break;
                                                        }
                                                        else
                                                        {
                                                            throw Oops.Bah("与PCL交互失败,绑定失败!");
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    // 读取plc失败
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                // 没有空闲道,进行剔除处理。防止堵塞件箱线
                                                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;
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // 不关联单据直接进行剔除处理
                                        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;
                                            }
                                        }
                                    }
                                }
@@ -1731,6 +2134,18 @@
                                        var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                        if (retVal.IsSucceed)
                                        {
                                            {  // liudl 此段程序不会执行 确认后直接删除
                                                if (modDevice.DbNumber == "DB102")//1L拆跺分拣后需要回传箱码
                                                {
                                                    var http = new HttpService();
                                                    IsBaleModel2 ret1 = http.RequestBoxno(boxNoVal);
                                                    if (ret1.Success == -1)
                                                    {
                                                        Log.Error("箱码分拣回传失败,需要手动拣货。失败箱码:"+boxNoVal);
                                                        break;
                                                    }
                                                }
                                            }
                                            break;
                                        }
                                    }
@@ -1741,7 +2156,7 @@
                    break;
                default: break;
            }
        }
        }
        else  
        {
            // 插码交互
@@ -1839,6 +2254,7 @@
                            }
                            var rowCount = _db.Updateable(boxInfo).ExecuteCommand();
                            Log.Information(string.Format("插码成功,箱码是:"+ boxNo, modDevice.StationNum));
                            if (rowCount > 0)
                            {
                                // 插码成功
@@ -1847,8 +2263,8 @@
                                //是否结批箱 
                                if (boxInfo[0].EndLotFlag == "1" && retVal.IsSucceed) 
                                {
                                    // 触发结批 解绑分道
                                    AutoEndLot(boxInfo[0].LotNo, plcConn, "0");
                                    // 触发结批 分道变为结批中
                                    AutoEndLot(boxInfo[0].LotNo, plcConn, "2");
                                }
                            }
                            else 
@@ -1983,14 +2399,15 @@
                                    }
                                    break;
                                }
                                // 组托成功后将信息存到log表
                                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}'";
                                    string sqlStr2 = $"delete from WCSBoxInfo where  IsDelete=0 and PalletNo='{palletNo}'";
                                    _db.Ado.ExecuteCommand(sqlStr2);
                                }
                                // 向WMS申请巷道
                                var http = new HttpService();
                                string TaskNo = "", EndLocate = "";
@@ -2003,6 +2420,29 @@
                                }
                                else
                                {
                                    //判断是否结批中
                                    var (res, jiepi) = plcConn.GetPlcDBValue(checkTaskMedel.PosType, modDevice.DbNumber, checkTaskMedel.PosLot);
                                    if (jiepi == 2)//结批中
                                    {
                                        // 分道解绑,抓箱品种写入0
                                        var ret1 = plcConn.SetPlcDBValue(checkTaskMedel.PosTypeLot, modDevice.DbNumber, checkTaskMedel.PlcPos, "0");
                                        if (ret1.IsSucceed)
                                        {
                                            //写入流程字成功后更新分拣任务    liudl 最后一托盘申请完入库才可清空
                                            checkTaskMedel.OrderNo = "";
                                            checkTaskMedel.TaskNo = "";
                                            checkTaskMedel.LotNo = "";
                                            checkTaskMedel.SkuNo = "";
                                            checkTaskMedel.SkuName = "";
                                            checkTaskMedel.BoxType = "";
                                            checkTaskMedel.Qty = 0;
                                            checkTaskMedel.PZNo = "";
                                            checkTaskMedel.Status = "0";      // 绑定分道 0:解绑  1:绑定
                                            //更新分拣任务
                                            _db.Updateable(checkTaskMedel).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                                        }
                                    }
                                    // 获取入库任务信息
                                    var taskModel = _db.Queryable<WcsTask>().First(m => m.TaskNo == TaskNo && m.IsDelete == false && m.Status == TaskStatusEnum.Wait);
                                    if (taskModel != null)
@@ -2059,22 +2499,157 @@
    }
    /// <summary>
    /// 拆垛机器人业务处理
    /// 出库件箱输送和拆垛机器人业务处理
    /// </summary>
    /// <param name="modDevice"></param>
    private static void StackingRobot(WcsDeviceDto modDevice)
    {
        var plcConn = modDevice.PLCUtil;
        switch (modDevice.Value.ToString())
        if (modDevice.DbNumber == "DB131" || modDevice.DbNumber == "DB132" || modDevice.DbNumber == "DB133" || modDevice.DbNumber == "DB134")
        {
            case "0":
                {
                    // 若拆垛工位为空闲,查询任务表是否有未绑定的出库任务,做绑定操作
                }
                break;
            default:
                break;
            switch (modDevice.Value.ToString())
            {
                case "10"://10  plc请求wcs读托盘码   20 wcs读取ok  wcs 写入数量及规格  30
                    var strMsg = "";
                    var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "20");
                    if (ret.IsSucceed)
                    {
                        //获取托盘码
                        var modPosPallet = modDevice.listStation.FirstOrDefault(m => m.Text == "托盘码");
                        var (res, palletVal) = plcConn.GetPlcDBValue(modPosPallet.PosType, modDevice.DbNumber, modPosPallet.PlcPos);
                        // 获取托盘任务号
                        var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号");
                        var (res1, val) = plcConn.GetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos);
                        string tasknoVal = val.ToString();
                        // 根据任务号获取任务信息
                        if (res1.IsSucceed)
                        {
                            var modTask = _db.Queryable<WcsTask>().First(m => m.TaskNo == tasknoVal && m.EndLocate == "009" && m.IsDelete == false);
                            if (modTask == null)
                            {
                                Log.Error(string.Format($"出库任务未下发,请人工处理,无法拆垛!"));
                                break;
                            }
                            //通过任务号和托盘号向WMS申请此托盘的拆垛信息
                            var http = new HttpService();
                            RequestBoxInfoCheckAll tasklist = http.RequestBoxCheckinfo(palletVal, tasknoVal);
                            if (tasklist.Success != -1)
                            {
                                //获取拆垛物料品种(需要增加物料判断,同一个物料号可能会出现不同的码垛规则)
                                var pz = _db.Queryable<WcsMateialPzInfo>().First(m => m.SkuNo == tasklist.data.SkuNo);
                                //下发拆托规格,拆箱数和托盘上总箱数(不绑定机器人,拆垛任务信息只下发一次)
                                // 给PLC写入任务数据
                                var listResult = new List<Result>();
                                // 获取托盘规则
                                var Standard = modDevice.listStation.FirstOrDefault(m => m.Text == "规格");
                                listResult.Add(plcConn.SetPlcDBValue(Standard.PosType, modDevice.DbNumber, Standard.PlcPos, pz.PZNo));
                                //抓箱数
                                var qty = modDevice.listStation.FirstOrDefault(m => m.Text == "拆箱数量");
                                listResult.Add(plcConn.SetPlcDBValue(qty.PosType, modDevice.DbNumber, qty.PlcPos, tasklist.data.Qty.ToString()));
                                //总箱数
                                var qtycount = modDevice.listStation.FirstOrDefault(m => m.Text == "总箱数");
                                listResult.Add(plcConn.SetPlcDBValue(qtycount.PosType, modDevice.DbNumber, qtycount.PlcPos, tasklist.data.QtyCount.ToString()));
                                // 是否写入成功
                                if (listResult.All(s => s.IsSucceed))
                                {
                                    var ret1 = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "30");
                                }
                                else
                                {
                                    Log.Error(string.Format($"码垛信息未写入!托盘号:" + palletVal + ",码垛位:" + modDevice.StationNum));
                                    break;
                                }
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        else
        {
            switch (modDevice.Value.ToString())
            {
                case "1":
                    // 1楼件箱PLC请求WCS读码
                    {
                        // 读取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写入剔除通道号:0
                            var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "0");
                            if (ret.IsSucceed)
                            {
                                // 写入流程控制字 2
                                var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                if (retVal.IsSucceed)
                                {
                                    Log.Error("箱码为null或已绑定托盘,进行剔除。");
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // 箱码
                            string boxNoVal = boxNo.ToString();
                            // 通道号
                            var modLineNo = modDevice.listStation.FirstOrDefault(m => m.Text == "通道号");
                            // 调用wms接口验证箱码是否可拣货并返回装车口
                            var http = new HttpService();
                            RequestloadingAddre requesModel = http.ResultBoxInfoExportWcs(boxNoVal);
                            if (requesModel.Success != "0")
                            {
                                // 箱信息为null写入剔除通道号:0
                                var ret = plcConn.SetPlcDBValue(modLineNo.PosType, modDevice.DbNumber, modLineNo.PlcPos, "0");
                                if (ret.IsSucceed)
                                {
                                    // 写入流程控制字 2
                                    var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                    if (retVal.IsSucceed)
                                    {
                                        Log.Error("出库分拣根据箱码获取装车口失败,进行剔除。" + requesModel.Message);
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                // 写入出库分道号
                                var ret = plcConn.SetPlcDBValue(modLineNo.PosType, modDevice.DbNumber, modLineNo.PlcPos, requesModel.loadingAddre);
                                if (ret.IsSucceed)
                                {
                                    // 写入流程控制字 2
                                    var retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "2");
                                    if (retVal.IsSucceed)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    };break;
                case "10":
                    // 1楼件箱PLC读码失败,WCS不做处理直接剔除手持拣货。
                    {
                    };break;
                default:
                    break;
            }
        }
    }
    /// <summary>
@@ -2141,7 +2716,7 @@
                // 写入结批信号
                var ret = plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PosLot, "1");
                // 分道解绑,抓箱品种写入0
                var ret1 = plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PlcPos, "0");
                //var ret1 = plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PlcPos, "0");
                if (ret.IsSucceed)
                {
                    //写入流程字成功后更新分拣任务    liudl 最后一托盘申请完入库才可清空
@@ -2153,7 +2728,7 @@
                    //item.BoxType = "";
                    //item.Qty = 0;
                    item.PZNo = "";
                    item.Status = status;      // 绑定分道 0:解绑  1:绑定
                    item.Status = status;      // 绑定分道 0:解绑  1:绑定  2:结批中
                    //更新分拣任务
                    _db.Updateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
@@ -2170,52 +2745,53 @@
    private static void Test(WcsDeviceDto modDevice)
    {
        //写死测试读string
        var (res, val) = modDevice.PLCUtil.GetPlcDBValue(PLCDataTypeEnum.String, "DB100", "64");
        Console.WriteLine("DB100.64----" + val);
        //测试批量读取
        Dictionary<string, PLCDataTypeEnum> listaddress = new Dictionary<string, PLCDataTypeEnum>();
        foreach (var modStation in modDevice.listStation)
        {
            listaddress.Add(modStation.PlcPos, modStation.PosType);
        }
        var result = modDevice.PLCUtil.GetPlcBatchDBValue(listaddress);
        if (result.Value.Count > 0)
        {
            foreach (var value in result.Value)
            {
                Console.WriteLine("地址" + value.Key + "----值" + value, value);
            }
        }
        if (!result.IsSucceed)
        {
            foreach (var err in result.ErrList)
            {
                Console.WriteLine(err);
            }
            if (result.Value.Count > 0)//有错误的也有成功的
            {
        //var strMsg = new HttpService().RequestPackWcs("LN000001");
        ////写死测试读string
        //var (res, val) = modDevice.PLCUtil.GetPlcDBValue(PLCDataTypeEnum.String, "DB100", "64");
        //Console.WriteLine("DB100.64----" + val);
        ////测试批量读取
        //Dictionary<string, PLCDataTypeEnum> listaddress = new Dictionary<string, PLCDataTypeEnum>();
        //foreach (var modStation in modDevice.listStation)
        //{
        //    listaddress.Add(modStation.PlcPos, modStation.PosType);
        //}
        //var result = modDevice.PLCUtil.GetPlcBatchDBValue(listaddress);
        //if (result.Value.Count > 0)
        //{
        //    foreach (var value in result.Value)
        //    {
        //        Console.WriteLine("地址" + value.Key + "----值" + value, value);
        //    }
        //}
        //if (!result.IsSucceed)
        //{
        //    foreach (var err in result.ErrList)
        //    {
        //        Console.WriteLine(err);
        //    }
        //    if (result.Value.Count > 0)//有错误的也有成功的
        //    {
            }
        }
        if (modDevice.Value == 820)
        {
            //测试写入830
            //var result = mod.PLCUtil.SetPlcDBValue(mod.PosType.Value, mod.DbNumber, mod.PlcPos, "830");
            ////写入是否成功
            //if (result.IsSucceed)
            //{
        //    }
        //}
        //if (modDevice.Value == 820)
        //{
        //    //测试写入830
        //    //var result = mod.PLCUtil.SetPlcDBValue(mod.PosType.Value, mod.DbNumber, mod.PlcPos, "830");
        //    ////写入是否成功
        //    //if (result.IsSucceed)
        //    //{
            //}
        }
        else if (modDevice.Value == 840)
        {
        //    //}
        //}
        //else if (modDevice.Value == 840)
        //{
        }
        else if (modDevice.Value == 860)
        {
        //}
        //else if (modDevice.Value == 860)
        //{
        }
        //}
    }