liurunyu
2024-05-13 2b2a90e952c2c59642c41d8af5759ceb51b9e099
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
package com.dy.common.mw.protocol.p206V202404.parse;
 
import com.alibaba.fastjson2.JSON;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V202404.CodeV202404;
import com.dy.common.mw.protocol.p206V202404.ParseParamsForDownV202404;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCd22Vo;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCd92_A2Vo;
import com.dy.common.mw.protocol.p206V202404.parse.global.GlCreate;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.NumUtil;
 
@AnnotationCodeDown(ifAny={
        CodeV202404.cd_92,
        CodeV202404.cd_A2
})
public class Cd_92_A2_Down implements CodeParse {
 
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback) throws Exception {
        ParseParamsForDownV202404 para = (ParseParamsForDownV202404) params ;
        byte[] bs = this.doParse(para) ;
 
        MidResultToRtu midRs = new MidResultToRtu() ;
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downBuffer = bs ;//下行命令数据
        midRs.downBufHex = ByteUtil.bytes2Hex(bs, true) ;//下行命令数据十六进制形式
        midRs.hasResponse = true ;//是否有应答
        midRs.maxSendTimes = null ;//命令最大发送次数(当收不到应答时,将重发),如果不设置,命令缓存器进行补充设置
        midRs.isCachForOffLine = false ;//RTU不在线,命令是否缓存,低功耗时为true
 
        midRs.isSendFirst = false ;//命令应答,首先发送,防止RTU重新上报
        if(isLowPower != null && isLowPower.booleanValue()){
            //低功耗时,尽快发送
            midRs.isQuickSend = true ;
        }
 
        return new MidResult[]{midRs} ;
    }
    /**
     * 构造下行数据
     * @param para 参数
     * @return 字节数组
     * @throws Exception 异常
     */
    public byte[] doParse(ParseParamsForDownV202404 para) throws Exception {
        byte[] bytes = GlCreate.createStart2Cd(para.rtuAddr, para.commandCode);
        if(para.param != null){
            String json = (String)para.param;
            ComCd92_A2Vo cvo = JSON.parseObject(json, ComCd92_A2Vo.class) ;
            if(cvo == null){
                throw new Exception("json转ComCd92_A2Vo为null") ;
            }
            if(cvo.waterRemain != null){
                if(cvo.waterRemain < 0 || cvo.waterRemain > 99999999.99){
                    throw new Exception("用户剩余水量必须是0~99999999.99范围内的数据") ;
                }
            }
            if(cvo.moneyRemain != null){
                if(cvo.moneyRemain < 0 || cvo.moneyRemain > 999999.99){
                    throw new Exception("用户剩余金额必须是0~999999.99范围内的数据") ;
                }
            }
            if(cvo.waterPrice != null){
                if(cvo.waterPrice < 0 || cvo.waterPrice > 99.99){
                    throw new Exception("水量单价必须是0~99.99范围内的数据") ;
                }
            }
            if(cvo.elePrice != null){
                if(cvo.elePrice < 0 || cvo.elePrice > 99.99){
                    throw new Exception("电量单价必须是0~99.99范围内的数据") ;
                }
            }
            if(!NumUtil.isPlusIntNumber(cvo.orderNo)){
                throw new Exception("订单号必须是16位数字") ;
            }
            if(cvo.orderNo.length() != 12){
                throw new Exception("订单号必须是16位数字") ;
            }
 
 
            byte[] bs = new byte[45] ;
            int index = 0 ;
            bs[index] = (byte)(Integer.parseInt(cvo.controllerType, 16));
 
            index ++ ;
            bs[index] = cvo.projectNo.byteValue() ;
 
            index ++ ;
            if(cvo.controllerType.equals("01")){
                bs[index] = (byte)0xF0 ;
            }else{
                bs[index] = (byte)0x00 ;
            }
 
            index ++ ;
            GlCreate.createIcCardNo(cvo.icCardNo, bs, index);
 
            index += 8 ;
            if(cvo.waterRemain != null){
                cvo.waterRemain = 0.0 ;
            }
            String strTemp = "" + Double.valueOf(cvo.waterRemain * 100).intValue() ;
            byte[] bTemp = ByteUtil.string2BCD_LE(strTemp) ;
            int bTempLen = bTemp.length ;
            int count = 0 ;
            for(int i = 0 ; i < bTempLen; i++){
                bs[index++] = bTemp[i] ;
                count ++ ;
                if(count >= 4){
                    break ;
                }
            }
            for(; count < 4; count++){
                bs[index++] = 0 ;
            }
 
            if(cvo.moneyRemain != null){
                cvo.moneyRemain = 0.0 ;
            }
            strTemp = "" + (Double.valueOf(cvo.moneyRemain * 100)).intValue() ;
            bTemp = ByteUtil.string2BCD_LE(strTemp) ;
            bTempLen = bTemp.length ;
            count = 0 ;
            for(int i = 0 ; i < bTempLen; i++){
                bs[index++] = bTemp[i] ;
                count ++ ;
                if(count >= 4){
                    break ;
                }
            }
            for(; count < 4; count++){
                bs[index++] = 0 ;
            }
 
 
            if(cvo.waterPrice != null){
                cvo.waterPrice = 0.0 ;
            }
            strTemp = "" + (Double.valueOf(cvo.waterPrice * 100)).intValue() ;
            bTemp = ByteUtil.string2BCD_LE(strTemp) ;
            bTempLen = bTemp.length ;
            count = 0 ;
            for(int i = 0 ; i < bTempLen; i++){
                bs[index++] = bTemp[i] ;
                count ++ ;
                if(count >= 2){
                    break ;
                }
            }
            for(; count < 2; count++){
                bs[index++] = 0 ;
            }
 
 
            if(cvo.elePrice != null){
                cvo.elePrice = 0.0 ;
            }
            strTemp = "" + (Double.valueOf(cvo.elePrice * 100)).intValue() ;
            bTemp = ByteUtil.string2BCD_LE(strTemp) ;
            bTempLen = bTemp.length ;
            count = 0 ;
            for(int i = 0 ; i < bTempLen; i++){
                bs[index++] = bTemp[i] ;
                count ++ ;
                if(count >= 2){
                    break ;
                }
            }
            for(; count < 2; count++){
                bs[index++] = 0 ;
            }
 
 
            ByteUtil.string2BCD_BE(bs, cvo.orderNo, index) ;
 
            index += 8 ;
            GlCreate.createDt(bs, index);
 
            index += 6 ;
            GlCreate.createPw(bs, index);
 
            index += 2 ;
            GlCreate.createS2D(bs, index) ;
 
            index += 4 ;
            bs[index] = 0 ; //时延
 
            bytes = ByteUtil.bytesMerge(bytes, bs) ;
        }else{
            throw new Exception("下行命令参数据为null") ;
        }
        GlCreate.createLen(bytes);//长度放字节数组中
 
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾
 
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
 
        return bytes ;
    }
 
 
}