| | |
| | | #region << 版 本 注 释 >> |
| | | |
| | | /*---------------------------------------------------------------- |
| | | * 命名空间:WIDESEAWCS_Communicator |
| | | * 创建者:胡童庆 |
| | |
| | | * 修改时间: |
| | | * 版本:V1.0.1 |
| | | * 修改说明: |
| | | * |
| | | * |
| | | *----------------------------------------------------------------*/ |
| | | |
| | | #endregion << 版 本 注 释 >> |
| | | |
| | | using HslCommunication; |
| | |
| | | using HslCommunication.LogNet; |
| | | using HslCommunication.Profinet.Siemens; |
| | | using Newtonsoft.Json; |
| | | using Newtonsoft.Json.Linq; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel; |
| | | using System.Diagnostics.CodeAnalysis; |
| | | using System.Linq; |
| | | using System.Net; |
| | | using System.Net.NetworkInformation; |
| | | using System.Reflection; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using System.Xml.Linq; |
| | | |
| | | namespace WIDESEAWCS_Communicator |
| | | { |
| | |
| | | public class SiemensS7 : BaseCommunicator |
| | | { |
| | | #region Private Member |
| | | |
| | | /// <summary> |
| | | /// HSLCommunication的西门子的S7协议的通讯类 |
| | | /// </summary> |
| | |
| | | private int _port; |
| | | |
| | | /// <summary> |
| | | /// 当前通讯器是否已连接到PLC。 |
| | | /// 当前通讯器是否已连接到PLC。 |
| | | /// </summary> |
| | | private bool _connected; |
| | | |
| | |
| | | private ILogNet _logNet; |
| | | |
| | | private bool _isPing = true; |
| | | |
| | | #endregion Private Member |
| | | |
| | | #region Public Member |
| | | /// <summary> |
| | | /// 获取当前通讯器是否已连接到PLC。 |
| | | |
| | | /// <summary> |
| | | /// 获取当前通讯器是否已连接到PLC。 |
| | | /// </summary> |
| | | public override bool IsConnected => _connected; |
| | | |
| | |
| | | /// <summary> |
| | | /// 是否在写入数据后读取数据确认。 |
| | | /// </summary> |
| | | public override bool IsReadAfterWrite { get; set; } = false; |
| | | public override bool IsReadAfterWrite { get; set; } = true; |
| | | |
| | | #endregion Public Member |
| | | |
| | | #region Constructor Function |
| | | |
| | | /// <summary> |
| | | /// 构造函数 |
| | | /// </summary> |
| | |
| | | _port = port;//通过构造函数赋值连接使用的端口号 |
| | | _name = name; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region Private Method |
| | | |
| | | /// <summary> |
| | | /// 从OperateResult对象中获取读取的数据。 |
| | | /// </summary> |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// |
| | | /// |
| | | /// </summary> |
| | | /// <typeparam name="T"></typeparam> |
| | | /// <param name="operateResult"></param> |
| | |
| | | try |
| | | { |
| | | Type type = value.GetType(); |
| | | |
| | | switch (Type.GetTypeCode(type)) |
| | | { |
| | | case TypeCode.Int32: |
| | | return plc.Write(address, Convert.ToInt32(value)); |
| | | |
| | | case TypeCode.UInt32: |
| | | return plc.Write(address, Convert.ToUInt32(value)); |
| | | |
| | | case TypeCode.Int16: |
| | | return plc.Write(address, Convert.ToInt16(value)); |
| | | |
| | | case TypeCode.UInt16: |
| | | return plc.Write(address, Convert.ToUInt16(value)); |
| | | |
| | | case TypeCode.Single: |
| | | return plc.Write(address, Convert.ToSingle(value)); |
| | | |
| | | case TypeCode.Boolean: |
| | | return plc.Write(address, Convert.ToBoolean(value)); |
| | | |
| | | case TypeCode.Byte: |
| | | return plc.Write(address, Convert.ToByte(value)); |
| | | |
| | | case TypeCode.String: |
| | | return plc.Write(address, Convert.ToString(value)); |
| | | |
| | | case TypeCode.Char: |
| | | return plc.Write(address, Convert.ToChar(value)); |
| | | //case TypeCode.arr: |
| | |
| | | return (int[])GetContent(plc.ReadInt32(address, length), address); |
| | | else |
| | | return (int)GetContent(plc.ReadInt32(address), address); |
| | | |
| | | case TypeCode.UInt32: |
| | | if (length > 1) |
| | | return (uint[])GetContent(plc.ReadUInt32(address, length), address); |
| | | else |
| | | return (uint)GetContent(plc.ReadUInt32(address), address); |
| | | |
| | | case TypeCode.Int16: |
| | | if (length > 1) |
| | | return (short[])GetContent(plc.ReadInt16(address, length), address); |
| | | else |
| | | return (short)GetContent(plc.ReadInt16(address), address); |
| | | |
| | | case TypeCode.UInt16: |
| | | if (length > 1) |
| | | return (ushort[])GetContent(plc.ReadUInt16(address, length), address); |
| | | else |
| | | return (ushort)GetContent(plc.ReadUInt16(address), address); |
| | | |
| | | case TypeCode.Single: |
| | | if (length > 1) |
| | | return (float[])GetContent(plc.ReadFloat(address, length), address); |
| | | else |
| | | return (float)GetContent(plc.ReadFloat(address), address); |
| | | |
| | | case TypeCode.Boolean: |
| | | if (length > 1) |
| | | return (bool[])GetContent(plc.ReadBool(address, length), address); |
| | | else |
| | | return (bool)GetContent(plc.ReadBool(address), address); |
| | | |
| | | case TypeCode.Byte: |
| | | if (length > 1) |
| | | return (byte)GetContent(plc.Read(address, length), address); |
| | | return (byte)GetContent(plc.ReadByte(address), address); |
| | | |
| | | case TypeCode.String: |
| | | if (length > 1) |
| | | return (string)GetContent(plc.ReadString(address, length), address); |
| | | else |
| | | return (string)GetContent(plc.ReadString(address), address); |
| | | |
| | | case TypeCode.Char: |
| | | if (length > 1) |
| | | return Encoding.Default.GetString((byte[])GetContent(plc.Read(address, length), address)).ToArray(); |
| | | return (char)GetContent(plc.ReadByte(address), address); |
| | | |
| | | default: |
| | | throw new CommunicationException(string.Format(CommunicationExceptionMessage.DataTypeErrorException, typeCode.ToString(), address), CommunicationErrorType.TypeError); |
| | | } |
| | |
| | | } |
| | | } |
| | | }); |
| | | |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region Public Method |
| | | /// <summary> |
| | | |
| | | /// <summary> |
| | | /// 连接到PLC。 |
| | | /// </summary> |
| | | /// </summary> |
| | | /// <returns>如果连接成功则返回true,否则返回false。</returns> |
| | | /// <exception cref="CommunicationException">自定义通讯异常类</exception> |
| | | public override bool Connect() |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 断开与工业设备的连接。 |
| | | /// </summary> |
| | | /// <returns>如果成功断开连接则返回true,如果已经是断开状态则返回false。</returns> |
| | | /// <summary> |
| | | /// 断开与工业设备的连接。 |
| | | /// </summary> |
| | | /// <returns>如果成功断开连接则返回true,如果已经是断开状态则返回false。</returns> |
| | | public override bool Disconnect() |
| | | { |
| | | try |
| | |
| | | } |
| | | |
| | | #region Read |
| | | /// <summary> |
| | | /// 从PLC读取数据。 |
| | | /// </summary> |
| | | /// <param name="address">源地址,具体格式取决于使用的工业协议。</param> |
| | | /// <param name="length">要读取的数据长度。</param> |
| | | /// <returns>读取到的数据,如果读取失败则可能返回null、空数组或抛出自定义通讯异常。</returns> |
| | | |
| | | /// <summary> |
| | | /// 从PLC读取数据。 |
| | | /// </summary> |
| | | /// <param name="address">源地址,具体格式取决于使用的工业协议。</param> |
| | | /// <param name="length">要读取的数据长度。</param> |
| | | /// <returns>读取到的数据,如果读取失败则可能返回null、空数组或抛出自定义通讯异常。</returns> |
| | | /// <exception cref="CommunicationException">自定义通讯异常类</exception> |
| | | public override byte[] Read(string address, int length) |
| | | { |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// |
| | | /// |
| | | /// </summary> |
| | | /// <typeparam name="T"></typeparam> |
| | | /// <param name="address"></param> |
| | |
| | | else |
| | | return Read(address, SiemensDBDataType.GetTypeCode(dataType)); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region Write |
| | | |
| | | /// <summary> |
| | | /// 向PLC写入数据。 |
| | | /// </summary> |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// |
| | | /// |
| | | /// </summary> |
| | | /// <typeparam name="T"></typeparam> |
| | | /// <param name="address"></param> |
| | |
| | | { |
| | | return GetResult(Write(address, value), address, value); |
| | | } |
| | | |
| | | |
| | | public override bool Write<T>(string address, T[] values) |
| | | { |
| | |
| | | obj = GetResult(Write(address, writeVal), address, writeVal); |
| | | } |
| | | break; |
| | | |
| | | case SiemensDBDataType.DataType_DW: |
| | | { |
| | | uint writeVal; |
| | |
| | | obj = GetResult(Write(address, writeVal), address, writeVal); |
| | | } |
| | | break; |
| | | |
| | | case SiemensDBDataType.DataType_Int: |
| | | { |
| | | short writeVal; |
| | |
| | | obj = GetResult(Write(address, writeVal), address, writeVal); |
| | | } |
| | | break; |
| | | |
| | | case SiemensDBDataType.DataType_W: |
| | | { |
| | | ushort writeVal; |
| | |
| | | obj = GetResult(Write(address, writeVal), address, writeVal); |
| | | } |
| | | break; |
| | | |
| | | case SiemensDBDataType.DataType_Float: |
| | | { |
| | | float writeVal; |
| | |
| | | obj = GetResult(Write(address, writeVal), address, writeVal); |
| | | } |
| | | break; |
| | | |
| | | case SiemensDBDataType.DataType_Bool: |
| | | { |
| | | bool writeVal; |
| | |
| | | obj = GetResult(Write(address, writeVal), address, writeVal); |
| | | } |
| | | break; |
| | | |
| | | case SiemensDBDataType.DataType_Byte: |
| | | { |
| | | byte writeVal; |
| | |
| | | obj = GetResult(Write(address, writeVal), address, writeVal); |
| | | } |
| | | break; |
| | | |
| | | case SiemensDBDataType.DataType_String: |
| | | { |
| | | string writeVal; |
| | |
| | | } |
| | | |
| | | break; |
| | | |
| | | case SiemensDBDataType.DataType_Char: |
| | | |
| | | break; |
| | |
| | | obj = GetResult(Write(address, writeVal), address, writeVal); |
| | | } |
| | | break; |
| | | |
| | | default: |
| | | throw new CommunicationException(string.Format(CommunicationExceptionMessage.DataTypeErrorException, dataType, address), CommunicationErrorType.TypeError); |
| | | } |
| | | return obj; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ReadCustomer |
| | | |
| | | /// <summary> |
| | | /// 读取自定义的数据类型,需要继承自IDataTransfer接口,返回一个新的类型的实例对象。 |
| | | /// </summary> |
| | |
| | | throw new CommunicationException(ex.Message, CommunicationErrorType.ReadException, innerException: ex); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region WriteCustomer |
| | | |
| | | /// <summary> |
| | | /// 写入自定义类型的数据,该类型必须继承自IDataTransfer接口。 |
| | | /// </summary> |
| | |
| | | LogNet.WriteInfo(Name, stringBuilder.ToString()); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | /// <summary> |
| | |
| | | case TypeCode.Int16: |
| | | OperateResult<TimeSpan> operateResultShort = plc.Wait(address, Convert.ToInt16(value), readInterval, waitTimeout); |
| | | return operateResultShort; |
| | | |
| | | case TypeCode.Int32: |
| | | OperateResult<TimeSpan> operateResultInt = plc.Wait(address, Convert.ToInt16(value), readInterval, waitTimeout); |
| | | return operateResultInt; |
| | | |
| | | case TypeCode.UInt16: |
| | | OperateResult<TimeSpan> operateResultUShort = plc.Wait(address, Convert.ToInt16(value), readInterval, waitTimeout); |
| | | return operateResultUShort; |
| | | |
| | | case TypeCode.UInt32: |
| | | OperateResult<TimeSpan> operateResultUInt = plc.Wait(address, Convert.ToInt16(value), readInterval, waitTimeout); |
| | | return operateResultUInt; |
| | | |
| | | default: |
| | | throw new NotSupportedException(); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region Destruction Function |
| | | |
| | | /// <summary> |
| | | /// 析构函数,确保在不再需要时关闭连接 |
| | | /// 析构函数,确保在不再需要时关闭连接 |
| | | /// </summary> |
| | | ~SiemensS7() |
| | | { |
| | | Dispose(); |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | | } |
| | | } |