2021与蓝度共同重构项目,服务端
zhanzhiqin
2022-10-14 ea8e8e7dd5f10cff4054f5fde8fd3961aaac1834
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
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;
 
/**
 * @author chenjiantian
 * @date 2021/12/6 18:20
 * A5-81-40
 * 灯读心跳包 上报
 */
@Data
@ToString(callSuper = true)
public class A5LightHeartbeatReportInnerFrame extends BaseResponseInnerFrame<A5LightHeartbeatReportInnerFrame> {
 
    //  目标地址    2
    private String destinationAddress;
    //  心跳包数据   58
    private HeartBeatDataPackage heartBeatDataPackage;
 
    private String originFrame;
 
    @Override
    public A5LightHeartbeatReportInnerFrame 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, 108);
        HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage();
        heartBeatDataPackage.transformFrame(heartBeatData);
        setHeartBeatDataPackage(heartBeatDataPackage);
 
        setCrc32(hex.substring(108, 116));
        //  校验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> {
        //  年RTC 1
        private Integer year;
        //  月RTC 1
        private Integer month;
        //  日RTC 1
        private Integer day;
        //  时RTC 1
        private Integer hour;
        //  分RTC 1
        private Integer min;
        //  秒RTC 1
        private Integer sec;
        //  设备温度 2  1字节整数1字节小数
        private Double deviceTemperature;
        //  灯1亮度百分比 1
        private Integer lightPercent;
        //  电网电压 2 1字节整数1字节小数
        private Double voltage;
        //  电网电流 2 1字节整数1字节小数
        private Double electricCurrent;
        //  赫兹 2 1字节整数1字节小数
        private Double hertz;
        //  功率因素 2 1字节整数1字节小数
        private Double powerFactor;
        //  有功功率 2 1字节整数1字节小数
        private Double activePower;
        //  无功功率 2 1字节整数1字节小数
        private Double reactivePower;
        //  最近一次亮灯时间 4 秒
        private Long recentlyLightSec;
        //  累计亮灯时间 4
        private Long totalLightSec;
        //  最近一次用电电量 4
        private Double recentlyUsingPower;
        //  累计用电电量 4
        private Double totalUsingPower;
        //  灯2亮度百分比 1
        private Integer light2Percent;
        //  保留 11
        private String retain;
        //  原帧
        private String originFrame;
 
        @Override
        public HeartBeatDataPackage transformFrame(String hex) {
            this.originFrame = hex;
            this.year = HexUtil.hexToInt(hex.substring(0, 2));
            this.month = HexUtil.hexToInt(hex.substring(2, 4));
            this.day = HexUtil.hexToInt(hex.substring(4, 6));
            this.hour = HexUtil.hexToInt(hex.substring(6, 8));
            this.min = HexUtil.hexToInt(hex.substring(8, 10));
            this.sec = HexUtil.hexToInt(hex.substring(10, 12));
 
//            //需要把十六进制转二进制
//            this.deviceTemperature = NumberUtil.round(HexUtil.hexToInt(hex.substring(12, 16)) * 0.01, 2).doubleValue();
            this.deviceTemperature = NumberUtil.round(temperatureTransition(hex.substring(12, 16)), 2).doubleValue();
            this.lightPercent = HexUtil.hexToInt(hex.substring(16, 18));
            this.voltage = NumberUtil.round(HexUtil.hexToInt(hex.substring(18, 22)) * 0.1, 1).doubleValue();
            this.electricCurrent = NumberUtil.round(HexUtil.hexToInt(hex.substring(22, 26)) * 0.001, 3).doubleValue();
            this.hertz = NumberUtil.round(HexUtil.hexToInt(hex.substring(26, 30)) * 0.01, 2).doubleValue();
            this.powerFactor = NumberUtil.round(HexUtil.hexToInt(hex.substring(30, 34)) * 0.001, 3).doubleValue();
            this.activePower = NumberUtil.round(HexUtil.hexToInt(hex.substring(34, 38)) * 0.01, 2).doubleValue();
            this.reactivePower = NumberUtil.round(HexUtil.hexToInt(hex.substring(38, 42)) * 0.01, 2).doubleValue();
            this.recentlyLightSec = HexUtil.hexToLong(hex.substring(42, 50));
            this.totalLightSec = HexUtil.hexToLong(hex.substring(50, 58));
            this.recentlyUsingPower = NumberUtil.round(HexUtil.hexToInt(hex.substring(58, 66)) * (double) 0.001, 3).doubleValue();
            this.totalUsingPower = NumberUtil.round(HexUtil.hexToInt(hex.substring(66, 74)) * (double) 0.001, 3).doubleValue();
            this.light2Percent = HexUtil.hexToInt(hex.substring(74, 76));
            this.retain = hex.substring(76, 96);
            return this;
        }
 
        /**
         * 将16进制转成2进制,进行补码(反码基础上+1),得到正确数值
         * 传入16进制的温度,类型为String
         * 如F500
         */
        public static 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 static 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;
        }
 
    }
 
}