package com.sandu.ximon.admin.manager.iot.frame.inner.report;
|
|
import cn.hutool.core.util.StrUtil;
|
import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
|
import com.sandu.ximon.admin.manager.iot.frame.inner.IResponseInnerFrame;
|
import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
|
import lombok.Data;
|
import lombok.ToString;
|
|
/**
|
* @author chenjiantian
|
* @date 2021/12/6 18:20
|
* A5-84-01
|
* 大气心跳包 应答
|
*/
|
@Data
|
@ToString(callSuper = true)
|
public class A5AtmosphereHeartbeatReportInnerFrame extends BaseResponseInnerFrame<A5AtmosphereHeartbeatReportInnerFrame> {
|
|
// 目标地址 2
|
private String destinationAddress;
|
// 心跳包数据 58
|
private HeartBeatDataPackage heartBeatDataPackage;
|
|
private String originFrame;
|
|
@Override
|
public A5AtmosphereHeartbeatReportInnerFrame transformFrame(String hex) {
|
// 长度不一致时,返回null
|
if (StrUtil.isBlank(hex) || hex.length() < 26 || hex.substring(18).length() % 8 != 0) {
|
System.out.println("数据校验异常!");
|
return null;
|
}
|
|
// MQTT通信方式(1)
|
setConnectType(hex.substring(0, 2));
|
// 功能码(1)
|
setFunctionCode(hex.substring(2, 4));
|
// 负荷长度(2)
|
setPayloadLength(hex.substring(4, 8));
|
|
setDestinationAddress(hex.substring(8, 12));
|
|
String heartBeatData = hex.substring(12, hex.length() - 8);
|
HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage();
|
heartBeatDataPackage.transformFrame(heartBeatData);
|
setHeartBeatDataPackage(heartBeatDataPackage);
|
|
setCrc32(hex.substring(hex.length() - 8));
|
// 校验CRC32
|
String frame = hex.substring(2, hex.length() - 8);
|
this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
|
return this;
|
}
|
|
@Data
|
public static class HeartBeatDataPackage implements IResponseInnerFrame<HeartBeatDataPackage> {
|
// 编号 数据 含义 单位
|
// D7:D6 D5:D4 D3:D2 D1:D0
|
// 0x01 空,用0x00填充 0x00~0xEC 0x00~0x09 温度 0.1℃
|
// 0x02 空,用0x00填充 0x00~0x64 0x00~0x09 湿度 0.1%
|
// 0x03 空,用0x00填充 0x00 0x00 风速 0.1m/s
|
// 0x04 空,用0x00填充 0xF8或0x00 0x00 风向 八方向/0.1℃
|
// 0x05 空,用0x00填充 空,用0x00填充 0x00~0x12 风力 级
|
// 0x06 0x00 0x00 0x00 大气压 0.01hPA(百帕斯卡)
|
// 0x07 0x00 0x00 0x00 光强 Lux
|
// 0x08 空,用0x00填充 0x00 0x00 噪音 0.1dB
|
// 0x09 空,用0x00填充 0x00 0x00 PM2.5 ug/m3
|
// 0x0A 空,用0x00填充 0x00 0x00 PM10 ug/m3
|
// 0x0B 空,用0x00填充 0x00 0x00 TSP ug/m3
|
// 0x0C 空,用0x00填充 0x00 0x00 雨量 0.1mm
|
// 0x0D 空,用0x00填充 0x00 0x00 甲醛 ppm
|
// 0x0E 空,用0x00填充 0x00 0x00 TVOC ppm
|
// 0x0F 空,用0x00填充 0x00 0x00 eCO2 ppm
|
// 0x10 空,用0x00填充 0x00 0x00 SO2二氧化硫 ppm
|
// 0x11 空,用0x00填充 0x00 0x00 NO2二氧化氮 ppm
|
// 0x12 空,用0x00填充 0x00 0x00 CO一氧化碳 ppm
|
// 0x13 空,用0x00填充 0x00 0x00 O3臭氧 ppm
|
// 0x14 空,用0x00填充 0x00 0x00 F氟化物 ppm
|
|
// 设备型号 2
|
private String deviceType;
|
// 模块预热状态标志 1
|
private String moduleWarmUpStatusFlag;
|
// 温度值
|
private String temperature;
|
// 湿度值
|
private String humidity;
|
// 风速
|
private String windSpeed;
|
// 风向
|
private String windDirection;
|
// 风力
|
private String windPower;
|
// 大气压
|
private String pressure;
|
// 光强
|
private String lightIntensity;
|
// 噪音
|
private String noise;
|
// PM2.5
|
private String pm25;
|
// PM10
|
private String pm10;
|
//总悬浮颗粒物TSP
|
private String tsp;
|
// 雨量
|
private String rain;
|
// SO2二氧化硫相对值
|
private String so2;
|
// 甲醛相对值
|
private String ech2o;
|
// NO2二氧化氮
|
private String no2;
|
// TVOC
|
private String tvoc;
|
// CO一氧化碳
|
private String co;
|
// 二氧化碳
|
private String co2;
|
// O3臭氧
|
private String o3;
|
// F氟化物
|
private String fluoride;
|
|
@Override
|
public HeartBeatDataPackage transformFrame(String hex) {
|
//判断数据长度是否正确
|
if (hex == null || hex.substring(6).length() % 8 != 0) {
|
System.out.println("hex:---" + hex);
|
System.out.println("心跳包数据异常!");
|
return null;
|
}
|
|
//设备型号
|
this.deviceType = hex.substring(0, 4);
|
|
//模块预热状态标志
|
this.moduleWarmUpStatusFlag = hex.substring(4, 6);
|
|
//心跳包设备数据
|
String data = hex.substring(6, hex.length() - 8);
|
int lenght = data.length() / 8;
|
//设备数据
|
String sub;
|
for (int i = 0; i < lenght; i++) {
|
sub = data.substring(i * 8, i * 8 + 8);
|
switch (data.substring(i * 8, i * 8 + 2)) {
|
//温度
|
case "01":
|
//01001E01
|
this.temperature = Double.parseDouble(
|
parseVal(sub, 4, 6)
|
+ "."
|
+ parseVal(sub, 6, 8)
|
) + "℃";
|
break;
|
//湿度
|
case "02":
|
//02003608
|
this.humidity = Double.parseDouble(
|
parseVal(sub, 4, 6)
|
+ "."
|
+ parseVal(sub, 6, 8)
|
) + "%";
|
break;
|
//风速
|
case "03":
|
//03000000
|
this.windSpeed = parseVal(sub, 4, 8) * .1 + "m/s";
|
break;
|
//风向
|
case "04":
|
//0400F804
|
if ("F8".equals(sub.substring(4, 6))) {
|
//八向款风向仪
|
switch (sub.substring(6, 8)) {
|
case "00":
|
this.windDirection = "北风";
|
break;
|
case "01":
|
this.windDirection = "东北风";
|
break;
|
case "02":
|
this.windDirection = "东风";
|
break;
|
case "03":
|
this.windDirection = "东南风";
|
break;
|
case "04":
|
this.windDirection = "南风";
|
break;
|
case "05":
|
this.windDirection = "西南风";
|
break;
|
case "06":
|
this.windDirection = "西风";
|
break;
|
case "07":
|
this.windDirection = "西北风";
|
break;
|
default:
|
this.windDirection = "未知风向";
|
}
|
} else if ("00".equals(sub.substring(4, 6))) {
|
//360度款风向仪
|
this.windDirection = parseVal(sub, 4, 8) * .1 + "度";
|
}
|
break;
|
//风力
|
case "05":
|
this.windPower = sub.substring(6, 8) + "级";
|
break;
|
//大气压
|
case "06":
|
//06000000
|
this.pressure = parseVal(sub, 2, 8) * .01 + "hPA";
|
break;
|
//光强
|
case "07":
|
this.lightIntensity = parseVal(sub, 2, 8) + "Lux";
|
break;
|
//噪音
|
case "08":
|
|
this.noise = parseVal(sub, 4, 8) * .1 + "dB";
|
break;
|
//PM2.5
|
case "09":
|
this.pm25 = parseVal(sub, 4, 8) + "ug/m3";
|
break;
|
//PM10
|
case "0A":
|
this.pm10 = parseVal(sub, 4, 8) + "ug/m3";
|
break;
|
//TSP
|
case "0B":
|
this.tsp = parseVal(sub, 4, 8) + "ug/m3";
|
break;
|
//雨量
|
case "0C":
|
this.rain = parseVal(sub, 4, 8) * .1 + "mm";
|
break;
|
//甲醛
|
case "0D":
|
this.ech2o = parseVal(sub, 4, 8) + "ppm";
|
break;
|
//TVOC
|
case "0E":
|
this.tvoc = parseVal(sub, 4, 8) + "ppm";
|
break;
|
//eCO2
|
case "0F":
|
this.co2 = parseVal(sub, 4, 8) + "ppm";
|
break;
|
//SO2二氧化硫
|
case "10":
|
this.so2 = parseVal(sub, 4, 8) + "ppm";
|
break;
|
//NO2二氧化氮
|
case "11":
|
this.no2 = parseVal(sub, 4, 8) + "ppm";
|
break;
|
//CO一氧化碳
|
case "12":
|
this.co = parseVal(sub, 4, 8) + "ppm";
|
break;
|
//O3臭氧
|
case "13":
|
this.o3 = parseVal(sub, 4, 8) + "ppm";
|
break;
|
//F氟化物
|
case "14":
|
this.fluoride = parseVal(sub, 4, 8) + "ppm";
|
break;
|
default:
|
return null;
|
}
|
}
|
return this;
|
}
|
|
private Integer parseVal(String frame, int start, int end) {
|
return Integer.parseInt(frame.substring(start, end), 16);
|
}
|
}
|
|
}
|