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) { if (ex != null) { _logger.LogError($"{message}:{ex.Message}"); } else { _logger.LogInformation(message); } } } }