liurunyu
2023-11-18 c1ddfd71223c1a7d704b6f21b669fbfcb37adc82
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
package com.dy.common.mw.protocol.pMeterV1_0_1.parse;
 
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
 
import com.dy.common.mw.protocol.AnnotationCodeUp;
import com.dy.common.mw.protocol.CodeParse;
import com.dy.common.mw.protocol.CodeParseCallback;
import com.dy.common.mw.protocol.CodeParseParams;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol.Data;
import com.dy.common.mw.protocol.MidResult;
import com.dy.common.mw.protocol.MidResultFromRtu;
import com.dy.common.mw.protocol.MidResultToRtu;
import com.dy.common.mw.protocol.pMeterV1_0_1.*;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
 
@AnnotationCodeUp(ifAny={
        CodeV1_0_1.cd_02
})
public class Cd_02_Up implements CodeParse{
 
    private static Logger log = LogManager.getLogger(Cd_02_Up.class);
 
    /**
     * 分析上行数据
     */
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback)throws Exception {
        ParseParamsForUpV1_0_1 para = (ParseParamsForUpV1_0_1)params ;
        int bsLen = new CommonV1_0_1().parseDataLen(para.upBuffer) ;
        if(bsLen > 0){
            this.doParse(para.upBuffer, 
                    bsLen,
                    para.upCode, 
                    para.data) ;
        }
        log.info("分析上行数据<" + CodeV1_0_1.getCodeName(para.upCode) + " 水表号=" + para.meterNo + ">:\n" + para.data.toString());
 
        MidResultFromRtu midRs = new MidResultFromRtu() ;
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//IMEI号
        midRs.meterNo = para.meterNo ;//水表号
        midRs.productId = para.productId ;//电信平台产品ID,当不在电信平台运行时,为null
        midRs.deviceId = para.deviceId ;//电信平台设备ID,当不在电信平台运行时,为null
        midRs.upCode = para.upCode ;//上行数据中的功能码
        midRs.upHex = para.upHex ;//上行数据十六进制形式
        midRs.upBuffer = para.upBuffer ;//上行数据字节数组
        midRs.data = para.data ;//解析后的数据
        
        midRs.reportOrResponse_trueOrFalse = true ;//主动上报
        
        String confirmComCode = CodeV1_0_1.cd_02 ;
        ParseParamsForDownV1_0_1 downCpParams  = new ParseParamsForDownV1_0_1() ;
        downCpParams.setValue(
                ProtocolConstantV1_0_1.protocolName, 
                para.rtuAddr, 
                para.meterNo,
                para.productId,
                para.deviceId,
                Command.defaultId,
                confirmComCode, 
                null, 
                null);
        //构造上报确认应答
        byte[] data = new Cd_XY_Down().doParse(downCpParams) ;
 
        MidResultToRtu confirmCommand = new MidResultToRtu() ;
        confirmCommand.protocolName = para.protocolName ;//协议名称
        confirmCommand.rtuAddr = para.rtuAddr ;//IMEI号
        confirmCommand.meterNo = para.meterNo ;//水表号
        confirmCommand.productId = para.productId ;//电信平台产品ID,当不在电信平台运行时,为null
        confirmCommand.deviceId = para.deviceId ;//电信平台设备ID,当不在电信平台运行时,为null
        confirmCommand.commandId = Command.defaultId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        confirmCommand.downCode = confirmComCode ;//下行命令功能码;
        confirmCommand.downBuffer = data ;//下行命令数据
        confirmCommand.downBufHex = ByteUtil.bytes2Hex(data, true) ;//下行命令数据十六进制形式
        confirmCommand.hasResponse = false ;//是否有应答
        confirmCommand.maxSendTimes = 1 ;//命令最大发送次数(当收不到应答时,将重发2次),如果不设置,命令缓存器进行补充设置
        confirmCommand.isSendFirst = true ;//确认命令,优先发送
        confirmCommand.isCachForOffLine = false ;//RTU不在线,命令是否缓存
 
        callback.callback(midRs.reportOrResponse_trueOrFalse);
        return new MidResult[]{midRs, confirmCommand} ;
    }
    /**
     * 执行分析
     * @param bs 
     * @param bsLen字节长度(总包长,包括包头和包尾)
     * @param dataCode
     * @param index
     * @param contentDataEndIndex
     * @param data
     * @throws Exception
     */
    protected void doParse(byte[] bs, int bsLen, String dataCode, Data data) throws Exception {
        DataV1_0_1 dV1 = (DataV1_0_1)data.getSubData() ;
        DataCd02Vo cdData = new DataCd02Vo() ;
        dV1.dataCd02Vo = cdData ;
        
        int index = ProtocolConstantV1_0_1.codeIndex + 1 ;
        
        cdData.dt = "20" + ByteUtil.BCD2String_BE(bs, index, index++)
                + "-" + ByteUtil.BCD2String_BE(bs, index, index++)
                + "-" + ByteUtil.BCD2String_BE(bs, index, index++)
                + " " + ByteUtil.BCD2String_BE(bs, index, index++)
                + ":" + ByteUtil.BCD2String_BE(bs, index, index++)
                + ":" + ByteUtil.BCD2String_BE(bs, index, index) ;
        
        index++ ;
        if(!ByteUtilUnsigned.bytesIsAll0xFF(bs, index, 4)){
            //当RTU实次上报时,因未初始化上报的字节是 0xFF
            cdData.totalAmount = ByteUtilUnsigned.bytes2Int_BE(bs, index)/100.0f;
        }else{
            cdData.totalAmount = 0.0f ;
        }
        
        index += 4 ;
        cdData.volt = ByteUtilUnsigned.byte2Byte(bs, index)/10.0f ;
        
        index += 1 ;
        cdData.signal = 0.0f + ByteUtilUnsigned.bytes2Short_BE(bs, index) ;
        
        index += 2 ;
        byte staAlarm = bs[index] ;
        cdData.valveSta = (byte)(staAlarm & 1) ;
        staAlarm = (byte)(staAlarm >> 2) ;
        cdData.alarmValve = (byte)(staAlarm & 1) ;
        staAlarm = (byte)(staAlarm >> 1) ;
        cdData.alarmMagnetism = (byte)(staAlarm & 1) ;
        staAlarm = (byte)(staAlarm >> 1) ;
        cdData.alarmVolt = (byte)(staAlarm & 1) ;
 
    }
}