燃气报警器解析\动火离人解析
parent
34ea26c4b6
commit
c696dc477d
@ -0,0 +1,44 @@
|
||||
package cc.iotkit.plugins.emqx.conf;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class GasDetectorParser {
|
||||
|
||||
// 探测器精度映射
|
||||
private static final Map<Integer, String> PRECISION_MAP = Map.of(
|
||||
0b000, "*1",
|
||||
0b001, "*0.1",
|
||||
0b010, "*0.01",
|
||||
0b011, "*0.001",
|
||||
0b100, "*0.0001"
|
||||
);
|
||||
|
||||
// 浓度单位映射
|
||||
private static final Map<Integer, String> UNIT_MAP = Map.of(
|
||||
0b000, "%LEL",
|
||||
0b001, "PPM",
|
||||
0b010, "%VOL"
|
||||
);
|
||||
|
||||
// 气体类型映射
|
||||
private static final Map<Integer, String> GAS_TYPE_MAP = Map.of(
|
||||
0b0000, "甲烷",
|
||||
0b0001, "一氧化碳",
|
||||
0b0010, "丙烷",
|
||||
0b0011, "氢气",
|
||||
0b0100, "苯",
|
||||
0b0101, "氧气"
|
||||
);
|
||||
|
||||
public static String parse(int data) {
|
||||
int precisionBits = (data >> 13) & 0b111; // 提取bit15-13
|
||||
int unitBits = (data >> 10) & 0b111; // 提取bit12-10
|
||||
int gasTypeBits = (data >> 6) & 0b1111; // 提取bit9-6
|
||||
|
||||
return String.format("探测器精度: %s, 浓度单位: %s, 测量气体: %s",
|
||||
PRECISION_MAP.getOrDefault(precisionBits, "未知精度"),
|
||||
UNIT_MAP.getOrDefault(unitBits, "未知单位"),
|
||||
GAS_TYPE_MAP.getOrDefault(gasTypeBits, "未知气体")
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package cc.iotkit.plugins.emqx.conf;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.mqtt.messages.MqttMessage;
|
||||
import io.vertx.mqtt.messages.MqttPublishMessage;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class MqttDataProcessor {
|
||||
private static final byte HEADER = (byte) 0xAA;
|
||||
private static final byte FOOTER = (byte) 0x55;
|
||||
private static final int CRC_START_INDEX = 3; // 帧长度开始位置
|
||||
private static final String HEX_FORMAT = "0x%02X";
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
sb.append(String.format("%02X", b));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
public static JsonObject parseFrame(byte[] frameData) {
|
||||
|
||||
// 基础校验
|
||||
if (frameData[0] != HEADER || frameData[frameData.length - 1] != FOOTER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 提取各字段
|
||||
ByteBuffer buffer = ByteBuffer.wrap(frameData);
|
||||
byte type = buffer.get(1);
|
||||
byte version = buffer.get(2);
|
||||
int length = Short.toUnsignedInt(buffer.getShort(3));
|
||||
byte mid = buffer.get(5);
|
||||
byte cmd = buffer.get(6);
|
||||
String hexCmd = String.format(HEX_FORMAT, cmd);
|
||||
// 数据域提取
|
||||
int dataLength = length - 10; // 总长减去固定字段长度
|
||||
byte[] data = new byte[dataLength];
|
||||
System.arraycopy(frameData, 7, data, 0, dataLength);
|
||||
String data1 = parseToHexString(data);
|
||||
// CRC校验
|
||||
byte[] crcData = new byte[length - 6]; // 从LENGTH到DATA
|
||||
System.arraycopy(frameData, 3, crcData, 0, crcData.length);
|
||||
int receivedCrc = (frameData[length-2] & 0xFF) << 8 | (frameData[length-3] & 0xFF);
|
||||
|
||||
int calculatedCrc = calculateModbusCRC(crcData);
|
||||
|
||||
if (receivedCrc != calculatedCrc) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// 转换为16进制字符串
|
||||
// 完整帧数据转16进制
|
||||
StringBuilder frameHexBuilder = new StringBuilder();
|
||||
for (byte b : frameData) {
|
||||
frameHexBuilder.append(String.format("%02X", b));
|
||||
}
|
||||
String rawHex = frameHexBuilder.toString();
|
||||
// 构建JSON
|
||||
// ObjectMapper mapper = new ObjectMapper();
|
||||
// ObjectNode json = mapper.createObjectNode();
|
||||
JsonObject json = new JsonObject();
|
||||
json.put("protocolType", type);
|
||||
json.put("protocolVersion", version);
|
||||
json.put("messageId", mid);
|
||||
json.put("cmd", hexCmd);
|
||||
json.put("data", data1);
|
||||
json.put("rawHex", rawHex);
|
||||
json.put("crcValid", true);
|
||||
System.out.println("拿到的所有数据++++++++++" + json);
|
||||
// JsonObject jsonObject = new JsonObject(json.toString());
|
||||
return json;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static String parseToHexString(byte[] frameData) {
|
||||
StringBuilder hexStr = new StringBuilder();
|
||||
for (byte b : frameData) {
|
||||
hexStr.append(String.format("%02X ", b));
|
||||
}
|
||||
return hexStr.toString().trim();
|
||||
}
|
||||
public static int calculateModbusCRC(byte[] data) {
|
||||
int crc = 0xFFFF;
|
||||
for (byte b : data) {
|
||||
crc ^= (b & 0xFF);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if ((crc & 1) == 1) {
|
||||
crc = (crc >>> 1) ^ 0xA001;
|
||||
} else {
|
||||
crc >>>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package cc.iotkit.plugins.emqx.conf;
|
||||
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class MqttHexProcessor {
|
||||
|
||||
|
||||
// 检测是否为HEX字符串格式
|
||||
private static boolean isHexString(byte[] data) {
|
||||
if (data.length % 2 != 0) return false;
|
||||
for (byte b : data) {
|
||||
char c = (char) b;
|
||||
if (!(Character.isDigit(c) ||
|
||||
(c >= 'A' && c <= 'F') ||
|
||||
(c >= 'a' && c <= 'f') ||
|
||||
Character.isWhitespace(c))) { // 新增空格检查
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// HEX字符串转字节数组
|
||||
/* private static byte[] parseHexString(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
||||
+ Character.digit(s.charAt(i+1), 16));
|
||||
}
|
||||
return data;
|
||||
}*/
|
||||
|
||||
// 统一返回byte[]的入口方法
|
||||
public static byte[] processToBytes(byte[] payload) {
|
||||
try {
|
||||
String payloadStr = new String(payload, StandardCharsets.UTF_8);
|
||||
System.out.println("payloadStr:" + payloadStr);
|
||||
System.out.println("payloadStr1:" + isHexString(payload));
|
||||
return isHexString(payload) ?
|
||||
Hex.decodeHex(payloadStr.replaceAll("\\s+", "")) :
|
||||
payload; // 原始字节直接返回
|
||||
} catch (Exception e) {
|
||||
return payload; // 异常时返回原始数据
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*public static void main(String[] args) throws DecoderException {
|
||||
String input = "AA 01 01 00 35001100013836323537313037393339313237393839383631313235323037303833363037383837000000000111b12255"; // 原始字符串
|
||||
// byte[] result = convertHexStringToBytes(input);
|
||||
byte[] bytes = Hex.decodeHex(input);
|
||||
// 基础校验
|
||||
|
||||
|
||||
// 提取各字段
|
||||
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
||||
byte type = buffer.get(1);
|
||||
byte version = buffer.get(2);
|
||||
System.out.println(String.format("%02X", bytes[0]));
|
||||
System.out.println(type);
|
||||
System.out.println(version);
|
||||
|
||||
}*/
|
||||
}
|
Loading…
Reference in New Issue