zxx
2025-05-19 839cd7bba832638a5ba1fb2d3e4e0619e33651e3
主动绑定接口
rgv安全交互
1个文件已添加
14个文件已修改
646 ■■■■ 已修改文件
.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/HH.WCS.JuShi.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/Program.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/api/WmsController.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/config/config.json 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/core/WCSCore.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/core/WMSCore.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/device/TcpServer.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/models/CameraMonitor.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/models/GetSubmitCheck.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/models/SafeInteraction.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/process/DeviceProcess.cs 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/process/TaskProcess.cs 359 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/util/Settings.cs 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/wms/ContainerHelper.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -185,3 +185,4 @@
# Microsoft Fakes
FakesAssemblies/
/.vs/HH.WCS.JuShi/FileContentIndex/3fc4eebc-46c2-4e7f-9d3f-1120aff520d4.vsidx
/.vs/HH.WCS.JuShi/FileContentIndex/e9cb8869-a58d-4485-bb3e-8bac64b53e74.vsidx
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/HH.WCS.JuShi.csproj
@@ -219,6 +219,7 @@
    <Compile Include="core\Monitor.cs" />
    <Compile Include="models\BaseModel.cs" />
    <Compile Include="models\Area.cs" />
    <Compile Include="models\SafeInteraction.cs" />
    <Compile Include="models\SafetyInteraction.cs" />
    <Compile Include="models\CntrItemDetail.cs" />
    <Compile Include="models\CameraMonitor.cs" />
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/Program.cs
@@ -79,7 +79,7 @@
                //摄像头监测满状态托盘
                tasks.Add(GetTask(WMSCore.MonitorFullStatus));
                ////常规送检空了自动从送检缓存区取一个送过去
                //tasks.Add(GetTask(WMSCore.AutoReplenish));
                tasks.Add(GetTask(WMSCore.AutoReplenish));
                //S7通讯
                //tasks.Add(GetTask(S7Helper.ReadSsxPLc));
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/api/WmsController.cs
@@ -73,7 +73,20 @@
            return res;
        }
        /// <summary>
        /// 主动物料绑定
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public Results BindMaterial(GetSubmitCheck model)
        {
            LogHelper.Info("BindMaterial 参数:" + JsonConvert.SerializeObject(model), "WMSAPI");
            var res = TaskProcess.bindMaterial(model);
            LogHelper.Info("BindMaterial 返回:" + JsonConvert.SerializeObject(res), "WMSAPI");
            return res;
        }
        /// <summary>
        /// 摄像头监测
        /// </summary>
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/config/config.json
@@ -192,26 +192,54 @@
    }
  ],
  //安全门
  "SafeDoor": [
  "SafeInteraction": [
    {
      "pointCode": "门1",
      "pointCode": "RGV1",
      "ip": "192.168.1.133",
      "port": "8080"
      "type": "RGV",
      "location": "RGV01"
    },
    {
      "pointCode": "门2",
      "pointCode": "RGV2",
      "ip": "192.168",
      "port": "8888"
      "type": "RGV",
      "location": "RGV02"
    },
    {
      "pointCode": "门3",
      "pointCode": "RGV3",
      "ip": "192.168",
      "port": "8888"
      "type": "RGV",
      "location": "RGV03"
    },
    {
      "pointCode": "门4",
      "pointCode": "RGV4",
      "ip": "192.168",
      "port": "8888"
      "type": "RGV",
      "location": "RGV04"
    },
    {
      "pointCode": "拆托机1入口",
      "ip": "192.168",
      "type": "CTJ",
      "location": "CPJ01-R"
    },
    {
      "pointCode": "拆托机1出口",
      "ip": "192.168",
      "type": "CTJ",
      "location": "CPJ01-C"
    },
    {
      "pointCode": "拆托机2入口",
      "ip": "192.168",
      "type": "CTJ",
      "location": "CPJ02-R"
    },
    {
      "pointCode": "拆托机2出口",
      "ip": "192.168",
      "type": "CTJ",
      "location": "CPJ02-C"
    }
  ]
  ////摄像头点位配置
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/core/WCSCore.cs
@@ -10,7 +10,7 @@
namespace HH.WCS.JuShi.core
{
    internal class WCSCore
    {
    {
        public static void OperateAgvTaskStatus(AgvTaskState model)
        {
            var TN_Task = WCSHelper.GetTask(model.No);
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/core/WMSCore.cs
@@ -233,15 +233,17 @@
                    var hcreservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "送检缓存区").FirstOrDefault();
                    //找送检缓存区有货的货位
                    var startloc = TaskProcess.OutWorkTransport(hcreservoirs.areaCode);
                    //创建送检任务
                    var locCntrRel = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startloc.S_CODE).First();
                    LogHelper.Info($"创建任务 起点:{startloc.S_CODE}终点:{endloc.S_CODE}", "自动补货");
                    var res = TaskProcess.CreateTransport(startloc.S_CODE, endloc.S_CODE, "自动补货", locCntrRel.S_CNTR_CODE, 1, 1);
                    if (!res)
                    {
                        LogHelper.Info($"任务 起点:{startloc.S_CODE}终点:{endloc.S_CODE}创建失败", "自动补货");
                    }
                    if (startloc!=null)
                    {
                        //创建送检任务
                        var locCntrRel = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startloc.S_CODE).First();
                        LogHelper.Info($"创建任务 起点:{startloc.S_CODE}终点:{endloc.S_CODE}", "自动补货");
                        var res = TaskProcess.CreateTransport(startloc.S_CODE, endloc.S_CODE, "自动补货", locCntrRel.S_CNTR_CODE, 1, 1);
                        if (!res)
                        {
                            LogHelper.Info($"任务 起点:{startloc.S_CODE}终点:{endloc.S_CODE}创建失败", "自动补货");
                        }
                    }
                }
            }
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/device/TcpServer.cs
@@ -82,6 +82,7 @@
                        var message = GetHexString(buffers[remote_ip], length);//16   10
                        Console.WriteLine(message);
                        //3A 00 01 00 01 05 73 00 02 01 01 B8
                        //按钮盒
                        if (message.Substring(0, 2) == "3A") {
                            //显示消息
                            if (length != 24) {
@@ -90,6 +91,18 @@
                            PlcHelper.Receive(remote_ip, message);
                            Array.Clear(buffers[remote_ip], 0, buffers[remote_ip].Length);//清空当前IP Buffer
                        }
                        //3F 00 10 20 30 40 0D 0A
                        //安全交互
                        else if (message.Substring(0, 4) == "3F00")
                        {
                            //显示消息
                            if (length != 16)
                            {
                                message = message.Substring(0, 16);
                            }
                            PlcHelper.Receive(remote_ip, message);
                            Array.Clear(buffers[remote_ip], 0, buffers[remote_ip].Length);//清空当前IP Buffer
                        }
                        else {
                            Console.WriteLine($"【TCP信息协议异常】:IP:{remote_ip},MSG:{message}");
                        }
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/models/CameraMonitor.cs
@@ -4,12 +4,12 @@
namespace HH.WCS.JuShi
{
    public  class CameraMonitor : BaseModel
    public  class SafeInteraction : BaseModel
    {
        //摄像头货位
        public string PointCode { get; set; }
        //摄像头货位空满状态
        public int PointStatus { get; set; }
        //站点ip
        public string ip { get; set; }
        //信号
        public string data { get; set; }
    }
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/models/GetSubmitCheck.cs
@@ -15,9 +15,9 @@
        public string END_LOC { get; set; }
        //物料编号
        public string S_ITEM_CODE { get; set; }
        ////解绑货位
        //public string MONITOR_LOC { get; set; }
        //绑定货位
        public string BIND_LOC { get; set; }
    }
}
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/models/SafeInteraction.cs
New file
@@ -0,0 +1,16 @@
using HH.WCS.JuShi.models;
using System;
namespace HH.WCS.JuShi
{
    public  class CameraMonitor : BaseModel
    {
        //摄像头货位
        public string PointCode { get; set; }
        //摄像头货位空满状态
        public int PointStatus { get; set; }
    }
}
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/process/DeviceProcess.cs
@@ -9,6 +9,7 @@
using System.Linq;
using System.Threading;
using static HH.WCS.JuShi.LISTA.process.HttpModel;
using static HH.WCS.JuShi.util.Settings;
namespace HH.WCS.JuShi.process
{
@@ -17,57 +18,113 @@
    /// </summary>
    internal class DeviceProcess
    {
        public static string rgvSafeInteraction = null;
        internal static void Analysis(string data, string ip)
        {
            //收
            //3A 00 01 00 01 05 73 00 02 01 01 B8
            //发
            //2A 00 01 00 01 05 73 00 02 01 01 A8
            if (data != null)
            {
                //数据序号
                data = data.Substring(16, 2);
                //根据ip找到起点/终点货位
                var plc = Settings.deviceInfos.Where(a => a.address == ip).FirstOrDefault();
                var loc = plc.TN_Location;
                //1入库2常规送检3紧急送检4三寸空托5六寸空托
                bool result = false;
                if (data.Equals("01"))
                {
                    var reservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "RGV库区").FirstOrDefault();
                    result= TaskProcess.tcpOffline(loc, reservoirs.areaCode);
                }
                else if (data.Equals("02"))
                {
                    var reservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "常规送检区").FirstOrDefault();
                    result = TaskProcess.tcpOffline(loc, reservoirs.areaCode);
                }
                else if (data.Equals("03"))
                {
                    var reservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "紧急送检区").FirstOrDefault();
                    result = TaskProcess.tcpOffline(loc, reservoirs.areaCode);
                }
                else if (data.Equals("04"))
                {
                    var reservoirs = Settings.linePlcInfos.Where(s => s.code == "拆托机1").FirstOrDefault();
                    result = TaskProcess.tcpEmptyTray(reservoirs.outLoca, loc);
                }
                else if (data.Equals("05"))
                {
                    var reservoirs = Settings.linePlcInfos.Where(s => s.code == "拆托机2").FirstOrDefault();
                    result = TaskProcess.tcpEmptyTray(reservoirs.outLoca, loc);
                }
                //按钮盒
                //收
                //3A 00 01 00 01 05 73 00 02 01 01 B8
                //发
                //2A 00 01 00 01 05 73 00 02 01 01 A8
                // 输入的十六进制字符串数组
                string[] hexValues = { "2A", "00", "01", "00", "01", "05", "73", "00", "02", data, "01" };
                // 计算总和
                int sum = hexValues.Sum(hex => Convert.ToInt32(hex, 16));
                string returndata= hexValues.ToString()+ sum;
                if (result)
                if (data.Substring(0, 2) == "3A")
                {
                    PlcHelper.SendHex(ip, returndata);
                    //数据序号
                    data = data.Substring(16, 2);
                    //根据ip找到起点/终点货位
                    var plc = Settings.deviceInfos.Where(a => a.address == ip).FirstOrDefault();
                    var loc = plc.TN_Location;
                    //1入库2常规送检3紧急送检4三寸空托5六寸空托
                    bool result = false;
                    if (data.Equals("01"))
                    {
                        var reservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "RGV库区").FirstOrDefault();
                        result = TaskProcess.tcpOffline(loc, reservoirs.areaCode);
                    }
                    else if (data.Equals("02"))
                    {
                        var reservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "常规送检区").FirstOrDefault();
                        result = TaskProcess.tcpOffline(loc, reservoirs.areaCode);
                    }
                    else if (data.Equals("03"))
                    {
                        var reservoirs = Settings.ReservoirAreas.Where(s => s.areaName == "紧急送检区").FirstOrDefault();
                        result = TaskProcess.tcpOffline(loc, reservoirs.areaCode);
                    }
                    else if (data.Equals("04"))
                    {
                        var reservoirs = Settings.linePlcInfos.Where(s => s.code == "拆托机1").FirstOrDefault();
                        result = TaskProcess.tcpEmptyTray(reservoirs.outLoca, loc);
                    }
                    else if (data.Equals("05"))
                    {
                        var reservoirs = Settings.linePlcInfos.Where(s => s.code == "拆托机2").FirstOrDefault();
                        result = TaskProcess.tcpEmptyTray(reservoirs.outLoca, loc);
                    }
                    //2A 00 01 00 01 05 73 00 02 01 01 A8
                    // 输入的十六进制字符串数组
                    string[] hexValues = { "2A", "00", "01", "00", "01", "05", "73", "00", "02", data, "01" };
                    // 计算总和
                    int sum = hexValues.Sum(hex => Convert.ToInt32(hex, 16));
                    string returndata = hexValues.ToString() + sum;
                    if (result)
                    {
                        PlcHelper.SendHex(ip, returndata);
                    }
                }
                //rgv安全交互
                else if (data.Substring(0, 4) == "3F00")
                {
                    //无信号不管
                    if (data.Trim() != "3F00102030400D0A")
                    {
                        LogHelper.Info($"RGV安全交互接收信号{data}");
                        var reservoirs = Settings.SafeInteractions.Where(s => s.ip == ip).FirstOrDefault();
                        //1允许卸货  2卸货完成确认
                        string datastr = "";
                        if (reservoirs.pointCode == "RGV1")
                        {
                            datastr = data.Substring(5, 1);
                        }
                        else if (reservoirs.pointCode == "RGV2")
                        {
                            datastr = data.Substring(7, 1);
                        }
                        else if (reservoirs.pointCode == "RGV3")
                        {
                            datastr = data.Substring(9, 1);
                        }
                        else if (reservoirs.pointCode == "RGV4")
                        {
                            datastr = data.Substring(11, 1);
                        }
                        //接受信号存到内存
                        if (rgvSafeInteraction != null)
                        {
                            //string转成list
                            var jsonList = JsonConvert.DeserializeObject<List<SafeInteraction>>(rgvSafeInteraction);
                            var list = jsonList.Where(s => s.ip == ip).First();
                            if (list != null)
                            {
                                //不为空就先删再加上
                                jsonList.Remove(list);
                            }
                            jsonList.Add(new SafeInteraction { ip = ip, data = datastr });
                            rgvSafeInteraction = JsonConvert.SerializeObject(jsonList);
                        }
                        else
                        {
                            //第一次进
                            var safeInteractions = new List<SafeInteraction>{new SafeInteraction { ip = ip, data = datastr }};
                            rgvSafeInteraction = JsonConvert.SerializeObject(safeInteractions);
                        }
                        LogHelper.Info($"RGV安全交互 存入内存参数{rgvSafeInteraction}");
                    }
                }
            }
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)
            {
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/util/Settings.cs
@@ -21,7 +21,7 @@
        public static List<PriorityLoc> PriorityLocs { get; set; }
        public static List<ConveyorLinesInfo> ConveyorLinesInfos { get; set; }
        public static List<linePlcInfo> linePlcInfos { get; set; }
        public static List<SafeDoor> SafeDoors { get; set; }
        public static List<SafeInteraction> SafeInteractions { get; set; }
        public static int port { get; set; }
        public static string WHCode { get; set; }
        public static string FacCode { get; set; }
@@ -110,9 +110,9 @@
                            {
                                PriorityLocs = JsonConvert.DeserializeObject<List<PriorityLoc>>(keyValue.Value.ToString());
                            }
                            if (keyValue.Name == "SafeDoor")
                            if (keyValue.Name == "SafeInteraction")
                            {
                                SafeDoors = JsonConvert.DeserializeObject<List<SafeDoor>>(keyValue.Value.ToString());
                                SafeInteractions = JsonConvert.DeserializeObject<List<SafeInteraction>>(keyValue.Value.ToString());
                            }
                        }
                    }
@@ -192,11 +192,12 @@
            public string SecondaryArea { get; set; }
        }
        public class SafeDoor
        public class SafeInteraction
        {
            public string pointCode { get; set; }
            public string ip { get; set; }
            public string port { get; set; }
            public string type { get; set; }
            public string location { get; set; }
        }
    }
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/wms/ContainerHelper.cs
@@ -626,6 +626,7 @@
                db.Insertable<CntrItemDetail>(cir).ExecuteCommand();
                db.Ado.CommitTran();
                res = true;
                LogHelper.Info($"绑定容器物料表托盘:{trayCode}物料编码:{itemCode}物料名称:{itemName}");
            }
            catch (Exception ex)
            {