liurunyu
2024-05-30 c929083f415ef98765afec91d5a8c88be4450f5b
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
package com.dy.common.mw.protocol.p206V1_0_0;
 
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
import com.dy.common.util.CRC8_for_2_0;
 
 
public class CommonV1_0_1 {
    /**
     * 检查头
     * @param bs 上行字节数组
     * @return true是,false否
     * @throws Exception  异常
     */
    public Boolean isThisProtocolHead(byte[] bs) throws Exception{
        if(bs == null){
            return null ;
        }else if(bs.length >= (ProtocolConstantV206V1_0_0.ctrlIndex - 1)
                && bs[0] == ProtocolConstantV206V1_0_0.P_Head_Byte
                && bs[2] == ProtocolConstantV206V1_0_0.P_Head_Byte){
            //String vs = this.parseVersion(bs) ;
            //return vs.equals(ProtocolConstantV206V1_0_0.version);
            return true ;
        }else{
            return false ;
        }
    }
    
    /**
     * 检查头
     * @param bs 上行字节数组
     * @throws Exception 异常
     */
    public void checkHead(byte[] bs) throws Exception{
        if(bs.length < 13 || bs[0] != ProtocolConstantV206V1_0_0.P_Head_Byte || bs[2] != ProtocolConstantV206V1_0_0.P_Head_Byte){
            throw new Exception("上行数据帧头不正确!") ;
        }
    }
    
    /**
     * 检查尾
     * @param bs 上行字节数组
     * @throws Exception 异常
     */
    public void checkTail(byte[] bs) throws Exception{
        if(bs.length < 1 || bs[bs.length - 1] != ProtocolConstantV206V1_0_0.P_Tail_Byte){
            throw new Exception("上行数据尾不正确!") ;
        }
    }
 
 
    /**
     * 分析帧长度
     * @param bs 上行字节数组
     * @return 数据长度
     * @throws Exception 异常
     */
    public int parseFrameLen(byte[] bs)throws Exception{
        int len = ByteUtilUnsigned.byte2Byte(bs, ProtocolConstantV206V1_0_0.dataLenIndex) ;
        return len + ProtocolConstantV206V1_0_0.lenHead2ctrl + ProtocolConstantV206V1_0_0.lenTail ;
    }
 
 
    /**
     * 分析用户数据域字节数
     * @param bs 上行字节数组
     * @return 数据长度
     * @throws Exception 异常
     */
    public int parseDataLen(byte[] bs)throws Exception{
        int len = ByteUtilUnsigned.byte2Byte(bs, ProtocolConstantV206V1_0_0.dataLenIndex) ;
        return len + ProtocolConstantV206V1_0_0.lenHead2ctrl + ProtocolConstantV206V1_0_0.lenTail ;
    }
 
 
    /**
     * 分析Rtu地址
     * @param bs 上行字节数组
     * @return 控制器地址
     * @throws Exception 异常
     */
    public String parseRtuAddr(byte[] bs)throws Exception{
        String rtuAddrBCD = "" + ByteUtil.BCD2Long_BE(bs, ProtocolConstantV206V1_0_0.rtuAddr1Index_start, ProtocolConstantV206V1_0_0.rtuAddr1Index_end) ;
        String rtuAddrStr = "" + ByteUtilUnsigned.bytes2Short_LE(bs, ProtocolConstantV206V1_0_0.rtuAddr2Index_start) ;
        while(rtuAddrStr.length() <= 5){
            rtuAddrStr = "0" + rtuAddrStr ;
        }
        return rtuAddrBCD + rtuAddrStr ;
    }
 
 
    /**
     * 分析Rtu地址
     * @param bs 上行字节数组
     * @param index 启始位
     * @return 控制器地址
     * @throws Exception 异常
     */
    public String parseRtuAddr(byte[] bs, int index)throws Exception{
        String rtuAddrBCD = "" + ByteUtil.BCD2Long_BE(bs, index, index + 2) ;//地址是大端模式
        String rtuAddrStr = "" + ByteUtilUnsigned.bytes2Short_LE(bs, index + 3) ;
        while(rtuAddrStr.length() < 5){
            rtuAddrStr = "0" + rtuAddrStr ;
        }
        return rtuAddrBCD + rtuAddrStr ;
    }
 
 
    /**
     * 分析功能码
     * @param bs 上行字节数组
     * @return 功能码
     */
    public String parseCode(byte[] bs){
        return ByteUtil.bytes2Hex(bs, false, ProtocolConstantV206V1_0_0.codeIndex, 1) ;
    }
 
