using HH.WCS.JuShi.api; using HH.WCS.JuShi.util; using Microsoft.Owin.BuilderProperties; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Opc.Ua; using S7.Net; using S7.Net.Types; using SqlSugar; using System; using System.Collections.Generic; 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; namespace HH.WCS.JuShi.device { /// /// 西门子plc /// public class S7Helper { private static bool debug = true; private static byte[] Ssxbytes = new byte[0]; private static S7.Net.Plc plc = null; static S7Helper() { Init(); } private static Dictionary plcDic = new Dictionary(); private static void Init() { //配置文件读取所有的plc进行初始化 try { var plc1 = new Plc(CpuType.S71500, "", 0, 1); plcDic.Add("plc1", plc1); Link(plc1); } catch (Exception ex) { Console.WriteLine("S7Helper Init err=" + ex.Message); } } private static Plc GetPlc(string plc) { if (plcDic.ContainsKey(plc)) { return plcDic[plc]; } else { return null; } } public static Dictionary s7TestData = new Dictionary(); private static void Link(Plc plc) { try { //if (!plc.IsConnected) { plc.Close(); plc.Open(); if (plc.IsConnected) { Console.WriteLine($"已连接到plc{plc.IP}"); } else { Console.WriteLine($"plc{plc.IP}连接失败"); LogHelper.Info($"plc{plc.IP}连接失败", "Plc"); } //} } catch (Exception ex) { Console.WriteLine($"plc{plc.IP}连接失败,err={ex.Message}"); LogHelper.Info($"plc{plc.IP}连接失败,err={ex.Message}"); //Init(); } } //https://www.ad.siemens.com.cn/productportal/Prods/S7-1200_PLC_EASY_PLUS/SmartSMS/060.html //https://www.ad.siemens.com.cn/productportal/Prods/S7-1200_PLC_EASY_PLUS/07-Program/02-basic/01-Data_Type/09-String.html internal static short[] ReadInt(string device, int db, int byteAddr, int count) { short[] result = null; try { if (debug) { var s7Key = $"int_{db}_{byteAddr}_{count}"; if (s7TestData.ContainsKey(s7Key)) { var data = s7TestData[s7Key].Split(','); if (data.Length == count) { result = Array.ConvertAll(data, s => short.Parse(s)); } else { result = new short[count]; s7TestData[s7Key] = string.Join(",", result); } Console.WriteLine($"读取plc {device}信息成功, addr={byteAddr} data={string.Join(",", result)}"); } } else { var plc = GetPlc(device); if (plc != null) { if (plc.IsConnected) { result = (short[])plc.Read(DataType.DataBlock, db, byteAddr, VarType.Int, count, 0); Console.WriteLine($"读取plc {device}信息成功,ip={plc.IP} addr={byteAddr} data={string.Join(",", result)}"); if (result.Length == 0) { Console.WriteLine($"plc {device}准备重新连接"); Link(plc); } } else { Console.WriteLine($"准备连接plc {device}"); Link(plc); } } else { Console.WriteLine($"plc {device}不存在"); } } } catch (Exception ex) { Console.WriteLine($"ReadInt,device={device} addr={byteAddr} count={count} err={ex.Message}"); LogHelper.Error($"ReadInt,device={device} addr={byteAddr} count={count} err={ex.Message}", ex); } return result; } /// /// /// /// /// /// /// internal static bool WriteInt(int db, int byteAddr, short data) { 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); Console.WriteLine($"写入plc信息,ip={plc.IP} addr={byteAddr} data={data} "); LogHelper.Info($"写入plc信息,ip={plc.IP} addr={byteAddr} data={data} "); if (result) { //写完再读一次确认 var readData = (short)plc.Read(DataType.DataBlock, db, byteAddr, VarType.Int, 1, 0); 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 { Console.WriteLine("准备连接plc1"); Link(plc); } } catch (Exception ex) { LogHelper.Error($"写入plc1信息失败,ip={plc.IP} addr={byteAddr} data={data} err={ex.Message}", ex); } return result; } public static object ReadBit(string device, int db, int byteAddr, byte bitAddr) { object result = null; try { if (debug) { var s7Key = $"bit_{db}_{byteAddr}_{bitAddr}"; if (s7TestData.ContainsKey(s7Key)) { var data = s7TestData[s7Key]; if (data == "1") { result = true; } else { result = false; } Console.WriteLine($"读取plc {device}信息成功, addr={byteAddr} data={result.ToString()}"); } } else { var plc = GetPlc(device); if (plc != null) { if (plc.IsConnected) { result = plc.Read(DataType.DataBlock, db, byteAddr, VarType.Int, 1, bitAddr); Console.WriteLine($"读取plc {device}信息成功,ip={plc.IP} addr={byteAddr} data={result.ToString()}"); } else { Console.WriteLine($"准备连接plc {device}"); Link(plc); } } else { Console.WriteLine($"plc {device}不存在"); } } } catch (Exception ex) { Console.WriteLine($"ReadBit,device={device} addr={byteAddr} bit={bitAddr} err={ex.Message}"); LogHelper.Error($"ReadBit,device={device} addr={byteAddr} bit={bitAddr} err={ex.Message}", ex); } return result; } public static string ReadStr(string device, int db, int byteAddr, int count) { string result = string.Empty; try { if (debug) { var s7Key = $"str_{db}_{byteAddr}_{count}"; if (s7TestData.ContainsKey(s7Key)) { var data = s7TestData[s7Key]; if (data.Length == count) { result = data; Console.WriteLine($"ReadStr 成功, addr={byteAddr} res={result}"); } } } else { if (plc.IsConnected) { result = plc.Read(DataType.DataBlock, 100, byteAddr, VarType.String, count, 0).ToString(); Console.WriteLine($"ReadStr 成功,ip={plc.IP} addr={byteAddr} res={result}"); if (result.Length == 0) { Link(plc); } } else { Console.WriteLine("准备连接plc"); Link(plc); } } } catch (Exception ex) { Console.WriteLine($"ReadStr,device={device} addr={byteAddr} count={count} err={ex.Message}"); LogHelper.Error($"ReadStr,device={device} addr={byteAddr} count={count} err={ex.Message}", ex); } return result; } public static PlcDeviceTable plcDeviceTables = new PlcDeviceTable(); /// /// 获取输送线数据 /// public static void ReadSsxPLc() { var db = new SqlHelper().GetInstance(); try { var linkplc = Settings.SafeInteractions.FindAll(a => a.code == 1|| a.code == 7).ToList(); var plc = new Plc(CpuType.S71500, linkplc[1].ip, 0, 1); Link(plc); var plc1 = new Plc(CpuType.S71200, linkplc[0].ip, 0, 1); Link(plc1); //拆托机 //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 //var rawValue = plc1.Read(DataType.DataBlock, 51, 0, VarType.Int, 1); //LogHelper.Info($"Raw value: {rawValue}, Type: {rawValue?.GetType()}"); // RGV允许卸货状态读取 (从DB51读取) int rgv1AllowUnload = Convert.ToInt32(plc1.Read(DataType.DataBlock, 51, 0, VarType.Int, 1)); int rgv2AllowUnload = Convert.ToInt32(plc1.Read(DataType.DataBlock, 51, 2, VarType.Int, 1)); int rgv3AllowUnload = Convert.ToInt32(plc1.Read(DataType.DataBlock, 51, 4, VarType.Int, 1)); int rgv4AllowUnload = Convert.ToInt32(plc1.Read(DataType.DataBlock, 51, 6, VarType.Int, 1)); int rgv5AllowUnload = Convert.ToInt32(plc1.Read(DataType.DataBlock, 51, 8, VarType.Int, 1)); int rgv6AllowUnload = Convert.ToInt32(plc1.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) { plcDeviceTables.requestTake1 = requestTake1; plcDeviceTables.requestPut1 = requestPut1; plcDeviceTables.requestTake2 = requestTake2; plcDeviceTables.requestPut2 = requestPut2; plcDeviceTables.RGVAllowUnload = new Dictionary { {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 { {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; } } ///// ///// 获取输送线数据 ///// //public static void oldReadSsxPLc() //{ // //#region 测试写入数据 // //List s7Models = new List(); // //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().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; // } //} ///// ///// 批量写入方法 ///// ///// 写入list ///// 写入db ///// 配置文件 //public static void Write(List writemodels, int readdb, LinePlcInfo plcInfo) //{ // // var plcInfo = Settings.linePlcInfo.Where(a => (a.deviceNo == "2") && a.enable == 1).FirstOrDefault(); // //获取配置文件写入的地址 // //List writemodels = Settings.plcValue.Find(a => a.address == plcInfo.address).read; // if (writemodels.Count > 0) // { // byte[] bytes = GetWriteByte(writemodels); // if (PLCWrite(plcInfo, readdb, bytes)) // { // Console.WriteLine("写入成功"); // //写入成功校验数据 // //Read(); // //if (Dictvalues[plcInfo.address].Find(a => a.addr == 2).value == "2") // //{ // // Console.WriteLine("数据校验成功,修改任务状态"); // //} // } // else // { // Console.WriteLine("写入失败"); // } // } // // int taskNo = 12100001; // //写入byte数据,杭叉堆垛机默认从偏移量6开始 6,8,10为起点排列层 12 14 16终点排列层 18任务类型以此类推,具体写入byte根据文档调整 // // byte[] bytes = new byte[30] { // //0,(byte)int.Parse("2"), // //0,(byte)int.Parse("3"), // //0,(byte)int.Parse("4"), // //0,(byte)int.Parse("5"), // //0,(byte)int.Parse("6"), // //0,(byte)int.Parse("7"), // //0,(byte)1, // //0,1, // //0,0, // //0,0, // //0,0, // //0,0, // //0,0, // //(byte)((uint)(taskNo >> 24) & 0xFFu), // //(byte)((uint)(taskNo >> 16) & 0xFFu), // //(byte)((uint)(taskNo >> 8) & 0xFFu), // //(byte)((uint)taskNo & 0xFFu) // //}; // //byte[] bytes = new byte[4] { // // 0,(byte)int.Parse("2"), // //0,(byte)int.Parse("3") // //}; //} ///// ///// S7写入byte数组 ///// ///// 配置文件 ///// DB块 ///// ///// //public static bool PLCWrite(Settings.LinePlcInfo plcInfo, int db, byte[] bytes) //{ // bool result = false; // var plc = new Plc(CpuType.S71500, plcInfo.address, 0, 1); // Link(plc); // try // { // result = plc.WriteBytes(DataType.DataBlock, Convert.ToInt16(db), Convert.ToInt16(plcInfo.writeAddr), bytes) == ErrorCode.NoError; // return result; // } // catch (Exception ex) // { // throw ex; // } //} /// /// 将要写的数据转换成byte /// /// /// public static byte[] GetWriteByte(List writemodels) { var model = writemodels.OrderByDescending(a => a.addr).First(); var readlen = model.addr + model.length; byte[] bytes = new byte[readlen]; foreach (var item in writemodels) { if (!string.IsNullOrEmpty(item.value)) { //转换byte switch (item.type) { case "Int": case "Bit": bytes[item.addr] = (byte)((uint)(int.Parse(item.value) >> 8) & 0xFFu); bytes[item.addr + 1] = (byte)((uint)(int.Parse(item.value) >> 0) & 0xFFu); break; case "DInt": case "Real": bytes[item.addr] = (byte)((uint)(int.Parse(item.value) >> 24) & 0xFFu); bytes[item.addr + 1] = (byte)((uint)(int.Parse(item.value) >> 16) & 0xFFu); bytes[item.addr + 2] = (byte)((uint)(int.Parse(item.value) >> 8) & 0xFFu); bytes[item.addr + 3] = (byte)((uint)(int.Parse(item.value) >> 0) & 0xFFu); break; case "String": case "Byte": var bytevalue = Encoding.UTF8.GetBytes(item.value); if (bytevalue.Count() <= item.length) { for (int i = 0; i < bytevalue.Count(); i++) { bytes[item.addr + item.length - bytevalue.Count() + i] = bytevalue[i]; } } break; } } } return bytes; } /// /// S7读取byte数组 /// /// 地址 /// DB块 /// 读取起始偏移量 /// 输出byte /// public static bool PLCRead(string address, int db, int addr, int len, out byte[] bytes) { bool result = false; var plc = new Plc(CpuType.S71500, address, 0, 1); Link(plc); string res = string.Empty; bytes = new byte[len]; try { bytes = plc.ReadBytes(DataType.DataBlock, Convert.ToInt16(db), Convert.ToInt16(addr), len); var r1 = "new byte[] {" + string.Join(",", bytes) + " }"; res = $" B{db} A{addr} L{len} A{r1}"; } catch (Exception ex) { res = "Err" + ex.Message + ex.StackTrace; } // result = plc.WriteBytes(DataType.DataBlock, Convert.ToInt16(1000), Convert.ToInt16(linePlcInfo.writeAddr + 6), bytes) == ErrorCode.NoError; return result; } /// /// 解析 /// /// /// /// /// /// public static string GetValue(int adr, VarType varType, byte[] d, int length = 1) { //计算类型长度,string类型为可变长度用配置文件定义的长度 var vlen = VarTypeToByteLength(varType); if (varType == VarType.String) { vlen = length; } if (adr + vlen > d.Length) { return ""; } var adrbyte = d.Skip(adr).Take(vlen).ToArray(); if (varType == VarType.String) { adrbyte = adrbyte.Skip(adrbyte.ToList().FindIndex(x => x > 0)).ToArray(); } var obj = ParseBytes(varType, adrbyte, 1, 0); return obj.ToString(); } private static int VarTypeToByteLength(VarType varType, int varCount = 1) { switch (varType) { case VarType.Bit: return varCount; case VarType.Byte: if (varCount >= 1) { return varCount; } return 1; case VarType.String: return varCount; case VarType.Word: case VarType.Int: case VarType.Timer: case VarType.Counter: return varCount * 2; case VarType.DWord: case VarType.DInt: case VarType.Real: return varCount * 4; default: return 0; } } private static object ParseBytes(VarType varType, byte[] bytes, int varCount, byte bitAdr = 0) { if (bytes == null) { return null; } switch (varType) { case VarType.Byte: if (varCount == 1) { return bytes[0]; } return bytes; case VarType.Word: if (varCount == 1) { return Word.FromByteArray(bytes); } return Word.ToArray(bytes); case VarType.Int: if (varCount == 1) { return Int.FromByteArray(bytes); } return Int.ToArray(bytes); case VarType.DWord: if (varCount == 1) { return DWord.FromByteArray(bytes); } return DWord.ToArray(bytes); case VarType.DInt: if (varCount == 1) { return DInt.FromByteArray(bytes); } return DInt.ToArray(bytes); case VarType.Real: if (varCount == 1) { return S7.Net.Types.Double.FromByteArray(bytes); } return S7.Net.Types.Double.ToArray(bytes); case VarType.String: return S7.Net.Types.String.FromByteArray(bytes); case VarType.Timer: if (varCount == 1) { return S7.Net.Types.Timer.FromByteArray(bytes); } return S7.Net.Types.Timer.ToArray(bytes); case VarType.Counter: if (varCount == 1) { return Counter.FromByteArray(bytes); } return Counter.ToArray(bytes); case VarType.Bit: if (varCount == 1) { if (bitAdr > 7) { return null; } return Bit.FromByte(bytes[0], bitAdr); } return Bit.ToBitArray(bytes); default: return null; } } internal static bool WriteDouble(string deviceNo, int db, int byteAddr, int offsetAddr, int data) { var result = false; try { var linkplcs = Settings.linePlcInfos.Find(a => a.deviceNo == deviceNo); var plc = new Plc(CpuType.S71500, linkplcs.address, 0, 1); Link(plc); if (plc.IsConnected) { 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} "); //睡三秒 如果还继续发请求的话就重写入 否则写入false Thread.Sleep(3000); var plcDeviceTable = S7Helper.plcDeviceTables; if (plcDeviceTable != null) { 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 { Console.WriteLine("准备连接plc1"); Link(plc); } } catch (Exception ex) { LogHelper.Error($"写入plc1信息失败,ip={plc.IP} addr={byteAddr} data={data} err={ex.Message}", ex); } return result; } ////单个写入 //public static bool WritePlc(int startAddr, int data, Settings.linePlcInfo plcInfo, int dataType = 16) //{ // var result = false; // S7.Net.Plc plc = null; // plc = plcInfo.deviceNo == "1" ? plc1 : plcInfo.deviceNo == "3" ? plc3 : null; // string rwAction = "写入"; // if (plc != null) // { // try // { // if (plc.IsConnected) // { // //CMMLog.Info($"{rwAction}plc信息-Start,ip={plc.IP} addr={startAddr} data={data}"); // var res = new ErrorCode { }; // //var res = plc7.Write(DataType.DataBlock, 101, Convert.ToInt16(startAddr),1, (Int16)data); // if (dataType == 16) res = plc.Write(DataType.DataBlock, Convert.ToInt16(1000), Convert.ToInt16(startAddr), Convert.ToInt16(data)); // else res = plc.Write(DataType.DataBlock, Convert.ToInt16(1000), Convert.ToInt16(startAddr), Convert.ToInt32(data)); // result = (int)res == 0; // //CMMLog.Info($"{rwAction}plc信息-End,ip={plc.IP} addr={startAddr} data={data} res={res}"); // } // else // { // //CMMLog.Error($"{rwAction}plc信息-UnLink,ip={plc.IP} addr={startAddr} data={data}"); // Link(plc); // //CMMLog.Error($"{rwAction}plc信息-UnLink_ReWrite,ip={plc.IP} addr={startAddr} data={data}"); // result = RWriteStackerPlc1(startAddr, data, plcInfo, dataType); // } // } // catch (Exception ex) // { // //CMMLog.Error($"{rwAction}plc信息失败-Failed,ip={plc.IP} addr={startAddr} data={data} err={ex.Message}"); // Link(plc); // } // if (!result) // { // //CMMLog.Error($"{rwAction}plc信息失败,重新写入-Failed_ReWrite,ip={plc.IP} addr={startAddr} data={data}"); // result = RWriteStackerPlc1(startAddr, data, plcInfo, dataType); // } // } // else CMMLog.Error($"{rwAction}plc信息失败,此设备未进行初始化,配置信息:{JsonConvert.SerializeObject(plcInfo)}"); // return result; // //} //} ////单个写入 //public static bool WriteStackerPlc1(int startAddr, int data, Settings.linePlcInfo plcInfo, int dataType = 16) //{ // //lock (WriteStackerPlc1Lock) // //{ // var result = false; // S7.Net.Plc plc = null; // plc = plcInfo.deviceNo == "1" ? plc1 : plcInfo.deviceNo == "3" ? plc3 : null; // string rwAction = "写入"; // if (plc != null) // { // try // { // if (plc.IsConnected) // { // //CMMLog.Info($"{rwAction}plc信息-Start,ip={plc.IP} addr={startAddr} data={data}"); // var res = new ErrorCode { }; // //var res = plc7.Write(DataType.DataBlock, 101, Convert.ToInt16(startAddr),1, (Int16)data); // if (dataType == 16) res = plc.Write(DataType.DataBlock, Convert.ToInt16(1000), Convert.ToInt16(startAddr), Convert.ToInt16(data)); // else res = plc.Write(DataType.DataBlock, Convert.ToInt16(1000), Convert.ToInt16(startAddr), Convert.ToInt32(data)); // result = (int)res == 0; // //CMMLog.Info($"{rwAction}plc信息-End,ip={plc.IP} addr={startAddr} data={data} res={res}"); // } // else // { // //CMMLog.Error($"{rwAction}plc信息-UnLink,ip={plc.IP} addr={startAddr} data={data}"); // Link(plc); // //CMMLog.Error($"{rwAction}plc信息-UnLink_ReWrite,ip={plc.IP} addr={startAddr} data={data}"); // result = RWriteStackerPlc1(startAddr, data, plcInfo, dataType); // } // } // catch (Exception ex) // { // //CMMLog.Error($"{rwAction}plc信息失败-Failed,ip={plc.IP} addr={startAddr} data={data} err={ex.Message}"); // Link(plc); // } // if (!result) // { // //CMMLog.Error($"{rwAction}plc信息失败,重新写入-Failed_ReWrite,ip={plc.IP} addr={startAddr} data={data}"); // result = RWriteStackerPlc1(startAddr, data, plcInfo, dataType); // } // } // else CMMLog.Error($"{rwAction}plc信息失败,此设备未进行初始化,配置信息:{JsonConvert.SerializeObject(plcInfo)}"); // return result; // //} //} /// /// 批量写入model /// public class S7Model { /// /// 偏移量 /// public int addr { get; set; } /// /// 类型 /// public string type { get; set; } /// /// 长度 /// public int length { get; set; } /// /// 值 /// public string value { get; set; } } //S7写入信号 测试用 internal static Results S7Write(Isusing offsetAddr) { //var linkplcs = Settings.linePlcInfos.Find(a => a.deviceNo == "1"); //var plc = new Plc(CpuType.S71200, linkplcs.address, 0, 1); var linkplc = Settings.SafeInteractions.First(); var plc = new Plc(CpuType.S71200, linkplc.ip, 0, 1); Link(plc); S7Helper.WriteInt(50, offsetAddr.S_STATUS*2-2, (short)(offsetAddr.S_STATUS * 10 + int.Parse(offsetAddr.S_TYPE))); //plc.WriteBit(DataType.DataBlock, 9, 182, offsetAddr, false); return new Results() { Code = "0", Message = $"写入成功", Data = null }; } #region 用于模拟测试 /// /// short类型,一个占2个byte /// public class DBWModel { public int db { get; set; } public int byteAddr { get; set; } /// /// int类型需要用逗号分开,string不需要 /// public string value { get; set; } } /// /// 字符串类型,一个占1个byte /// public class DBBModel { public int db { get; set; } public int byteAddr { get; set; } public string value { get; set; } } public class DBXModel { public int db { get; set; } public int byteAddr { get; set; } public int bitAddr { get; set; } /// /// 1:true 0:false /// public int value { get; set; } } public static void s7SetInt(DBWModel model) { var data = model.value.Replace(",", ""); var s7Key = $"int_{model.db}_{model.byteAddr}_{data.Length}"; if (s7TestData.ContainsKey(s7Key)) { s7TestData[s7Key] = model.value; } else { s7TestData.Add(s7Key, model.value); } } internal static void s7SetBit(DBXModel model) { var s7Key = $"bit_{model.db}_{model.byteAddr}_{model.bitAddr}"; var value = model.value == 1 ? "1" : "0"; if (s7TestData.ContainsKey(s7Key)) { s7TestData[s7Key] = value; } else { s7TestData.Add(s7Key, value); } } internal static void s7SetStr(DBBModel model) { var s7Key = $"str_{model.db}_{model.byteAddr}_{model.value.Length}"; if (s7TestData.ContainsKey(s7Key)) { s7TestData[s7Key] = model.value; } else { s7TestData.Add(s7Key, model.value); } } } #endregion }