zxx
2025-05-19 9e694f7e393e6ad751f970b5f5b3e8c45e9c3c0a
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/process/TaskProcess.cs
@@ -20,6 +20,9 @@
using Opc.Ua;
using System.Collections;
using System.Xml.Linq;
using System.Threading;
using static HH.WCS.JuShi.dispatch.NDC;
using static HH.WCS.JuShi.util.Settings;
namespace HH.WCS.JuShi.process
{
@@ -99,17 +102,121 @@
        /// <param name="state"></param>
        internal static void OperateStatus(WCSTask mst, int state)
        {
            if (state == 4)
            if (state == 4)//取货完成
            {
                CacheBitUpdate(mst, true);
                //拆托机安全交互
                ctjSafe(mst);
            }
            if (state == 6)//卸货完成
            {
                CacheBitUpdate(mst, false);
                //rgv安全交互
                rgvSafe(mst);
                //拆托机安全交互
                ctjSafe(mst);
            }
            if (state == 7)
            {
                CacheBitCancelUpdate(mst);
            }
        }
        //rgv安全交互
        private static void rgvSafe(WCSTask mst)
        {
            //rgv安全交互  根据终点货位找到是哪个rgv
            var reservoir = Settings.ReservoirAreas.Where(a => a.areaName == "RGV库区").FirstOrDefault();
            if (mst.S_END_AREA.Equals(reservoir.areaCode))
            {
                var safeInteractions = Settings.SafeInteractions.Where(a => a.location == mst.S_END_LOC).FirstOrDefault();
                var safelists = JsonConvert.DeserializeObject<List<SafeInteraction>>(DeviceProcess.rgvSafeInteraction);
                if (safelists.Any())
                {
                    var safelist = safelists.Where(s => s.ip == safeInteractions.ip).First();
                    LogHelper.Info($"RGV安全交互参数{safelist}");
                    //不等于 2卸货完成确认信号 就接着发
                    if (safelist.data != "2")
                    {
                        string datastr = "3F00102030400D0A";
                        // 返回信号
                        switch (safeInteractions.pointCode)
                        {
                            case "RGV1":
                                datastr = datastr.Replace("10", "11");
                                break;
                            case "RGV2":
                                datastr = datastr.Replace("20", "21");
                                break;
                            case "RGV3":
                                datastr = datastr.Replace("30", "31");
                                break;
                            case "RGV4":
                                datastr = datastr.Replace("40", "41");
                                break;
                        }
                        LogHelper.Info($"RGV安全交互发送信号{safelist.ip},{datastr}");
                        PlcHelper.SendHex(safelist.ip, datastr);
                        //休眠3秒再调
                        Thread.Sleep(3000);
                        rgvSafe(mst);
                    }
                    else
                    {
                        LogHelper.Info($"RGV安全交互发送信号{safelist.ip},3F00102030400D0A");
                        //无状态信号
                        PlcHelper.SendHex(safelist.ip, "3F00102030400D0A");
                    }
                }
            }
        }
        //拆托机安全交互
        private static void ctjSafe(WCSTask mst)
        {
            PlcDeviceTable plcDeviceTable = null;
            //找到线体 根据线体找内存里的状态
            var rkreservoirs = Settings.ConveyorLinesInfos.Where(s => s.location == mst.S_END_LOC).FirstOrDefault();
            var ckreservoirs = Settings.ConveyorLinesInfos.Where(s => s.location == mst.S_START_LOC).FirstOrDefault();
            if (rkreservoirs != null)
            {
                plcDeviceTable = S7Helper.plcDeviceTables.Find(a => a.DeviceNo == rkreservoirs.code);
            }
            else if (ckreservoirs != null)
            {
                plcDeviceTable = S7Helper.plcDeviceTables.Find(a => a.DeviceNo == ckreservoirs.code);
            }
            LogHelper.Info($"拆托机安全交互写入参数{plcDeviceTable}");
            if (plcDeviceTable != null)
            {
                //s7写入
                double addr = 0;         //偏移量
                string deviceNo = null;//拆托机号
                if (plcDeviceTable.DeviceNo == 1003)
                {
                    addr = 90.1;
                    deviceNo = "1";
                }
                else if (plcDeviceTable.DeviceNo == 1006)
                {
                    addr = 180.1;
                    deviceNo = "2";
                }
                else if (plcDeviceTable.DeviceNo == 1001)
                {
                    addr = 30.0;
                    deviceNo = "1";
                }
                else if (plcDeviceTable.DeviceNo == 1004)
                {
                    addr = 120.0;
                    deviceNo = "2";
                }
                LogHelper.Info($"拆托机安全交互写入{deviceNo},{addr}");
                S7Helper.WriteDouble(deviceNo, 9, addr, 1);
            }
        }
@@ -316,70 +423,45 @@
                    string parmeD = "}";
                    string parme = parmeS + src + dst + parmeD;
                    int res = 0;
                    if (mst.S_TYPE == "呼叫空托" || mst.S_TYPE == "按钮盒调用空托" || mst.S_TYPE == "拆托")
                    {
                        PlcDeviceTable plcDeviceTable = null;
                        //找到线体 根据线体找内存里的状态
                        var reservoirs1 = Settings.ConveyorLinesInfos.Where(s => s.location == startLoc.S_CODE).FirstOrDefault();
                        plcDeviceTable = S7Helper.plcDeviceTables.Find(a => a.DeviceNo == reservoirs1.code);
                        if (plcDeviceTable != null)
                        {
                            if (mst.S_TYPE == "呼叫空托" || mst.S_TYPE == "按钮盒调用空托")
                            {
                                LogHelper.Info($"呼叫空托状态参数{JsonConvert.SerializeObject(plcDeviceTable)}", "任务");
                                //0-脱机状态,1-待机状态,2-运行中    待机且有托盘且请求取框才走
                                if (plcDeviceTable.workMode == 1 && plcDeviceTable.lightAction == 1 && plcDeviceTable.requestTake)
                                {
                                    LogHelper.Info($"推送任务参数{parme}", "任务");
                                    res = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, parme);
                                }
                            }
                            else if (mst.S_TYPE == "拆托")
                            {
                                LogHelper.Info($"拆托状态参数{JsonConvert.SerializeObject(plcDeviceTable)}", "任务");
                                //0-脱机状态,1-待机状态,2-运行中    待机且无托盘且允许放框才走
                                if (plcDeviceTable.workMode == 1 && plcDeviceTable.lightAction == 0 && plcDeviceTable.requestPut)
                                {
                                    LogHelper.Info($"推送任务参数{parme}", "任务");
                                    res = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, parme);
                                }
                            }
                            //任务完成写入s7
                            if (res > 0)
                            {
                                //s7写入 agv取框完成
                                double addr = 0;         //偏移量
                                string deviceNo = null;//拆托机号
                                if (plcDeviceTable.DeviceNo == 1003)
                                {
                                    addr = 90.1;
                                    deviceNo = "1";
                                }
                                else if (plcDeviceTable.DeviceNo == 1006)
                                {
                                    addr = 180.1;
                                    deviceNo = "2";
                                }
                                else if (plcDeviceTable.DeviceNo == 1001)
                                {
                                    addr = 30.0;
                                    deviceNo = "1";
                                }
                                else if (plcDeviceTable.DeviceNo == 1004)
                                {
                                    addr = 120.0;
                                    deviceNo = "2";
                                }
                                S7Helper.WriteDouble(deviceNo, 9, addr, 1);
                            }
                        }
                    }
                    else
                    {
                        LogHelper.Info($"推送任务参数{parme}", "任务");
                        res = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, parme);
                    }
                    LogHelper.Info($"推送任务参数{parme}", "任务");
                    res = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, parme);
                    #region
                    //if (mst.S_TYPE == "呼叫空托" || mst.S_TYPE == "按钮盒调用空托" || mst.S_TYPE == "拆托")
                    //{
                    //    PlcDeviceTable plcDeviceTable = null;
                    //    //找到线体 根据线体找内存里的状态
                    //    var reservoirs1 = Settings.ConveyorLinesInfos.Where(s => s.location == startLoc.S_CODE).FirstOrDefault();
                    //    plcDeviceTable = S7Helper.plcDeviceTables.Find(a => a.DeviceNo == reservoirs1.code);
                    //    if (plcDeviceTable != null)
                    //    {
                    //        if (mst.S_TYPE == "呼叫空托" || mst.S_TYPE == "按钮盒调用空托")
                    //        {
                    //            LogHelper.Info($"呼叫空托状态参数{JsonConvert.SerializeObject(plcDeviceTable)}", "任务");
                    //            //0-脱机状态,1-待机状态,2-运行中    待机且有托盘且请求取框才走
                    //            if (plcDeviceTable.workMode == 1 && plcDeviceTable.lightAction == 1 && plcDeviceTable.requestTake)
                    //            {
                    //                LogHelper.Info($"推送任务参数{parme}", "任务");
                    //                res = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, parme);
                    //            }
                    //        }
                    //        else if (mst.S_TYPE == "拆托")
                    //        {
                    //            LogHelper.Info($"拆托状态参数{JsonConvert.SerializeObject(plcDeviceTable)}", "任务");
                    //            //0-脱机状态,1-待机状态,2-运行中    待机且无托盘且允许放框才走
                    //            if (plcDeviceTable.workMode == 1 && plcDeviceTable.lightAction == 0 && plcDeviceTable.requestPut)
                    //            {
                    //                LogHelper.Info($"推送任务参数{parme}", "任务");
                    //                res = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, parme);
                    //            }
                    //        }
                    //    }
                    //}
                    //else
                    //{
                    //    LogHelper.Info($"推送任务参数{parme}", "任务");
                    //    res = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, parme);
                    //}
                    #endregion
                    if (res > 0)
                    {
                        //更新任务状态
@@ -713,7 +795,7 @@
            {
                //查询这个库区的空托盘与满托盘
                var list = db.Queryable<Location>().Where(a => a.S_AREA_CODE.Trim() == area).OrderByDescending(a => a.N_ROW).ToList();
                LogHelper.Info($"查询这个库区的空托盘与满托盘:{JsonConvert.SerializeObject(list)}");
                //LogHelper.Info($"查询这个库区的空托盘与满托盘:{JsonConvert.SerializeObject(list)}");
                if (list.Count > 0)
                {
                    List<string> loca = new List<string>();
@@ -1263,12 +1345,11 @@
            try
            {
                var db = new SqlHelper<object>().GetInstance();
                //三表联查查出有该物料的货位编号
                //两表联查查出有该物料的货位编号  (现场没有物料表)
                var locCntrs = db.Queryable<LocCntrRel>().LeftJoin<CntrItemDetail>((p, m) => p.S_CNTR_CODE == m.S_CNTR_CODE)
                .LeftJoin<TN_Material>((p, m, s) => m.S_ITEM_CODE == s.S_ITEM_CODE)
                .Where((p, m, s) => s.S_ITEM_CODE == itemCode)
                .OrderBy((p, m, s) => p.T_CREATE)  //按创建时间顺序
                .Select((p, m, s) => p.S_LOC_CODE) // 选择托盘物料表的数据
                .Where((p, m) => m.S_ITEM_CODE == itemCode)
                .OrderBy((p, m) => p.T_CREATE)  //按创建时间顺序
                .Select((p, m) => p.S_LOC_CODE) // 选择托盘物料表的数据
                .ToList();
                LogHelper.Info($"有物料{itemCode}的货位编号{JsonConvert.SerializeObject(locCntrs)}");
                //找常规送检区内含有查出物料货位的货位
@@ -1438,7 +1519,7 @@
                //根据物料找某库区的货位
                var cgreservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "送检缓存区").FirstOrDefault();
                var startloc = getLocByMaterial(model.S_ITEM_CODE, cgreservoirs.areaCode);
                if (startloc==null)
                if (startloc == null)
                {
                    return new Results { Code = "1", Message = $"未找到包含物料{model.S_ITEM_CODE}的货位", Data = null };
                }
@@ -1467,7 +1548,38 @@
                throw;
            }
        }
        /// <summary>
        /// 主动物料绑定
        /// </summary>
        /// <param name="model.S_ITEM_CODE">物料编码</param>
        /// <param name="model.BIND_LOC">绑定货位</param>
        /// <returns></returns>
        internal static Results bindMaterial(GetSubmitCheck model)
        {
            var result = new Results() { Code = "0", Message = "物料绑定成功!", Data = null };
            var db = new SqlHelper<Location>().GetInstance();
            try
            {
                string cntrStr = ContainerHelper.GenerateCntrNo();
                var locCntrRel = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == model.BIND_LOC).First();
                if (locCntrRel != null)
                {
                    cntrStr = locCntrRel.S_CNTR_CODE;
                }
                var res = ContainerHelper.BindLocCntrs(model.BIND_LOC, cntrStr, model.S_ITEM_CODE, "布卷");
                if (!res)
                {
                    return new Results { Code = "1", Message = $"物料{model.S_ITEM_CODE}货位{model.BIND_LOC}绑定失败", Data = null };
                }
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine("bindMaterial:" + ex.Message + ex.StackTrace);
                LogHelper.Error("bindMaterial:" + ex.Message, ex);
                throw;
            }
        }
        /// <summary>
        /// 按钮盒调用下线
        /// </summary>
