pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CodeV1_0_1.java
@@ -41,6 +41,8 @@ public static final String cd_98 = "98" ;//APP远程关阀 public static final String cd_99 = "99" ;//定时关阀开阀 public static final String cd_A0 = "A0" ;//定量关阀开阀 public static final String cd_A1 = "A1" ;//定时关阀计划开阀 public static final String cd_A2 = "A2" ;//定量关阀计划开阀 public static final String cd_B0 = "B0" ;//查询实时数据(未实现) public static final String cd_C0 = "C0" ;//遥测站整点上报实时数据 ok @@ -84,9 +86,11 @@ (code.equals(cd_98) ? "APP远程关阀" : (code.equals(cd_99) ? "定时关阀开阀" : (code.equals(cd_A0) ? "定量关阀开阀" : (code.equals(cd_A1) ? "定时关阀计划开阀" : (code.equals(cd_A2) ? "定量关阀计划开阀" : (code.equals(cd_B0) ? "查询实时数据" : (code.equals(cd_C0) ? "自报(整点)实时数据" : ""))))))))))))))))))))))))))))))))))))))))) ; ""))))))))))))))))))))))))))))))))))))))))))) ; return name ; } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/downVos/ComA1Vo.java
New file @@ -0,0 +1,23 @@ package com.dy.common.mw.protocol.p206V1_0_0.downVos; import lombok.Data; /** * @Author: liurunyu * @Date: 2024/5/28 21:30 * @Description 定时关阀开阀 */ @Data public class ComA1Vo { public String icCardNo ;//17位虚拟IC卡编号(协议是10位数字) public Double moneyRemain;//剩余金额(取值范围0.00~999999.99,单位为元) public Double waterPrice;//水价(取值范围0.00~99.99元/m3) public Integer minutes ;//用水时长(0~9999分钟) public Integer year ; //计划开阀时间---年 public Integer month ;//计划开阀时间---月 public Integer day ;//计划开阀时间---日 public Integer hour ;//计划开阀时间---时 public Integer minute ;//计划开阀时间---分 public String orderNo ;//订单号(16位数字) } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/downVos/ComA2Vo.java
New file @@ -0,0 +1,22 @@ package com.dy.common.mw.protocol.p206V1_0_0.downVos; import lombok.Data; /** * @Author: liurunyu * @Date: 2024/5/28 21:30 * @Description 定时关阀开阀 */ @Data public class ComA2Vo { public String icCardNo ;//17位虚拟IC卡编号(协议是10位数字) public Double moneyRemain;//剩余金额(取值范围0.00~999999.99,单位为元) public Double waterPrice;//水价(取值范围0.00~99.99元/m3) public Integer waterAmount ;//预用水量(0~9999 m3) public Integer year ; //计划开阀时间---年 public Integer month ;//计划开阀时间---月 public Integer day ;//计划开阀时间---日 public Integer hour ;//计划开阀时间---时 public Integer minute ;//计划开阀时间---分 public String orderNo ;//订单号(16位数字) } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_83_Up.java
@@ -84,12 +84,14 @@ * @throws Exception 异常 */ protected void doParse(byte[] bs, int bsLen, String dataCode, Data data) throws Exception { byte opType = bs[ProtocolConstantV206V1_0_0.dataIndex]; byte opType = (byte)ByteUtil.BCD2Int_LE(bs[ProtocolConstantV206V1_0_0.dataIndex]) ; Boolean isCloseType = CommonV1_0_1.isCloseValveType(opType) ; if(isCloseType != null && isCloseType.booleanValue()){ this.doParseClose(opType, bs, bsLen, dataCode, data); }else if(isCloseType != null && !isCloseType.booleanValue()){ this.doParseOpen(opType, bs, bsLen, dataCode, data); }else{ throw new Exception("开关阀类型[" + ByteUtil.bytes2Hex(new byte[]{opType}, false) + "(hex)]不可识别" ) ; } } private void doParseOpen(byte opType, byte[] bs, int bsLen, String dataCode, Data data) throws Exception { @@ -122,22 +124,6 @@ cdData.openDt = GlParse.parseTp(bs, index) ; index += 6 ; /* 开阀时,此部分没有 cdData.priceType = bs[index] ; index++ ; cdData.price = 0.0D ; tpInt = ByteUtil.BCD2Int_LE(bs, index, index) ; index++ ; cdData.price += tpInt/100.0 ; tpInt = ByteUtil.BCD2Int_LE(bs, index, index) ; index++ ; cdData.price += tpInt; cdData.cardType = bs[index] ; index++ ; */ //控制器时钟 cdData.rtuDt = GlParse.parseTp(bs, index) ; //index += 6 ; pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_84_Up.java
@@ -88,7 +88,7 @@ dV1.subData = cdData ; short index = ProtocolConstantV206V1_0_0.dataIndex ; cdData.opType = bs[index] ; cdData.opType = (byte)ByteUtil.BCD2Int_LE(bs[index]) ; index++ ; cdData.cardType = bs[index] ; pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_A1_Down.java
New file @@ -0,0 +1,214 @@ package com.dy.common.mw.protocol.p206V1_0_0.parse; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.dy.common.mw.protocol.*; import com.dy.common.mw.protocol.p206V1_0_0.CodeV1_0_1; import com.dy.common.mw.protocol.p206V1_0_0.CommonV1_0_1; import com.dy.common.mw.protocol.p206V1_0_0.ParseParamsForDownV1_0_1; import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0; import com.dy.common.mw.protocol.p206V1_0_0.downVos.Com99Vo; import com.dy.common.mw.protocol.p206V1_0_0.downVos.ComA1Vo; import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlCreate; import com.dy.common.util.ByteUtil; /** * @Author liurunyu * @Date 2024/06/12 9:30 * @Description */ @AnnotationCodeDown(ifAny={ CodeV1_0_1.cd_A1 }) public class Cd_A1_Down implements CodeParse { @Override public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback) throws Exception { ParseParamsForDownV1_0_1 para = (ParseParamsForDownV1_0_1) params ; MidResultToRtu midRs = new MidResultToRtu() ; byte[] bs = this.doParse(midRs, para) ; midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;//rtu返回命令结果 发向目的地web URL 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 if(isLowPower != null && isLowPower.booleanValue()){ //低功耗时,尽快发送 midRs.isQuickSend = true ; } return new MidResult[]{midRs} ; } /** * 构造下行数据 * @param midRs 参数 * @param para 参数 * @return 字节数组 * @throws Exception 异常 */ public byte[] doParse(MidResultToRtu midRs, ParseParamsForDownV1_0_1 para) throws Exception { CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ; byte[] bytes ; byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ; byte index = 0 ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = 0 ;//帧长度 index++ ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = commonV1_0_1.createCtrl((byte)0, (byte)0) ; index++ ; GlCreate.createRtuAddr(para.rtuAddr, bsHead, index); index += 5 ; ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ; JSONObject obj = (JSONObject)para.param; String json = obj.toJSONString(); ComA1Vo cvo = JSON.parseObject(json, ComA1Vo.class) ; if(cvo == null){ throw new Exception("json转Com99Vo为null") ; } if(cvo.icCardNo == null){ throw new Exception("虚拟IC卡编号不能为空") ; } if(cvo.moneyRemain == null){ throw new Exception("剩余金额不能为空") ; } if(cvo.waterPrice == null){ throw new Exception("水价不能为空") ; } if(cvo.minutes == null){ throw new Exception("用水时长不能为空") ; } if(cvo.minutes < 0 || cvo.minutes > 9999){ throw new Exception("用水时长取值范围是0~9999分钟") ; } if(cvo.year == null){ throw new Exception("计划开阀时间---年不能为空") ; } if(cvo.year < 24 || cvo.year > 9999){ throw new Exception("计划开阀时间---年不正确") ; } if(cvo.year > 24 && cvo.year < 2024){ throw new Exception("计划开阀时间---年不正确") ; } if(cvo.month == null){ throw new Exception("计划开阀时间---月不能为空") ; } if(cvo.month < 1 || cvo.month > 12){ throw new Exception("计划开阀时间---月不正确") ; } if(cvo.day == null){ throw new Exception("计划开阀时间---日不能为空") ; } if(cvo.day < 1 || cvo.day > 31){ throw new Exception("计划开阀时间---日不正确") ; } if(cvo.hour == null){ throw new Exception("计划开阀时间---时不能为空") ; } if(cvo.hour < 0 || cvo.hour > 23){ throw new Exception("计划开阀时间---时不正确") ; } if(cvo.minute == null){ throw new Exception("计划开阀时间---时不能为空") ; } if(cvo.minute < 0 || cvo.minute > 59){ throw new Exception("计划开阀时间---分不正确") ; } byte[] bs = new byte[8] ; GlCreate.createIcCardNo(cvo.icCardNo, bs, 0); bytes = ByteUtil.bytesMerge(bsHead, bs) ; bs = new byte[4] ; index = 0 ; Integer money = Double.valueOf(cvo.moneyRemain * 100.0D).intValue() ; byte[] bTemp = ByteUtil.int2BCD_LE(money) ; 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 ; } bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[2] ; index = 0 ; Integer price = Double.valueOf(cvo.waterPrice * 100.0D).intValue() ; bTemp = ByteUtil.int2BCD_LE(price) ; 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 ; } bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[2] ; index = 0 ; bTemp = ByteUtil.int2BCD_LE(cvo.minutes) ; 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 ; } bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ; if(cvo.year >= 2024){ cvo.year = cvo.year - 2000 ; } bs[0] = ByteUtil.int2BCD_LE(cvo.minute)[0] ; bs[1] = ByteUtil.int2BCD_LE(cvo.hour)[0] ; bs[2] = ByteUtil.int2BCD_LE(cvo.day)[0] ; bs[3] = ByteUtil.int2BCD_LE(cvo.month)[0] ; bs[4] = ByteUtil.int2BCD_LE(cvo.year)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; GlCreate.createLen(bytes);//长度放字节数组中 byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中 bytes = ByteUtil.bytesMerge(bytes, bsTail) ; return bytes ; } } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_A1_Up.java
New file @@ -0,0 +1,73 @@ package com.dy.common.mw.protocol.p206V1_0_0.parse; import com.dy.common.mw.protocol.*; import com.dy.common.mw.protocol.p206V1_0_0.*; import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlParse; import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd99Vo; import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCdA1Vo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * @Author liurunyu * @Date 2024/06/12 9:30 * @Description */ @AnnotationCodeUp(ifAny={ CodeV1_0_1.cd_A1 }) @SuppressWarnings("unused") public class Cd_A1_Up implements CodeParse { private static final Logger log = LogManager.getLogger(Cd_A1_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) + " RTU地址=" + para.rtuAddr + ">:\n" + para.data.toString()); MidResultFromRtu midRs = new MidResultFromRtu() ; midRs.protocolName = para.protocolName ;//协议名称 midRs.rtuAddr = para.rtuAddr ;//Rtu地址 midRs.upCode = para.upCode ;//上行数据中的功能码 midRs.upHex = para.upHex ;//上行数据十六进制形式 midRs.upBuffer = para.upBuffer ;//上行数据字节数组 midRs.data = para.data ;//解析后的数据 midRs.reportOrResponse_trueOrFalse = false ;//主动上报 callback.callback(midRs.reportOrResponse_trueOrFalse); return new MidResult[]{midRs} ; } /** * 执行分析 * @param bs 字节数组 * @param bsLen 字节长度(总包长,包括包头和包尾) * @param dataCode 功能码 * @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() ; DataCdA1Vo cdData = new DataCdA1Vo() ; dV1.subData = cdData ; //虚拟卡号 cdData.cardNo = GlParse.parseIcCardNo(bs, ProtocolConstantV206V1_0_0.dataIndex) ; if(bs[ProtocolConstantV206V1_0_0.dataIndex + 8] == (byte)0xAA){ cdData.success = true ; }else{ cdData.success = false ; } } } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_A2_Down.java
New file @@ -0,0 +1,221 @@ package com.dy.common.mw.protocol.p206V1_0_0.parse; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.dy.common.mw.protocol.*; import com.dy.common.mw.protocol.p206V1_0_0.CodeV1_0_1; import com.dy.common.mw.protocol.p206V1_0_0.CommonV1_0_1; import com.dy.common.mw.protocol.p206V1_0_0.ParseParamsForDownV1_0_1; import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0; import com.dy.common.mw.protocol.p206V1_0_0.downVos.ComA0Vo; import com.dy.common.mw.protocol.p206V1_0_0.downVos.ComA2Vo; import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlCreate; import com.dy.common.util.ByteUtil; /** * @Author liurunyu * @Date 2024/06/12 9:30 * @Description */ @AnnotationCodeDown(ifAny={ CodeV1_0_1.cd_A2 }) public class Cd_A2_Down implements CodeParse { @Override public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback) throws Exception { ParseParamsForDownV1_0_1 para = (ParseParamsForDownV1_0_1) params ; MidResultToRtu midRs = new MidResultToRtu() ; byte[] bs = this.doParse(midRs, para) ; midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;//rtu返回命令结果 发向目的地web URL 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 if(isLowPower != null && isLowPower.booleanValue()){ //低功耗时,尽快发送 midRs.isQuickSend = true ; } return new MidResult[]{midRs} ; } /** * 构造下行数据 * @param midRs 参数 * @param para 参数 * @return 字节数组 * @throws Exception 异常 */ public byte[] doParse(MidResultToRtu midRs, ParseParamsForDownV1_0_1 para) throws Exception { CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ; byte[] bytes ; byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ; byte index = 0 ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = 0 ;//帧长度 index++ ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = commonV1_0_1.createCtrl((byte)0, (byte)0) ; index++ ; GlCreate.createRtuAddr(para.rtuAddr, bsHead, index); index += 5 ; ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ; JSONObject obj = (JSONObject)para.param; String json = obj.toJSONString(); ComA2Vo cvo = JSON.parseObject(json, ComA2Vo.class) ; if(cvo == null){ throw new Exception("json转ComA0Vo为null") ; } if(cvo.icCardNo == null){ throw new Exception("虚拟IC卡编号不能为空") ; } if(cvo.moneyRemain == null){ throw new Exception("剩余金额不能为空") ; } if(cvo.waterPrice == null){ throw new Exception("水价不能为空") ; } if(cvo.waterAmount == null){ throw new Exception("预用水量不能为空") ; } if(cvo.waterAmount < 0 || cvo.waterAmount > 9999){ throw new Exception("预用水量取值范围是0~9999m3") ; } if(cvo.year == null){ throw new Exception("计划开阀时间---年不能为空") ; } if(cvo.year < 24 || cvo.year > 9999){ throw new Exception("计划开阀时间---年不正确") ; } if(cvo.year > 24 && cvo.year < 2024){ throw new Exception("计划开阀时间---年不正确") ; } if(cvo.month == null){ throw new Exception("计划开阀时间---月不能为空") ; } if(cvo.month < 1 || cvo.month > 12){ throw new Exception("计划开阀时间---月不正确") ; } if(cvo.day == null){ throw new Exception("计划开阀时间---日不能为空") ; } if(cvo.day < 1 || cvo.day > 31){ throw new Exception("计划开阀时间---日不正确") ; } if(cvo.hour == null){ throw new Exception("计划开阀时间---时不能为空") ; } if(cvo.hour < 0 || cvo.hour > 23){ throw new Exception("计划开阀时间---时不正确") ; } if(cvo.minute == null){ throw new Exception("计划开阀时间---时不能为空") ; } if(cvo.minute < 0 || cvo.minute > 59){ throw new Exception("计划开阀时间---分不正确") ; } //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ; //if(icCardNoGrp[0] != null){ // midRs.param = icCardNoGrp[0] ; //} //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ; byte[] bs = new byte[16] ; index = 0 ; GlCreate.createIcCardNo(cvo.icCardNo, bs, 0); bytes = ByteUtil.bytesMerge(bsHead, bs) ; bs = new byte[4] ; index = 0 ; Integer money = Double.valueOf(cvo.moneyRemain * 100.0D).intValue() ; byte[] bTemp = ByteUtil.int2BCD_LE(money) ; 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 ; } bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[2] ; index = 0 ; Integer price = Double.valueOf(cvo.waterPrice * 100.0D).intValue() ; bTemp = ByteUtil.int2BCD_LE(price) ; 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 ; } bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[2] ; index = 0 ; bTemp = ByteUtil.int2BCD_LE(cvo.waterAmount) ; 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 ; } bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ; if(cvo.year >= 2024){ cvo.year = cvo.year - 2000 ; } bs[0] = ByteUtil.int2BCD_LE(cvo.minute)[0] ; bs[1] = ByteUtil.int2BCD_LE(cvo.hour)[0] ; bs[2] = ByteUtil.int2BCD_LE(cvo.day)[0] ; bs[3] = ByteUtil.int2BCD_LE(cvo.month)[0] ; bs[4] = ByteUtil.int2BCD_LE(cvo.year)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; GlCreate.createLen(bytes);//长度放字节数组中 byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中 bytes = ByteUtil.bytesMerge(bytes, bsTail) ; return bytes ; } } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_A2_Up.java
New file @@ -0,0 +1,73 @@ package com.dy.common.mw.protocol.p206V1_0_0.parse; import com.dy.common.mw.protocol.*; import com.dy.common.mw.protocol.p206V1_0_0.*; import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlParse; import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCdA0Vo; import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCdA2Vo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * @Author liurunyu * @Date 2024/06/12 9:30 * @Description */ @AnnotationCodeUp(ifAny={ CodeV1_0_1.cd_A2 }) @SuppressWarnings("unused") public class Cd_A2_Up implements CodeParse { private static final Logger log = LogManager.getLogger(Cd_A2_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) + " RTU地址=" + para.rtuAddr + ">:\n" + para.data.toString()); MidResultFromRtu midRs = new MidResultFromRtu() ; midRs.protocolName = para.protocolName ;//协议名称 midRs.rtuAddr = para.rtuAddr ;//Rtu地址 midRs.upCode = para.upCode ;//上行数据中的功能码 midRs.upHex = para.upHex ;//上行数据十六进制形式 midRs.upBuffer = para.upBuffer ;//上行数据字节数组 midRs.data = para.data ;//解析后的数据 midRs.reportOrResponse_trueOrFalse = false ;//主动上报 callback.callback(midRs.reportOrResponse_trueOrFalse); return new MidResult[]{midRs} ; } /** * 执行分析 * @param bs 字节数组 * @param bsLen 字节长度(总包长,包括包头和包尾) * @param dataCode 功能码 * @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() ; DataCdA2Vo cdData = new DataCdA2Vo() ; dV1.subData = cdData ; //虚拟卡号 cdData.cardNo = GlParse.parseIcCardNo(bs, ProtocolConstantV206V1_0_0.dataIndex) ; if(bs[ProtocolConstantV206V1_0_0.dataIndex + 8] == (byte)0xAA){ cdData.success = true ; }else{ cdData.success = false ; } } } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/upVos/DataCd84Vo.java
@@ -9,7 +9,7 @@ @Data public class DataCd84Vo { public Byte opType;//开关阀类型(1:刷卡开阀;2:刷卡关阀;3:中心站开阀;4:中心站关阀;5:欠费关阀;6:流量计故障关阀;7:紧急关闭;8:用户远程开阀;9:用户远程关阀;10:开关阀卡关阀;11:开关阀卡刷卡卡开阀;) public Byte opType; public Byte cardType ;//卡类型(0:无卡;1:用户卡;2:管理员卡;3:调试卡;4:开关阀卡;5:清空卡) public String cardAddr ;//IC卡地址(8位字符) public String cardNo ;//IC卡编号 pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/upVos/DataCdA1Vo.java
New file @@ -0,0 +1,41 @@ package com.dy.common.mw.protocol.p206V1_0_0.upVos; import lombok.Data; /** * @Author liurunyu * @Date 2024/01/13 10:08 * @LastEditTime 2024/01/13 10:08 * @Description */ @Data public class DataCdA1Vo { public String cardNo ;//虚拟卡号 public boolean success; public String toString(){ StringBuilder sb = new StringBuilder() ; sb.append(" 定时关阀开阀应答:\n"); sb.append(" 虚拟卡号:"); sb.append(cardNo); sb.append("\n"); sb.append(" 结果:"); sb.append(success?"执行":"失败"); sb.append("\n"); return sb.toString() ; } public String comLog(){ StringBuilder sb = new StringBuilder() ; sb.append("定时关阀开阀命令回复:\n"); sb.append(" 虚拟卡号:"); sb.append(cardNo); sb.append("\n"); sb.append(" 结果:"); sb.append(success?"执行":"失败"); sb.append("\n"); return sb.toString() ; } } pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/upVos/DataCdA2Vo.java
New file @@ -0,0 +1,41 @@ package com.dy.common.mw.protocol.p206V1_0_0.upVos; import lombok.Data; /** * @Author liurunyu * @Date 2024/01/13 10:08 * @LastEditTime 2024/01/13 10:08 * @Description */ @Data public class DataCdA2Vo { public String cardNo ;//虚拟卡号 public boolean success; public String toString(){ StringBuilder sb = new StringBuilder() ; sb.append(" 定量关阀开阀应答:\n"); sb.append(" 虚拟卡号:"); sb.append(cardNo); sb.append("\n"); sb.append(" 结果:"); sb.append(success?"执行":"失败"); sb.append("\n"); return sb.toString() ; } public String comLog(){ StringBuilder sb = new StringBuilder() ; sb.append("定量关阀开阀命令回复:\n"); sb.append(" 虚拟卡号:"); sb.append(cardNo); sb.append("\n"); sb.append(" 结果:"); sb.append(success?"执行":"失败"); sb.append("\n"); return sb.toString() ; } } pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/src/main/java/com/dy/pipIrrMwTestWeb/p206V1_0_0/CommandP206V1_0_0Ctrl.java
@@ -193,7 +193,7 @@ comVo.icCardNo = CommandP206V1_0_0Ctrl.vsIcCardNo; comVo.moneyRemain = 234.56 ; comVo.waterPrice = 1.2 ; comVo.minutes = 5 ; comVo.minutes = 3 ; return this.sendCom2Mw(this.command(CodeV1_0_1.cd_99, comVo, null)) ; }