SerialDeviceBase.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using MECF.Framework.RT.Core.IoProviders.Common.Net;
  6. using MECF.Framework.RT.Core.IoProviders.Common.Transfer;
  7. namespace MECF.Framework.RT.Core.IoProviders.Common.Serial
  8. {
  9. /// <summary>
  10. /// 基于串口的设备交互类的对象,需要从本类继承,然后实现不同的设备读写操作。
  11. /// </summary>
  12. /// <typeparam name="TTransform">数据解析的规则泛型</typeparam>
  13. public class SerialDeviceBase<TTransform> : SerialBase, IReadWriteNet where TTransform : IByteTransform, new()
  14. {
  15. #region Constructor
  16. /// <summary>
  17. /// 默认的构造方法实现的设备信息
  18. /// </summary>
  19. public SerialDeviceBase( )
  20. {
  21. byteTransform = new TTransform( ); // 实例化数据转换规则
  22. }
  23. #endregion
  24. #region Virtual Method
  25. /**************************************************************************************************
  26. *
  27. * 说明:子类中需要重写基础的读取和写入方法,来支持不同的数据访问规则
  28. *
  29. * 此处没有将读写位纳入进来,因为各种设备的支持不尽相同,比较麻烦
  30. *
  31. **************************************************************************************************/
  32. /// <summary>
  33. /// 从设备读取原始数据
  34. /// </summary>
  35. /// <param name="address">起始地址</param>
  36. /// <param name="length">地址长度</param>
  37. /// <returns>带有成功标识的结果对象</returns>
  38. /// <remarks>需要在继承类中重写实现,并且实现地址解析操作</remarks>
  39. public virtual OperateResult<byte[]> Read( string address, ushort length )
  40. {
  41. return new OperateResult<byte[]>( );
  42. }
  43. /// <summary>
  44. /// 将原始数据写入设备
  45. /// </summary>
  46. /// <param name="address">起始地址</param>
  47. /// <param name="value">原始数据</param>
  48. /// <returns>带有成功标识的结果对象</returns>
  49. /// <remarks>需要在继承类中重写实现,并且实现地址解析操作</remarks>
  50. public virtual OperateResult Write( string address, byte[] value )
  51. {
  52. return new OperateResult( );
  53. }
  54. #endregion
  55. #region Protect Member
  56. /// <summary>
  57. /// 单个数据字节的长度,西门子为2,三菱,欧姆龙,modbusTcp就为1
  58. /// </summary>
  59. /// <remarks>对设备来说,一个地址的数据对应的字节数,或是1个字节或是2个字节</remarks>
  60. protected ushort WordLength { get; set; } = 1;
  61. #endregion
  62. #region Public Member
  63. /// <summary>
  64. /// 当前客户端的数据变换机制,当你需要从字节数据转换类型数据的时候需要。
  65. /// </summary>
  66. /// <example>
  67. /// 主要是用来转换数据类型的,下面仅仅演示了2个方法,其他的类型转换,类似处理。
  68. /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkDoubleBase.cs" region="ByteTransform" title="ByteTransform示例" />
  69. /// </example>
  70. public TTransform ByteTransform
  71. {
  72. get { return byteTransform; }
  73. set { byteTransform = value; }
  74. }
  75. /// <summary>
  76. /// 当前连接的唯一ID号,默认为长度20的guid码加随机数组成,方便列表管理,也可以自己指定
  77. /// </summary>
  78. /// <remarks>
  79. /// Current Connection ID, conclude guid and random data, also, you can spcified
  80. /// </remarks>
  81. public string ConnectionId
  82. {
  83. get { return connectionId; }
  84. set { connectionId = value; }
  85. }
  86. #endregion
  87. #region Customer Support
  88. /// <summary>
  89. /// 读取自定义类型的数据,需要规定解析规则
  90. /// </summary>
  91. /// <typeparam name="T">类型名称</typeparam>
  92. /// <param name="address">起始地址</param>
  93. /// <returns>带有成功标识的结果对象</returns>
  94. /// <remarks>
  95. /// 需要是定义一个类,选择好相对于的ByteTransform实例,才能调用该方法。
  96. /// </remarks>
  97. public OperateResult<T> ReadCustomer<T>( string address ) where T : IDataTransfer, new()
  98. {
  99. OperateResult<T> result = new OperateResult<T>( );
  100. T Content = new T( );
  101. OperateResult<byte[]> read = Read( address, Content.ReadCount );
  102. if (read.IsSuccess)
  103. {
  104. Content.ParseSource( read.Content );
  105. result.Content = Content;
  106. result.IsSuccess = true;
  107. }
  108. else
  109. {
  110. result.ErrorCode = read.ErrorCode;
  111. result.Message = read.Message;
  112. }
  113. return result;
  114. }
  115. /// <summary>
  116. /// 写入自定义类型的数据到设备去,需要规定生成字节的方法
  117. /// </summary>
  118. /// <typeparam name="T">自定义类型</typeparam>
  119. /// <param name="address">起始地址</param>
  120. /// <param name="data">实例对象</param>
  121. /// <returns>带有成功标识的结果对象</returns>
  122. /// <remarks>
  123. /// 需要是定义一个类,选择好相对于的<see cref="IDataTransfer"/>实例,才能调用该方法。
  124. /// </remarks>
  125. public OperateResult WriteCustomer<T>( string address, T data ) where T : IDataTransfer, new()
  126. {
  127. return Write( address, data.ToSource( ) );
  128. }
  129. #endregion
  130. #region Read Support
  131. /// <summary>
  132. /// 读取设备的short类型的数据
  133. /// </summary>
  134. /// <param name="address">起始地址</param>
  135. /// <returns>带成功标志的结果数据对象</returns>
  136. public OperateResult<short> ReadInt16( string address )
  137. {
  138. return ByteTransformHelper.GetResultFromArray( ReadInt16( address, 1 ) );
  139. }
  140. /// <summary>
  141. /// 读取设备的short类型的数组
  142. /// </summary>
  143. /// <param name="address">起始地址</param>
  144. /// <param name="length">数组长度</param>
  145. /// <returns>带成功标志的结果数据对象</returns>
  146. public OperateResult<short[]> ReadInt16( string address, ushort length )
  147. {
  148. return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength) ), m => ByteTransform.TransInt16( m, 0, length ) );
  149. }
  150. /// <summary>
  151. /// 读取设备的ushort数据类型的数据
  152. /// </summary>
  153. /// <param name="address">起始地址</param>
  154. /// <returns>带成功标志的结果数据对象</returns>
  155. public OperateResult<ushort> ReadUInt16( string address )
  156. {
  157. return ByteTransformHelper.GetResultFromArray( ReadUInt16( address, 1 ) );
  158. }
  159. /// <summary>
  160. /// 读取设备的ushort类型的数组
  161. /// </summary>
  162. /// <param name="address">起始地址</param>
  163. /// <param name="length">数组长度</param>
  164. /// <returns>带成功标志的结果数据对象</returns>
  165. public OperateResult<ushort[]> ReadUInt16( string address, ushort length )
  166. {
  167. return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength) ), m => ByteTransform.TransUInt16( m, 0, length ) );
  168. }
  169. /// <summary>
  170. /// 读取设备的int类型的数据
  171. /// </summary>
  172. /// <param name="address">起始地址</param>
  173. /// <returns>带成功标志的结果数据对象</returns>
  174. public OperateResult<int> ReadInt32( string address )
  175. {
  176. return ByteTransformHelper.GetResultFromArray( ReadInt32( address, 1 ) );
  177. }
  178. /// <summary>
  179. /// 读取设备的int类型的数组
  180. /// </summary>
  181. /// <param name="address">起始地址</param>
  182. /// <param name="length">数组长度</param>
  183. /// <returns>带成功标志的结果数据对象</returns>
  184. public OperateResult<int[]> ReadInt32( string address, ushort length )
  185. {
  186. return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 2) ), m => ByteTransform.TransInt32( m, 0, length ) );
  187. }
  188. /// <summary>
  189. /// 读取设备的uint类型的数据
  190. /// </summary>
  191. /// <param name="address">起始地址</param>
  192. /// <returns>带成功标志的结果数据对象</returns>
  193. public OperateResult<uint> ReadUInt32( string address )
  194. {
  195. return ByteTransformHelper.GetResultFromArray( ReadUInt32( address, 1 ) );
  196. }
  197. /// <summary>
  198. /// 读取设备的uint类型的数组
  199. /// </summary>
  200. /// <param name="address">起始地址</param>
  201. /// <param name="length">数组长度</param>
  202. /// <returns>带成功标志的结果数据对象</returns>
  203. public OperateResult<uint[]> ReadUInt32( string address, ushort length )
  204. {
  205. return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 2) ), m => ByteTransform.TransUInt32( m, 0, length ) );
  206. }
  207. /// <summary>
  208. /// 读取设备的float类型的数据
  209. /// </summary>
  210. /// <param name="address">起始地址</param>
  211. /// <returns>带成功标志的结果数据对象</returns>
  212. public OperateResult<float> ReadFloat( string address )
  213. {
  214. return ByteTransformHelper.GetResultFromArray( ReadFloat( address, 1 ) );
  215. }
  216. /// <summary>
  217. /// 读取设备的float类型的数组
  218. /// </summary>
  219. /// <param name="address">起始地址</param>
  220. /// <param name="length">数组长度</param>
  221. /// <returns>带成功标志的结果数据对象</returns>
  222. public OperateResult<float[]> ReadFloat( string address, ushort length )
  223. {
  224. return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 2) ), m => ByteTransform.TransSingle( m, 0, length ) );
  225. }
  226. /// <summary>
  227. /// 读取设备的long类型的数据
  228. /// </summary>
  229. /// <param name="address">起始地址</param>
  230. /// <returns>带成功标志的结果数据对象</returns>
  231. public OperateResult<long> ReadInt64( string address )
  232. {
  233. return ByteTransformHelper.GetResultFromArray( ReadInt64( address, 1 ) );
  234. }
  235. /// <summary>
  236. /// 读取设备的long类型的数组
  237. /// </summary>
  238. /// <param name="address">起始地址</param>
  239. /// <param name="length">数组长度</param>
  240. /// <returns>带成功标志的结果数据对象</returns>
  241. public OperateResult<long[]> ReadInt64( string address, ushort length )
  242. {
  243. return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 4) ), m => ByteTransform.TransInt64( m, 0, length ) );
  244. }
  245. /// <summary>
  246. /// 读取设备的ulong类型的数据
  247. /// </summary>
  248. /// <param name="address">起始地址</param>
  249. /// <returns>带成功标志的结果数据对象</returns>
  250. public OperateResult<ulong> ReadUInt64( string address )
  251. {
  252. return ByteTransformHelper.GetResultFromArray( ReadUInt64( address, 1 ) );
  253. }
  254. /// <summary>
  255. /// 读取设备的ulong类型的数组
  256. /// </summary>
  257. /// <param name="address">起始地址</param>
  258. /// <param name="length">数组长度</param>
  259. /// <returns>带成功标志的结果数据对象</returns>
  260. public OperateResult<ulong[]> ReadUInt64( string address, ushort length )
  261. {
  262. return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 4) ), m => ByteTransform.TransUInt64( m, 0, length ) );
  263. }
  264. /// <summary>
  265. /// 读取设备的double类型的数据
  266. /// </summary>
  267. /// <param name="address">起始地址</param>
  268. /// <returns>带成功标志的结果数据对象</returns>
  269. public OperateResult<double> ReadDouble( string address )
  270. {
  271. return ByteTransformHelper.GetResultFromArray( ReadDouble( address, 1 ) );
  272. }
  273. /// <summary>
  274. /// 读取设备的double类型的数组
  275. /// </summary>
  276. /// <param name="address">起始地址</param>
  277. /// <param name="length">数组长度</param>
  278. /// <returns>带成功标志的结果数据对象</returns>
  279. public OperateResult<double[]> ReadDouble( string address, ushort length )
  280. {
  281. return ByteTransformHelper.GetResultFromBytes( Read( address, (ushort)(length * WordLength * 4) ), m => ByteTransform.TransDouble( m, 0, length ) );
  282. }
  283. /// <summary>
  284. /// 读取设备的字符串数据,编码为ASCII
  285. /// </summary>
  286. /// <param name="address">起始地址</param>
  287. /// <param name="length">地址长度</param>
  288. /// <returns>带成功标志的结果数据对象</returns>
  289. public OperateResult<string> ReadString( string address, ushort length )
  290. {
  291. return ByteTransformHelper.GetResultFromBytes( Read( address, length ), m => ByteTransform.TransString( m, 0, m.Length, Encoding.ASCII ) );
  292. }
  293. #endregion
  294. #region Write Int16
  295. /// <summary>
  296. /// 向设备中写入short数组,返回是否写入成功
  297. /// </summary>
  298. /// <param name="address">数据地址</param>
  299. /// <param name="values">实际数据</param>
  300. /// <returns>返回写入结果</returns>
  301. public virtual OperateResult Write( string address, short[] values )
  302. {
  303. return Write( address, ByteTransform.TransByte( values ) );
  304. }
  305. /// <summary>
  306. /// 向设备中写入short数据,返回是否写入成功
  307. /// </summary>
  308. /// <param name="address">数据地址</param>
  309. /// <param name="value">实际数据</param>
  310. /// <returns>返回写入结果</returns>
  311. public virtual OperateResult Write( string address, short value )
  312. {
  313. return Write( address, new short[] { value } );
  314. }
  315. #endregion
  316. #region Write UInt16
  317. /// <summary>
  318. /// 向设备中写入ushort数组,返回是否写入成功
  319. /// </summary>
  320. /// <param name="address">要写入的数据地址</param>
  321. /// <param name="values">要写入的实际数据</param>
  322. /// <returns>返回写入结果</returns>
  323. public virtual OperateResult Write( string address, ushort[] values )
  324. {
  325. return Write( address, ByteTransform.TransByte( values ) );
  326. }
  327. /// <summary>
  328. /// 向设备中写入ushort数据,返回是否写入成功
  329. /// </summary>
  330. /// <param name="address">数据地址</param>
  331. /// <param name="value">实际数据</param>
  332. /// <returns>返回写入结果</returns>
  333. public virtual OperateResult Write( string address, ushort value )
  334. {
  335. return Write( address, new ushort[] { value } );
  336. }
  337. #endregion
  338. #region Write Int32
  339. /// <summary>
  340. /// 向设备中写入int数组,返回是否写入成功
  341. /// </summary>
  342. /// <param name="address">数据地址</param>
  343. /// <param name="values">实际数据</param>
  344. /// <returns>返回写入结果</returns>
  345. public virtual OperateResult Write( string address, int[] values )
  346. {
  347. return Write( address, ByteTransform.TransByte( values ) );
  348. }
  349. /// <summary>
  350. /// 向设备中写入int数据,返回是否写入成功
  351. /// </summary>
  352. /// <param name="address">数据地址</param>
  353. /// <param name="value">实际数据</param>
  354. /// <returns>返回写入结果</returns>
  355. public virtual OperateResult Write( string address, int value )
  356. {
  357. return Write( address, new int[] { value } );
  358. }
  359. #endregion
  360. #region Write UInt32
  361. /// <summary>
  362. /// 向设备中写入uint数组,返回是否写入成功
  363. /// </summary>
  364. /// <param name="address">数据地址</param>
  365. /// <param name="values">实际数据</param>
  366. /// <returns>返回写入结果</returns>
  367. public virtual OperateResult Write( string address, uint[] values )
  368. {
  369. return Write( address, ByteTransform.TransByte( values ) );
  370. }
  371. /// <summary>
  372. /// 向设备中写入uint数据,返回是否写入成功
  373. /// </summary>
  374. /// <param name="address">数据地址</param>
  375. /// <param name="value">实际数据</param>
  376. /// <returns>返回写入结果</returns>
  377. public virtual OperateResult Write( string address, uint value )
  378. {
  379. return Write( address, new uint[] { value } );
  380. }
  381. #endregion
  382. #region Write Float
  383. /// <summary>
  384. /// 向设备中写入float数组,返回是否写入成功
  385. /// </summary>
  386. /// <param name="address">数据地址</param>
  387. /// <param name="values">实际数据</param>
  388. /// <returns>返回写入结果</returns>
  389. public virtual OperateResult Write( string address, float[] values )
  390. {
  391. return Write( address, ByteTransform.TransByte( values ) );
  392. }
  393. /// <summary>
  394. /// 向设备中写入float数据,返回是否写入成功
  395. /// </summary>
  396. /// <param name="address">数据地址</param>
  397. /// <param name="value">实际数据</param>
  398. /// <returns>返回写入结果</returns>
  399. public virtual OperateResult Write( string address, float value )
  400. {
  401. return Write( address, new float[] { value } );
  402. }
  403. #endregion
  404. #region Write Int64
  405. /// <summary>
  406. /// 向设备中写入long数组,返回是否写入成功
  407. /// </summary>
  408. /// <param name="address">数据地址</param>
  409. /// <param name="values">实际数据</param>
  410. /// <returns>返回写入结果</returns>
  411. public virtual OperateResult Write( string address, long[] values )
  412. {
  413. return Write( address, ByteTransform.TransByte( values ) );
  414. }
  415. /// <summary>
  416. /// 向设备中写入long数据,返回是否写入成功
  417. /// </summary>
  418. /// <param name="address">数据地址</param>
  419. /// <param name="value">实际数据</param>
  420. /// <returns>返回写入结果</returns>
  421. public virtual OperateResult Write( string address, long value )
  422. {
  423. return Write( address, new long[] { value } );
  424. }
  425. #endregion
  426. #region Write UInt64
  427. /// <summary>
  428. /// 向P设备中写入ulong数组,返回是否写入成功
  429. /// </summary>
  430. /// <param name="address">数据地址</param>
  431. /// <param name="values">实际数据</param>
  432. /// <returns>返回写入结果</returns>
  433. public virtual OperateResult Write( string address, ulong[] values )
  434. {
  435. return Write( address, ByteTransform.TransByte( values ) );
  436. }
  437. /// <summary>
  438. /// 向设备中写入ulong数据,返回是否写入成功
  439. /// </summary>
  440. /// <param name="address">数据地址</param>
  441. /// <param name="value">实际数据</param>
  442. /// <returns>返回写入结果</returns>
  443. public virtual OperateResult Write( string address, ulong value )
  444. {
  445. return Write( address, new ulong[] { value } );
  446. }
  447. #endregion
  448. #region Write Double
  449. /// <summary>
  450. /// 向设备中写入double数组,返回是否写入成功
  451. /// </summary>
  452. /// <param name="address">数据地址</param>
  453. /// <param name="values">实际数据</param>
  454. /// <returns>返回写入结果</returns>
  455. public virtual OperateResult Write( string address, double[] values )
  456. {
  457. return Write( address, ByteTransform.TransByte( values ) );
  458. }
  459. /// <summary>
  460. /// 向设备中写入double数据,返回是否写入成功
  461. /// </summary>
  462. /// <param name="address">数据地址</param>
  463. /// <param name="value">实际数据</param>
  464. /// <returns>返回写入结果</returns>
  465. public virtual OperateResult Write( string address, double value )
  466. {
  467. return Write( address, new double[] { value } );
  468. }
  469. #endregion
  470. #region Write String
  471. /// <summary>
  472. /// 向设备中写入字符串,编码格式为ASCII
  473. /// </summary>
  474. /// <param name="address">数据地址</param>
  475. /// <param name="value">字符串数据</param>
  476. /// <returns>是否写入成功的结果对象</returns>
  477. /// <example>
  478. /// 以下为三菱的连接对象示例,其他的设备读写情况参照下面的代码:
  479. /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkDeviceBase.cs" region="WriteString" title="String类型示例" />
  480. /// </example>
  481. public virtual OperateResult Write( string address, string value )
  482. {
  483. byte[] temp = ByteTransform.TransByte( value, Encoding.ASCII );
  484. if (WordLength == 1) temp = SoftBasic.ArrayExpandToLengthEven( temp );
  485. return Write( address, temp );
  486. }
  487. /// <summary>
  488. /// 向设备中写入指定长度的字符串,超出截断,不够补0,编码格式为ASCII
  489. /// </summary>
  490. /// <param name="address">数据地址</param>
  491. /// <param name="value">字符串数据</param>
  492. /// <param name="length">指定的字符串长度,必须大于0</param>
  493. /// <returns>是否写入成功的结果对象 -> Whether to write a successful result object</returns>
  494. public virtual OperateResult Write( string address, string value, int length )
  495. {
  496. byte[] temp = ByteTransform.TransByte( value, Encoding.ASCII );
  497. if (WordLength == 1) temp = SoftBasic.ArrayExpandToLengthEven( temp );
  498. temp = SoftBasic.ArrayExpandToLength( temp, length );
  499. return Write( address, temp );
  500. }
  501. /// <summary>
  502. /// 向设备中写入字符串,编码格式为Unicode
  503. /// </summary>
  504. /// <param name="address">数据地址</param>
  505. /// <param name="value">字符串数据</param>
  506. /// <returns>是否写入成功的结果对象</returns>
  507. public virtual OperateResult WriteUnicodeString( string address, string value )
  508. {
  509. byte[] temp = ByteTransform.TransByte( value, Encoding.Unicode );
  510. return Write( address, temp );
  511. }
  512. /// <summary>
  513. /// 向设备中写入指定长度的字符串,超出截断,不够补0,编码格式为Unicode
  514. /// </summary>
  515. /// <param name="address">数据地址</param>
  516. /// <param name="value">字符串数据</param>
  517. /// <param name="length">指定的字符串长度,必须大于0</param>
  518. /// <returns>是否写入成功的结果对象 -> Whether to write a successful result object</returns>
  519. public virtual OperateResult WriteUnicodeString( string address, string value, int length )
  520. {
  521. byte[] temp = ByteTransform.TransByte( value, Encoding.Unicode );
  522. temp = SoftBasic.ArrayExpandToLength( temp, length * 2 );
  523. return Write( address, temp );
  524. }
  525. #endregion
  526. #region Private Member
  527. private TTransform byteTransform; // 数据变换的接口
  528. private string connectionId = string.Empty; // 当前连接
  529. #endregion
  530. #region Object Override
  531. /// <summary>
  532. /// 返回表示当前对象的字符串
  533. /// </summary>
  534. /// <returns>字符串数据</returns>
  535. public override string ToString( )
  536. {
  537. return "SerialDeviceBase<TTransform>";
  538. }
  539. #endregion
  540. }
  541. }