liurunyu
2025-06-27 566d6dba9ac3309a716efa43ecbeaaf09e46e394
表阀一体机协议增加35、36、37、38、9D功能码协议实现
12个文件已添加
5个文件已修改
1 文件已重命名
1438 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/CodeV202404.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd35Vo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd36Vo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd37Vo.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd38Vo.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd9DVo.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_35_36_37_38Up.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_35_Down.java 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_36_Down.java 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_37_Down.java 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_38_Down.java 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_93_A3_Up.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_9D_Down.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/global/GlParse.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/upVos/DataCd35_36Vo.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/upVos/DataCd93_9D_A3Vo.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd93/CdCtrl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cdA3/CdCtrl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/CodeV202404.java
@@ -41,6 +41,12 @@
    public static final String cd_9B = "9B" ; //清除设备终端注册号
    public static final String cd_9C = "9C" ; //黑名单远程强制关闭水泵/阀门
    public static final String cd_C2 = "C2" ; //开关水泵/阀门成功/失败上报
    public static final String cd_9D = "9D" ; //正常远程关闭水泵/阀门
    public static final String cd_35 = "35" ; //APP端远程定时开启水泵/阀门
    public static final String cd_36 = "36" ; //APP端远程定量开启水泵/阀门
    public static final String cd_37 = "37" ; //APP端计划远程定时开启水泵/阀门
    public static final String cd_38 = "38" ; //APP端远程计划定量开启水泵/阀门
    public static final String cd_1600 = "1600" ;//升级复位
    public static final String cd_1601 = "1601" ;//升级配置
@@ -90,6 +96,13 @@
            (code.equals(cd_9B) ? "清除设备终端注册号" :
            (code.equals(cd_9C) ? "黑名单远程强制关闭水泵/阀门" :
            (code.equals(cd_C2) ? "开关水泵/阀门结果上报" :
            (code.equals(cd_9D) ? "正常远程关闭水泵/阀门" :
            (code.equals(cd_35) ? "APP端远程定时开启水泵/阀门" :
            (code.equals(cd_36) ? "APP端远程定量开启水泵/阀门" :
            (code.equals(cd_37) ? "APP端计划远程定时开启水泵/阀门" :
            (code.equals(cd_38) ? "APP端远程计划定量开启水泵/阀门" :
            (code.equals(cd_1600) ? "升级复位" :
            (code.equals(cd_1601) ? "升级配置" :
            (code.equals(cd_1602) ? "升级数据" :
@@ -97,7 +110,7 @@
            (code.equals(cd_9601) ? "升级配置" :
            (code.equals(cd_9602) ? "升级数据" :
            (code.equals(cd_9603) ? "升级校验" :
            "")))))))))))))))))))))))))))))))))))))))))))))) ;
            ""))))))))))))))))))))))))))))))))))))))))))))))))))) ;
        if(name == null || name.equals("")){
            name = code ;
        }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd35Vo.java