    /**
     * 校验和检查
     * @param bs  上行字节数组
     * @return 通过null,未通过返回原因
     * @throws Exception 异常
     */
    public String checkCrc_str(byte[] bs) throws Exception {
        byte crcCompute = (byte)new CRC8_for_2_0().CRC8(bs, ProtocolConstantV206V1_0_0.ctrlIndex, bs.length - 3) ;
        byte crcInBs = bs[bs.length - 2] ;
        if(crcCompute == crcInBs){
            return null ;
        }else{
            return "计算CRC是:" + crcCompute + ",上传CRC是" + crcInBs ;
        }
    }
 
 
    /*
    构造控制域
    D7                  D6                  D5~D4            D3~D0
    传输方向位 DIR        拆分标志位 DIV       帧计数位 FCB       功能码
    */
    public byte createCtrl(byte dir, byte funcCode){
        byte b = dir;//(byte)0x80//控制域:DIR=1,表示此帧报文是由终端发出的上行报文;
        b = (byte)(b | funcCode) ;
        //FCB == 3
        b = (byte)(b | (byte)0x18) ;
        //DIV = 0
        //DIR = 0
        return b ;
    }
    /**
     * 得到IC卡类型名称 ( 卡类型(1:用户卡;2:管理员卡;3:调试卡;4:开关阀卡;5:清空卡))
     * @param type 字节
     * @return 名称
     */
    public static String icCardType(byte type){
        return switch (type) {
            case 1 -> "用户卡";
            case 2 -> "管理员卡";
            case 3 -> "调试卡";
            case 4 -> "开关阀卡";
            case 5 -> "清空卡";
            default -> "未知";
        };
    }
 
    /**
     * 得到关开阀类型名称
     * 开关阀类型(1:刷卡开阀;2:刷卡关阀;3:中心站开阀;4:中心站关阀;5:欠费关阀;6:流量计故障关阀;7:紧急关闭;8:用户远程开阀;9:用户远程关阀;10:开关阀卡关阀;11:开关阀卡刷卡卡开阀;)
     * @param type 字节
     * @return 名称
     */
    public static String openCloseValveType(byte type){
        return switch (type) {
            case 1 -> "刷卡开阀";
            case 2 -> "刷卡关阀";
            case 3 -> "中心站开阀";
            case 4 -> "中心站关阀";
            case 5 -> "欠费关阀";
            case 6 -> "流量计故障关阀";
            case 7 -> "紧急关阀";
            case 8 -> "用户远程开阀";
            case 9 -> "用户远程关阀";
            case 10 -> "开关阀卡关阀";
            case 11 -> "开关阀卡开阀";
            default -> "未知";
        };
    }
    public static Boolean isCloseValveType(byte type){
        return switch (type) {
            case 1 -> false ;
            case 2 -> true ;
            case 3 -> false ;
            case 4 -> true ;
            case 5 -> true ;
            case 6 -> true ;
            case 7 -> true ;
            case 8 -> false ;
            case 9 -> true ;
            case 10 -> true ;
            case 11 -> false ;
            default -> null ;
        };
    }
 
    /**
     * 处理IC卡编号,靳总制定的协议要求10位IC卡编号
     * @param icCardNo
     * @return
     */
    public static String[] dealIcCardNo(String icCardNo){
        if(icCardNo.length() > 10){
            String tail = icCardNo.substring(icCardNo.length() - 10) ;
            String head = icCardNo.substring(0, icCardNo.length() - 10) ;
            return new String[]{head , tail} ;
        }else if(icCardNo.length() < 10){
            while(icCardNo.length() != 10){
                icCardNo = "0" + icCardNo ;
            }
            return new String[]{null , icCardNo} ;
        }else{
            return new String[]{null , icCardNo} ;
        }
    }
    
    /*
     * 分析版本号
     * @param bs  上行字节数组
     * @return 版本号
     * @throws Exception 异常
    public String parseVersion(byte[] bs)throws Exception{
        short ver = ByteUtilUnsigned.byte2Byte(bs, ProtocolConstantV206V1_0_0.versionIndex) ;
        char[] cs = ("" + ver).toCharArray() ;
        StringBuilder vs = new StringBuilder() ;
        for(byte i = 0 ; i < cs.length; i++){
            if(i == 0){
                vs.append(cs[i]) ;
            }else{
                vs.append(".").append(cs[i]) ;
            }
        }
        return vs.toString() ;
    }
    */
 
}