2021与蓝度共同重构项目,服务端
MercuryZ
2022-03-31 ef270bd1855b5ce3f398c5df024840a498e33a8f
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
package com.sandu.ximon.admin.manager.iot.frame.inner.report;
 
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.NumberUtil;
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;
 
/**
 * 灯杆倾斜心跳包上报
 */
@Data
@ToString(callSuper = true)
public class A5LightPoleHeelingHeartbeatReportInnerFrame extends BaseResponseInnerFrame<A5LightPoleHeelingHeartbeatReportInnerFrame> {
 
    //  目标地址    4
    private String destinationAddress;
    //  心跳包数据
    private HeartBeatDataPackage heartBeatDataPackage;
 
 
    @Override
    public A5LightPoleHeelingHeartbeatReportInnerFrame 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 = 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> {
        //设备型号
        private String equipmentModel;
        //X轴
        private double theXAxis;
        //Y轴
        private double theYAxis;
        //Z轴
        private double theZAxis;
        //预留
        private String reservedA;
        private String reservedB;
        private String reservedC;
        private String reservedD;
 
        @Override
        public HeartBeatDataPackage transformFrame(String hex) {
            if (StrUtil.isBlank(hex)) {
                return null;
            }
            this.equipmentModel = "V" + (parseVal(hex, 0, 2)) + "." + String.format("%02d", parseVal(hex, 2, 4));
            this.theXAxis = NumberUtil.round(temperatureTransition(hex.substring(4, 8)) * 0.1, 1).doubleValue();
            this.theYAxis = NumberUtil.round(temperatureTransition(hex.substring(8, 12)) * 0.1, 1).doubleValue();
            this.theZAxis = NumberUtil.round(temperatureTransition(hex.substring(12, 16)) * 0.1, 1).doubleValue();
            this.reservedA = hex.substring(16, 20);
            this.reservedB = hex.substring(20, 24);
            this.reservedC = hex.substring(24, 28);
            this.reservedD = hex.substring(28, 32);
            //72-80保留,暂未使用
 
            return this;
        }
 
        private Integer parseVal(String frame, int start, int end) {
            return Integer.parseInt(frame.substring(start, end), 16);
        }
 
        private String parseVal(String hex) {
            return Integer.parseInt(hex, 16) + "";
        }
 
        /**
         * 将16进制转成2进制,进行补码(反码基础上+1),得到正确数值
         * 传入16进制的温度,类型为String
         * 如F500
         */
        public Double temperatureTransition(String temperature) {
 
            //将传进来的16进制的转为2进制
            String twoBinStr = hexStr2BinStr(temperature);
 
            if ("1".equals(twoBinStr.substring(0, 1))) {
                //最高位是1,为负数,将16进制的进行补码,返回
                int max = 0b1111111111111111;
                double result = (max - HexUtil.hexToInt(temperature)) * (-0.01);
                return result;
 
            } else if ("0".equals(twoBinStr.substring(0, 1))) {
                //最高位是0,正数,直接返回
                double result = (HexUtil.hexToInt(temperature)) * (0.01);
                return result;
 
            }
            //
            return 0.00;
        }
 
        /**
         * 16进制字符串转为二进制
         */
        public String hexStr2BinStr(String hexStr) {
            if (hexStr == null || hexStr.length() % 2 != 0) {
                return null;
            }
            String bString = "", tmp;
            for (int i = 0; i < hexStr.length(); i++) {
                tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexStr.substring(i, i + 1), 16));
                bString += tmp.substring(tmp.length() - 4);
            }
            return bString;
        }
    }
}