@@ -1570,40 +1682,93 @@
        {
            //0允许进入 1不允许进入
            var result = new safeResult() { code = "1", msg = "success" };
            var db = new SqlHelper<Location>().GetInstance();
            try
            {
                var reservoirs = Settings.SafeDoors.Where(s => s.pointCode == model.STATION_NAME).FirstOrDefault();//y0-0000 y1-0001  on-FF00  off-0000
                TcpClient tcpClient = new TcpClient();
                //请求进入
                if (model.APPLY_CODE.Equals("1") || model.APPLY_CODE.Equals("5"))
                var reservoirs = Settings.SafeInteractions.Where(s => s.pointCode == model.STATION_NAME).FirstOrDefault();//y0-0000 y1-0001  on-FF00  off-0000
                var rgvSafeInteraction = DeviceProcess.rgvSafeInteraction;
                //RGV
                if (reservoirs.type.Equals("RGV"))
                {
                    //发送信号写请求开门
                    var str = tcpClient.WriteSingleRegisterRtu("01050000FF008C3A", reservoirs.ip, int.Parse(reservoirs.port));
                    //发送信号读门状态
                    var x0bool = tcpClient.ReadInputRegistersRtu("010200000001B9CA", reservoirs.ip, int.Parse(reservoirs.port));
                    //如果开门到位
                    if (x0bool)
                    LogHelper.Info($"RGV安全交互  请求点位:{model.STATION_NAME}请求码:{model.APPLY_CODE}");
                    //卸货请求进入
                    if (model.APPLY_CODE.Equals("5"))
                    {
                        return new safeResult() { code = "0", msg = "success" };
                        //根据ip读状态
                        if (rgvSafeInteraction != null)
                        {
                            LogHelper.Info($"RGV安全交互参数{JsonConvert.SerializeObject(rgvSafeInteraction)}");
                            var safelist = JsonConvert.DeserializeObject<List<SafeInteraction>>(rgvSafeInteraction);
                            if (safelist.Any())
                            {
                                var safedata = safelist.Where(s => s.ip == reservoirs.ip).First();
                                //1允许卸货  2卸货完成确认
                                if (safedata.data == "1")
                                {
                                    LogHelper.Info($"RGV安全交互 允许卸货");
                                    return new safeResult() { code = "0", msg = "success" };
                                }
                            }
                        }
                    }
                }
                //请求离开
                else if (model.APPLY_CODE.Equals("4") || model.APPLY_CODE.Equals("8"))
                //拆托机
                else if (reservoirs.type.Equals("CTJ"))
                {
                    //发送信号写请求关门
                    var str = tcpClient.WriteSingleRegisterRtu("010500000000CDCA", reservoirs.ip, int.Parse(reservoirs.port));
                    var str2 = tcpClient.WriteSingleRegisterRtu("01050001FF00DDFA", reservoirs.ip, int.Parse(reservoirs.port));
                    //发送信号读门状态
                    var x0bool = tcpClient.ReadInputRegistersRtu("010200010001E80A", reservoirs.ip, int.Parse(reservoirs.port));
                    //如果门已关
                    if (x0bool)
                    LogHelper.Info($"拆托机安全交互  请求点位:{model.STATION_NAME}请求码:{model.APPLY_CODE}");
                    //找到线体 根据线体找内存里的状态
                    var reservoirs1 = Settings.ConveyorLinesInfos.Where(s => s.location == model.STATION_NAME).FirstOrDefault();
                    var plcDeviceTable = S7Helper.plcDeviceTables.Find(a => a.DeviceNo == reservoirs1.code);
                    if (plcDeviceTable != null)
                    {
                        return new safeResult() { code = "0", msg = "success" };
                    }
                        LogHelper.Info($"拆托机安全交互参数{JsonConvert.SerializeObject(plcDeviceTable)}");
                        if (model.APPLY_CODE.Equals("1"))
                        {
                            //0-脱机状态,1-待机状态,2-运行中    待机且有托盘且请求取框才走
                            if (plcDeviceTable.workMode == 1 && plcDeviceTable.lightAction == 1 && plcDeviceTable.requestTake)
                            {
                                LogHelper.Info($"拆托机安全交互 允许取框");
                                return new safeResult() { code = "0", msg = "success" };
                            }
                        }
                        else if (model.APPLY_CODE.Equals("5"))
                        {
                            //0-脱机状态,1-待机状态,2-运行中    待机且无托盘且允许放框才走
                            if (plcDeviceTable.workMode == 1 && plcDeviceTable.lightAction == 0 && plcDeviceTable.requestPut)
                            {
                                LogHelper.Info($"拆托机安全交互 允许放框");
                                return new safeResult() { code = "0", msg = "success" };
                            }
                        }
                    }
                }
                return null;
                //TcpClient tcpClient = new TcpClient();
                ////发送信号写请求开门
                //var str = tcpClient.WriteSingleRegisterRtu("01050000FF008C3A", reservoirs.ip, int.Parse(reservoirs.port));
                ////发送信号读门状态
                //var x0bool = tcpClient.ReadInputRegistersRtu("010200000001B9CA", reservoirs.ip, int.Parse(reservoirs.port));
                ////如果开门到位
                //if (x0bool)
                //{
                //    return new safeResult() { code = "0", msg = "success" };
                //}
                ////请求离开
                //else if (model.APPLY_CODE.Equals("8"))
                //{
                //    ////发送信号写请求关门
                //    //var str = tcpClient.WriteSingleRegisterRtu("010500000000CDCA", reservoirs.ip, int.Parse(reservoirs.port));
                //    //var str2 = tcpClient.WriteSingleRegisterRtu("01050001FF00DDFA", reservoirs.ip, int.Parse(reservoirs.port));
                //    ////发送信号读门状态
                //    //var x0bool = tcpClient.ReadInputRegistersRtu("010200010001E80A", reservoirs.ip, int.Parse(reservoirs.port));
                //    ////如果门已关
                //    //if (x0bool)
                //    //{
                //    //    return new safeResult() { code = "0", msg = "success" };
                //    //}
                //}
                return result;
            }
            catch (Exception ex)
            {