Iec104Util.java 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package com.ydl.iec.util;
  2. import com.ydl.iec.iec104.message.MessageDetail;
  3. import com.ydl.iec.iec104.enums.TypeIdentifierEnum;
  4. import com.ydl.iec.iec104.enums.UControlEnum;
  5. /**
  6. *
  7. * @ClassName: Iec104Util
  8. * @Description: 工具类
  9. * @author YDL
  10. * @date 2020年5月13日
  11. */
  12. public class Iec104Util {
  13. private static int controlLength = 4;
  14. // public static int port = 8404;
  15. // public static String host = "192.168.2.21";
  16. public static int port = 2404;
  17. public static String host = "127.0.0.1";
  18. /**
  19. * I 格式 低位在前
  20. * @param accept 接收序列号
  21. * @param send 发送序列号
  22. * @return
  23. */
  24. public static byte[] getIcontrol(short accept, short send) {
  25. byte[] control = new byte[4];
  26. // 向左移动一位 保证低位的D0 是0
  27. send = (short) (send << 1);
  28. control[0] = (byte) ((send));
  29. control[1] = (byte) ((send >> 8));
  30. accept = (short) (accept << 1);
  31. control[2] = (byte) ((accept));
  32. control[3] = (byte) ((accept >> 8));
  33. return control;
  34. }
  35. /**
  36. * 返回控制域中的接收序号
  37. * @param control
  38. * @return
  39. */
  40. public static short getAccept(byte[] control) {
  41. int accept = 0;
  42. short acceptLow = (short) (control[2] & 0xff);
  43. short acceptHigh = (short) (control[3] & 0xff);
  44. accept += acceptLow;
  45. accept += acceptHigh << 8;
  46. accept = accept >> 1;
  47. return (short) accept;
  48. }
  49. /**
  50. * 返回控制域中的发送序号
  51. * @param control
  52. * @return
  53. */
  54. public static short getSend(byte[] control) {
  55. int send = 0;
  56. short acceptLow = (short) (control[0] & 0xff);
  57. short acceptHigh = (short) (control[1] & 0xff);
  58. send += acceptLow;
  59. send += acceptHigh << 8;
  60. send = send >> 1;
  61. return (short) send;
  62. }
  63. /**
  64. * S 格式
  65. * @param accept
  66. * @return
  67. */
  68. public static byte[] getScontrol(short accept) {
  69. byte[] control = new byte[4];
  70. // 向左移动一位 保证低位的D0 是0
  71. short send = 1;
  72. control[0] = (byte) ((send));
  73. control[1] = (byte) ((send >> 8));
  74. accept = (short) (accept << 1);
  75. control[2] = (byte) ((accept));
  76. control[3] = (byte) ((accept >> 8));
  77. return control;
  78. }
  79. /**
  80. *
  81. * @Title: 返回U帧
  82. * @Description: 判断是否是
  83. * @param @param control
  84. * @param @return
  85. * @return boolean
  86. * @throws
  87. */
  88. public static UControlEnum getUcontrol(byte[] control) {
  89. if (control.length < controlLength || control[1] != 0 || control[3] != 0 || control[2] != 0) {
  90. return null;
  91. }
  92. int controlInt = ByteUtil.byteArrayToInt(control);
  93. for (UControlEnum ucontrolEnum : UControlEnum.values()) {
  94. if (ucontrolEnum.getValue() == controlInt) {
  95. return ucontrolEnum;
  96. }
  97. }
  98. return null;
  99. }
  100. /**
  101. * 返回消息地址 其中低位在前
  102. * @param i
  103. * @return
  104. */
  105. public static byte[] intToMessageAddress(int i) {
  106. byte[] result = new byte[3];
  107. result[0] = (byte) (i & 0xFF);
  108. result[1] = (byte) ((i >> 8) & 0xFF);
  109. result[2] = (byte) ((i >> 16) & 0xFF);
  110. return result;
  111. }
  112. /**
  113. * 消息地址 只有三个
  114. * @param bytes
  115. * @return
  116. */
  117. public static int messageAddressToInt(byte[] bytes) {
  118. int value = 0;
  119. for (int i = 2; i >= 0; i--) {
  120. int shift = (2 - i) * 8;
  121. value += (bytes[2 - i] & 0xFF) << shift;
  122. }
  123. return value;
  124. }
  125. /**
  126. * 设置可以变限定词
  127. * @param ruleDetail104
  128. * @param byteItem
  129. */
  130. public static void setChanged(MessageDetail ruleDetail104, byte byteItem) {
  131. // 第一位是 0 则是有序的
  132. ruleDetail104.setContinuous((byteItem & 0x80) == 0 ? false : true);
  133. // 先将第一位数置零 然后转换成int
  134. ruleDetail104.setMeasgLength(byteItem & (byte) 0x7F);
  135. }
  136. /**
  137. * 返回可变限定词数组
  138. * @param ruleDetail104
  139. * @return
  140. */
  141. public static byte getChangedQualifiers(MessageDetail ruleDetail104) {
  142. // 将长度转换成 byte
  143. byte changedQualifiers = (byte) ruleDetail104.getMeasgLength();
  144. // 判断SQ 置 isContinuous false SQ = 0;否则 SQ =1 , 同时将SQ置 设置在 可变限定词的 D7位置
  145. int sq = ruleDetail104.isContinuous() ? 0x80 : 0;
  146. changedQualifiers = (byte) (sq | changedQualifiers);
  147. return changedQualifiers;
  148. }
  149. public static void setMeaageAttribute(MessageDetail ruleDetail104) {
  150. boolean isMessage = !(TypeIdentifierEnum.generalCall.equals(ruleDetail104.getTypeIdentifier()) //总召唤无此项
  151. || TypeIdentifierEnum.timeSynchronization.equals(ruleDetail104.getTypeIdentifier()) // 时钟同步
  152. || TypeIdentifierEnum.resetPprocess.equals(ruleDetail104.getTypeIdentifier()) // 复位进程
  153. || TypeIdentifierEnum.initEnd.equals(ruleDetail104.getTypeIdentifier()));
  154. ruleDetail104.setMessage(isMessage);
  155. boolean isQualifiers = !(TypeIdentifierEnum.timeSynchronization.equals(ruleDetail104.getTypeIdentifier()) // 时钟同步
  156. || TypeIdentifierEnum.onePointTeleindication.equals(ruleDetail104.getTypeIdentifier()) //单点摇信
  157. || TypeIdentifierEnum.twoPointTeleindication.equals(ruleDetail104.getTypeIdentifier()) // 双点摇信
  158. || TypeIdentifierEnum.onePointTelecontrol.equals(ruleDetail104.getTypeIdentifier()) // 单命令遥控
  159. || TypeIdentifierEnum.twoPointTelecontrol.equals(ruleDetail104.getTypeIdentifier())); // 双命令遥控
  160. ruleDetail104.setQualifiers(isQualifiers);
  161. boolean isTimeScale = TypeIdentifierEnum.timeSynchronization.equals(ruleDetail104.getTypeIdentifier()) // 时钟同步
  162. || TypeIdentifierEnum.onePointTimeTeleindication.equals(ruleDetail104.getTypeIdentifier()) // 摇信带时标 单点
  163. || TypeIdentifierEnum.twoPointTimeTeleindication.equals(ruleDetail104.getTypeIdentifier()); //摇信带时标 双点
  164. ruleDetail104.setTimeScaleExit(isTimeScale);
  165. }
  166. /**
  167. * short 转换成两个 字节后是163 00 也就是 value[1] 中才有值
  168. * test 在D7位置 因此 值应该和 01000000 做与运算
  169. * P/N 0肯定确认 1否定确认
  170. * @return 肯定或否定确认
  171. */
  172. public static boolean isYes(byte[] values) {
  173. return (values[0] & 1 << 6) == 0;
  174. }
  175. /**
  176. * short 转换成两个 字节后是163 00 也就是 value[1] 中才有值
  177. * test 在D7位置 因此 值应该和 10000000 做与运算
  178. * tets 0 为试验 1 试验
  179. * @return 是否试验
  180. */
  181. public static boolean isTets(byte[] values) {
  182. return (values[0] & 1 << 7) != 0;
  183. }
  184. /**
  185. * 返回具体的原因
  186. * @param values
  187. * @return
  188. */
  189. public static short getTransferReasonShort(byte[] values) {
  190. byte transferReason = values[0];
  191. // 前两位置零
  192. transferReason = (byte) (transferReason & 0x3E);
  193. return transferReason;
  194. }
  195. public static short getTransferReasonShort(boolean isTets, boolean isYes, short transferReason) {
  196. int t = isTets ? 1 : 0;
  197. int y = isYes ? 0 : 1;
  198. int transferReasonInt = t << 7 | transferReason;
  199. transferReasonInt = y << 6 | transferReasonInt;
  200. short transferReasonShort = (short) (transferReasonInt << 8);
  201. return transferReasonShort;
  202. }
  203. /**
  204. * 返回终端地址对应的byte数组 其中低位在前
  205. * @param terminalAddress
  206. * @return
  207. */
  208. public static byte[] getTerminalAddressByte(short terminalAddress) {
  209. byte[] b = new byte[2];
  210. b[1] = (byte) ((terminalAddress >> 8) & 0xff);
  211. b[0] = (byte) (terminalAddress & 0xff);
  212. return b;
  213. }
  214. /**
  215. * 返回回终端地址 其中低位在前
  216. * @param terminalAddress
  217. * @return
  218. */
  219. public static short getTerminalAddressShort(byte[] terminalAddress) {
  220. short value = 0;
  221. value += (terminalAddress[0] & 0xFF);
  222. value += (terminalAddress[1] & 0xFF) << 8;
  223. return value;
  224. }
  225. }