2021与蓝度共同重构项目,服务端
liuhaonan
2022-08-03 4dd0d4864ecd0be365d8a5350a3ac9463d0c2ae4
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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
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)) {
            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;
            }
 
            //设备型号
            Integer type = 0;
            this.deviceType = hex.substring(0, 4);
            if (this.deviceType.equals(DeviceType.SENSOR_V1.getType())) {
                type = 1;
            }
            //模块预热状态标志
            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);
        }
    }
 
    public enum DeviceType {
 
        SENSOR_V1("0101");
 
        private String type;
 
        DeviceType(String type) {
            this.type = type;
        }
 
        public String getType() {
            return type;
        }
    }
}