using System; using System.Collections.Generic; using System.Linq; using System.Text; using MECF.Framework.RT.Core.IoProviders.Siemens.Net; using MECF.Framework.RT.Core.IoProviders.Siemens.Transfer; namespace MECF.Framework.RT.Core.IoProviders.Siemens.Serial { /// /// 基于串口的设备交互类的对象,需要从本类继承,然后实现不同的设备读写操作。 /// /// 数据解析的规则泛型 public class SerialDeviceBase : SerialBase, IReadWriteNet where TTransform : IByteTransform, new() { #region Constructor /// /// 默认的构造方法实现的设备信息 /// public SerialDeviceBase( ) { byteTransform = new TTransform( ); // 实例化数据转换规则 } #endregion #region Virtual Method /************************************************************************************************** * * 说明:子类中需要重写基础的读取和写入方法,来支持不同的数据访问规则 * * 此处没有将读写位纳入进来,因为各种设备的支持不尽相同,比较麻烦 * **************************************************************************************************/ /// /// 从设备读取原始数据 /// /// 起始地址 /// 地址长度 /// 带有成功标识的结果对象 /// 需要在继承类中重写实现,并且实现地址解析操作 public virtual OperateResult Read( string address, ushort length ) { return new OperateResult( ); } /// /// 将原始数据写入设备 /// /// 起始地址 /// 原始数据 /// 带有成功标识的结果对象 /// 需要在继承类中重写实现,并且实现地址解析操作 public virtual OperateResult Write( string address, byte[] value ) { return new OperateResult( ); } #endregion #region Protect Member /// /// 单个数据字节的长度,西门子为2,三菱,欧姆龙,modbusTcp就为1 /// /// 对设备来说,一个地址的数据对应的字节数,或是1个字节或是2个字节 protected ushort WordLength { get; set; } = 1; #endregion #region Public Member /// /// 当前客户端的数据变换机制,当你需要从字节数据转换类型数据的时候需要。 /// /// /// 主要是用来转换数据类型的,下面仅仅演示了2个方法,其他的类型转换,类似处理。 /// /// public TTransform ByteTransform { get { return byteTransform; } set { byteTransform = value; } } /// /// 当前连接的唯一ID号,默认为长度20的guid码加随机数组成,方便列表管理,也可以自己指定 /// /// /// Current Connection ID, conclude guid and random data, also, you can spcified /// public string ConnectionId { get { return connectionId; } set { connectionId = value; } } #endregion #region Customer Support /// /// 读取自定义类型的数据,需要规定解析规则 /// /// 类型名称 /// 起始地址 /// 带有成功标识的结果对象 /// /// 需要是定义一个类,选择好相对于的ByteTransform实例,才能调用该方法。 /// public OperateResult ReadCustomer( string address ) where T : IDataTransfer, new() { OperateResult result = new OperateResult( ); T Content = new T( ); OperateResult read = Read( address, Content.ReadCount ); if (read.IsSuccess) { Content.ParseSource( read.Content ); result.Content = Content; result.IsSuccess = true; } else { result.ErrorCode = read.ErrorCode; result.Message = read.Message; } return result; } /// /// 写入自定义类型的数据到设备去,需要规定生成字节的方法 /// /// 自定义类型 /// 起始地址 /// 实例对象 /// 带有成功标识的结果对象 /// /// 需要是定义一个类,选择好相对于的实例,才能调用该方法。 /// public OperateResult WriteCustomer( string address, T data ) where T : IDataTransfer, new() { return Write( address, data.ToSource( ) ); } #endregion #region Read Support /// /// 读取设备的short类型的数据 /// /// 起始地址 /// 带成功标志的结果数据对象 public OperateResult ReadInt16( string address ) { return ByteTransformHelper.GetResultFromArray( ReadInt16( address, 1 ) ); } /// /// 读取设备的short类型的数组 /// /// 起始地址 /// 数组长度 /// 带成功标志的结果数据对象 public OperateResult ReadInt16( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength) ), m => ByteTransform.TransInt16( m, 0, length ) ); } /// /// 读取设备的ushort数据类型的数据 /// /// 起始地址 /// 带成功标志的结果数据对象 public OperateResult ReadUInt16( string address ) { return ByteTransformHelper.GetResultFromArray( ReadUInt16( address, 1 ) ); } /// /// 读取设备的ushort类型的数组 /// /// 起始地址 /// 数组长度 /// 带成功标志的结果数据对象 public OperateResult ReadUInt16( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength) ), m => ByteTransform.TransUInt16( m, 0, length ) ); } /// /// 读取设备的int类型的数据 /// /// 起始地址 /// 带成功标志的结果数据对象 public OperateResult ReadInt32( string address ) { return ByteTransformHelper.GetResultFromArray( ReadInt32( address, 1 ) ); } /// /// 读取设备的int类型的数组 /// /// 起始地址 /// 数组长度 /// 带成功标志的结果数据对象 public OperateResult ReadInt32( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 2) ), m => ByteTransform.TransInt32( m, 0, length ) ); } /// /// 读取设备的uint类型的数据 /// /// 起始地址 /// 带成功标志的结果数据对象 public OperateResult ReadUInt32( string address ) { return ByteTransformHelper.GetResultFromArray( ReadUInt32( address, 1 ) ); } /// /// 读取设备的uint类型的数组 /// /// 起始地址 /// 数组长度 /// 带成功标志的结果数据对象 public OperateResult ReadUInt32( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 2) ), m => ByteTransform.TransUInt32( m, 0, length ) ); } /// /// 读取设备的float类型的数据 /// /// 起始地址 /// 带成功标志的结果数据对象 public OperateResult ReadFloat( string address ) { return ByteTransformHelper.GetResultFromArray( ReadFloat( address, 1 ) ); } /// /// 读取设备的float类型的数组 /// /// 起始地址 /// 数组长度 /// 带成功标志的结果数据对象 public OperateResult ReadFloat( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 2) ), m => ByteTransform.TransSingle( m, 0, length ) ); } /// /// 读取设备的long类型的数据 /// /// 起始地址 /// 带成功标志的结果数据对象 public OperateResult ReadInt64( string address ) { return ByteTransformHelper.GetResultFromArray( ReadInt64( address, 1 ) ); } /// /// 读取设备的long类型的数组 /// /// 起始地址 /// 数组长度 /// 带成功标志的结果数据对象 public OperateResult ReadInt64( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 4) ), m => ByteTransform.TransInt64( m, 0, length ) ); } /// /// 读取设备的ulong类型的数据 /// /// 起始地址 /// 带成功标志的结果数据对象 public OperateResult ReadUInt64( string address ) { return ByteTransformHelper.GetResultFromArray( ReadUInt64( address, 1 ) ); } /// /// 读取设备的ulong类型的数组 /// /// 起始地址 /// 数组长度 /// 带成功标志的结果数据对象 public OperateResult ReadUInt64( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 4) ), m => ByteTransform.TransUInt64( m, 0, length ) ); } /// /// 读取设备的double类型的数据 /// /// 起始地址 /// 带成功标志的结果数据对象 public OperateResult ReadDouble( string address ) { return ByteTransformHelper.GetResultFromArray( ReadDouble( address, 1 ) ); } /// /// 读取设备的double类型的数组 /// /// 起始地址 /// 数组长度 /// 带成功标志的结果数据对象 public OperateResult ReadDouble( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 4) ), m => ByteTransform.TransDouble( m, 0, length ) ); } /// /// 读取设备的字符串数据,编码为ASCII /// /// 起始地址 /// 地址长度 /// 带成功标志的结果数据对象 public OperateResult ReadString( string address, ushort length ) { return ByteTransformHelper.GetResultFromBytes( Read( address, length ), m => ByteTransform.TransString( m, 0, m.Length, Encoding.ASCII ) ); } #endregion #region Write Int16 /// /// 向设备中写入short数组,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, short[] values ) { return Write( address, ByteTransform.TransByte( values ) ); } /// /// 向设备中写入short数据,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, short value ) { return Write( address, new short[] { value } ); } #endregion #region Write UInt16 /// /// 向设备中写入ushort数组,返回是否写入成功 /// /// 要写入的数据地址 /// 要写入的实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, ushort[] values ) { return Write( address, ByteTransform.TransByte( values ) ); } /// /// 向设备中写入ushort数据,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, ushort value ) { return Write( address, new ushort[] { value } ); } #endregion #region Write Int32 /// /// 向设备中写入int数组,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, int[] values ) { return Write( address, ByteTransform.TransByte( values ) ); } /// /// 向设备中写入int数据,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, int value ) { return Write( address, new int[] { value } ); } #endregion #region Write UInt32 /// /// 向设备中写入uint数组,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, uint[] values ) { return Write( address, ByteTransform.TransByte( values ) ); } /// /// 向设备中写入uint数据,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, uint value ) { return Write( address, new uint[] { value } ); } #endregion #region Write Float /// /// 向设备中写入float数组,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, float[] values ) { return Write( address, ByteTransform.TransByte( values ) ); } /// /// 向设备中写入float数据,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, float value ) { return Write( address, new float[] { value } ); } #endregion #region Write Int64 /// /// 向设备中写入long数组,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, long[] values ) { return Write( address, ByteTransform.TransByte( values ) ); } /// /// 向设备中写入long数据,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, long value ) { return Write( address, new long[] { value } ); } #endregion #region Write UInt64 /// /// 向P设备中写入ulong数组,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, ulong[] values ) { return Write( address, ByteTransform.TransByte( values ) ); } /// /// 向设备中写入ulong数据,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, ulong value ) { return Write( address, new ulong[] { value } ); } #endregion #region Write Double /// /// 向设备中写入double数组,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, double[] values ) { return Write( address, ByteTransform.TransByte( values ) ); } /// /// 向设备中写入double数据,返回是否写入成功 /// /// 数据地址 /// 实际数据 /// 返回写入结果 public virtual OperateResult Write( string address, double value ) { return Write( address, new double[] { value } ); } #endregion #region Write String /// /// 向设备中写入字符串,编码格式为ASCII /// /// 数据地址 /// 字符串数据 /// 是否写入成功的结果对象 /// /// 以下为三菱的连接对象示例,其他的设备读写情况参照下面的代码: /// /// public virtual OperateResult Write( string address, string value ) { byte[] temp = ByteTransform.TransByte( value, Encoding.ASCII ); if (WordLength == 1) temp = SoftBasic.ArrayExpandToLengthEven( temp ); return Write( address, temp ); } /// /// 向设备中写入指定长度的字符串,超出截断,不够补0,编码格式为ASCII /// /// 数据地址 /// 字符串数据 /// 指定的字符串长度,必须大于0 /// 是否写入成功的结果对象 -> Whether to write a successful result object public virtual OperateResult Write( string address, string value, int length ) { byte[] temp = ByteTransform.TransByte( value, Encoding.ASCII ); if (WordLength == 1) temp = SoftBasic.ArrayExpandToLengthEven( temp ); temp = SoftBasic.ArrayExpandToLength( temp, length ); return Write( address, temp ); } /// /// 向设备中写入字符串,编码格式为Unicode /// /// 数据地址 /// 字符串数据 /// 是否写入成功的结果对象 public virtual OperateResult WriteUnicodeString( string address, string value ) { byte[] temp = ByteTransform.TransByte( value, Encoding.Unicode ); return Write( address, temp ); } /// /// 向设备中写入指定长度的字符串,超出截断,不够补0,编码格式为Unicode /// /// 数据地址 /// 字符串数据 /// 指定的字符串长度,必须大于0 /// 是否写入成功的结果对象 -> Whether to write a successful result object public virtual OperateResult WriteUnicodeString( string address, string value, int length ) { byte[] temp = ByteTransform.TransByte( value, Encoding.Unicode ); temp = SoftBasic.ArrayExpandToLength( temp, length * 2 ); return Write( address, temp ); } #endregion #region Private Member private TTransform byteTransform; // 数据变换的接口 private string connectionId = string.Empty; // 当前连接 #endregion #region Object Override /// /// 返回表示当前对象的字符串 /// /// 字符串数据 public override string ToString( ) { return "SerialDeviceBase"; } #endregion } }