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.CRC16Utils;
|
import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
|
import com.sandu.ximon.admin.manager.iot.rrpc.util.CRCUtils;
|
import lombok.Data;
|
|
import java.math.BigDecimal;
|
|
/**
|
* @author ZZQ
|
* @date 2022/4/25 10:55
|
*/
|
@Data
|
public class A5AtmosphereNewHeartbeatReportInnerFrame extends BaseResponseInnerFrame<A5AtmosphereNewHeartbeatReportInnerFrame> {
|
//010326FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B341022277F000D05B5000000015DDD0000FFFF000070C9 主动上报心跳包
|
private HeartBeatDataPackage heartBeatDataPackage;
|
|
@Override
|
public A5AtmosphereNewHeartbeatReportInnerFrame transformFrame(String hex) {
|
// 长度不一致时,返回null
|
if (StrUtil.isBlank(hex)) {
|
return null;
|
}
|
//校验
|
hex = hex.replaceAll(" ", "");
|
if (hex.length() != 86) {
|
return null;
|
}
|
|
// MQTT通信方式(1)
|
setConnectType(hex.substring(0, 2));
|
// 功能码(1)
|
setFunctionCode(hex.substring(2, 4));
|
// 负荷长度(2)
|
setPayloadLength(hex.substring(4, 6));
|
|
|
String heartBeatData = hex.substring(0, hex.length() - 4);
|
HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage();
|
heartBeatDataPackage.transformFrame(heartBeatData);
|
setHeartBeatDataPackage(heartBeatDataPackage);
|
|
setCrc16(hex.substring(hex.length() - 4));
|
// 校验CRC16
|
String frame = hex.substring(0, hex.length() - 4);
|
this.setValidate(getCrc16().equals(CRCUtils.getCRC16(frame)));
|
return this;
|
}
|
|
@Data
|
public static class HeartBeatDataPackage implements IResponseInnerFrame<HeartBeatDataPackage> {
|
//("噪声")
|
private BigDecimal noise;
|
//("硫化氢")
|
private BigDecimal hydrogenSulfide;
|
//("SO2 浓度")
|
private BigDecimal so2;
|
//("NO2 浓度")
|
private BigDecimal no2;
|
//("CO 浓度")
|
private BigDecimal co;
|
//("O3 浓度")
|
private BigDecimal o3;
|
//("PM2.5 浓度")
|
private BigDecimal pm2point5;
|
//("PM10")
|
private BigDecimal pm10;
|
//("空气温度")
|
private BigDecimal airTemperature;
|
//("空气湿度")
|
private BigDecimal airHumidity;
|
//("大气压强")
|
private BigDecimal airPressure;
|
//("风速")
|
private BigDecimal windSpeed;
|
//("风向")
|
private BigDecimal windDirection;
|
//("10 分钟雨量")
|
private BigDecimal tenRainfallMin;
|
//("辐射")
|
private BigDecimal radiation;
|
//("光照")
|
private BigDecimal illumination;
|
//紫外指数
|
private BigDecimal ultraviolet;
|
//CO2
|
private BigDecimal co2;
|
//负氧离子
|
private BigDecimal o2;
|
|
@Override
|
public HeartBeatDataPackage transformFrame(String hex) {
|
// 010326FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B341022277F000D05B5000000015DDD0000FFFF000070C9 主动上报心跳包
|
// 01:系统地址
|
// 03:功能码
|
// 26:数据段字 节数量
|
// FFFF:噪声-------》
|
// FFFF:硫化氢-------》
|
// FFFF:SO2 浓度-------》
|
// FFFF:NO2 浓度-------》
|
// FFFF:CO 浓度-------》
|
// FFFF:O3 浓度-------》
|
// FFFF:PM2.5 浓度-------》
|
// FFFF:PM10 浓度-------》
|
// 1B34:空气温度-------》29.64℃
|
// 1022:空气湿度-------》41.30%
|
// 277F:大气压强-------》101.11hPa
|
// 000D:风速-------》0.13m/s
|
// 05B5:风向-------》146.1°
|
// 0000:连续雨量-------》0mm
|
// 0001:辐射-------》1W/㎡
|
// 5DDD:光照-------》240.29Klux
|
// 0000:紫外指数-------》
|
// FFFF:CO2-------》
|
// 0000:负氧离子-------》
|
// 70C9:CRC16 校验位
|
|
//噪声
|
if (isValidData(hex, 6, 10)) {
|
this.noise = new BigDecimal(parseVal(hex, 6, 10)).divide(new BigDecimal(10), 1, BigDecimal.ROUND_HALF_UP);
|
}
|
//硫化氢
|
if (isValidData(hex, 10, 14)) {
|
this.hydrogenSulfide = new BigDecimal(parseVal(hex, 10, 14));
|
}
|
//SO2 浓度
|
if (isValidData(hex, 14, 18)) {
|
this.so2 = new BigDecimal(parseVal(hex, 14, 18));
|
}
|
//NO2 浓度
|
if (isValidData(hex, 18, 22)) {
|
this.no2 = new BigDecimal(parseVal(hex, 18, 22));
|
}
|
//CO 浓度
|
if (isValidData(hex, 22, 26)) {
|
this.co = new BigDecimal(parseVal(hex, 22, 26));
|
}
|
//O3 浓度
|
if (isValidData(hex, 26, 30)) {
|
this.o3 = new BigDecimal(parseVal(hex, 26, 30));
|
}
|
//PM2.5 浓度
|
if (isValidData(hex, 30, 34)) {
|
this.pm2point5 = new BigDecimal(parseVal(hex, 30, 34));
|
}
|
//PM10 浓度
|
if (isValidData(hex, 34, 38)) {
|
this.pm10 = new BigDecimal(parseVal(hex, 34, 38));
|
}
|
//空气温度
|
if (isValidData(hex, 38, 42)) {
|
this.airTemperature = new BigDecimal(parseVal(hex, 38, 42)).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP).subtract(new BigDecimal(40));
|
}
|
//空气湿度
|
if (isValidData(hex, 42, 46)) {
|
this.airHumidity = new BigDecimal(parseVal(hex, 42, 46)).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
}
|
//大气压强
|
if (isValidData(hex, 46, 50)) {
|
this.airPressure = new BigDecimal(parseVal(hex, 46, 50)).divide(new BigDecimal(10), 1, BigDecimal.ROUND_HALF_UP);
|
}
|
//风速
|
if (isValidData(hex, 50, 54)) {
|
this.windSpeed = new BigDecimal(parseVal(hex, 50, 54)).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
}
|
//风向
|
if (isValidData(hex, 54, 58)) {
|
this.windDirection = new BigDecimal(parseVal(hex, 54, 58)).divide(new BigDecimal(10), 1, BigDecimal.ROUND_HALF_UP);
|
}
|
//10 分钟雨量
|
if (isValidData(hex, 58, 62)) {
|
this.tenRainfallMin = new BigDecimal(parseVal(hex, 58, 62)).divide(new BigDecimal(10), 1, BigDecimal.ROUND_HALF_UP);
|
}
|
//辐射
|
if (isValidData(hex, 62, 66)) {
|
this.radiation = new BigDecimal(parseVal(hex, 62, 66));
|
}
|
//光照
|
if (isValidData(hex, 66, 70)) {
|
this.illumination = new BigDecimal(parseVal(hex, 66, 70)).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
}
|
//紫外指数
|
if (isValidData(hex, 70, 74)) {
|
this.ultraviolet = new BigDecimal(parseVal(hex, 70, 74)).divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP);
|
}
|
//CO2
|
if (isValidData(hex, 74, 78)) {
|
this.co2 = new BigDecimal(parseVal(hex, 74, 78));
|
}
|
//负氧离子
|
if (isValidData(hex, 78, 82)) {
|
this.o2 = BigDecimal.valueOf(parseVal(hex, 78, 82) * 10.0);
|
this.o2 = new BigDecimal(parseVal(hex, 78, 82)).multiply(new BigDecimal(1));
|
}
|
return this;
|
}
|
|
/**
|
* 判断该大气设备是否有对应的感应器
|
*
|
* @param value
|
* @param startIndex
|
* @param endIndex
|
* @return
|
*/
|
private boolean isValidData(String value, int startIndex, int endIndex) {
|
//FFFF是代表这个设备不支持这个数据项。0000是表示支持但是数据为零
|
if ("FFFF".equals(value.substring(startIndex, endIndex))) {
|
return false;
|
} else {
|
return true;
|
}
|
}
|
|
private Integer parseVal(String frame, int start, int end) {
|
return Integer.parseInt(frame.substring(start, end), 16);
|
}
|
}
|
|
}
|