New file
@@ -0,0 +1,16 @@
package com.dy.common.mw.protocol.p206V202404.downVos;
import lombok.Data;
@Data
public class ComCd35Vo {
    public String controllerType;//控制器类型 01(0x01):测控一体阀;02(0x02):表阀一体机;57(0x57):井电控制器
    public Integer projectNo ;//项目编号
    public String icCardNo ;//用户卡序列号(17位数字)(6字节BCD,2字节HEX)
    public Double waterRemain ;//用户剩余水量, 两个小数点, 单位m3, 0~99999999.99
    public Double moneyRemain ;//用户剩余金额, 两个小数点, 单位元, 0~999999.99
    public Double waterPrice ;//水量单价 单位:元, 2个小数点
    public Double elePrice ;//电量单价 单位:元, 2个小数点
    public String orderNo ;//订单号(16位数字)
    public Integer minutes ;//用水时长(0~9999分钟)
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd36Vo.java
New file
@@ -0,0 +1,16 @@
package com.dy.common.mw.protocol.p206V202404.downVos;
import lombok.Data;
@Data
public class ComCd36Vo {
    public String controllerType;//控制器类型 01(0x01):测控一体阀;02(0x02):表阀一体机;57(0x57):井电控制器
    public Integer projectNo ;//项目编号
    public String icCardNo ;//用户卡序列号(17位数字)(6字节BCD,2字节HEX)
    public Double waterRemain ;//用户剩余水量, 两个小数点, 单位m3, 0~99999999.99
    public Double moneyRemain ;//用户剩余金额, 两个小数点, 单位元, 0~999999.99
    public Double waterPrice ;//水量单价 单位:元, 2个小数点
    public Double elePrice ;//电量单价 单位:元, 2个小数点
    public String orderNo ;//订单号(16位数字)
    public Integer waterAmount ;//预用水量(0~9999 m3)
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd37Vo.java
New file
@@ -0,0 +1,23 @@
package com.dy.common.mw.protocol.p206V202404.downVos;
import lombok.Data;
@Data
public class ComCd37Vo {
    public String controllerType;//控制器类型 01(0x01):测控一体阀;02(0x02):表阀一体机;57(0x57):井电控制器
    public Integer projectNo ;//项目编号
    public String icCardNo ;//用户卡序列号(17位数字)(6字节BCD,2字节HEX)
    public Double waterRemain ;//用户剩余水量, 两个小数点, 单位m3, 0~99999999.99
    public Double moneyRemain ;//用户剩余金额, 两个小数点, 单位元, 0~999999.99
    public Double waterPrice ;//水量单价 单位:元, 2个小数点
    public Double elePrice ;//电量单价 单位:元, 2个小数点
    public String orderNo ;//订单号(16位数字)
    public Integer year ; //计划开阀时间---年
    public Integer month ;//计划开阀时间---月
    public Integer day ;//计划开阀时间---日
    public Integer hour ;//计划开阀时间---时
    public Integer minute ;//计划开阀时间---分
    public Integer minutes ;//用水时长(0~9999分钟)
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd38Vo.java
New file
@@ -0,0 +1,23 @@
package com.dy.common.mw.protocol.p206V202404.downVos;
import lombok.Data;
@Data
public class ComCd38Vo {
    public String controllerType;//控制器类型 01(0x01):测控一体阀;02(0x02):表阀一体机;57(0x57):井电控制器
    public Integer projectNo ;//项目编号
    public String icCardNo ;//用户卡序列号(17位数字)(6字节BCD,2字节HEX)
    public Double waterRemain ;//用户剩余水量, 两个小数点, 单位m3, 0~99999999.99
    public Double moneyRemain ;//用户剩余金额, 两个小数点, 单位元, 0~999999.99
    public Double waterPrice ;//水量单价 单位:元, 2个小数点
    public Double elePrice ;//电量单价 单位:元, 2个小数点
    public String orderNo ;//订单号(16位数字)
    public Integer year ; //计划开阀时间---年
    public Integer month ;//计划开阀时间---月
    public Integer day ;//计划开阀时间---日
    public Integer hour ;//计划开阀时间---时
    public Integer minute ;//计划开阀时间---分
    public Integer waterAmount ;//预用水量(0~9999 m3)
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/downVos/ComCd9DVo.java
New file
@@ -0,0 +1,12 @@
package com.dy.common.mw.protocol.p206V202404.downVos;
import lombok.Data;
@Data
public class ComCd9DVo {
    public String controllerType;//控制器类型 01(0x01):测控一体阀;02(0x02):表阀一体机;57(0x57):井电控制器
    public Integer projectNo ;//项目编号
    public String icCardAddr ;//用户卡地址)(4字节HEX)
    public String icCardNo ;//用户卡序列号(17位数字)(6字节BCD,2字节HEX)
    public String orderNo ;//订单号(16位数字)
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_35_36_37_38Up.java
New file
@@ -0,0 +1,92 @@
package com.dy.common.mw.protocol.p206V202404.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V202404.*;
import com.dy.common.mw.protocol.p206V202404.parse.global.GlParse;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd35_36Vo;
import com.dy.common.mw.protocol.rtuState.ValveStateInfo;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@AnnotationCodeUp(ifAny={
        CodeV202404.cd_35,
        CodeV202404.cd_36,
        CodeV202404.cd_37,
        CodeV202404.cd_38
})
@SuppressWarnings("unused")
public class Cd_35_36_37_38Up implements CodeParse{
    private static final Logger log = LogManager.getLogger(Cd_35_36_37_38Up.class);
    /**
     * 分析上行数据
     */
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback)throws Exception {
        ParseParamsForUpV202404 para = (ParseParamsForUpV202404)params ;
        int bsLen = new CommonV202404().parseDataLen4P202404(para.upBuffer) ;
        if(bsLen > 0){
            this.doParse(para.upBuffer,
                    bsLen,
                    para.upCode,
                    para.data) ;
        }
        log.info("\n分析命令应答数据<" + CodeV202404.getCodeName(para.upCode) + " RTU地址=" + para.rtuAddr + ">:\n" + para.data.toString());
        MidResultFromRtu midRs = new MidResultFromRtu() ;
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.protocolVersion = para.protocolVersion ;//协议版本号
        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, para.data.subData==null?null:((DataV202404)(para.data.subData)).subData);
        if(para.data != null && para.data.getSubData() != null){
            DataCd35_36Vo subData = (DataCd35_36Vo)((DataV202404)para.data.getSubData()).subData ;
            //opResult ;//开启泵/阀结果: 0x00:成功 0x81:失败
            callback.notify(new ValveStateInfo(subData.opResult.byteValue() == 0 ? true:false));
        }
        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 {
        DataV202404 dV202404 = (DataV202404)data.getSubData() ;
        DataCd35_36Vo cdData = new DataCd35_36Vo(CodeV202404.getCodeName(dataCode)) ;
        dV202404.subData = cdData ;
        int index = ProtocolConstantV206V202404.dataIndex ;
        cdData.controllerType = ByteUtil.bytes2Hex(bs, false, index, 1) ;
        index++ ;
        cdData.projectNo = (int)bs[index];
        index++ ;
        cdData.icCardNo = GlParse.parseIcCardNo(bs, index, 6, 2) ;
        index += 8 ;
        cdData.orderNo = ByteUtil.BCD2String_BE(bs, index, index + 7) ;
        //index += 8 ;
        //cdData.opDt = GlParse.parseRtuDt(bs, index) ;
        index += 6 ;
        cdData.opType = bs[index];
        index ++ ;
        cdData.opResult = bs[index];
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_35_Down.java
New file
@@ -0,0 +1,225 @@
package com.dy.common.mw.protocol.p206V202404.parse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
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.ComCd35Vo;
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_35
})
public class Cd_35_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.protocolVersion = para.protocolVersion ;//协议版本号
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downCodeName = CodeV202404.getCodeName(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){
            JSONObject obj = (JSONObject)para.param;
            String json = obj.toJSONString();
            ComCd35Vo cvo = JSON.parseObject(json, ComCd35Vo.class) ;
            if(cvo == null){
                throw new Exception("json转ComCd35Vo为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() != 16){
                throw new Exception("订单号必须是16位数字") ;
            }
            if(cvo.minutes == null || cvo.minutes == 0.0){
                throw new Exception("用水时长不能为空或为0") ;
            }
            if(cvo.minutes < 0 || cvo.minutes > 9999){
                throw new Exception("用水时长取值范围是0~9999分钟") ;
            }
            byte[] bs = new byte[47] ;
            int index = 0 ;
            bs[index] = (byte)(Integer.parseInt(cvo.controllerType, 16));
            index ++ ;
            bs[index] = cvo.projectNo.byteValue() ;
            index ++ ;
            GlCreate.createValveOrPump(cvo.controllerType, bs, index) ;
            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 >= 5){
                    break ;
                }
            }
            for(; count < 5; count++){
                bs[index++] = 0 ;
            }
            if(cvo.moneyRemain == null){
                cvo.moneyRemain = 0.0 ;
            }
            strTemp = "" + (Double.valueOf(cvo.moneyRemain * 10000)).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 ;
            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 ;
            }
            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 ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_36_Down.java
New file
@@ -0,0 +1,225 @@
package com.dy.common.mw.protocol.p206V202404.parse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
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.ComCd35Vo;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCd36Vo;
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_36
})
public class Cd_36_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.protocolVersion = para.protocolVersion ;//协议版本号
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downCodeName = CodeV202404.getCodeName(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){
            JSONObject obj = (JSONObject)para.param;
            String json = obj.toJSONString();
            ComCd36Vo cvo = JSON.parseObject(json, ComCd36Vo.class) ;
            if(cvo == null){
                throw new Exception("json转ComCd35Vo为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() != 16){
                throw new Exception("订单号必须是16位数字") ;
            }
            if(cvo.waterAmount == null || cvo.waterAmount == 0.0){
                throw new Exception("预用水量不能为空或为0") ;
            }
            if(cvo.waterAmount < 0 || cvo.waterAmount > 9999){
                throw new Exception("预用水量取值范围是0~9999m3") ;
            }
            byte[] bs = new byte[47] ;
            int index = 0 ;
            bs[index] = (byte)(Integer.parseInt(cvo.controllerType, 16));
            index ++ ;
            bs[index] = cvo.projectNo.byteValue() ;
            index ++ ;
            GlCreate.createValveOrPump(cvo.controllerType, bs, index) ;
            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 >= 5){
                    break ;
                }
            }
            for(; count < 5; count++){
                bs[index++] = 0 ;
            }
            if(cvo.moneyRemain == null){
                cvo.moneyRemain = 0.0 ;
            }
            strTemp = "" + (Double.valueOf(cvo.moneyRemain * 10000)).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 ;
            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 ;
            }
            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 ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_37_Down.java
