FestoSocketSimulator.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using MECF.Framework.Common.Net;
  2. using MECF.Framework.Simulator.Core.Driver;
  3. using System;
  4. using System.Collections.Generic;
  5. namespace CyberX8_Simulator.Devices
  6. {
  7. public class FestoSocketSimulator : SocketDeviceSimulator
  8. {
  9. //Write Address
  10. private const ushort FESTO_DO_START_ADDRESS = 0x9C43;//FestoDO起始地址(40003)
  11. //Read Address
  12. private const ushort FESTO_DI_START_ADDRESS = 0xB153;//FestoDI起始地址(45395)
  13. //Register Count
  14. private const int FESTO_REGISTER_COUNT = 100;
  15. private IByteTransform byteTransform = new BigEndianByteTransformBase();
  16. /// <summary>
  17. /// 数据(DO_address - data)
  18. /// </summary>
  19. private short[] _festoOutputDataDic = new short[FESTO_REGISTER_COUNT];
  20. /// <summary>
  21. /// 构造函数
  22. /// </summary>
  23. /// <param name="port"></param>
  24. public FestoSocketSimulator(int port) : base(port)
  25. {
  26. for(int i = 0; i < FESTO_REGISTER_COUNT; i++)
  27. {
  28. _festoOutputDataDic[i] = 0x00;
  29. }
  30. }
  31. /// <summary>
  32. /// 解析信息
  33. /// </summary>
  34. /// <param name="data"></param>
  35. protected override void ProcessUnsplitMessage(byte[] data)
  36. {
  37. short flag = byteTransform.TransInt16(data, 0);//事务标识符
  38. byte channel = data[6];//单元标识符
  39. byte command = data[7];//功能码
  40. if (command == 0x03)//读取
  41. {
  42. ushort startAddress = byteTransform.TransUInt16(data, 8);//起始寄存器地址
  43. short registerCount = byteTransform.TransInt16(data, 10);//寄存器数量
  44. byte[] bytes = new byte[2 * registerCount];//读取2*registerCount Byte数据
  45. if (startAddress >= FESTO_DI_START_ADDRESS)
  46. {
  47. for (int i = 0; i < registerCount; i++)
  48. {
  49. Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[i]), 0, bytes, i * 2, 2);
  50. }
  51. OnWriteMessage(CreateReadResponse(flag, channel, command, registerCount, bytes));
  52. }
  53. else
  54. {
  55. OnWriteMessage(CreateError(flag, channel, command, 0x8A));
  56. }
  57. }
  58. else if(command == 0x06)//写入
  59. {
  60. ushort startAddress = byteTransform.TransUInt16(data, 8);//起始寄存器地址
  61. short value = byteTransform.TransInt16(data, 10);//写入的值(2 Byte)
  62. if(startAddress >= FESTO_DO_START_ADDRESS)
  63. {
  64. //modbus起始地址n为数据,n+1为诊断数据,取地址n下的数据
  65. int index = (startAddress - FESTO_DO_START_ADDRESS) * 2;
  66. _festoOutputDataDic[index] = value;
  67. OnWriteMessage(CreateWriteResponse(flag, channel, command, startAddress, value));
  68. }
  69. else
  70. {
  71. OnWriteMessage(CreateError(flag, channel, command, 0x8A));
  72. }
  73. }
  74. else
  75. {
  76. OnWriteMessage(CreateError(flag, channel, command, 0x84));
  77. }
  78. }
  79. /// <summary>
  80. /// 读回复
  81. /// </summary>
  82. /// <param name="flag"></param>
  83. /// <param name="channel"></param>
  84. /// <param name="command"></param>
  85. /// <param name="registerCount"></param>
  86. /// <param name="values"></param>
  87. /// <returns></returns>
  88. private byte[] CreateReadResponse(short flag, byte channel, byte command, short registerCount, byte[] values)
  89. {
  90. byte[] bytes = new byte[6 + 3 + values.Length];
  91. Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
  92. bytes[2] = 0x00;
  93. bytes[3] = 0x00;
  94. short dataLength = (short)(3 + values.Length);
  95. Array.Copy(byteTransform.GetBytes(dataLength), 0, bytes, 4, 2);
  96. bytes[6] = channel;
  97. bytes[7] = command;
  98. bytes[8] = (byte)(2 * registerCount);
  99. Array.Copy(values, 0, bytes, 9, values.Length);
  100. return bytes;
  101. }
  102. /// <summary>
  103. /// 写回复
  104. /// </summary>
  105. /// <param name="flag"></param>
  106. /// <param name="channel"></param>
  107. /// <param name="command"></param>
  108. /// <param name="startAddress"></param>
  109. /// <param name="value"></param>
  110. /// <returns></returns>
  111. private byte[] CreateWriteResponse(short flag, byte channel, byte command, ushort startAddress, short value)
  112. {
  113. byte[] bytes = new byte[12];
  114. Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
  115. bytes[2] = 0x00;
  116. bytes[3] = 0x00;
  117. bytes[4] = 0x00;
  118. bytes[5] = 0x06;
  119. bytes[6] = channel;
  120. bytes[7] = command;
  121. byte[] addressByt = byteTransform.GetBytes(startAddress);
  122. Array.Copy(addressByt, 0, bytes, 8, 2);
  123. byte[] valueByt = byteTransform.GetBytes(value);
  124. Array.Copy(valueByt, 0, bytes, 10, 2);
  125. return bytes;
  126. }
  127. /// <summary>
  128. /// 错误回复
  129. /// </summary>
  130. /// <param name="flag"></param>
  131. /// <param name="channel"></param>
  132. /// <param name="command"></param>
  133. /// <param name="error"></param>
  134. /// <returns></returns>
  135. private byte[] CreateError(short flag, byte channel, byte command, byte error)
  136. {
  137. byte[] bytes = new byte[9];
  138. Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
  139. bytes[2] = 0x00;
  140. bytes[3] = 0x00;
  141. bytes[4] = 0x00;
  142. bytes[5] = 0x03;
  143. bytes[6] = channel;
  144. bytes[7] = (byte)(command | 0x80);
  145. bytes[8] = error;
  146. return bytes;
  147. }
  148. }
  149. }