2021与蓝度共同重构项目,服务端
liuhaonan
2022-10-14 09afe52c3ef2a09055fb621b25aa5416394a5382
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
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);
        }
    }
 
}