DataParser.java 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package com.zksy.gas.utils;
  2. import com.zksy.gas.domain.GasMonitorData;
  3. import java.math.BigDecimal;
  4. import java.time.LocalDateTime;
  5. public class DataParser {
  6. public static GasMonitorData parseMessage(byte[] frame) {
  7. GasMonitorData data = new GasMonitorData();
  8. // 帧类型
  9. data.setFrameType(frame[2] & 0xFF);
  10. // MAC 地址
  11. byte[] macBytes = new byte[8];
  12. System.arraycopy(frame, 3, macBytes, 0, 8);
  13. data.setMacAddress(ProtocolUtils.bytesToHex(macBytes));
  14. // 短地址
  15. data.setShortAddress(String.format("%02X%02X", frame[11], frame[12]));
  16. // 自动应答
  17. data.setAutoReplyOption(frame[13] & 0xFF);
  18. // 序号
  19. data.setSequenceNo(frame[15] & 0xFF);
  20. // 命令
  21. data.setCommand(frame[16] & 0xFF);
  22. // 设备属性
  23. data.setDeviceAttr(frame[17] & 0xFF);
  24. // 协议版本
  25. data.setProtocolVersion(String.format("%02X", frame[18]));
  26. // 报警信息(小端序 00 04 -> 0x0400)
  27. int alarmInfo = ((frame[20] & 0xFF) << 8) | (frame[19] & 0xFF);
  28. data.setAlarmInfo(alarmInfo);
  29. // 时间戳(BCD)
  30. LocalDateTime reportTime = ProtocolUtils.parseTimestamp(frame, 21);
  31. data.setReportTime(reportTime);
  32. // 数据个数
  33. int dataCount = frame[27] & 0xFF;
  34. // ------- 数据段开始(例子里有 5 个数据) -------
  35. int offset = 28;
  36. // 1. 气体浓度 + 气体类型
  37. // 格式:04 10 00 00 00 00 -> 1004 (浓度=100, 类型=CH4)
  38. int gasValue = ((frame[offset + 1] & 0xFF) << 8) | (frame[offset] & 0xFF);
  39. int gasTypeCode = ((frame[offset + 3] & 0xFF) << 8) | (frame[offset + 2] & 0xFF);
  40. data.setGasConcentration(BigDecimal.valueOf(gasValue));
  41. data.setGasType(gasTypeCode == 0x0004 ? "CH4" : "未知");
  42. offset += 6;
  43. // 2. 电池电量
  44. float battery = ProtocolUtils.bytesToFloatLE(frame, offset + 2);
  45. data.setBattery(BigDecimal.valueOf(battery));
  46. offset += 6;
  47. // 3. 信号强度
  48. float signal = ProtocolUtils.bytesToFloatLE(frame, offset + 2);
  49. data.setSignalStrength(signal);
  50. offset += 6;
  51. // 4. 经度
  52. float lon = ProtocolUtils.bytesToFloatLE(frame, offset + 2);
  53. data.setLongitude(BigDecimal.valueOf(lon));
  54. offset += 6;
  55. // 5. 纬度
  56. float lat = ProtocolUtils.bytesToFloatLE(frame, offset + 2);
  57. data.setLatitude(BigDecimal.valueOf(lat));
  58. offset += 6;
  59. // 入库时间
  60. data.setCreateTime(LocalDateTime.now());
  61. return data;
  62. }
  63. public static void main(String[] args) {
  64. // 示例报文
  65. String hex = "7E003A902509040070010000FFFE01AA2B00010813000425091908473305"
  66. + "041000000000F96F00000000F76F0000F841FA6F00000000FB6F0000000007";
  67. byte[] frame = ProtocolUtils.hexStringToBytes(hex);
  68. GasMonitorData parsed = parseMessage(frame);
  69. System.out.println("========== 解析结果 ==========");
  70. System.out.println("帧类型: " + parsed.getFrameType());
  71. System.out.println("MAC地址: " + parsed.getMacAddress());
  72. System.out.println("短地址: " + parsed.getShortAddress());
  73. System.out.println("自动应答: " + parsed.getAutoReplyOption());
  74. System.out.println("序号: " + parsed.getSequenceNo());
  75. System.out.println("命令: " + parsed.getCommand());
  76. System.out.println("设备属性: " + parsed.getDeviceAttr());
  77. System.out.println("协议版本: " + parsed.getProtocolVersion());
  78. System.out.println("报警信息: " + parsed.getAlarmInfo());
  79. System.out.println("时间戳: " + parsed.getReportTime());
  80. System.out.println("气体浓度: " + parsed.getGasConcentration() + " %LEL");
  81. System.out.println("气体类型: " + parsed.getGasType());
  82. System.out.println("电池电量: " + parsed.getBattery());
  83. System.out.println("信号强度: " + parsed.getSignalStrength());
  84. System.out.println("经度: " + parsed.getLongitude());
  85. System.out.println("纬度: " + parsed.getLatitude());
  86. System.out.println("入库时间: " + parsed.getCreateTime());
  87. }
  88. }