| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- 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());
- }
- }
|