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 { //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 { //("噪声") 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); } } }