diff --git a/SlnMesnac.Common/CommonSetup.cs b/SlnMesnac.Common/CommonSetup.cs new file mode 100644 index 0000000..dc9fb33 --- /dev/null +++ b/SlnMesnac.Common/CommonSetup.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; + +namespace SlnMesnac.Common +{ + public static class CommonSetup + { + public static void AddCommonSetup(this IServiceCollection services) + { + services.AddSingleton(); + } + } +} diff --git a/SlnMesnac.Common/SlnMesnac.Common.csproj b/SlnMesnac.Common/SlnMesnac.Common.csproj index 8ef8970..d031ec1 100644 --- a/SlnMesnac.Common/SlnMesnac.Common.csproj +++ b/SlnMesnac.Common/SlnMesnac.Common.csproj @@ -5,4 +5,9 @@ enable + + + + + diff --git a/SlnMesnac.Common/StringChange.cs b/SlnMesnac.Common/StringChange.cs new file mode 100644 index 0000000..7a52411 --- /dev/null +++ b/SlnMesnac.Common/StringChange.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; + +namespace SlnMesnac.Common +{ + public class StringChange + { + //private static readonly Lazy lazy = new Lazy(() => new StringChange()); + //public static StringChange Instance + //{ + // get + // { + // return lazy.Value; + // } + //} + + //private StringChange() { } + + /// + /// 将字符串强制转换成int,转换失败则返回0 + /// + /// + /// + public int ParseToInt(string str) + { + int returnInt = 0; + if (str == null || str.Trim().Length < 1) + { + return returnInt; + } + if (int.TryParse(str, out returnInt)) + { + return returnInt; + } + else + { + return 0; + } + } + + /// + /// char数组转Array + /// + /// + /// + /// + public string CharArrayToString(char[] cha, int len) + { + string str = ""; + for (int i = 0; i < len; i++) + { + str += string.Format("{0}", cha[i]); + } + + return str; + } + + public string bytesToHexStr(byte[] bytes, int iLen)//e.g. { 0x01, 0x01} ---> " 01 01" + { + string returnStr = ""; + if (bytes != null) + { + for (int i = 0; i < iLen; i++) + { + returnStr += bytes[i].ToString("X2"); + } + } + return returnStr; + } + + public byte[] HexStrTorbytes(string strHex)//e.g. " 01 01" ---> { 0x01, 0x01} + { + strHex = strHex.Replace(" ", ""); + if ((strHex.Length % 2) != 0) + strHex += " "; + byte[] returnBytes = new byte[strHex.Length / 2]; + for (int i = 0; i < returnBytes.Length; i++) + returnBytes[i] = Convert.ToByte(strHex.Substring(i * 2, 2), 16); + return returnBytes; + } + + public string StringToHexString(string s, Encoding encode) + { + byte[] b = encode.GetBytes(s); //按照指定编码将string编程字节数组 + string result = string.Empty; + for (int i = 0; i < b.Length; i++) //逐字节变为16进制字符,以%隔开 + { + result += "%" + Convert.ToString(b[i], 16); + } + return result; + } + + public string HexStringToString(string hs, Encoding encode) + { + //以%分割字符串,并去掉空字符 + string[] chars = hs.Split(new char[] { '%' }, StringSplitOptions.RemoveEmptyEntries); + byte[] b = new byte[chars.Length]; + //逐个字符变为16进制字节数据 + for (int i = 0; i < chars.Length; i++) + { + b[i] = Convert.ToByte(chars[i], 16); + } + //按照指定编码将字节数组变为字符串 + return encode.GetString(b); + } + + public byte[] Swap16Bytes(byte[] OldU16) + { + byte[] ReturnBytes = new byte[2]; + ReturnBytes[1] = OldU16[0]; + ReturnBytes[0] = OldU16[1]; + return ReturnBytes; + } + + + /// 64Base码 + /// 保存路径 + /// 文件名称 + /// + public bool Base64ToImage(string strbase64, string path, string filename) + { + bool Flag = false; + try + { + //base64编码的文本 转为 图片 + //图片名称 + byte[] arr = Convert.FromBase64String(strbase64);//将指定的字符串(它将二进制数据编码为 Base64 数字)转换为等效的 8 位无符号整数数组。 + using (MemoryStream ms = new MemoryStream(arr)) + { + Bitmap bmp = new Bitmap(ms);//加载图像 + if (!Directory.Exists(path))//判断保存目录是否存在 + { + Directory.CreateDirectory(path); + } + bmp.Save((path + "\\" + filename + ".png"), System.Drawing.Imaging.ImageFormat.Png);//将图片以JPEG格式保存在指定目录(可以选择其他图片格式) + ms.Close();//关闭流并释放 + if (File.Exists(path + "\\" + filename + ".png"))//判断是否存在 + { + Flag = true; + } + } + } + catch (Exception ex) + { + Console.WriteLine("图片保存失败:" + ex.Message); + } + return Flag; + } + + /// + /// 获取时间戳 + /// + /// + public long GetTimeStamp() + { + TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); + return Convert.ToInt64(ts.TotalSeconds); + } + + public byte[] ConvertFloatToINt(byte[] floatBytes) + { + byte[] intBytes = new byte[floatBytes.Length / 2]; + for (int i = 0; i < intBytes.Length; i++) + { + intBytes[i] = floatBytes[i * 2]; + } + return intBytes; + } + + //CRC异或校验 + public byte CalculateVerify(byte[] pMessage, int iLength) + { + UInt16 i; + byte iVerify = 0; + + iVerify = pMessage[0]; + for (i = 1; i < iLength; i++) + { + iVerify = (byte)(iVerify ^ pMessage[i]); + } + return iVerify; + } + + public int HexStringToNegative(string strNumber) + { + + int iNegate = 0; + int iNumber = Convert.ToInt32(strNumber, 16); + if (iNumber > 127) + { + int iComplement = iNumber - 1; + string strNegate = string.Empty; + char[] binchar = Convert.ToString(iComplement, 2).PadLeft(8, '0').ToArray(); + foreach (char ch in binchar) + { + if (Convert.ToInt32(ch) == 48) + { + strNegate += "1"; + } + else + { + strNegate += "0"; + } + } + iNegate = -Convert.ToInt32(strNegate, 2); + } + return iNegate; + } + } +} \ No newline at end of file diff --git a/SlnMesnac.Library/HslCommunication.dll b/SlnMesnac.Library/HslCommunication.dll new file mode 100644 index 0000000..7082ca2 Binary files /dev/null and b/SlnMesnac.Library/HslCommunication.dll differ diff --git a/SlnMesnac.Plc/IPlc.cs b/SlnMesnac.Plc/IPlc.cs new file mode 100644 index 0000000..c1b1055 --- /dev/null +++ b/SlnMesnac.Plc/IPlc.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SlnMesnac.Plc +{ + public interface IPlc + { + /// + /// 连接标识 + /// + bool IsConnected { get; set; } + + /// + /// 建立连接 + /// + /// + /// + /// + bool Connect(string IP, int port); + + /// + /// 断开连接 + /// + /// + bool DisConnect(); + + /// + /// 通过地址和长度读取PLC数据 + /// + /// + /// + /// + byte[] readValueByAddress(int len, string address); + + /// + /// 通过PLC地址写入int类型数据 + /// + /// + /// + /// + bool writeValueByAddress(int value, string address); + + /// + /// 通过PLC地址清零数据 + /// + /// + /// + /// + bool resetByAddress(string address, int len); + + /// + /// 通过PLC地址读取EA值 + /// + /// + /// + string readEaByAddress(string address); + + /// + /// 通过PLC地址读取交互信号 + /// + /// + /// + int readInteractiveSignal(string address); + + /// + /// 通过PLC地址读取int32类型数据 + /// + /// + /// + int readInt32ByAddress(string address); + + /// + /// 通过PLC地址写入int32类型数据 + /// + /// + /// + /// + bool writeInt32ByAddress(string address, int value); + + /// + /// 通过PLC地址读取string类型数据 + /// + /// + /// + string readStringByAddress(string address, ushort length); + + /// + /// 通过PLC地址写入String类型数据 + /// + /// + /// + /// + bool writeStringByAddress(string address, string value); + + /// + /// 通过PLC地址读取Bool类型数据 + /// + /// + /// + bool readBoolByAddress(string address); + + /// + /// 通过PLC地址写入Bool类型数据 + /// + /// + /// + bool writeBoolByAddress(string address, bool value); + + /// + /// 通过PLC地址写入Double类型数据 + /// + /// + /// + /// + bool writeDoubleByAddress(string address, int value); + } +} diff --git a/SlnMesnac.Plc/Impl/InovancePlc.cs b/SlnMesnac.Plc/Impl/InovancePlc.cs new file mode 100644 index 0000000..9510fbf --- /dev/null +++ b/SlnMesnac.Plc/Impl/InovancePlc.cs @@ -0,0 +1,492 @@ +using HslCommunication.Profinet.Inovance; +using HslCommunication; +using System; +using System.Collections.Generic; +using System.Text; +using SlnMesnac.Common; +using Microsoft.Extensions.Logging; + +namespace SlnMesnac.Plc.Impl +{ + /// + /// 汇川PLC + /// + public class InovancePlc : IPlc + { + private ILogger _logger; + + private StringChange _stringChange; + + private InovanceTcpNet inovanceTcp = null; + + public InovancePlc(ILogger logger, StringChange stringChange) + { + this._logger = logger; + _stringChange = stringChange; + + this.inovanceTcp = new InovanceTcpNet(); + this.inovanceTcp.ConnectTimeOut = 2000; + } + + public bool IsConnected { get; set; } + + /// + /// 建立连接 + /// + /// + /// + /// + public bool Connect(string IP, int port) + { + inovanceTcp?.ConnectClose(); + + PrintLogInfo("汇川PLC连接开始"); + inovanceTcp.IpAddress = IP; + inovanceTcp.Port = 502; + inovanceTcp.DataFormat = HslCommunication.Core.DataFormat.CDAB; + try + { + OperateResult connect = inovanceTcp.ConnectServer(); + if (connect.IsSuccess) + { + this.IsConnected = true; + PrintLogInfo("汇川PLC建立连接成功!!!"); + return true; + } + else + { + this.IsConnected = false; + PrintLogInfo("汇川PLC建立连接失败!!!"); + return false; + } + } + catch (Exception ex) + { + this.IsConnected = false; + PrintLogInfo("欧姆龙NJ系列PLC建立连接异常", ex); + return false; + } + } + + /// + /// 断开连接 + /// + /// + public bool DisConnect() + { + return inovanceTcp.ConnectClose().IsSuccess; + } + + /// + /// 通过地址和长度读取PLC数据 + /// + /// + /// + /// + /// + public byte[] readValueByAddress(int len, string address) + { + //PrintLogInfo("开始通过PLC地址和长度读取PLC数据"); + try + { + OperateResult read = inovanceTcp.Read(address, (ushort)(len)); + if (read.IsSuccess) + { + byte[] result = _stringChange.ConvertFloatToINt(read.Content); + PrintLogInfo(String.Format("通过地址和长度读取PLC数据成功:{0}", _stringChange.bytesToHexStr(result, result.Length))); + return result; + } + else + { + PrintLogInfo("通过地址和长度读取PLC数据失败!!!"); + this.IsConnected = false; + return new byte[0]; + } + } + catch (Exception ex) + { + PrintLogInfo("通过地址和长度读取PLC数据异常", ex); + this.IsConnected = false; + return new byte[0]; + } + } + + /// + /// 通过PLC地址写入int类型数据,模切汇川PLC复位逻辑 + /// + /// + /// + /// + /// + public bool writeValueByAddress(int value, string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}", address, value)); + OperateResult operateResult = new OperateResult(); + try + { + int s = 0; + string[] strArry = address.Split('.'); + + //先读取整个块的内容 + var info = inovanceTcp.ReadInt16(strArry[0]); + if (info.Content == 0) + { + int length = _stringChange.ParseToInt(strArry[1]) + 1; + string[] array = new string[length]; + for (int i = 0; i < length; i++) + { + if (i == _stringChange.ParseToInt(strArry[1])) + { + array[i] = value.ToString(); + } + else + { + array[i] = "0"; + } + } + //反转 + Array.Reverse(array); + byte[] buffer = new byte[array.Length]; + string result = ""; + for (int i = 0; i < array.Length; i++) + { + result += (byte)Convert.ToInt32(array[i], 16); + } + s = Convert.ToInt32(result.Trim(), 2); + operateResult = inovanceTcp.Write(strArry[0], (ushort)s); + } + else + { + var inf2 = Convert.ToString(info.Content, 2); + string[] infoArray = new string[inf2.Length]; + for (int i = 0; i < inf2.Length; i++) + { + infoArray[i] = inf2.Substring(i, 1); + } + Array.Reverse(infoArray); + infoArray[_stringChange.ParseToInt(strArry[1])] = value.ToString(); + string result = ""; + foreach (var item in infoArray) + { + result = result + item; + } + s = Convert.ToInt32(result.Trim(), 10); + operateResult = inovanceTcp.Write(strArry[0], s); + } + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址写入int类型数据", ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址清零数据 + /// + /// + /// + /// + /// + public bool resetByAddress(string address, int len) + { + // PrintLogInfo(String.Format("开发通过PLC地址{0}清零数据", address)); + try + { + byte[] write = new byte[len * 2]; + for (int i = 0; i < len * 2; i++) + { + write[i] = 0; + } + OperateResult operateResult = inovanceTcp.Write(address, write); + + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}清零数据成功", address)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}清零数据失败!!!", address)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}清零数据异常", address), ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址读取EA值 + /// + /// + /// + /// + public string readEaByAddress(string address) + { + //PrintLogInfo(String.Format("通过PLC地址{0}读取EA值", address)); + try + { + OperateResult read = inovanceTcp.Read(address, (ushort)(8)); + + if (read.IsSuccess && read.Content != null) + { + string result = Convert.ToString(read.Content); + PrintLogInfo(String.Format("通过PLC地址{0}读取EA值成功:{1}", address, result)); + return result; + } + else + { + PrintLogInfo(String.Format("通过PLC地址{0}读取EA值失败!!!", address)); + this.IsConnected = false; + return ""; + } + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取EA值异常", ex); + this.IsConnected = false; + return ""; + } + } + + /// + /// 通过PLC地址读取交互信号 + /// + /// + /// + public int readInteractiveSignal(string address) + { + // PrintLogInfo(String.Format("开始通过PLC地址{0}读取交互信号", address)); + try + { + OperateResult read = inovanceTcp.ReadInt16(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号失败!!!", address)); + this.IsConnected = false; + return 0; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取交互信号异常", ex); + this.IsConnected = false; + return 0; + } + } + + /// + /// 通过PLC地址读取int32类型数据 + /// + /// + /// + public int readInt32ByAddress(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取int32类型数据", address)); + try + { + OperateResult read = inovanceTcp.ReadInt16(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据失败!!!", address)); + this.IsConnected = false; + return 0; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + this.IsConnected = false; + return 0; + } + } + + /// + /// 通过PLC地址写入int32类型数据 + /// + /// + /// + /// + /// + public bool writeInt32ByAddress(string address, int value) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address, value)); + try + { + OperateResult write = inovanceTcp.Write(address, short.Parse(Convert.ToString(value))); + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address, value)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据异常", address), ex); + return false; + } + } + + /// + /// 通过PLC地址写入String类型数据 + /// + /// + /// + /// + /// + public bool writeStringByAddress(string address, string value) + { + //PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}", address, value)); + try + { + OperateResult operateResult = inovanceTcp.Write(address, value); + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据异常", address), ex); + return false; + } + } + + /// + /// 通过PLC地址读取string类型数据 + /// + /// + /// + /// + public string readStringByAddress(string address, ushort length) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取string类型数据", address)); + try + { + OperateResult read = inovanceTcp.ReadString(address, length); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据失败!!!", address)); + return ""; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + return ""; + } + } + + /// + /// 通过PLC地址读取Bool类型数据 + /// + /// + /// + /// + public bool readBoolByAddress(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取bool类型数据", address)); + try + { + OperateResult read = inovanceTcp.ReadBool(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据成功{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据失败!!!", address)); + return false; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取bool类型数据异常", ex); + return false; + } + } + + /// + /// 通过PLC地址写入Bool类型数据 + /// + /// + /// + /// + /// + public bool writeBoolByAddress(string address, bool value) + { + // PrintLogInfo(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value)); + try + { + + OperateResult write = inovanceTcp.Write(address, value); + + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据异常", address), ex); + return false; + } + } + + /// + /// 写入Double类型 + /// + /// + /// + /// + public bool writeDoubleByAddress(string address, int value) + { + try + { + OperateResult write = inovanceTcp.Write(address, Convert.ToDouble(value)); + + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据{1}失败!!!", address, value)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据异常", address), ex); + return false; + } + } + + private void PrintLogInfo(string message, Exception ex = null) + { + + } + + } +} \ No newline at end of file diff --git a/SlnMesnac.Plc/Impl/MelsecBinaryPlc.cs b/SlnMesnac.Plc/Impl/MelsecBinaryPlc.cs new file mode 100644 index 0000000..5533efa --- /dev/null +++ b/SlnMesnac.Plc/Impl/MelsecBinaryPlc.cs @@ -0,0 +1,443 @@ +using HslCommunication.Profinet.Melsec; +using HslCommunication; +using SlnMesnac.Common; +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Extensions.Logging; + +namespace SlnMesnac.Plc.Impl +{ + /// + /// 三菱Q系列Plc-Binary + /// + public class MelsecBinaryPlc : IPlc + { + private ILogger _logger; + + private StringChange _stringChange; + + private MelsecMcNet melsec_net = null; + + public MelsecBinaryPlc(ILogger logger, StringChange stringChange) + { + _logger = logger; + _stringChange = stringChange; + + this.melsec_net = new MelsecMcNet(); + this.melsec_net.ConnectTimeOut = 2000; + } + + public bool IsConnected { get; set; } + + /// + /// 建立连接 + /// + /// + /// + /// + public bool Connect(string IP, int port) + { + PrintLogInfo("三菱Q系列PLC连接开始"); + melsec_net.IpAddress = IP; + melsec_net.Port = port; + try + { + OperateResult connect = melsec_net.ConnectServer(); + if (connect.IsSuccess) + { + this.IsConnected = true; + PrintLogInfo("三菱Q系列PLC建立连接成功!!!"); + return true; + } + else + { + this.IsConnected = false; + PrintLogInfo("三菱Q系列PLC建立连接失败!!!"); + return false; + } + } + catch (Exception ex) + { + this.IsConnected = false; + PrintLogInfo("三菱Q系列PLC建立连接异常", ex); + return false; + } + } + + /// + /// 断开连接 + /// + /// + public bool DisConnect() + { + return melsec_net.ConnectClose().IsSuccess; + } + + /// + /// 通过地址和长度读取PLC数据 + /// + /// + /// + /// + /// + public byte[] readValueByAddress(int len, string address) + { + //PrintLogInfo("开始通过PLC地址和长度读取PLC数据"); + try + { + OperateResult read = melsec_net.Read(address, (ushort)(len)); + if (read.IsSuccess) + { + byte[] result = _stringChange.ConvertFloatToINt(read.Content); + PrintLogInfo(String.Format("通过地址和长度读取PLC数据成功:{0}", _stringChange.bytesToHexStr(result, result.Length))); + return result; + } + else + { + PrintLogInfo("通过地址和长度读取PLC数据失败!!!"); + this.IsConnected = false; + return new byte[0]; + } + } + catch (Exception ex) + { + PrintLogInfo("通过地址和长度读取PLC数据异常", ex); + this.IsConnected = false; + return new byte[0]; + } + } + + /// + /// 通过PLC地址写入int类型数据 + /// + /// + /// + /// + /// + public bool writeValueByAddress(int value, string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}",address,value)); + try + { + OperateResult operateResult = melsec_net.Write(address, Convert.ToInt32(value)); + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址写入int类型数据", ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址清零数据 + /// + /// + /// + /// + /// + public bool resetByAddress(string address, int len) + { + //PrintLogInfo(String.Format("开发通过PLC地址{0}清零数据", address)); + try + { + byte[] write = new byte[len * 2]; + for (int i = 0; i < len * 2; i++) + { + write[i] = 0; + } + OperateResult operateResult = melsec_net.Write(address, write); + + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}清零数据成功", address)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}清零数据失败!!!", address)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}清零数据异常", address), ex); + return false; + } + } + + /// + /// 通过PLC地址读取EA值 + /// + /// + /// + /// + public string readEaByAddress(string address) + { + //PrintLogInfo(String.Format("通过PLC地址{0}读取EA值", address)); + try + { + OperateResult read = melsec_net.Read(address, (ushort)(8)); + + if (read.IsSuccess && read.Content != null) + { + string result = Convert.ToString(read.Content); + PrintLogInfo(String.Format("通过PLC地址{0}读取EA值成功:{1}", address, result)); + return result; + } + else + { + PrintLogInfo(String.Format("通过PLC地址{0}读取EA值失败!!!", address)); + this.IsConnected = false; + return ""; + } + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取EA值异常", ex); + this.IsConnected = false; + return ""; + } + } + + /// + /// 通过PLC地址读取交互信号 + /// + /// + /// + public int readInteractiveSignal(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取交互信号", address)); + try + { + OperateResult read = melsec_net.ReadInt16(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号失败!!!", address)); + this.IsConnected = false; + return 0; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取交互信号异常", ex); + this.IsConnected = false; + return 0; + } + } + + /// + /// 通过PLC地址读取int32类型数据 + /// + /// + /// + public int readInt32ByAddress(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取int32类型数据",address)); + try + { + OperateResult read = melsec_net.ReadInt16(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据失败!!!", address)); + this.IsConnected = false; + return 0; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + this.IsConnected = false; + return 0; + } + } + + /// + /// 通过PLC地址写入int32类型数据 + /// + /// + /// + /// + /// + public bool writeInt32ByAddress(string address, int value) + { + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address, value)); + try + { + OperateResult write = melsec_net.Write(address, short.Parse(Convert.ToString(value))); + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据异常", address), ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址写入String类型数据 + /// + /// + /// + /// + /// + public bool writeStringByAddress(string address, string value) + { + //PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}",address,value)); + try + { + OperateResult operateResult = melsec_net.Write(address, value); + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value)); + //this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据异常", address), ex); + //this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址读取string类型数据 + /// + /// + /// + /// + public string readStringByAddress(string address, ushort length) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取string类型数据", address)); + try + { + OperateResult read = melsec_net.ReadString(address, length); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据失败!!!", address)); + this.IsConnected = false; + return ""; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + return ""; + } + } + + /// + /// 通过PLC地址读取Bool类型数据 + /// + /// + /// + /// + public bool readBoolByAddress(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取bool类型数据", address)); + try + { + OperateResult read = melsec_net.ReadBool(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据失败!!!", address)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址写入Bool类型数据 + /// + /// + /// + /// + public bool writeBoolByAddress(string address, bool value) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value)); + try + { + OperateResult write = melsec_net.Write(address, short.Parse(_stringChange.ParseToInt(value ? "1" : "0").ToString())); + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据异常", address), ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 写入Double类型 + /// + /// + /// + /// + public bool writeDoubleByAddress(string address, int value) + { + try + { + OperateResult write = melsec_net.Write(address, Convert.ToDouble(value)); + + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据{1}失败!!!", address, value)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据异常", address), ex); + return false; + } + } + + private void PrintLogInfo(string message, Exception ex = null) + { + + } + } +} diff --git a/SlnMesnac.Plc/Impl/OmronNJPlc.cs b/SlnMesnac.Plc/Impl/OmronNJPlc.cs new file mode 100644 index 0000000..ee47ece --- /dev/null +++ b/SlnMesnac.Plc/Impl/OmronNJPlc.cs @@ -0,0 +1,448 @@ +using HslCommunication.Profinet.Omron; +using HslCommunication; +using SlnMesnac.Common; +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Extensions.Logging; + +namespace SlnMesnac.Plc.Impl +{ + /// + /// 欧姆龙NJ系列PLC + /// + public class OmronNJPlc : IPlc + { + + private ILogger _logger; + + private StringChange _stringChange; + + private OmronFinsNet omronFinsNet = null; + + public OmronNJPlc(ILogger logger,StringChange stringChange) + { + _logger = logger; + _stringChange = stringChange; + + this.omronFinsNet = new OmronFinsNet(); + this.omronFinsNet.ConnectTimeOut = 2000; + } + + public bool IsConnected { get; set; } + + /// + /// 建立连接 + /// + /// + /// + /// + /// + public bool Connect(string IP, int port) + { + PrintLogInfo("欧姆龙NJ系列PLC连接开始"); + omronFinsNet.IpAddress = IP; + omronFinsNet.Port = 9600; + omronFinsNet.SA1 = (byte)192; + omronFinsNet.DA1 = (byte)239; + omronFinsNet.DA2 = (byte)0; + try + { + OperateResult connect = omronFinsNet.ConnectServer(); + if (connect.IsSuccess) + { + this.IsConnected = true; + PrintLogInfo("欧姆龙NJ系列PLC建立连接成功!!!"); + return true; + } + else + { + this.IsConnected = false; + PrintLogInfo("欧姆龙NJ系列PLC建立连接失败!!!"); + return false; + } + } + catch (Exception ex) + { + this.IsConnected = false; + PrintLogInfo("欧姆龙NJ系列PLC建立连接异常", ex); + return false; + } + } + + /// + /// 断开连接 + /// + /// + public bool DisConnect() + { + return omronFinsNet.ConnectClose().IsSuccess; + } + + /// + /// 通过地址和长度读取PLC数据 + /// + /// + /// + /// + /// + public byte[] readValueByAddress(int len, string address) + { + //PrintLogInfo("开始通过PLC地址和长度读取PLC数据"); + try + { + OperateResult read = omronFinsNet.Read(address, (ushort)(len)); + if (read.IsSuccess) + { + byte[] result = _stringChange.ConvertFloatToINt(read.Content); + PrintLogInfo(String.Format("通过地址和长度读取PLC数据成功:{0}", _stringChange.bytesToHexStr(result, result.Length))); + return result; + } + else + { + PrintLogInfo("通过地址和长度读取PLC数据失败!!!"); + this.IsConnected = false; + return new byte[0]; + } + } + catch (Exception ex) + { + PrintLogInfo("通过地址和长度读取PLC数据异常", ex); + this.IsConnected = false; + return new byte[0]; + } + } + + /// + /// 通过PLC地址写入int类型数据 + /// + /// + /// + /// + /// + public bool writeValueByAddress(int value, string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}",address,value)); + try + { + OperateResult operateResult = omronFinsNet.Write(address, Convert.ToInt32(value)); + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址写入int类型数据", ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址清零数据 + /// + /// + /// + /// + /// + public bool resetByAddress(string address, int len) + { + //PrintLogInfo(String.Format("开发通过PLC地址{0}清零数据", address)); + try + { + byte[] write = new byte[len * 2]; + for (int i = 0; i < len * 2; i++) + { + write[i] = 0; + } + OperateResult operateResult = omronFinsNet.Write(address, write); + + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}清零数据成功", address)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}清零数据失败!!!", address)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}清零数据异常", address), ex); + return false; + } + } + + /// + /// 通过PLC地址读取EA值 + /// + /// + /// + /// + public string readEaByAddress(string address) + { + //PrintLogInfo(String.Format("通过PLC地址{0}读取EA值", address)); + try + { + OperateResult read = omronFinsNet.Read(address, (ushort)(8)); + + if (read.IsSuccess && read.Content != null) + { + string result = Convert.ToString(read.Content); + PrintLogInfo(String.Format("通过PLC地址{0}读取EA值成功:{1}", address, result)); + return result; + } + else + { + PrintLogInfo(String.Format("通过PLC地址{0}读取EA值失败!!!", address)); + this.IsConnected = false; + return ""; + } + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取EA值异常", ex); + this.IsConnected = false; + return ""; + } + } + + /// + /// 通过PLC地址读取交互信号 + /// + /// + /// + public int readInteractiveSignal(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取交互信号", address)); + try + { + OperateResult read = omronFinsNet.ReadInt16(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号失败!!!", address)); + this.IsConnected = false; + return 0; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取交互信号异常", ex); + this.IsConnected = false; + return 0; + } + } + + /// + /// 通过PLC地址读取int32类型数据 + /// + /// + /// + public int readInt32ByAddress(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取int32类型数据",address)); + try + { + OperateResult read = omronFinsNet.ReadInt16(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据失败!!!", address)); + this.IsConnected = false; + return 0; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + this.IsConnected = false; + return 0; + } + } + + /// + /// 通过PLC地址写入int32类型数据 + /// + /// + /// + /// + /// + public bool writeInt32ByAddress(string address, int value) + { + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address, value)); + try + { + OperateResult write = omronFinsNet.Write(address, short.Parse(Convert.ToString(value))); + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据异常", address), ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址写入String类型数据 + /// + /// + /// + /// + /// + public bool writeStringByAddress(string address, string value) + { + //PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}",address,value)); + try + { + OperateResult operateResult = omronFinsNet.Write(address, value); + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value)); + //this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据异常", address), ex); + //this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址读取string类型数据 + /// + /// + /// + /// + public string readStringByAddress(string address, ushort length) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取string类型数据", address)); + try + { + OperateResult read = omronFinsNet.ReadString(address, length); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据失败!!!", address)); + this.IsConnected = false; + return ""; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + return ""; + } + } + + /// + /// 通过PLC地址读取Bool类型数据 + /// + /// + /// + /// + public bool readBoolByAddress(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取bool类型数据", address)); + try + { + OperateResult read = omronFinsNet.ReadBool(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据失败!!!", address)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址写入Bool类型数据 + /// + /// + /// + /// + public bool writeBoolByAddress(string address, bool value) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value)); + try + { + OperateResult write = omronFinsNet.Write(address, short.Parse(_stringChange.ParseToInt(value ? "1" : "0").ToString())); + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据异常", address), ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 写入Double类型 + /// + /// + /// + /// + public bool writeDoubleByAddress(string address, int value) + { + try + { + OperateResult write = omronFinsNet.Write(address, Convert.ToDouble(value)); + + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据{1}失败!!!", address, value)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入Double类型数据异常", address), ex); + return false; + } + } + + private void PrintLogInfo(string message, Exception ex = null) + { + + } + } +} diff --git a/SlnMesnac.Plc/Impl/SiemensPlc.cs b/SlnMesnac.Plc/Impl/SiemensPlc.cs new file mode 100644 index 0000000..13c9b41 --- /dev/null +++ b/SlnMesnac.Plc/Impl/SiemensPlc.cs @@ -0,0 +1,415 @@ +using HslCommunication.Profinet.Siemens; +using HslCommunication; +using SlnMesnac.Common; +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Extensions.Logging; + +namespace SlnMesnac.Plc.Impl +{ + public class SiemensPlc : IPlc + { + private ILogger _logger; + + private StringChange _stringChange; + + private const SiemensPLCS type = SiemensPLCS.S200Smart; + + private SiemensS7Net s7 = new SiemensS7Net(type); + + public SiemensPlc(ILogger logger, StringChange stringChange) + { + this._logger = logger; + _stringChange = stringChange; + + } + + public bool IsConnected { get; set; } + + /// + /// 建立连接 + /// + /// + /// + /// + /// + public bool Connect(string IP, int port) + { + PrintLogInfo("西门子S7系列PLC连接开始"); + s7.IpAddress = IP; + s7.Port = 102; + try + { + OperateResult connect = s7.ConnectServer(); + if (connect.IsSuccess) + { + this.IsConnected = true; + PrintLogInfo("西门子S7系列PLC建立连接成功!!!"); + return true; + } + else + { + this.IsConnected = false; + PrintLogInfo("西门子S7系列PLC建立连接失败!!!"); + return false; + } + } + catch (Exception ex) + { + this.IsConnected = false; + PrintLogInfo("西门子S7系列PLC建立连接异常", ex); + return false; + } + } + + /// + /// 通过地址和长度读取PLC数据 + /// + /// + /// + /// + /// + public byte[] readValueByAddress(int len, string address) + { + //PrintLogInfo("开始通过PLC地址和长度读取PLC数据"); + try + { + OperateResult read = s7.Read(address, (ushort)(len)); + if (read.IsSuccess) + { + byte[] result = _stringChange.ConvertFloatToINt(read.Content); + PrintLogInfo(String.Format("通过地址和长度读取PLC数据成功:{0}", _stringChange.bytesToHexStr(result, result.Length))); + return result; + } + else + { + PrintLogInfo("通过地址和长度读取PLC数据失败!!!"); + this.IsConnected = false; + return new byte[0]; + } + } + catch (Exception ex) + { + PrintLogInfo("通过地址和长度读取PLC数据异常", ex); + this.IsConnected = false; + return new byte[0]; + } + } + + /// + /// 通过PLC地址写入int类型数据 + /// + /// + /// + /// + /// + public bool writeValueByAddress(int value, string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}",address,value)); + try + { + OperateResult operateResult = s7.Write(address, Convert.ToInt32(value)); + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址写入int类型数据", ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址清零数据 + /// + /// + /// + /// + /// + public bool resetByAddress(string address, int len) + { + //PrintLogInfo(String.Format("开发通过PLC地址{0}清零数据", address)); + try + { + byte[] write = new byte[len * 2]; + for (int i = 0; i < len * 2; i++) + { + write[i] = 0; + } + OperateResult operateResult = s7.Write(address, write); + + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}清零数据成功", address)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}清零数据失败!!!", address)); + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}清零数据异常", address), ex); + return false; + } + } + + /// + /// 通过PLC地址读取EA值 + /// + /// + /// + /// + public string readEaByAddress(string address) + { + //PrintLogInfo(String.Format("通过PLC地址{0}读取EA值", address)); + try + { + OperateResult read = s7.Read(address, (ushort)(8)); + + if (read.IsSuccess && read.Content != null) + { + string result = Convert.ToString(read.Content); + PrintLogInfo(String.Format("通过PLC地址{0}读取EA值成功:{1}", address, result)); + return result; + } + else + { + PrintLogInfo(String.Format("通过PLC地址{0}读取EA值失败!!!", address)); + this.IsConnected = false; + return ""; + } + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取EA值异常", ex); + this.IsConnected = false; + return ""; + } + } + + /// + /// 通过PLC地址读取交互信号 + /// + /// + /// + public int readInteractiveSignal(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取交互信号", address)); + try + { + OperateResult read = s7.ReadInt16(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取交互信号失败!!!", address)); + this.IsConnected = false; + return 0; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取交互信号异常", ex); + this.IsConnected = false; + return 0; + } + } + + /// + /// 通过PLC地址读取int32类型数据 + /// + /// + /// + public int readInt32ByAddress(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取int32类型数据",address)); + try + { + OperateResult read = s7.ReadInt16(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取int32类型数据失败!!!", address)); + this.IsConnected = false; + return 0; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + this.IsConnected = false; + return 0; + } + } + + /// + /// 通过PLC地址写入int32类型数据 + /// + /// + /// + /// + /// + public bool writeInt32ByAddress(string address, int value) + { + PrintLogInfo(String.Format("开始通过PLC地址{0}写入int32类型数据{1}", address, value)); + try + { + OperateResult write = s7.Write(address, short.Parse(Convert.ToString(value))); + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入int32类型数据异常", address), ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址写入String类型数据 + /// + /// + /// + /// + /// + public bool writeStringByAddress(string address, string value) + { + //PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}",address,value)); + try + { + OperateResult operateResult = s7.Write(address, value); + if (operateResult.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据{1}失败!!!", address, value)); + //this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入String类型数据异常", address), ex); + //this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址读取string类型数据 + /// + /// + /// + /// + public string readStringByAddress(string address, ushort length) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取string类型数据", address)); + try + { + OperateResult read = s7.ReadString(address, length); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取string类型数据失败!!!", address)); + this.IsConnected = false; + return ""; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + return ""; + } + } + + /// + /// 通过PLC地址读取Bool类型数据 + /// + /// + /// + /// + public bool readBoolByAddress(string address) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}读取bool类型数据", address)); + try + { + OperateResult read = s7.ReadBool(address); + if (read.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据成功:{1}", address, read.Content)); + return read.Content; + } + PrintLogInfo(String.Format("通过PLC地址{0}读取bool类型数据失败!!!", address)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo("通过PLC地址读取int32类型数据异常", ex); + this.IsConnected = false; + return false; + } + } + + /// + /// 通过PLC地址写入Bool类型数据 + /// + /// + /// + /// + public bool writeBoolByAddress(string address, bool value) + { + //PrintLogInfo(String.Format("开始通过PLC地址{0}写入bool类型数据{1}", address, value)); + try + { + OperateResult write = s7.Write(address, short.Parse(_stringChange.ParseToInt(value ? "1" : "0").ToString())); + if (write.IsSuccess) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}成功", address, value)); + return true; + } + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据{1}失败!!!", address, value)); + this.IsConnected = false; + return false; + } + catch (Exception ex) + { + PrintLogInfo(String.Format("通过PLC地址{0}写入bool类型数据异常", address), ex); + this.IsConnected = false; + return false; + } + } + + public bool DisConnect() + { + throw new NotImplementedException(); + } + + public bool writeDoubleByAddress(string address, int value) + { + throw new NotImplementedException(); + } + + private void PrintLogInfo(string message, Exception ex = null) + { + + } + } +} \ No newline at end of file diff --git a/SlnMesnac.Plc/PlcPool.cs b/SlnMesnac.Plc/PlcPool.cs new file mode 100644 index 0000000..66446e6 --- /dev/null +++ b/SlnMesnac.Plc/PlcPool.cs @@ -0,0 +1,127 @@ +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using SlnMesnac.Plc.Impl; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace SlnMesnac.Plc +{ + /// + /// PLC连接池 + /// + public class PlcPool + { + + private ILogger _logger; + + private Dictionary keyValuePairs = new Dictionary(); + + private readonly InovancePlc _inovancePlc; + private readonly MelsecBinaryPlc _melsecBinaryPlc; + private readonly OmronNJPlc _omronNJPlc; + private readonly SiemensPlc _siemensPlc; + + public PlcPool(ILogger logger, InovancePlc inovancePlc,MelsecBinaryPlc melsecBinaryPlc,OmronNJPlc omronNJPlc,SiemensPlc siemensPlc) + { + _logger = logger; + _inovancePlc = inovancePlc; + _melsecBinaryPlc = melsecBinaryPlc; + _omronNJPlc = omronNJPlc; + _siemensPlc = siemensPlc; + + if (!HslCommunication.Authorization.SetAuthorizationCode("ed1415f8-e06a-43ad-95f7-c04f7ae93b41")) + { + _logger.LogInformation("HslCommunication激活失败,可用时长24小时"); + } + _logger.LogInformation("HslCommunication 11.0.6.0激活成功"); + } + + /// + /// 初始化Plc + /// + /// + /// + /// + /// + public void InitPlc(string plcType, string ip, int port, string key) + { + IPlc _plc = null; + switch (plcType) + { + case "InovancePlc": + _plc = _inovancePlc; + break; + case "MelsecBinaryPlc": + _plc = _melsecBinaryPlc; + break; + case "OmronNJPlc": + _plc = _omronNJPlc; + break; + case "SiemensPlc": + _plc = _siemensPlc; + break; + default: + break; + } + var connectResult = _plc.Connect(ip, port); + if (connectResult) + { + keyValuePairs.Add(key, _plc); + if (!keyValuePairs.ContainsKey(key)) + { + keyValuePairs.Add(key, _plc); + } + else + { + keyValuePairs[key] = _plc; + } + } + } + + /// + /// 获取PLC + /// + /// + /// + public IPlc GetPlcByKey(string key) + { + return keyValuePairs[key]; + } + + /// + /// 获取所有PLC信息 + /// + /// + public Dictionary GetAll() + { + return keyValuePairs; + } + + /// + /// 关闭所有连接 + /// + /// + public bool disConnectAll() + { + bool result = false; + try + { + foreach (var kv in keyValuePairs) + { + if (kv.Value != null) + { + kv.Value.DisConnect(); + } + } + result = true; + } + catch (Exception ex) + { + _logger.LogError("关闭PLC连接异常", ex); + } + + return result; + } + } +} diff --git a/SlnMesnac.Plc/PlcSetup.cs b/SlnMesnac.Plc/PlcSetup.cs new file mode 100644 index 0000000..53afcc5 --- /dev/null +++ b/SlnMesnac.Plc/PlcSetup.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection; +using SlnMesnac.Common; +using SlnMesnac.Plc.Impl; +using System; +using System.Collections.Generic; +using System.Text; + +namespace SlnMesnac.Plc +{ + public static class PlcSetup + { + public static void AddPlcSetup(this IServiceCollection services) + { + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + } + } +} diff --git a/SlnMesnac.Plc/SlnMesnac.Plc.csproj b/SlnMesnac.Plc/SlnMesnac.Plc.csproj new file mode 100644 index 0000000..d2d19be --- /dev/null +++ b/SlnMesnac.Plc/SlnMesnac.Plc.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.1 + enable + + + + + + + + + + + + diff --git a/SlnMesnac.sln b/SlnMesnac.sln index a273972..9f80800 100644 --- a/SlnMesnac.sln +++ b/SlnMesnac.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Quartz", "SlnMesn EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Serilog", "SlnMesnac.Serilog\SlnMesnac.Serilog.csproj", "{DEE2F305-733C-47C8-891C-502121ABAD00}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Plc", "SlnMesnac.Plc\SlnMesnac.Plc.csproj", "{D17E9024-9D25-4CE4-8E98-8A6C859CE436}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,6 +53,10 @@ Global {DEE2F305-733C-47C8-891C-502121ABAD00}.Debug|Any CPU.Build.0 = Debug|Any CPU {DEE2F305-733C-47C8-891C-502121ABAD00}.Release|Any CPU.ActiveCfg = Release|Any CPU {DEE2F305-733C-47C8-891C-502121ABAD00}.Release|Any CPU.Build.0 = Release|Any CPU + {D17E9024-9D25-4CE4-8E98-8A6C859CE436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D17E9024-9D25-4CE4-8E98-8A6C859CE436}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D17E9024-9D25-4CE4-8E98-8A6C859CE436}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D17E9024-9D25-4CE4-8E98-8A6C859CE436}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SlnMesnac/Controllers/BaseUserController.cs b/SlnMesnac/Controllers/BaseUserController.cs index a59c154..3cd1395 100644 --- a/SlnMesnac/Controllers/BaseUserController.cs +++ b/SlnMesnac/Controllers/BaseUserController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using SlnMesnac.Model.domain; +using SlnMesnac.Plc; using SlnMesnac.Repository.service; namespace SlnMesnac.Controllers @@ -16,15 +17,18 @@ namespace SlnMesnac.Controllers private readonly IBaseUserService _service; + private readonly PlcPool _plcPool; + /// /// /// /// /// - public BaseUserController(ILogger logger, IBaseUserService service) + public BaseUserController(ILogger logger, IBaseUserService service, PlcPool plcPool) { _logger = logger; _service = service; + _plcPool = plcPool; } /// @@ -34,6 +38,7 @@ namespace SlnMesnac.Controllers [HttpGet] public IEnumerable Get() { + _plcPool.InitPlc("SiemensPlc", "127.0.0.1", 102, "SiemensPlc"); IEnumerable users = null; try { diff --git a/SlnMesnac/SlnMesnac.csproj b/SlnMesnac/SlnMesnac.csproj index 9e05945..f623be7 100644 --- a/SlnMesnac/SlnMesnac.csproj +++ b/SlnMesnac/SlnMesnac.csproj @@ -14,6 +14,7 @@ + diff --git a/SlnMesnac/Startup.cs b/SlnMesnac/Startup.cs index bb3ea97..07f9445 100644 --- a/SlnMesnac/Startup.cs +++ b/SlnMesnac/Startup.cs @@ -1,7 +1,10 @@ using Microsoft.OpenApi.Models; using Serilog; using Serilog.Events; +using SlnMesnac.Common; using SlnMesnac.Config; +using SlnMesnac.Plc; +using SlnMesnac.Plc.Impl; using SlnMesnac.Quartz; using SlnMesnac.Repository; using SlnMesnac.Serilog; @@ -72,6 +75,9 @@ namespace SlnMesnac }); + //注册通用类 + services.AddCommonSetup(); + //注册SqlSugar services.AddSqlSugarSetup(); @@ -80,6 +86,9 @@ namespace SlnMesnac //注册任务调度 services.AddQuartzSetUp(); + + //注册PLC + services.AddPlcSetup(); } ///