New file
@@ -0,0 +1,267 @@
package com.dy.common.mw.protocol.p206V202404.parse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
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.ComCd35Vo;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCd37Vo;
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_37
})
public class Cd_37_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.protocolVersion = para.protocolVersion ;//协议版本号
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downCodeName = CodeV202404.getCodeName(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){
            JSONObject obj = (JSONObject)para.param;
            String json = obj.toJSONString();
            ComCd37Vo cvo = JSON.parseObject(json, ComCd37Vo.class) ;
            if(cvo == null){
                throw new Exception("json转ComCd37Vo为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() != 16){
                throw new Exception("订单号必须是16位数字") ;
            }
            if(cvo.year == null){
                throw new Exception("计划开阀时间---年不能为空") ;
            }
            if(cvo.year < 24 || cvo.year > 9999){
                throw new Exception("计划开阀时间---年不正确") ;
            }
            if(cvo.year > 99 && 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("计划开阀时间---分不正确") ;
            }
            if(cvo.minutes == null || cvo.minutes == 0.0){
                throw new Exception("用水时长不能为空或为0") ;
            }
            if(cvo.minutes < 0 || cvo.minutes > 9999){
                throw new Exception("用水时长取值范围是0~9999分钟") ;
            }
            byte[] bs = new byte[53] ;
            int index = 0 ;
            bs[index] = (byte)(Integer.parseInt(cvo.controllerType, 16));
            index ++ ;
            bs[index] = cvo.projectNo.byteValue() ;
            index ++ ;
            GlCreate.createValveOrPump(cvo.controllerType, bs, index) ;
            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 >= 5){
                    break ;
                }
            }
            for(; count < 5; count++){
                bs[index++] = 0 ;
            }
            if(cvo.moneyRemain == null){
                cvo.moneyRemain = 0.0 ;
            }
            strTemp = "" + (Double.valueOf(cvo.moneyRemain * 10000)).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 ;
            bs[index++] = 0 ;//秒
            bs[index++] = ByteUtil.int2BCD_LE(cvo.minute)[0] ;
            bs[index++] = ByteUtil.int2BCD_LE(cvo.hour)[0] ;
            bs[index++] = ByteUtil.int2BCD_LE(cvo.day)[0] ;
            bs[index++] = ByteUtil.int2BCD_LE(cvo.month)[0] ;
            bs[index++] = ByteUtil.int2BCD_LE(cvo.year)[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 ;
            }
            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 ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_38_Down.java
