| | |
| | | using HH.WCS.JiaTong.api; |
| | | using Microsoft.Owin.BuilderProperties; |
| | | using Newtonsoft.Json.Linq; |
| | | using Opc.UaFx; |
| | | using S7.Net; |
| | | using S7.Net.Types; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | using System.Web.Services.Description; |
| | | using System.Web.UI.WebControls.WebParts; |
| | | |
| | | namespace HH.WCS.JiaTong.device { |
| | | namespace HH.WCS.JiaTong.device |
| | | { |
| | | |
| | | /// <summary> |
| | | /// 西门子plc |
| | | /// </summary> |
| | | public class S7Helper { |
| | | public class S7Helper |
| | | { |
| | | private static bool debug = true; |
| | | private static S7.Net.Plc plc = null; |
| | | static S7Helper() { |
| | | |
| | | static S7Helper() |
| | | { |
| | | Init(); |
| | | } |
| | | private static Dictionary<string, Plc> plcDic = new Dictionary<string, Plc>(); |
| | | private static void Init() { |
| | | private static void Init() |
| | | { |
| | | //配置文件读取所有的plc进行初始化 |
| | | try { |
| | | try |
| | | { |
| | | var plc1 = new Plc(CpuType.S71500, "", 0, 1); |
| | | plcDic.Add("plc1", plc1); |
| | | Link(plc1); |
| | | } |
| | | catch (Exception ex) { |
| | | catch (Exception ex) |
| | | { |
| | | |
| | | Console.WriteLine("S7Helper Init err=" + ex.Message); |
| | | } |
| | | } |
| | | private static Plc GetPlc(string plc) { |
| | | if (plcDic.ContainsKey(plc)) { |
| | | private static Plc GetPlc(string plc) |
| | | { |
| | | if (plcDic.ContainsKey(plc)) |
| | | { |
| | | return plcDic[plc]; |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | public static Dictionary<string, string> s7TestData = new Dictionary<string, string>(); |
| | | 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"); |
| | | } |
| | | 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}"); |
| | | catch (Exception ex) |
| | | { |
| | | // Console.WriteLine($"plc{plc.IP}连接失败,err={ex.Message}"); |
| | | LogHelper.Error($"Link Error plc{plc.IP}连接失败,err={ex.Message}", ex); |
| | | //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 |
| | | |
| | | private static object _lockdpj = new object(); |
| | | |
| | | /// <summary> |
| | | /// 合肥佳通读取叠盘机 |
| | | /// </summary> |
| | | /// <param name="startByte">偏移量地址 vb2001</param> |
| | | /// /// <param name="varType">值类型</param> |
| | | /// <returns></returns> |
| | | public static int ReadDpj(string ip, int startByte, S7.Net.VarType varType) |
| | | { |
| | | // string ip = "10.68.9.15"; |
| | | short port = 102; |
| | | lock (_lockdpj) |
| | | { |
| | | try |
| | | { |
| | | var plc = new Plc(CpuType.S7200Smart, ip, port, 0, 0); |
| | | LogHelper.Info($"链接叠盘机,ip:{ip},端口:{port}"); |
| | | S7Helper.Link(plc); |
| | | int result = 0; |
| | | if (varType == VarType.Int) |
| | | { |
| | | var value = (short)plc.Read(DataType.DataBlock, 1, startByte, VarType.Int, 1); |
| | | LogHelper.Info($"链接叠盘机,ip:{ip},端口:{port},读取类型{varType},读取值{value}"); |
| | | result = int.Parse(value.ToString()); |
| | | } |
| | | else//合肥佳通除了数量,其他都是byte类型 |
| | | { |
| | | |
| | | byte value = (byte)plc.Read(DataType.DataBlock, 1, startByte, VarType.Byte, 1); |
| | | LogHelper.Info($"链接叠盘机,ip:{ip},端口:{port},读取类型{varType},读取值{value}"); |
| | | result = value; |
| | | } |
| | | |
| | | LogHelper.Info($"读取叠盘机,ip:{ip},端口:{port},地址:{startByte},读取值转换:{result}"); |
| | | return result; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info($"叠盘机:{ip}链接失败"); |
| | | LogHelper.Error($"ReadDpj ip:{ip},startByte:{startByte} Error:{ex}", ex); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | |
| | | internal static short[] ReadInt(string device, int db, int byteAddr, int count) { |
| | | |
| | | } |
| | | /// <summary> |
| | | /// 合肥佳通写入叠盘机 |
| | | /// </summary> |
| | | /// <param name="startByte">偏移量地址</param> |
| | | /// <param name="value">写入值 byte类型只能0 1</param> |
| | | /// <returns></returns> |
| | | public static bool WriteDpj(string ip, int startByte, byte value) |
| | | { |
| | | bool result = false; |
| | | // string ip = "10.68.9.15"; |
| | | short port = 102; |
| | | lock (_lockdpj) |
| | | { |
| | | try |
| | | { |
| | | var plc = new Plc(CpuType.S7200Smart, ip, port, 0, 0); |
| | | |
| | | LogHelper.Info($"链接叠盘机,ip:{ip},端口:{port}"); |
| | | S7Helper.Link(plc); |
| | | // plc.Write($"VB{startByte}", value); |
| | | Thread.Sleep(300); |
| | | plc.Write( |
| | | dataType: DataType.DataBlock, |
| | | db: 1, |
| | | startByteAdr: startByte, |
| | | value: value |
| | | ); |
| | | LogHelper.Info($"写入叠盘机,ip:{ip},端口:{port},地址:{startByte},写入值:{value}"); |
| | | Thread.Sleep(300); |
| | | byte fdvalue = (byte)plc.Read(DataType.DataBlock, 1, startByte, VarType.Byte, 1); |
| | | if (fdvalue == value) |
| | | { |
| | | result = true; |
| | | LogHelper.Info($"叠盘机写入成功,回读值:{fdvalue}"); |
| | | } |
| | | else |
| | | { |
| | | // Task.Run(() => WriteDpj(ip, startByte, value)); |
| | | LogHelper.Info($"叠盘机写入失败,回读值:{fdvalue}"); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | // Task.Run(() => WriteDpj(ip, startByte, value)); |
| | | LogHelper.Info($"叠盘机:{ip}链接失败"); |
| | | LogHelper.Error($"WriteDpj ip:{ip},startByte:{startByte} Error:{ex}", ex); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // S7-200 Smart的V区也映射为DB1 |
| | | |
| | | |
| | | |
| | | } |
| | | internal static short[] ReadInt(string device, int db, int byteAddr, int count) |
| | | { |
| | | short[] result = null; |
| | | try { |
| | | if (debug) { |
| | | try |
| | | { |
| | | if (debug) |
| | | { |
| | | var s7Key = $"int_{db}_{byteAddr}_{count}"; |
| | | if (s7TestData.ContainsKey(s7Key)) { |
| | | if (s7TestData.ContainsKey(s7Key)) |
| | | { |
| | | var data = s7TestData[s7Key].Split(','); |
| | | if (data.Length == count) { |
| | | if (data.Length == count) |
| | | { |
| | | result = Array.ConvertAll(data, s => short.Parse(s)); |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | result = new short[count]; |
| | | s7TestData[s7Key] = string.Join(",", result); |
| | | } |
| | | Console.WriteLine($"读取plc {device}信息成功, addr={byteAddr} data={string.Join(",", result)}"); |
| | | } |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | var plc = GetPlc(device); |
| | | if (plc != null) { |
| | | if (plc.IsConnected) { |
| | | 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) { |
| | | if (result.Length == 0) |
| | | { |
| | | Console.WriteLine($"plc {device}准备重新连接"); |
| | | Link(plc); |
| | | } |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | Console.WriteLine($"准备连接plc {device}"); |
| | | Link(plc); |
| | | } |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | Console.WriteLine($"plc {device}不存在"); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) { |
| | | 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; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// |
| | |
| | | /// <param name="byteAddr"></param> |
| | | /// <param name="data"></param> |
| | | /// <returns></returns> |
| | | internal static bool WriteInt(int db, int byteAddr, short data) { |
| | | internal static bool WriteInt(int db, int byteAddr, short data) |
| | | { |
| | | var result = false; |
| | | try { |
| | | if (plc.IsConnected) { |
| | | try |
| | | { |
| | | 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) { |
| | | 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)}"); |
| | |
| | | |
| | | |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | Console.WriteLine("准备连接plc1"); |
| | | Link(plc); |
| | | } |
| | | } |
| | | catch (Exception ex) { |
| | | 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) { |
| | | public static object ReadBit(string device, int db, int byteAddr, byte bitAddr) |
| | | { |
| | | object result = null; |
| | | try { |
| | | if (debug) { |
| | | try |
| | | { |
| | | if (debug) |
| | | { |
| | | var s7Key = $"bit_{db}_{byteAddr}_{bitAddr}"; |
| | | if (s7TestData.ContainsKey(s7Key)) { |
| | | if (s7TestData.ContainsKey(s7Key)) |
| | | { |
| | | var data = s7TestData[s7Key]; |
| | | if (data == "1") { |
| | | if (data == "1") |
| | | { |
| | | result = true; |
| | | } |
| | | else { result = false; } |
| | | Console.WriteLine($"读取plc {device}信息成功, addr={byteAddr} data={result.ToString()}"); |
| | | } |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | var plc = GetPlc(device); |
| | | if (plc != null) { |
| | | if (plc.IsConnected) { |
| | | 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 { |
| | | else |
| | | { |
| | | Console.WriteLine($"准备连接plc {device}"); |
| | | Link(plc); |
| | | } |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | Console.WriteLine($"plc {device}不存在"); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) { |
| | | 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) { |
| | | public static string ReadStr(string device, int db, int byteAddr, int count) |
| | | { |
| | | string result = string.Empty; |
| | | try { |
| | | if (debug) { |
| | | try |
| | | { |
| | | if (debug) |
| | | { |
| | | var s7Key = $"str_{db}_{byteAddr}_{count}"; |
| | | if (s7TestData.ContainsKey(s7Key)) { |
| | | if (s7TestData.ContainsKey(s7Key)) |
| | | { |
| | | var data = s7TestData[s7Key]; |
| | | if (data.Length == count) { |
| | | if (data.Length == count) |
| | | { |
| | | result = data; |
| | | Console.WriteLine($"ReadStr 成功, addr={byteAddr} res={result}"); |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | if (plc.IsConnected) { |
| | | 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) { |
| | | if (result.Length == 0) |
| | | { |
| | | Link(plc); |
| | | } |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | Console.WriteLine("准备连接plc"); |
| | | Link(plc); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) { |
| | | 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); |
| | | } |
| | |
| | | /// <summary> |
| | | /// short类型,一个占2个byte |
| | | /// </summary> |
| | | public class DBWModel { |
| | | public class DBWModel |
| | | { |
| | | public int db { get; set; } |
| | | public int byteAddr { get; set; } |
| | | /// <summary> |
| | |
| | | /// <summary> |
| | | /// 字符串类型,一个占1个byte |
| | | /// </summary> |
| | | public class DBBModel { |
| | | public class DBBModel |
| | | { |
| | | public int db { get; set; } |
| | | public int byteAddr { get; set; } |
| | | public string value { get; set; } |
| | | } |
| | | public class DBXModel { |
| | | public class DBXModel |
| | | { |
| | | public int db { get; set; } |
| | | public int byteAddr { get; set; } |
| | | public int bitAddr { get; set; } |
| | |
| | | /// </summary> |
| | | public int value { get; set; } |
| | | } |
| | | public static void s7SetInt(DBWModel model) { |
| | | public static void s7SetInt(DBWModel model) |
| | | { |
| | | var data = model.value.Replace(",", ""); |
| | | var s7Key = $"int_{model.db}_{model.byteAddr}_{data.Length}"; |
| | | if (s7TestData.ContainsKey(s7Key)) { |
| | | if (s7TestData.ContainsKey(s7Key)) |
| | | { |
| | | s7TestData[s7Key] = model.value; |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | s7TestData.Add(s7Key, model.value); |
| | | } |
| | | } |
| | | |
| | | internal static void s7SetBit(DBXModel model) { |
| | | 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)) { |
| | | if (s7TestData.ContainsKey(s7Key)) |
| | | { |
| | | s7TestData[s7Key] = value; |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | s7TestData.Add(s7Key, value); |
| | | } |
| | | } |
| | | |
| | | internal static void s7SetStr(DBBModel model) { |
| | | internal static void s7SetStr(DBBModel model) |
| | | { |
| | | var s7Key = $"str_{model.db}_{model.byteAddr}_{model.value.Length}"; |
| | | if (s7TestData.ContainsKey(s7Key)) { |
| | | if (s7TestData.ContainsKey(s7Key)) |
| | | { |
| | | s7TestData[s7Key] = model.value; |
| | | } |
| | | else { |
| | | else |
| | | { |
| | | s7TestData.Add(s7Key, model.value); |
| | | } |
| | | } |