package com.zksy.gas.utils; import com.zksy.gas.domain.GasMonitorData; import java.math.BigDecimal; import java.time.LocalDateTime; public class DataParser { public static GasMonitorData parseMessage(byte[] frame) { GasMonitorData data = new GasMonitorData(); // 帧类型 data.setFrameType(frame[2] & 0xFF); // MAC 地址 byte[] macBytes = new byte[8]; System.arraycopy(frame, 3, macBytes, 0, 8); data.setMacAddress(ProtocolUtils.bytesToHex(macBytes)); // 短地址 data.setShortAddress(String.format("%02X%02X", frame[11], frame[12])); // 自动应答 data.setAutoReplyOption(frame[13] & 0xFF); // 序号 data.setSequenceNo(frame[15] & 0xFF); // 命令 data.setCommand(frame[16] & 0xFF); // 设备属性 data.setDeviceAttr(frame[17] & 0xFF); // 协议版本 data.setProtocolVersion(String.format("%02X", frame[18])); // 报警信息(小端序 00 04 -> 0x0400) int alarmInfo = ((frame[20] & 0xFF) << 8) | (frame[19] & 0xFF); data.setAlarmInfo(alarmInfo); // 时间戳(BCD) LocalDateTime reportTime = ProtocolUtils.parseTimestamp(frame, 21); data.setReportTime(reportTime); // 数据个数 int dataCount = frame[27] & 0xFF; // ------- 数据段开始(例子里有 5 个数据) ------- int offset = 28; // 1. 气体浓度 + 气体类型 // 格式:04 10 00 00 00 00 -> 1004 (浓度=100, 类型=CH4) int gasValue = ((frame[offset + 1] & 0xFF) << 8) | (frame[offset] & 0xFF); int gasTypeCode = ((frame[offset + 3] & 0xFF) << 8) | (frame[offset + 2] & 0xFF); data.setGasConcentration(BigDecimal.valueOf(gasValue)); data.setGasType(gasTypeCode == 0x0004 ? "CH4" : "未知"); offset += 6; // 2. 电池电量 float battery = ProtocolUtils.bytesToFloatLE(frame, offset + 2); data.setBattery(BigDecimal.valueOf(battery)); offset += 6; // 3. 信号强度 float signal = ProtocolUtils.bytesToFloatLE(frame, offset + 2); data.setSignalStrength(signal); offset += 6; // 4. 经度 float lon = ProtocolUtils.bytesToFloatLE(frame, offset + 2); data.setLongitude(BigDecimal.valueOf(lon)); offset += 6; // 5. 纬度 float lat = ProtocolUtils.bytesToFloatLE(frame, offset + 2); data.setLatitude(BigDecimal.valueOf(lat)); offset += 6; // 入库时间 data.setCreateTime(LocalDateTime.now()); return data; } public static void main(String[] args) { // 示例报文 String hex = "7E003A902509040070010000FFFE01AA2B00010813000425091908473305" + "041000000000F96F00000000F76F0000F841FA6F00000000FB6F0000000007"; byte[] frame = ProtocolUtils.hexStringToBytes(hex); GasMonitorData parsed = parseMessage(frame); System.out.println("========== 解析结果 =========="); System.out.println("帧类型: " + parsed.getFrameType()); System.out.println("MAC地址: " + parsed.getMacAddress()); System.out.println("短地址: " + parsed.getShortAddress()); System.out.println("自动应答: " + parsed.getAutoReplyOption()); System.out.println("序号: " + parsed.getSequenceNo()); System.out.println("命令: " + parsed.getCommand()); System.out.println("设备属性: " + parsed.getDeviceAttr()); System.out.println("协议版本: " + parsed.getProtocolVersion()); System.out.println("报警信息: " + parsed.getAlarmInfo()); System.out.println("时间戳: " + parsed.getReportTime()); System.out.println("气体浓度: " + parsed.getGasConcentration() + " %LEL"); System.out.println("气体类型: " + parsed.getGasType()); System.out.println("电池电量: " + parsed.getBattery()); System.out.println("信号强度: " + parsed.getSignalStrength()); System.out.println("经度: " + parsed.getLongitude()); System.out.println("纬度: " + parsed.getLatitude()); System.out.println("入库时间: " + parsed.getCreateTime()); } }