New file
@@ -0,0 +1,266 @@
package com.dy.common.mw.protocol.p206V202404.parse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
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.ComCd38Vo;
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_38
})
public class Cd_38_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.protocolVersion = para.protocolVersion ;//协议版本号
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downCodeName = CodeV202404.getCodeName(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){
            JSONObject obj = (JSONObject)para.param;
            String json = obj.toJSONString();
            ComCd38Vo cvo = JSON.parseObject(json, ComCd38Vo.class) ;
            if(cvo == null){
                throw new Exception("json转ComCd35Vo为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() != 16){
                throw new Exception("订单号必须是16位数字") ;
            }
            if(cvo.year == null){
                throw new Exception("计划开阀时间---年不能为空") ;
            }
            if(cvo.year < 24 || cvo.year > 9999){
                throw new Exception("计划开阀时间---年不正确") ;
            }
            if(cvo.year > 99 && 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("计划开阀时间---分不正确") ;
            }
            if(cvo.waterAmount == null || cvo.waterAmount == 0.0){
                throw new Exception("预用水量不能为空或为0") ;
            }
            if(cvo.waterAmount < 0 || cvo.waterAmount > 9999){
                throw new Exception("预用水量取值范围是0~9999m3") ;
            }
            byte[] bs = new byte[53] ;
            int index = 0 ;
            bs[index] = (byte)(Integer.parseInt(cvo.controllerType, 16));
            index ++ ;
            bs[index] = cvo.projectNo.byteValue() ;
            index ++ ;
            GlCreate.createValveOrPump(cvo.controllerType, bs, index) ;
            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 >= 5){
                    break ;
                }
            }
            for(; count < 5; count++){
                bs[index++] = 0 ;
            }
            if(cvo.moneyRemain == null){
                cvo.moneyRemain = 0.0 ;
            }
            strTemp = "" + (Double.valueOf(cvo.moneyRemain * 10000)).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 ;
            bs[index++] = 0 ;//秒
            bs[index++] = ByteUtil.int2BCD_LE(cvo.minute)[0] ;
            bs[index++] = ByteUtil.int2BCD_LE(cvo.hour)[0] ;
            bs[index++] = ByteUtil.int2BCD_LE(cvo.day)[0] ;
            bs[index++] = ByteUtil.int2BCD_LE(cvo.month)[0] ;
            bs[index++] = ByteUtil.int2BCD_LE(cvo.year)[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 ;
            }
            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 ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_93_A3_Up.java
