IPC-610
2024-09-26 c283573b53247033cf83b8fcddd8a022ea6454ab
Admin.NET/WCS.Application/PLC/PLCService.cs
@@ -1,4 +1,5 @@

using Dm.filter;
using DocumentFormat.OpenXml.Bibliography;
using Elastic.Clients.Elasticsearch.Tasks;
using Furion.Logging;
@@ -35,8 +36,8 @@
                case PLCTypeEnum.AGV:
                    AGV(mod);                                       // AGV调度
                    break;
                case PLCTypeEnum.RobotPalletizer:
                    RobotPalletizer(mod);                             // 码垛机器人
                case PLCTypeEnum.BoxConveyorLine:
                    BoxConveyorLine(mod);                             // 码垛机器人
                    break;
                case PLCTypeEnum.StackingRobot:
                    PalletMachine(mod);
@@ -1387,58 +1388,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)
                                {
                                    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 +1440,295 @@
                                    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.RoboatNo);
                                    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(string.Format("码垛工位{0},箱码为null插码失败!请人工强制结批。"), modDevice.StationNum);
                                // 写入插入结果 2:插码失败
                                var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2");
                                break;
                            }
                            // 验证箱码表是否存在此箱码
                            var boxInfo = _db.Queryable<WcsBoxInfo>().First(w => w.IsDelete == false && w.BoxNo == boxNo);
                            if (boxInfo == null)
                            {
                                Log.Error(string.Format("码垛工位{0},箱码{1}不存在!请人工强制结批。"), 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;
                            }
                            // 修改插码表
                            boxInfo.PalletNo = palletNo;
                            boxInfo.UpdateTime = DateTime.Now;
                            var rowCount = _db.Updateable(boxInfo).ExecuteCommand();
                            if (rowCount > 0)
                            {
                                // 插码成功
                                var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "1");
                            }
                            else
                            {
                                // 插码失败
                                Log.Error(string.Format("箱码{0};码垛工位{1},插码失败,请强制结批"),boxNo,modDevice.StationNum);
                                var retVal = plcConn.SetPlcDBValue(modAddCode.PosType, modDevice.DbNumber, modAddCode.PlcPos, "2");
                            }
                        }
                    }
                    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);
                        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));
                }
                break;
            default: break;
        }
                            // 写入交互工位目标地址
                            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);
                                if (taskModel != null)
                                {
                                    // 写入码垛工位目标工位,写入交互流程组托成功 执行入库
                                    string endLocatVlue = PLCCommon.RoadwayToStationNum(taskModel.EndRoadway, "2");     // 获取入库取货工位
                                    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)
                            {
                                string sqlStr2 = $"delete from WCSBoxInfo 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 retVal = plcConn.SetPlcDBValue(posModel.PosType, numModel.DbNumber, posModel.PlcPos, endLocatVlue);
                                    if (retVal.IsSucceed)
                                    {
                                        // 写入组托回复流程字
                                        retVal = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "50");
                                        if (retVal.IsSucceed)
                                        {
                                            // 将入库任务由正在执行改为正在执行
                                            taskModel.Status = TaskStatusEnum.Doing;
                                            _db.Updateable(taskModel).ExecuteCommand();
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                default:break;
            }
        }
    }
    /// <summary>