zxx
2025-05-27 cdf20a4525a2ff9f6fe2c1e9b69fa2854c5848fd
HH.WCS.Mobox3/HH.WCS.Mobox3.JuShi/device/S7Helper.cs
@@ -11,6 +11,7 @@
using System.Data.SqlTypes;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Services.Description;
using static HH.WCS.JuShi.util.Settings;
@@ -164,6 +165,9 @@
            var result = false;
            try
            {
                var linkplc = Settings.SafeInteractions.First();
                var plc = new Plc(CpuType.S71200, linkplc.ip, 0, 1);
                Link(plc);
                if (plc.IsConnected)
                {
                    plc.Write(DataType.DataBlock, db, byteAddr, data);
@@ -285,76 +289,181 @@
        }
        public static List<PlcDeviceTable> plcDeviceTables = new List<PlcDeviceTable>();
        public static PlcDeviceTable plcDeviceTables = new PlcDeviceTable();
        /// <summary>
        /// 获取输送线数据
        /// </summary>
        public static void ReadSsxPLc()
        {
            //#region 测试写入数据
            //List<S7Model> s7Models = new List<S7Model>();
            //s7Models.Add(new S7Model() { addr = 0, value = "1", type = "Int", length = 2 });
            //s7Models.Add(new S7Model() { addr = 2, value = "2", type = "Int", length = 2 });
            //s7Models.Add(new S7Model() { addr = 4, value = "4", type = "Int", length = 2 });
            //s7Models.Add(new S7Model() { addr = 18, value = "TP24121108", type = "String", length = 20 });
            //var plcInfo = Settings.linePlcInfo.Where(a => (a.deviceNo == "2") && a.enable == 1).FirstOrDefault();
            //Write(s7Models, 100, plcInfo);
            //#endregion
            var db = new SqlHelper<WCSTask>().GetInstance();
            //两个拆托机
            var linkplcs = Settings.linePlcInfos.FindAll(a => a.enable == 1).ToList();
            foreach (var linkplc in linkplcs){
                //获取设备配置文件
                var deviceInfos = Settings.ConveyorLinesInfos.Where(a => a.enable == 1 &&a.deviceNo== linkplc.deviceNo).ToList();
                if (deviceInfos.Count > 0)
            try
            {
                var linkplc = Settings.linePlcInfos.Find(a => a.enable == 1);
                var plc = new Plc(CpuType.S71500, linkplc.address, 0, 1);
                Link(plc);
                //拆托机
                //object rawValue = plc.Read(DataType.DataBlock, 8, 230, VarType.Byte, 1);
                //LogHelper.Info($"Raw value: {rawValue} (Type: {rawValue?.GetType()})");
                // 先读取整个字节
                byte data = (byte)plc.Read(DataType.DataBlock, 8, 230, VarType.Byte, 1);
                // 然后提取各个位
                bool requestPut1 = (data & 0x01) != 0;  // 230.0   1001
                bool requestTake1 = (data & 0x02) != 0;   // 230.1    1003
                bool requestPut2 = (data & 0x04) != 0;  // 230.2     1004
                bool requestTake2 = (data & 0x08) != 0;   // 230.3    1006
                LogHelper.Info($"拆托机接收信号====={requestPut1},{requestTake1},{requestPut2},{requestTake2}");
                //RGV
                // RGV允许卸货状态读取 (从DB51读取)
                int rgv1AllowUnload = (int)plc.Read(DataType.DataBlock, 51, 0, VarType.Int, 1);
                int rgv2AllowUnload = (int)plc.Read(DataType.DataBlock, 51, 2, VarType.Int, 1);
                int rgv3AllowUnload = (int)plc.Read(DataType.DataBlock, 51, 4, VarType.Int, 1);
                int rgv4AllowUnload = (int)plc.Read(DataType.DataBlock, 51, 6, VarType.Int, 1);
                int rgv5AllowUnload = (int)plc.Read(DataType.DataBlock, 51, 8, VarType.Int, 1);
                int rgv6AllowUnload = (int)plc.Read(DataType.DataBlock, 51, 10, VarType.Int, 1);
                LogHelper.Info($"RGV接收信号=== 1={rgv1AllowUnload}, 2={rgv2AllowUnload}, 3={rgv3AllowUnload}, 4={rgv4AllowUnload}, 5={rgv5AllowUnload}, 6={rgv6AllowUnload}");
                //存到缓存
                if (plcDeviceTables != null)
                {
                    int slen =int.Parse(deviceInfos.Min(a => a.readAddr).ToString());
                    int elen = int.Parse(deviceInfos.Max(a => a.readAddr).ToString());
                    //读取输送线整个偏移量的byte数组 放内存里一起解析,防止过度读取
                    //PLCRead(linkplc.address, 8, slen, elen + 18, out Ssxbytes);
                    var plc = new Plc(CpuType.S71500, linkplc.address, 0, 1);
                    Link(plc);
                    //一个拆托机两个线体
                    foreach (var device in deviceInfos)
                    plcDeviceTables.requestTake1 = requestTake1;
                    plcDeviceTables.requestPut1 = requestPut1;
                    plcDeviceTables.requestTake2 = requestTake2;
                    plcDeviceTables.requestPut2 = requestPut2;
                    plcDeviceTables.RGVAllowUnload = new Dictionary<int, int>
                    {
                        //int workMode = int.Parse(GetValue(int.Parse(device.readAddr.ToString()), VarType.Int, Ssxbytes));        //工作模式
                        //int lightAction = int.Parse(GetValue(int.Parse((device.readAddr + 2).ToString()), VarType.Int, Ssxbytes));     //是否有货,光电信号
                        int workMode = (short)plc.Read(DataType.DataBlock, 8, int.Parse(device.readAddr.ToString()), VarType.Int, 1, 0);
                        int lightAction = (short)plc.Read(DataType.DataBlock, 8, int.Parse((device.readAddr + 2).ToString()), VarType.Int, 1, 0);
                        var requestTake = plc.Read("DB8.DBX"+ device.readAddr+16.0);//输送线请求取框
                        var requestPut = plc.Read("DB8.DBX"+ device.readAddr + 16.1);//输送线允许放框
                        //存到缓存
                        var task = plcDeviceTables.Find(a => a.DeviceNo == device.code);
                        if (task != null)
                        {
                            task.DeviceNo = device.code;
                            task.workMode = workMode;
                            task.lightAction = lightAction;
                            task.requestTake =bool.Parse(requestTake.ToString());
                            task.requestPut = bool.Parse(requestPut.ToString());
                        }
                        else
                        {
                            var plcDeviceTable = new PlcDeviceTable();
                            plcDeviceTable.DeviceNo = device.code;
                            plcDeviceTable.workMode = workMode;
                            plcDeviceTable.lightAction = lightAction;
                            plcDeviceTable.requestTake = bool.Parse(requestTake.ToString());
                            plcDeviceTable.requestPut = bool.Parse(requestPut.ToString());
                            plcDeviceTables.Add(plcDeviceTable);
                        }
                    }
                        {1, rgv1AllowUnload},
                        {2, rgv2AllowUnload},
                        {3, rgv3AllowUnload},
                        {4, rgv4AllowUnload},
                        {5, rgv5AllowUnload},
                        {6, rgv6AllowUnload}
                    };
                    LogHelper.Info($"S7协议第一次读取参数:{JsonConvert.SerializeObject(plcDeviceTables)}");
                }
                else
                {
                    var plcDeviceTable = new PlcDeviceTable();
                    plcDeviceTable.requestTake1 = requestTake1;
                    plcDeviceTable.requestPut1 = requestPut1;
                    plcDeviceTable.requestTake2 = requestTake2;
                    plcDeviceTable.requestPut2 = requestPut2;
                    plcDeviceTable.RGVAllowUnload = new Dictionary<int, int>
                    {
                        {1, rgv1AllowUnload},
                        {2, rgv2AllowUnload},
                        {3, rgv3AllowUnload},
                        {4, rgv4AllowUnload},
                        {5, rgv5AllowUnload},
                        {6, rgv6AllowUnload}
                    };
                    plcDeviceTables = plcDeviceTable;
                    LogHelper.Info($"S7协议读取参数:{JsonConvert.SerializeObject(plcDeviceTable)}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ReadSsxPLc:" + ex.Message + ex.StackTrace);
                LogHelper.Error("ReadSsxPLc:" + ex.Message, ex);
                throw;
            }
        }
        ///// <summary>
        ///// 获取输送线数据
        ///// </summary>
        //public static void oldReadSsxPLc()
        //{
        //    //#region 测试写入数据
        //    //List<S7Model> s7Models = new List<S7Model>();
        //    //s7Models.Add(new S7Model() { addr = 0, value = "1", type = "Int", length = 2 });
        //    //s7Models.Add(new S7Model() { addr = 2, value = "2", type = "Int", length = 2 });
        //    //s7Models.Add(new S7Model() { addr = 4, value = "4", type = "Int", length = 2 });
        //    //s7Models.Add(new S7Model() { addr = 18, value = "TP24121108", type = "String", length = 20 });
        //    //var plcInfo = Settings.linePlcInfo.Where(a => (a.deviceNo == "2") && a.enable == 1).FirstOrDefault();
        //    //Write(s7Models, 100, plcInfo);
        //    //#endregion
        //    var db = new SqlHelper<WCSTask>().GetInstance();
        //    try
        //    {
        //        //两个拆托机
        //        var linkplcs = Settings.linePlcInfos.FindAll(a => a.enable == 1).ToList();
        //        foreach (var linkplc in linkplcs)
        //        {
        //            //获取设备配置文件
        //            var deviceInfos = Settings.ConveyorLinesInfos.Where(a => a.enable == 1 && a.deviceNo == linkplc.deviceNo).ToList();
        //            if (deviceInfos.Count > 0)
        //            {
        //                int slen = int.Parse(deviceInfos.Min(a => a.readAddr).ToString());
        //                int elen = int.Parse(deviceInfos.Max(a => a.readAddr).ToString());
        //                //读取输送线整个偏移量的byte数组 放内存里一起解析,防止过度读取
        //                //PLCRead(linkplc.address, 8, slen, elen + 18, out Ssxbytes);
        //                var plc = new Plc(CpuType.S71500, linkplc.address, 0, 1);
        //                Link(plc);
        //                //一个拆托机两个线体
        //                foreach (var device in deviceInfos)
        //                {
        //                    //int workMode = int.Parse(GetValue(int.Parse(device.readAddr.ToString()), VarType.Int, Ssxbytes));        //工作模式
        //                    //int lightAction = int.Parse(GetValue(int.Parse((device.readAddr + 2).ToString()), VarType.Int, Ssxbytes));     //是否有货,光电信号
        //                    //int workMode = (short)plc.Read(DataType.DataBlock, 8, int.Parse(device.readAddr.ToString()), VarType.Int, 1, 0);
        //                    //int lightAction = (short)plc.Read(DataType.DataBlock, 8, int.Parse((device.readAddr + 2).ToString()), VarType.Int, 1, 0);
        //                    int requestTake1 = (short)plc.Read(DataType.DataBlock, 8, 230, VarType.Int, 1, 0);
        //                    int requestPut1 = (short)plc.Read(DataType.DataBlock, 8, 230, VarType.Int, 1, 1);
        //                    int requestTake2 = (short)plc.Read(DataType.DataBlock, 8, 230, VarType.Int, 1, 2);
        //                    int requestPut2 = (short)plc.Read(DataType.DataBlock, 8, 230, VarType.Int, 1, 3);
        //                    LogHelper.Info($"readbool2================={requestTake1},{requestPut1},{requestTake2},{requestPut2}");
        //                    //var requestTake = plc.Read("DB8.DBX" + device.readAddr + 16.0);//输送线请求取框
        //                    //var requestPut = plc.Read("DB8.DBX" + device.readAddr + 16.1);//输送线允许放框
        //                    //存到缓存
        //                    //var task = plcDeviceTables.Find(a => a.DeviceNo == device.code);
        //                    if (task != null)
        //                    {
        //                        task.DeviceNo = device.code;
        //                        //task.workMode = workMode;
        //                        //task.lightAction = lightAction;
        //                        task.requestTake1 = requestTake1;
        //                        task.requestPut1 = requestPut1;
        //                        task.requestTake2 = requestTake2;
        //                        task.requestPut2 = requestPut2;
        //                        LogHelper.Info($"S7协议第一次读取参数:{JsonConvert.SerializeObject(task)}");
        //                    }
        //                    else
        //                    {
        //                        var plcDeviceTable = new PlcDeviceTable();
        //                        plcDeviceTable.DeviceNo = device.code;
        //                        //plcDeviceTable.workMode = workMode;
        //                        //plcDeviceTable.lightAction = lightAction;
        //                        plcDeviceTable.requestTake1 = requestTake1;
        //                        plcDeviceTable.requestPut1 = requestPut1;
        //                        plcDeviceTable.requestTake2 = requestTake2;
        //                        plcDeviceTable.requestPut2 = requestPut2;
        //                        plcDeviceTables.Add(plcDeviceTable);
        //                        LogHelper.Info($"S7协议读取参数:{JsonConvert.SerializeObject(plcDeviceTable)}");
        //                    }
        //                }
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine("ReadSsxPLc:" + ex.Message + ex.StackTrace);
        //        LogHelper.Error("ReadSsxPLc:" + ex.Message, ex);
        //        throw;
        //    }
        //}
        ///// <summary>
        ///// 批量写入方法
        ///// </summary>
@@ -669,7 +778,7 @@
            }
        }
        internal static bool WriteDouble(string deviceNo,int db, double? byteAddr, int data)
        internal static bool WriteDouble(string deviceNo, int db, int byteAddr, int offsetAddr, int data)
        {
            var result = false;
            try
@@ -679,22 +788,47 @@
                Link(plc);
                if (plc.IsConnected)
                {
                    if (byteAddr != 0) {
                        plc.Write("DB9.DBX" + byteAddr, data);
                        //plc.Write(DataType.DataBlock, db, byteAddr, data);
                    if (byteAddr != 0)
                    {
                        plc.WriteBit(DataType.DataBlock, db, byteAddr, offsetAddr, true);
                        Console.WriteLine($"写入plc信息,ip={plc.IP} addr={byteAddr} data={data} ");
                        LogHelper.Info($"写入plc信息,ip={plc.IP} addr={byteAddr} data={data} ");
                        if (result)
                        //睡三秒 如果还继续发请求的话就重写入 否则写入false
                        Thread.Sleep(3000);
                        var plcDeviceTable = S7Helper.plcDeviceTables;
                        if (plcDeviceTable != null)
                        {
                            //写完再读一次确认
                            //var readData = (short)plc.Read(DataType.DataBlock, db, byteAddr, VarType.Int, 1, 0);
                            var readData = (short)plc.Read("DB9.DBX" + byteAddr);
                            Console.WriteLine($"读取plc信息,ip={plc.IP} addr={byteAddr} data={data} res={string.Join(", ", readData)}");
                            LogHelper.Info($"读取plc信息,ip={plc.IP} addr={byteAddr} data={data} res={string.Join(", ", readData)}", "PLC");
                            result = readData == data;
                            if ((offsetAddr == 0 && plcDeviceTable.requestPut1)
                                || (offsetAddr == 1 && plcDeviceTable.requestTake1)
                                || (offsetAddr == 2 && plcDeviceTable.requestPut2)
                                || (offsetAddr == 3 && plcDeviceTable.requestTake2))
                            {
                                WriteDouble(deviceNo, db, byteAddr, offsetAddr, data);
                            }
                            else
                            {
                                plc.WriteBit(DataType.DataBlock, db, byteAddr, offsetAddr, false);
                                LogHelper.Info($"S7发送复位信号");
                            }
                        }
                        //if (result)
                        //{
                        //    //写完再读一次确认
                        //    //var readData = (short)plc.Read(DataType.DataBlock, db, byteAddr, VarType.Int, 1, 0);
                        //    //byte data1 = (byte)plc.Read(DataType.DataBlock, db, byteAddr, VarType.Byte, 1);
                        //    //// 然后提取各个位
                        //    //bool requestPut1 = (data1 & 0x01) != 0;  // 230.0   1001
                        //    var readData = (short)plc.Read("DB9.DBX" + byteAddr);
                        //    Console.WriteLine($"读取plc信息,ip={plc.IP} addr={byteAddr} data={data} res={string.Join(", ", readData)}");
                        //    LogHelper.Info($"读取plc信息,ip={plc.IP} addr={byteAddr} data={data} res={string.Join(", ", readData)}", "PLC");
                        //    result = readData == data;
                        //}
                    }
                }
                else
                {
@@ -829,7 +963,15 @@
            public string value { get; set; }
        }
        //S7写入信号 测试用
        internal static Results S7Write(int offsetAddr)
        {
            var linkplcs = Settings.linePlcInfos.Find(a => a.deviceNo == "1");
            var plc = new Plc(CpuType.S71500, linkplcs.address, 0, 1);
            Link(plc);
            plc.WriteBit(DataType.DataBlock, 9, 182, offsetAddr, false);
            return new Results() { Code = "0", Message = $"写入成功", Data = null };
        }
        #region 用于模拟测试
        /// <summary>