@@ -4,13 +4,14 @@
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V202404.*;
import com.dy.common.mw.protocol.p206V202404.parse.global.GlParse;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd93_A3Vo;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd93_9D_A3Vo;
import com.dy.common.mw.protocol.rtuState.ValveStateInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@AnnotationCodeUp(ifAny={
        CodeV202404.cd_93,
        CodeV202404.cd_9D,
        CodeV202404.cd_A3
})
@SuppressWarnings("unused")
@@ -46,7 +47,7 @@
        callback.callback(midRs.reportOrResponse_trueOrFalse, para.data.subData==null?null:((DataV202404)(para.data.subData)).subData);
        if(para.data != null && para.data.getSubData() != null){
            DataCd93_A3Vo subData = (DataCd93_A3Vo)((DataV202404)para.data.getSubData()).subData ;
            DataCd93_9D_A3Vo subData = (DataCd93_9D_A3Vo)((DataV202404)para.data.getSubData()).subData ;
            //opResult ;//关泵/阀结果: 0x00:成功 0x81:失败
            callback.notify(new ValveStateInfo(subData.clResult.byteValue()==0?false:true));
        }
@@ -63,7 +64,7 @@
     */
    protected void doParse(byte[] bs, int bsLen, String dataCode, Data data) throws Exception {
        DataV202404 dV202404 = (DataV202404)data.getSubData() ;
        DataCd93_A3Vo cdData = new DataCd93_A3Vo(CodeV202404.getCodeName(dataCode)) ;
        DataCd93_9D_A3Vo cdData = new DataCd93_9D_A3Vo(CodeV202404.getCodeName(dataCode)) ;
        dV202404.subData = cdData ;
        GlParse.parseCd93A3(bs, cdData) ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_9D_Down.java
New file
@@ -0,0 +1,120 @@
package com.dy.common.mw.protocol.p206V202404.parse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
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.ComCd92_A2Vo;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCd9DVo;
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_9D
})
public class Cd_9D_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.protocolVersion = para.protocolVersion ;//协议版本号
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downCodeName = CodeV202404.getCodeName(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){
            JSONObject obj = (JSONObject)para.param;
            String json = obj.toJSONString();
            ComCd9DVo cvo = JSON.parseObject(json, ComCd9DVo.class) ;
            if(cvo == null){
                throw new Exception("json转ComCd9DVo为null") ;
            }
            if(cvo.icCardAddr == null || cvo.icCardAddr.trim().equals("")){
                throw new Exception("用户IC卡地址必须提供") ;
            }
            if(cvo.icCardNo == null || cvo.icCardNo.trim().equals("")){
                throw new Exception("用户IC卡号必须提供") ;
            }
            if(cvo.orderNo == null || cvo.orderNo.trim().equals("")){
                throw new Exception("订单号必须提供") ;
            }
            if(!NumUtil.isPlusIntNumber(cvo.orderNo)){
                throw new Exception("订单号必须是16位数字") ;
            }
            if(cvo.orderNo.length() != 16){
                throw new Exception("订单号必须是16位数字") ;
            }
            byte[] bs = new byte[29] ;
            int index = 0 ;
            bs[index] = (byte)(Integer.parseInt(cvo.controllerType, 16));
            index ++ ;
            bs[index] = cvo.projectNo.byteValue() ;
            index ++ ;
            GlCreate.createValveOrPump(cvo.controllerType, bs, index) ;
            index ++ ;
            GlCreate.createIcCardAddr(cvo.icCardAddr, bs, index) ;
            index += 4 ;
            GlCreate.createIcCardNo(cvo.icCardNo, bs, index);
            index += 8 ;
            ByteUtil.string2BCD_BE(bs, cvo.orderNo, index) ;
            index += 8 ;
            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 ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/global/GlParse.java
@@ -306,7 +306,7 @@
     * @param cdData
     * @throws Exception
     */
    public static void parseCd93A3(byte[] bs, DataCd93_A3Vo cdData) throws Exception {
    public static void parseCd93A3(byte[] bs, DataCd93_9D_A3Vo cdData) throws Exception {
        int index = ProtocolConstantV206V202404.dataIndex ;
        cdData.controllerType = ByteUtil.bytes2Hex(bs, false, index, 1) ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/upVos/DataCd35_36Vo.java
New file
@@ -0,0 +1,114 @@
package com.dy.common.mw.protocol.p206V202404.upVos;
import com.dy.common.mw.protocol.UpComResVo;
import com.dy.common.mw.protocol.p206V202404.CodeV202404;
import com.dy.common.mw.protocol.p206V202404.CommonV202404;
import lombok.Data;
//APP端远程定时开启水泵/阀门
@Data
public class DataCd35_36Vo implements UpComResVo {
    public String controllerType;//控制器类型
    public Integer projectNo ;//项目编号
    public String icCardNo ;//IC卡编号(17位数字)
    public String orderNo ;//订单号(16位数字)
    //public String opDt ;//开泵/阀时间(yyyy-mm-dd HH:MM:SS)
    public Byte opType ;//开阀类型
    public Byte opResult ;//开启泵/阀结果: 0x01:成功 0x81:失败
    public String comName ;//命令名称
    //无参构造函数,设置命令名称
    public DataCd35_36Vo(){
        this.comName = CodeV202404.getCodeName(CodeV202404.cd_35) ;
    }
    //有参构造函数,设置命令名称
    public DataCd35_36Vo(String comName){
        this.comName = comName ;
    }
    //重写toString方法,返回DataCd35Vo对象的字符串表示
    public String toString(){
        StringBuffer sb = new StringBuffer() ;
        sb.append("      " + comName + " : \n") ;
        sb.append("      控制器类型 : ") ;
        sb.append(CommonV202404.ctrlDevType(controllerType)) ;
        sb.append("\n") ;
        sb.append("      项目编号 : ") ;
        sb.append(projectNo == null?"未知":projectNo) ;
        sb.append("\n") ;
        sb.append("      IC卡编号 : ") ;
        sb.append(icCardNo == null?"未知":icCardNo) ;
        sb.append("\n") ;
        sb.append("      订单号 : ") ;
        sb.append(orderNo == null?"未知":orderNo) ;
        sb.append("\n") ;
        /*
        sb.append("      开泵/阀时间 : ") ;
        sb.append(opDt == null?"未知":opDt) ;
        sb.append("\n") ;
         */
        sb.append("      开启泵/阀类型 : ") ;
        sb.append(opType == null?"未知":(opType.byteValue() == 0x02 ? "平台":"用户")) ;
        sb.append("\n") ;
        sb.append("      开启泵/阀结果 : ") ;
        sb.append(opResult == null?"未知":(opResult.byteValue() == 0x01 ? "成功":"失败")) ;
        sb.append("\n") ;
        return sb.toString() ;
    }
    //重写toStr方法,返回DataCd35Vo对象的字符串表示,根据showBase参数决定是否显示基础信息
    public String toStr(boolean showBase){
        StringBuffer sb = new StringBuffer() ;
        if(showBase){
            sb.append(comName + " : \n") ;
            sb.append("控制器类型 : ") ;
            sb.append(CommonV202404.ctrlDevType(controllerType)) ;
            sb.append("\n") ;
            sb.append("项目编号 : ") ;
            sb.append(projectNo == null?"未知":projectNo) ;
            sb.append("\n") ;
        }
        sb.append("IC卡编号 : ") ;
        sb.append(icCardNo == null?"未知":icCardNo) ;
        sb.append("\n") ;
        sb.append("订单号 : ") ;
        sb.append(orderNo == null?"未知":orderNo) ;
        sb.append("\n") ;
        /*
        sb.append("开泵/阀时间 : ") ;
        sb.append(opDt == null?"未知":opDt) ;
        sb.append("\n") ;
         */
        sb.append("开启泵/阀类型 : ") ;
        sb.append(opType == null?"未知":(opType.byteValue() == 0x02 ? "平台":"用户")) ;
        sb.append("\n") ;
        sb.append("开启泵/阀结果 : ") ;
        sb.append(opResult == null?"未知":(opResult.byteValue() == 0x01 ? "成功":"失败")) ;
        sb.append("\n") ;
        return sb.toString() ;
    }
    //重写comLog方法,返回DataCd35Vo对象的字符串表示,用于记录日志
    public String comLog(){
        StringBuilder sb = new StringBuilder() ;
        sb.append("远程开阀命令回复:\n");
        sb.append(opResult == null?"未知":(opResult.byteValue() == 0x01 ? "成功":"失败"));
        sb.append("\n");
        return sb.toString() ;
    }
    //重写comLog方法,根据code参数返回DataCd35Vo对象的字符串表示,用于记录日志
    @Override
    public String comLog(String code) {
        return null;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/upVos/DataCd93_9D_A3Vo.java
File was renamed from pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/upVos/DataCd93_A3Vo.java
@@ -9,7 +9,7 @@
//平台/APP远程关闭水泵/阀门   +  刷卡关泵/阀上报
@Data
@EqualsAndHashCode(callSuper=false)
public class DataCd93_A3Vo extends AlarmVo implements UpComResVo {
public class DataCd93_9D_A3Vo extends AlarmVo implements UpComResVo {
    public String controllerType;//控制器类型
    public Integer projectNo ;//项目编号
@@ -30,10 +30,10 @@
    public Integer thisDuration;//本次使用时间长, 单位:分钟
    public String comName ;//命令名称
    public DataCd93_A3Vo(){
    public DataCd93_9D_A3Vo(){
        this.comName = CodeV202404.getCodeName(CodeV202404.cd_93) ;
    }
    public DataCd93_A3Vo(String comName){
    public DataCd93_9D_A3Vo(String comName){
        this.comName = comName ;
    }
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd93/CdCtrl.java
@@ -4,7 +4,7 @@
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd93_A3Vo;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd93_9D_A3Vo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
@@ -145,7 +145,7 @@
                msg = RtuSuccessMsg ;
            }else {
                String json = codeData.toJSONString();
                DataCd93_A3Vo cvo = JSON.parseObject(json, DataCd93_A3Vo.class) ;
                DataCd93_9D_A3Vo cvo = JSON.parseObject(json, DataCd93_9D_A3Vo.class) ;
                if(cvo != null){
                    if(callback != null){
                        if(cvo.clResult != null && cvo.clResult == 0){
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cdA3/CdCtrl.java
@@ -4,12 +4,11 @@
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd93_A3Vo;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd93_9D_A3Vo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrGlobal.pojoRm.RmCommandOpen;
import com.dy.pipIrrGlobal.voRm.VoUnclosedParam;
import com.dy.pipIrrRemote.common.dto.DtoBase;
import com.dy.pipIrrRemote.monitor.common.ComCtrl;
import com.dy.pipIrrRemote.monitor.p202404V201.cd93.CdParam;
@@ -147,7 +146,7 @@
                msg = RtuSuccessMsg ;
            }else {
                String json = codeData.toJSONString();
                DataCd93_A3Vo cvo = JSON.parseObject(json, DataCd93_A3Vo.class) ;
                DataCd93_9D_A3Vo cvo = JSON.parseObject(json, DataCd93_9D_A3Vo.class) ;
                if(cvo != null){
                    if(callback != null){
                        if(cvo.clResult != null && cvo.clResult == 0){