Administrator
2024-07-11 a5b7ba070f03327f8848593a31c44cc79e7bb24a
Merge branch 'master' of http://8.140.179.55:20000/r/pipIrr-SV
37个文件已修改
26个文件已添加
2965 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultFromRtu.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultToRtu.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CommonV1_0_1.java 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_83_Up.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_84_Up.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Down.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Up.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Down.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Up.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_99_Down.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_A0_Down.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlCreate.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlParse.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/ByteUtil.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmClientAmountDayLastMapper.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmClientAmountDayMapper.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrControllerTramp.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmClientAmountDay.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmClientAmountDayLast.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrControllerMapper.xml 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrControllerTrampMapper.xml 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmClientAmountDayLastMapper.xml 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmClientAmountDayMapper.xml 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/Server.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/ServerProperties.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/forTcp/MidResultActionFromRtu.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/dbSv/DbSv.java 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealClientAmountDay.java 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealIntakeAmountDay.java 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealLoss.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkPreGenObjs.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V202404/TkPreGenObjsV202404.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/RtuDataDealTree.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/config.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/MyThreadJob.java 158 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/RtuUpData.java 287 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/resources/log4j2.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-server/src/main/java/com/dy/testServer/Server.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-server/src/main/resources/log4j2.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/.gitignore 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/.mvn/wrapper/maven-wrapper.properties 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/mvnw 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/mvnw.cmd 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/pom.xml 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/AdapterImp_TcpClUnit.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/PipIrrMwTestRtuApplication.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalCodecFactory.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalDecoder.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalEncoder.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpClUnitAdapter.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpClUnitConfigVo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpConnect.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpHandler.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/Config.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/application.yml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/log4j2.xml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/test/java/com/dy/pipIrrMwTestRtu/PipIrrMwTestRtuApplicationTests.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/src/main/java/com/dy/pipIrrMwTestWeb/PipIrrMwTestWebApplication.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/src/main/java/com/dy/pipIrrMwTestWeb/p206V1_0_0/ComSupportP206V1_0_0.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pom.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultFromRtu.java
@@ -1,9 +1,5 @@
package com.dy.common.mw.protocol;
import com.dy.common.mw.protocol.p206V1_0_0.*;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd97Vo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd98Vo;
/**
 * 从RTU收到数据
 */
@@ -30,11 +26,12 @@
        ProtocolUnit.getInstance().adapter.getSingleActionFromRtu(this.protocolName).doAction(this); 
    }
    
    public void matchedCommand(String commandId, Object toRtuMidResultParam, String rtuResultSendWebUrl){
    public void matchedCommand(String commandId, String rtuResultSendWebUrl){
        this.commandId = commandId ;
        if(this.data != null){
            this.data.setCommandId(commandId);
        }
        /*
        if(toRtuMidResultParam != null){
            if(protocolName != null && protocolName.equals(ProtocolConstantV206V1_0_0.protocolName)){
                if(upCode != null && upCode.equals(CodeV1_0_1.cd_97)){
@@ -60,6 +57,7 @@
                }
            }
        }
         */
        this.rtuResultSendWebUrl = rtuResultSendWebUrl ;
        if(this.data != null){
            this.data.setRtuResultSendWebUrl(rtuResultSendWebUrl);
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultToRtu.java
@@ -24,7 +24,7 @@
    public boolean isSendFirst;//优先其他发送,例如各命令的应答
    public boolean isQuickSend;//速发命令,即不受下发数据时间间隔限制
    public Object param ;//缓存一些数据,例如为兼容王工(江海)协议与靳总协议(虚拟IC卡编号长度不一致),把不兼容的虚拟IC卡编号的前半部分放入此处
    //public Object param ;//缓存一些数据,例如为兼容王工(江海)协议与靳总协议(虚拟IC卡编号长度不一致),把不兼容的虚拟IC卡编号的前半部分放入此处
    public MidResultToRtu(){
        hasResponse = true ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CommonV1_0_1.java
@@ -202,25 +202,25 @@
        };
    }
    /**
     * 处理IC卡编号,靳总制定的协议要求10位IC卡编号
     * @param icCardNo
     * @return
     */
    public static String[] dealIcCardNo(String icCardNo){
        if(icCardNo.length() > 10){
            String tail = icCardNo.substring(icCardNo.length() - 10) ;
            String head = icCardNo.substring(0, icCardNo.length() - 10) ;
            return new String[]{head , tail} ;
        }else if(icCardNo.length() < 10){
            while(icCardNo.length() != 10){
                icCardNo = "0" + icCardNo ;
            }
            return new String[]{null , icCardNo} ;
        }else{
            return new String[]{null , icCardNo} ;
        }
    }
//    /**
//     * 处理IC卡编号,靳总制定的协议要求10位IC卡编号
//     * @param icCardNo
//     * @return
//     */
//    public static String[] dealIcCardNo(String icCardNo){
//        if(icCardNo.length() > 10){
//            String tail = icCardNo.substring(icCardNo.length() - 10) ;
//            String head = icCardNo.substring(0, icCardNo.length() - 10) ;
//            return new String[]{head , tail} ;
//        }else if(icCardNo.length() < 10){
//            while(icCardNo.length() != 10){
//                icCardNo = "0" + icCardNo ;
//            }
//            return new String[]{null , icCardNo} ;
//        }else{
//            return new String[]{null , icCardNo} ;
//        }
//    }
    
    /*
     * 分析版本号
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_83_Up.java
@@ -105,10 +105,10 @@
        cdData.totalAmount = tpInt/100.0 ;
        index += 5 ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.icCardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        //用水户号数据格式:8字节低位在前高位在后。
        cdData.icCardNo = GlParse.parseIcCardNo(bs, index) ;
        index += 5 ;
        index += 8 ;
        //IC卡号格式:4字节HEX码低位在前高位在后。
        cdData.icCardAddr = ByteUtil.bytes2Hex_LE(bs, false,  index, 4) ;
@@ -156,10 +156,10 @@
        cdData.totalAmount = tpInt/100.0 ;
        index += 5 ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.icCardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        //用水户号数据格式:8字节低位在前高位在后。
        cdData.icCardNo = GlParse.parseIcCardNo(bs, index) ;
        index += 5 ;
        index += 8 ;
        //IC卡号格式:4字节HEX码低位在前高位在后。
        cdData.icCardAddr = ByteUtil.bytes2Hex_LE(bs, false,  index, 4) ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_84_Up.java
@@ -97,10 +97,10 @@
        cdData.cardAddr = ByteUtil.bytes2Hex_LE(bs, false,  index, 4) ;
        index += 4 ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        //用水户号数据格式:8字节低位在前高位在后。
        cdData.cardNo = GlParse.parseIcCardNo(bs, index) ;
        index += 5 ;
        index += 8 ;
        //用水户余额:用户余额4字节BCD码,取值范围0.00~999999.99,单位为元。
        int tpInt = ByteUtil.BCD2Int_LE(bs, index, index + 3) ;
        cdData.remainMoney = tpInt/100.0 ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Down.java
@@ -92,16 +92,17 @@
            throw new Exception("水价不能为空") ;
        }
        String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        if(icCardNoGrp[0] != null){
            midRs.param = icCardNoGrp[0] ;
        }
        //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        //if(icCardNoGrp[0] != null){
        //    midRs.param = icCardNoGrp[0] ;
        //}
        byte[] bs = new byte[11] ;
        byte[] bs = new byte[14] ;
        index = 0 ;
        ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        GlCreate.createIcCardNo(cvo.icCardNo, bs, index);
        //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        index += 5 ;
        index += 8 ;
        Integer money = Double.valueOf(cvo.moneyRemain * 100.0D).intValue() ;
        byte[] bTemp = ByteUtil.int2BCD_LE(money) ;
        int bTempLen = bTemp.length ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Up.java
@@ -2,6 +2,7 @@
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.DataCd97Vo;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
@@ -62,8 +63,9 @@
        DataCd97Vo cdData = new DataCd97Vo() ;
        dV1.subData = cdData ;
        //虚拟卡号
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, ProtocolConstantV206V1_0_0.dataIndex, ProtocolConstantV206V1_0_0.dataIndex+4) ;
        if(bs[ProtocolConstantV206V1_0_0.dataIndex + 5] == (byte)0xAA){
        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_98_Down.java
@@ -86,12 +86,15 @@
            throw new Exception("虚拟IC卡编号不能为空") ;
        }
        String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        if(icCardNoGrp[0] != null){
            midRs.param = icCardNoGrp[0] ;
        }
        byte[] bs = new byte[5] ;
        ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], 0) ;
        //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        //if(icCardNoGrp[0] != null){
        //    midRs.param = icCardNoGrp[0] ;
        //}
        //byte[] bs = new byte[5] ;
        //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], 0) ;
        byte[] bs = new byte[8] ;
        GlCreate.createIcCardNo(cvo.icCardNo, bs, 0);
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Up.java
@@ -2,6 +2,7 @@
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.DataCd98Vo;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
@@ -62,8 +63,9 @@
        DataCd98Vo cdData = new DataCd98Vo() ;
        dV1.subData = cdData ;
        //虚拟卡号
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, ProtocolConstantV206V1_0_0.dataIndex, ProtocolConstantV206V1_0_0.dataIndex+4) ;
        if(bs[ProtocolConstantV206V1_0_0.dataIndex + 5] == (byte)0xAA){
        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_99_Down.java
@@ -97,14 +97,16 @@
            throw new Exception("用水时长取值范围是0~9999分钟") ;
        }
        String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        if(icCardNoGrp[0] != null){
            midRs.param = icCardNoGrp[0] ;
        }
        //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        //if(icCardNoGrp[0] != null){
        //    midRs.param = icCardNoGrp[0] ;
        //}
        //byte[] bs = new byte[13] ;
        //index = 0 ;
        //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        byte[] bs = new byte[8] ;
        GlCreate.createIcCardNo(cvo.icCardNo, bs, 0);
        byte[] bs = new byte[13] ;
        index = 0 ;
        ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        index += 5 ;
        Integer money = Double.valueOf(cvo.moneyRemain * 100.0D).intValue() ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_A0_Down.java
@@ -97,14 +97,14 @@
            throw new Exception("预用水量取值范围是0~9999m3") ;
        }
        String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        if(icCardNoGrp[0] != null){
            midRs.param = icCardNoGrp[0] ;
        }
        byte[] bs = new byte[13] ;
        //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        //if(icCardNoGrp[0] != null){
        //    midRs.param = icCardNoGrp[0] ;
        //}
        byte[] bs = new byte[16] ;
        index = 0 ;
        ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        GlCreate.createIcCardNo(cvo.icCardNo, bs, 0);
        index += 5 ;
        Integer money = Double.valueOf(cvo.moneyRemain * 100.0D).intValue() ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlCreate.java
@@ -28,11 +28,35 @@
        ByteUtil.string2BCD_LE(bs, DateTime.yyMMddhhmmss(), index) ;
    }
    public static void createTp(String yyMMddhhmmss, byte[] bs, int index) throws Exception {
        ByteUtil.string2BCD_LE(bs, yyMMddhhmmss, index) ;
    }
    public static void createLen(byte[] bsNoTail) throws Exception {
        int len = bsNoTail.length - ProtocolConstantV206V1_0_0.lenHead2ctrl;
        bsNoTail[ProtocolConstantV206V1_0_0.dataLenIndex] = (byte)len ;
    }
    /**
     * 生成IC卡编码
     * 6字节BCD码(12位行政区划) + 2字节HEX
     * @param icCardNo
     * @param bs
     * @param index
     * @throws Exception
     */
    public static void createIcCardNo(String icCardNo, byte[] bs, int index) throws Exception {
        String icCardNo1 = icCardNo.substring(0, 12) ;
        String icCardNo2 = icCardNo.substring(12) ;
        Integer icCardNo2Int = Integer.parseInt(icCardNo2) ;
        ByteUtilUnsigned.short2Bytes_LE(bs, icCardNo2Int.shortValue(), index);
        index += 2 ;
        ByteUtil.string2BCD_LE(bs, icCardNo1, index) ;
    }
    public static byte[] createCrcTail(byte[] bsNoTail) throws Exception {
        int crc = new CRC8_for_2_0().CRC8(bsNoTail, ProtocolConstantV206V1_0_0.ctrlIndex, bsNoTail.length -1) ;
        byte[] bytes = new byte[ProtocolConstantV206V1_0_0.lenTail] ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlParse.java
@@ -3,6 +3,7 @@
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataAlarmVo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataStateVo;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -39,6 +40,24 @@
        return avo ;
    }
    /**
     * 分析IC卡编号
     * @param bs 上行字节数组
     * @param index 启始位
     * @return 控制器地址
     * @throws Exception 异常
     */
    public static String parseIcCardNo(byte[] bs, int index)throws Exception{
        String rtuAddrStr = "" + ByteUtilUnsigned.bytes2Short_LE(bs, index) ;
        String rtuAddrBCD = "" + ByteUtil.BCD2Long_LE(bs, index + 2, index + 7) ;
        while(rtuAddrStr.length() < 5){
            rtuAddrStr = "0" + rtuAddrStr ;
        }
        return rtuAddrBCD + rtuAddrStr ;
    }
    public static String parseTp(byte[] bs, short index){
        String dt = "" ;
        try{
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/ByteUtil.java
@@ -1035,6 +1035,31 @@
        return fromIndex ;
    }
    /**
     * 十六进制转字节数组
     * @param hex the hex string
     * @return 返回 byte[]
     */
    public static int hex2Bytes_LE(String hex, byte[] bs, int fromIndex) {
        if (hex == null || hex.equals("")) {
            return fromIndex;
        }
        hex = hex.toUpperCase(Locale.ENGLISH);
        int length = hex.length() / 2;
        char[] hexChars = hex.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        for(int i = 0 ; i < d.length; i++){
            bs[fromIndex++] = d[(d.length - 1) - i] ;
        }
        return fromIndex ;
    }
    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
//    /**
//     * 将byte[]转换为16进制字符串
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmClientAmountDayLastMapper.java
New file
@@ -0,0 +1,65 @@
package com.dy.pipIrrGlobal.daoRm;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 14:33
 * @Description
 */
@Mapper
public interface RmClientAmountDayLastMapper extends BaseMapper<RmClientAmountDayLast> {
    /**
     * delete by primary key
     *
     * @param id primaryKey
     * @return deleteCount
     */
    int deleteByPrimaryKey(Long id);
    List<RmClientAmountDayLast> selectByClientId(Long clientId) ;
    /**
     * insert record to table
     *
     * @param record the record
     * @return insert count
     */
    int insert(RmClientAmountDayLast record);
    /**
     * insert record to table selective
     *
     * @param record the record
     * @return insert count
     */
    int insertSelective(RmClientAmountDayLast record);
    /**
     * select by primary key
     *
     * @param id primary key
     * @return object by primary key
     */
    RmClientAmountDayLast selectByPrimaryKey(Long id);
    /**
     * update record selective
     *
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKeySelective(RmClientAmountDayLast record);
    /**
     * update record
     *
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKey(RmClientAmountDayLast record);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmClientAmountDayMapper.java
New file
@@ -0,0 +1,74 @@
package com.dy.pipIrrGlobal.daoRm;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 14:33
 * @Description
 */
@Mapper
public interface RmClientAmountDayMapper  extends BaseMapper<RmClientAmountDay> {
    /**
     * delete by primary key
     *
     * @param id primaryKey
     * @return deleteCount
     */
    int deleteByPrimaryKey(Long id);
    /**
     * insert record to table
     *
     * @param record the record
     * @return insert count
     */
    int insert(RmClientAmountDay record);
    /**
     * insert record to table selective
     *
     * @param record the record
     * @return insert count
     */
    int insertSelective(RmClientAmountDay record);
    /**
     * select by primary key
     *
     * @param id primary key
     * @return object by primary key
     */
    RmClientAmountDay selectByPrimaryKey(Long id);
    /**
     * select by primary key
     *
     * @param clientId clientId
     * @param dt dt
     * @return objects by ByClientAndDate
     */
    List<RmClientAmountDay> selectByClientAndDate(@Param("clientId")Long clientId, @Param("dt")Date dt) ;
    /**
     * update record selective
     *
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKeySelective(RmClientAmountDay record);
    /**
     * update record
     *
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKey(RmClientAmountDay record);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrController.java
@@ -69,6 +69,12 @@
     */
    @Schema(description = "发现日期时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private Date findDt;
    /**
     * 机构tag
     */
    @Schema(description = "机构tag", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "机构tag不能为空")
    public String orgTag;
    /**
     * 添加方式;1-系统自动,2-手动
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrControllerTramp.java
@@ -61,5 +61,11 @@
    @Schema(description = "发现时间", requiredMode = Schema.RequiredMode.REQUIRED)
//    @NotNull(message = "发现时间不能为空")
    public Date findDt;//发现时间( yyyy-mm-dd HH:MM:SS)
    /**
     * 机构tag
     */
    @Schema(description = "机构tag", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "机构tag不能为空")
    public String orgTag;
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmClientAmountDay.java
New file
@@ -0,0 +1,94 @@
package com.dy.pipIrrGlobal.pojoRm;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson2.writer.ObjectWriterImplToString;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.dy.common.po.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.Date;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 14:33
 * @Description 农户日用水量统计
 */
@TableName(value="rm_client_amount_day", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "农户日用水量统计")
public class RmClientAmountDay implements BaseEntity {
    public static final long serialVersionUID = 2024007091435002L;
    /**
     * 主键
     */
    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED)
    @JSONField(serializeUsing= ObjectWriterImplToString.class)
    @TableId(type = IdType.INPUT)
    public Long id;
    /**
     * 农户id
     */
    public Long clientId;
    /**
     * 日取水量
     */
    public Double amount;
    /**
     * 日取花费金额
     */
    public Double money;
    /**
     * 统计日期(yyyy-mm-dd)
     */
    @Schema(description = "统计日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @JsonFormat(pattern = "yyyy-MM-dd")
    public Date dt;
    /**
     * 统计日最后一次开阀日期时间(yyyy-mm-dd HH:MM:SS)
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date openDtLast;
    /**
     * 统计日最后一次关阀日期时间(yyyy-mm-dd HH:MM:SS)
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date closeDtLast;
    /**
     * 统计日最后一次开阀取水量
     */
    public Double thisAmountLast;
    /**
     * 统计日最后一次开阀花费金额
     */
    public Double thisMoneyLast;
    /**
     * 统计日最后一次开阀取水时长(分钟)
     */
    public Integer thisTimeLast;
    /**
     * 统计日最后一次关阀上报控制器时钟
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date rtuDtLast;
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmClientAmountDayLast.java
New file
@@ -0,0 +1,102 @@
package com.dy.pipIrrGlobal.pojoRm;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson2.writer.ObjectWriterImplToString;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.dy.common.po.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.Date;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 14:33
 * @Description 农户日用水量统计
 */
@TableName(value="rm_client_amount_day_last", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "农户日用水量统计")
public class RmClientAmountDayLast implements BaseEntity {
    public static final long serialVersionUID = 2024007091435001L;
    /**
     * 主键
     */
    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED)
    @JSONField(serializeUsing= ObjectWriterImplToString.class)
    @TableId(type = IdType.INPUT)
    public Long id;
    /**
     * 由最新数据持有历史数据中的最新记录ID,以方便快速查询
     * json不序列化此属性,即不向前端页面发送及显示
     */
    @Schema(hidden=true)
    @JSONField(serialize = false)
    public Long lastHistoryId;
    /**
     * 农户id
     */
    public Long clientId;
    /**
     * 日取水量
     */
    public Double amount;
    /**
     * 日取花费金额
     */
    public Double money;
    /**
     * 统计日期(yyyy-mm-dd)
     */
    @Schema(description = "统计日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @JsonFormat(pattern = "yyyy-MM-dd")
    public Date dt;
    /**
     * 统计日最后一次开阀日期时间(yyyy-mm-dd HH:MM:SS)
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date openDtLast;
    /**
     * 统计日最后一次关阀日期时间(yyyy-mm-dd HH:MM:SS)
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date closeDtLast;
    /**
     * 统计日最后一次开阀取水量
     */
    public Double thisAmountLast;
    /**
     * 统计日最后一次开阀花费金额
     */
    public Double thisMoneyLast;
    /**
     * 统计日最后一次开阀取水时长(分钟)
     */
    public Integer thisTimeLast;
    /**
     * 统计日最后一次关阀上报控制器时钟
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date rtuDtLast;
}
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml
@@ -133,8 +133,11 @@
#通讯协议
#protocol: DYJS_2023,DYJS_2024
mw:
    #命令发送地址
    comSendUrl: "http://127.0.0.1:8070/rtuMw/com/send"
    #命令发送地址(中缀是机构tag,其也是数据源后缀名称)
    ym:
        comSendUrl: "http://127.0.0.1:8070/rtuMw/com/send"
    sp:
        comSendUrl: "http://127.0.0.1:8071/rtuMw/com/send"
    #监测控制模块回调地址
    rtuCallbackUrl_rm: "http://127.0.0.1:8081/remote/comRes/receive"
    #微信小程序回调地址
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrControllerMapper.xml
@@ -9,6 +9,7 @@
    <result column="rtuAddr" jdbcType="VARCHAR" property="rtuAddr" />
    <result column="protocol" jdbcType="VARCHAR" property="protocol" />
    <result column="findDt" jdbcType="TIMESTAMP" property="findDt" />
    <result column="orgTag" jdbcType="VARCHAR" property="orgTag" />
    <result column="addWays" jdbcType="TINYINT" property="addWays" />
    <result column="operator" jdbcType="BIGINT" property="operator" />
    <result column="operateDt" jdbcType="TIMESTAMP" property="operateDt" />
@@ -22,7 +23,7 @@
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, intakeId, rtuAddr, protocol, findDt, addWays, `operator`, operateDt, deleted
    id, intakeId, rtuAddr, protocol, findDt, orgTag, addWays, `operator`, operateDt, deleted
  </sql>
  <sql id="Part_Column_List">
    <!--@mbg.generated-->
@@ -43,12 +44,13 @@
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoPr.PrController">
    <!--@mbg.generated-->
    insert into pr_controller (id, intakeId, rtuAddr,
      protocol, findDt, addWays,
      protocol, findDt, orgTag, addWays,
      `operator`, operateDt, deleted
      )
    values (#{id,jdbcType=BIGINT}, #{intakeId,jdbcType=BIGINT}, #{rtuAddr,jdbcType=VARCHAR},
      #{protocol,jdbcType=VARCHAR}, #{findDt,jdbcType=TIMESTAMP}, #{addWays,jdbcType=TINYINT},
      #{operator,jdbcType=BIGINT}, #{operateDt,jdbcType=TIMESTAMP}, #{deleted,jdbcType=TINYINT}
      #{protocol,jdbcType=VARCHAR}, #{findDt,jdbcType=TIMESTAMP}, #{orgTag,jdbcType=VARCHAR},
      #{addWays,jdbcType=TINYINT}, #{operator,jdbcType=BIGINT}, #{operateDt,jdbcType=TIMESTAMP},
      #{deleted,jdbcType=TINYINT}
      )
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrController">
@@ -69,6 +71,9 @@
      </if>
      <if test="findDt != null">
        findDt,
      </if>
      <if test="orgTag != null">
        orgTag,
      </if>
      <if test="addWays != null">
        addWays,
@@ -98,6 +103,9 @@
      </if>
      <if test="findDt != null">
        #{findDt,jdbcType=TIMESTAMP},
      </if>
      <if test="orgTag != null">
        #{orgTag,jdbcType=VARCHAR},
      </if>
      <if test="addWays != null">
        #{addWays,jdbcType=TINYINT},
@@ -129,6 +137,9 @@
      <if test="findDt != null">
        findDt = #{findDt,jdbcType=TIMESTAMP},
      </if>
     <if test="orgTag != null">
       orgTag = #{orgTag,jdbcType=VARCHAR},
      </if>
      <if test="addWays != null">
        addWays = #{addWays,jdbcType=TINYINT},
      </if>
@@ -151,6 +162,7 @@
      rtuAddr = #{rtuAddr,jdbcType=VARCHAR},
      protocol = #{protocol,jdbcType=VARCHAR},
      findDt = #{findDt,jdbcType=TIMESTAMP},
      orgTag = #{orgTag,jdbcType=VARCHAR},
      addWays = #{addWays,jdbcType=TINYINT},
      `operator` = #{operator,jdbcType=BIGINT},
      operateDt = #{operateDt,jdbcType=TIMESTAMP},
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrControllerTrampMapper.xml
@@ -8,10 +8,11 @@
    <result column="rtuAddr" jdbcType="VARCHAR" property="rtuAddr" />
    <result column="protocol" jdbcType="VARCHAR" property="protocol" />
    <result column="findDt" jdbcType="TIMESTAMP" property="findDt" />
    <result column="orgTag" jdbcType="VARCHAR" property="orgTag" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, rtuAddr, protocol, findDt
    id, rtuAddr, protocol, findDt, orgTag
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
@@ -37,9 +38,9 @@
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoPr.PrControllerTramp">
    <!--@mbg.generated-->
    insert into pr_controller_tramp (id, rtuAddr, protocol,
      findDt)
      findDt, orgTag)
    values (#{id,jdbcType=BIGINT}, #{rtuAddr,jdbcType=VARCHAR}, #{protocol,jdbcType=VARCHAR},
      #{findDt,jdbcType=TIMESTAMP})
      #{findDt,jdbcType=TIMESTAMP},#{orgTag,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrControllerTramp">
    <!--@mbg.generated-->
@@ -57,6 +58,9 @@
      <if test="findDt != null">
        findDt,
      </if>
      <if test="orgTag != null">
          orgTag,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
@@ -70,6 +74,9 @@
      </if>
      <if test="findDt != null">
        #{findDt,jdbcType=TIMESTAMP},
      </if>
      <if test="orgTag != null">
        #{orgTag,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
@@ -86,6 +93,9 @@
      <if test="findDt != null">
        findDt = #{findDt,jdbcType=TIMESTAMP},
      </if>
      <if test="orgTag != null">
          orgTag = #{orgTag,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
@@ -94,7 +104,8 @@
    update pr_controller_tramp
    set rtuAddr = #{rtuAddr,jdbcType=VARCHAR},
      protocol = #{protocol,jdbcType=VARCHAR},
      findDt = #{findDt,jdbcType=TIMESTAMP}
      findDt = #{findDt,jdbcType=TIMESTAMP},
      orgTag = #{orgTag,jdbcType=VARCHAR}
    where id = #{id,jdbcType=BIGINT}
  </update>
@@ -113,7 +124,8 @@
        select CAST(id AS char)AS id,
        rtuAddr,
        protocol,
        findDt
        findDt,
        orgTag
        FROM pr_controller_tramp
        <where>
            <if test="id != null and id !=''">
@@ -125,7 +137,6 @@
            <if test="protocol != null and protocol != ''">
                AND  protocol = #{protocol,jdbcType=VARCHAR}
            </if>
        </where>
    </select>
    <!--    根据条件获取流浪控制器数量-->
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmClientAmountDayLastMapper.xml
New file
@@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dy.pipIrrGlobal.daoRm.RmClientAmountDayLastMapper">
  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    <!--@Table rm_client_amount_day_last-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="last_history_id" jdbcType="BIGINT" property="lastHistoryId" />
    <result column="client_id" jdbcType="BIGINT" property="clientId" />
    <result column="amount" jdbcType="FLOAT" property="amount" />
    <result column="money" jdbcType="FLOAT" property="money" />
    <result column="dt" jdbcType="DATE" property="dt" />
    <result column="open_dt_last" jdbcType="TIMESTAMP" property="openDtLast" />
    <result column="close_dt_last" jdbcType="TIMESTAMP" property="closeDtLast" />
    <result column="this_amount_last" jdbcType="FLOAT" property="thisAmountLast" />
    <result column="this_money_last" jdbcType="FLOAT" property="thisMoneyLast" />
    <result column="this_time_last" jdbcType="INTEGER" property="thisTimeLast" />
    <result column="rtu_dt_last" jdbcType="TIMESTAMP" property="rtuDtLast" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, last_history_id, client_id, amount, money, dt, open_dt_last, close_dt_last, this_amount_last,
    this_money_last, this_time_last, rtu_dt_last
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from rm_client_amount_day_last
    where id = #{id,jdbcType=BIGINT}
  </select>
  <select id="selectByClientId" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from rm_client_amount_day_last
    where client_id = #{ClientId,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from rm_client_amount_day_last
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    insert into rm_client_amount_day_last (id, last_history_id, client_id,
      amount, money, dt, open_dt_last,
      close_dt_last, this_amount_last, this_money_last,
      this_time_last, rtu_dt_last)
    values (#{id,jdbcType=BIGINT}, #{lastHistoryId,jdbcType=BIGINT}, #{clientId,jdbcType=BIGINT},
    #{amount,jdbcType=FLOAT}, #{money,jdbcType=FLOAT}, #{dt,jdbcType=DATE}, #{openDtLast,jdbcType=TIMESTAMP},
      #{closeDtLast,jdbcType=TIMESTAMP}, #{thisAmountLast,jdbcType=FLOAT}, #{thisMoneyLast,jdbcType=FLOAT},
      #{thisTimeLast,jdbcType=INTEGER}, #{rtuDtLast,jdbcType=TIMESTAMP})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    insert into rm_client_amount_day_last
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="lastHistoryId != null">
        last_history_id,
      </if>
      <if test="clientId != null">
        client_id,
      </if>
      <if test="amount != null">
        amount,
      </if>
      <if test="money != null">
        money,
      </if>
      <if test="dt != null">
        dt,
      </if>
      <if test="openDtLast != null">
        open_dt_last,
      </if>
      <if test="closeDtLast != null">
        close_dt_last,
      </if>
      <if test="thisAmountLast != null">
        this_amount_last,
      </if>
      <if test="thisMoneyLast != null">
        this_money_last,
      </if>
      <if test="thisTimeLast != null">
        this_time_last,
      </if>
      <if test="rtuDtLast != null">
        rtu_dt_last,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="lastHistoryId != null">
        #{lastHistoryId,jdbcType=BIGINT},
      </if>
      <if test="clientId != null">
        #{clientId,jdbcType=BIGINT},
      </if>
      <if test="amount != null">
        #{amount,jdbcType=FLOAT},
      </if>
      <if test="money != null">
        #{money,jdbcType=FLOAT},
      </if>
      <if test="dt != null">
        #{dt,jdbcType=DATE},
      </if>
      <if test="openDtLast != null">
        #{openDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="closeDtLast != null">
        #{closeDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="thisAmountLast != null">
        #{thisAmountLast,jdbcType=FLOAT},
      </if>
      <if test="thisMoneyLast != null">
        #{thisMoneyLast,jdbcType=FLOAT},
      </if>
      <if test="thisTimeLast != null">
        #{thisTimeLast,jdbcType=INTEGER},
      </if>
      <if test="rtuDtLast != null">
        #{rtuDtLast,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    update rm_client_amount_day_last
    <set>
      <if test="lastHistoryId != null">
        last_history_id = #{lastHistoryId,jdbcType=BIGINT},
      </if>
      <if test="clientId != null">
        client_id = #{clientId,jdbcType=BIGINT},
      </if>
      <if test="amount != null">
        amount = #{amount,jdbcType=FLOAT},
      </if>
      <if test="money != null">
        money = #{money,jdbcType=FLOAT},
      </if>
      <if test="dt != null">
        dt = #{dt,jdbcType=DATE},
      </if>
      <if test="openDtLast != null">
        open_dt_last = #{openDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="closeDtLast != null">
        close_dt_last = #{closeDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="thisAmountLast != null">
        this_amount_last = #{thisAmountLast,jdbcType=FLOAT},
      </if>
      <if test="thisMoneyLast != null">
        this_money_last = #{thisMoneyLast,jdbcType=FLOAT},
      </if>
      <if test="thisTimeLast != null">
        this_time_last = #{thisTimeLast,jdbcType=INTEGER},
      </if>
      <if test="rtuDtLast != null">
        rtu_dt_last = #{rtuDtLast,jdbcType=TIMESTAMP},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    update rm_client_amount_day_last
    set last_history_id = #{lastHistoryId,jdbcType=BIGINT},
      client_id = #{clientId,jdbcType=BIGINT},
      amount = #{amount,jdbcType=FLOAT},
      money = #{money,jdbcType=FLOAT},
      dt = #{dt,jdbcType=DATE},
      open_dt_last = #{openDtLast,jdbcType=TIMESTAMP},
      close_dt_last = #{closeDtLast,jdbcType=TIMESTAMP},
      this_amount_last = #{thisAmountLast,jdbcType=FLOAT},
      this_money_last = #{thisMoneyLast,jdbcType=FLOAT},
      this_time_last = #{thisTimeLast,jdbcType=INTEGER},
      rtu_dt_last = #{rtuDtLast,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmClientAmountDayMapper.xml
New file
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dy.pipIrrGlobal.daoRm.RmClientAmountDayMapper">
  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    <!--@Table rm_client_amount_day-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="client_id" jdbcType="BIGINT" property="clientId" />
    <result column="amount" jdbcType="FLOAT" property="amount" />
    <result column="money" jdbcType="FLOAT" property="money" />
    <result column="dt" jdbcType="DATE" property="dt" />
    <result column="open_dt_last" jdbcType="TIMESTAMP" property="openDtLast" />
    <result column="close_dt_last" jdbcType="TIMESTAMP" property="closeDtLast" />
    <result column="this_amount_last" jdbcType="FLOAT" property="thisAmountLast" />
    <result column="this_money_last" jdbcType="FLOAT" property="thisMoneyLast" />
    <result column="this_time_last" jdbcType="INTEGER" property="thisTimeLast" />
    <result column="rtu_dt_last" jdbcType="TIMESTAMP" property="rtuDtLast" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, client_id, amount, money, dt, open_dt_last, close_dt_last, this_amount_last, this_money_last,
    this_time_last, rtu_dt_last
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from rm_client_amount_day
    where id = #{id,jdbcType=BIGINT}
  </select>
  <select id="selectByClientAndDate" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from rm_client_amount_day
    where client_id = #{clientId,jdbcType=BIGINT} and dt = #{dt,jdbcType=DATE}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from rm_client_amount_day
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    insert into rm_client_amount_day (id, client_id, amount, money,
      dt, open_dt_last, close_dt_last,
      this_amount_last, this_money_last, this_time_last,
      rtu_dt_last)
    values (#{id,jdbcType=BIGINT}, #{clientId,jdbcType=BIGINT}, #{amount,jdbcType=FLOAT}, #{money,jdbcType=FLOAT},
      #{dt,jdbcType=DATE}, #{openDtLast,jdbcType=TIMESTAMP}, #{closeDtLast,jdbcType=TIMESTAMP},
      #{thisAmountLast,jdbcType=FLOAT}, #{thisMoneyLast,jdbcType=FLOAT}, #{thisTimeLast,jdbcType=INTEGER},
      #{rtuDtLast,jdbcType=TIMESTAMP})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    insert into rm_client_amount_day
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="clientId != null">
        client_id,
      </if>
      <if test="amount != null">
        amount,
      </if>
      <if test="money != null">
        money,
      </if>
      <if test="dt != null">
        dt,
      </if>
      <if test="openDtLast != null">
        open_dt_last,
      </if>
      <if test="closeDtLast != null">
        close_dt_last,
      </if>
      <if test="thisAmountLast != null">
        this_amount_last,
      </if>
      <if test="thisMoneyLast != null">
        this_money_last,
      </if>
      <if test="thisTimeLast != null">
        this_time_last,
      </if>
      <if test="rtuDtLast != null">
        rtu_dt_last,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="clientId != null">
        #{clientId,jdbcType=BIGINT},
      </if>
      <if test="amount != null">
        #{amount,jdbcType=FLOAT},
      </if>
      <if test="money != null">
        #{money,jdbcType=FLOAT},
      </if>
      <if test="dt != null">
        #{dt,jdbcType=DATE},
      </if>
      <if test="openDtLast != null">
        #{openDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="closeDtLast != null">
        #{closeDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="thisAmountLast != null">
        #{thisAmountLast,jdbcType=FLOAT},
      </if>
      <if test="thisMoneyLast != null">
        #{thisMoneyLast,jdbcType=FLOAT},
      </if>
      <if test="thisTimeLast != null">
        #{thisTimeLast,jdbcType=INTEGER},
      </if>
      <if test="rtuDtLast != null">
        #{rtuDtLast,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    update rm_client_amount_day
    <set>
      <if test="clientId != null">
        client_id = #{clientId,jdbcType=BIGINT},
      </if>
      <if test="amount != null">
        amount = #{amount,jdbcType=FLOAT},
      </if>
      <if test="money != null">
        money = #{money,jdbcType=FLOAT},
      </if>
      <if test="dt != null">
        dt = #{dt,jdbcType=DATE},
      </if>
      <if test="openDtLast != null">
        open_dt_last = #{openDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="closeDtLast != null">
        close_dt_last = #{closeDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="thisAmountLast != null">
        this_amount_last = #{thisAmountLast,jdbcType=FLOAT},
      </if>
      <if test="thisMoneyLast != null">
        this_money_last = #{thisMoneyLast,jdbcType=FLOAT},
      </if>
      <if test="thisTimeLast != null">
        this_time_last = #{thisTimeLast,jdbcType=INTEGER},
      </if>
      <if test="rtuDtLast != null">
        rtu_dt_last = #{rtuDtLast,jdbcType=TIMESTAMP},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    update rm_client_amount_day
    set client_id = #{clientId,jdbcType=BIGINT},
      amount = #{amount,jdbcType=FLOAT},
      money = #{money,jdbcType=FLOAT},
      dt = #{dt,jdbcType=DATE},
      open_dt_last = #{openDtLast,jdbcType=TIMESTAMP},
      close_dt_last = #{closeDtLast,jdbcType=TIMESTAMP},
      this_amount_last = #{thisAmountLast,jdbcType=FLOAT},
      this_money_last = #{thisMoneyLast,jdbcType=FLOAT},
      this_time_last = #{thisTimeLast,jdbcType=INTEGER},
      rtu_dt_last = #{rtuDtLast,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/Server.java
@@ -130,6 +130,10 @@
        try {
            ///////////////
            //基本配置
            ServerProperties.orgTag = this.conf.getSetAttrTxt(this.doc, "config.base", "orgTag", null, false, null) ;
            if(ServerProperties.orgTag==null || ServerProperties.orgTag.trim().equals("")){
                throw new Exception("机构tag不能为空") ;
            }
            ServerProperties.isLowPower = conf.getSetAttrBoolean(doc, "config.base", "isLowPower", null, null) ; 
            if(ServerProperties.isLowPower == null){
                ServerProperties.isLowPower = false ;
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/ServerProperties.java
@@ -3,6 +3,8 @@
public class ServerProperties {
    
    //是否为低功耗
    public static String orgTag = "ym" ;
    //是否为低功耗
    public static Boolean isLowPower = false ;
    //在支持多通信协议时,只有RTU上线了,才能识别出该RTU实际用的通信协议,进而用此协议解析上行数据及构造下行命令。
    //如果RTU未曾上线(通信中间件启动后该RTU未曾上线),那么在向它发送下行命令时,不能判断出其采用的协议,也不能构造命令,尤其是低功耗情况下,不上线是正常现象。
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/forTcp/MidResultActionFromRtu.java
@@ -30,7 +30,7 @@
                MidResultToRtu resToRtu = TcpDownCommandCache.matchFromHead(resFromRtu) ;
                if(resToRtu != null){
                    //匹配到下发的命令
                    resFromRtu.matchedCommand(resToRtu.commandId, resToRtu.param, resToRtu.rtuResultSendWebUrl) ;
                    resFromRtu.matchedCommand(resToRtu.commandId, resToRtu.rtuResultSendWebUrl) ;
                    this.nextDealRtuData(false, resFromRtu);
                    this.nextDealRtuComResult(resFromRtu);
                }else{
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/dbSv/DbSv.java
@@ -50,9 +50,13 @@
    @Autowired
    private RmWorkReportHistoryMapper rmWorkReportHistoryMapperDao ;//控制器历史工作报数据DAO
    @Autowired
    private RmIntakeAmountDayLastMapper rmIntakeAmountDayLastMapperDao ;//取水口取水和漏损统计最新数据DAO
    private RmIntakeAmountDayLastMapper rmIntakeAmountDayLastMapperDao ;//取水口取水统计最新数据DAO
    @Autowired
    private RmIntakeAmountDayMapper rmIntakeAmountDayMapperDao ;//取水口取水和漏损统计DAO
    @Autowired
    private RmClientAmountDayLastMapper rmClientAmountDayLastMapperDao ;//农户日用水量统计最新数据DAO
    @Autowired
    private RmClientAmountDayMapper rmClientAmountDayMapperDao ;//农户日用水量统计数据DAO
    @Autowired
    private RmLossLastMapper rmLossLastMapperDao ;//控制器漏损水量统计最新数据DAO
    @Autowired
@@ -417,7 +421,7 @@
    //
    ////////////////////////////////////////////////
    /**
     * 得到控制器漏损水量统计最新记录
     * 得到最新记录
     * @param intakeId
     * @return
     */
@@ -429,7 +433,7 @@
        return null ;
    }
    /**
     * 保存控制器漏损水量统计最新记录
     * 保存最新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
@@ -437,7 +441,7 @@
        this.rmIntakeAmountDayLastMapperDao.insert(po) ;
    }
  /**
     * 保存控制器漏损水量统计最新记录
     * 保存记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
@@ -445,15 +449,15 @@
        this.rmIntakeAmountDayMapperDao.insert(po) ;
    }
    /**
     * 保存控制器漏损水量统计最新记录
     * 保存最新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRmIntakeAmountLast(RmIntakeAmountDay po){
        this.rmIntakeAmountDayMapperDao.updateByPrimaryKey(po) ;
    public void updateRmIntakeAmountLast(RmIntakeAmountDayLast po){
        this.rmIntakeAmountDayLastMapperDao.updateByPrimaryKey(po) ;
    }
    /**
     * 保存控制器漏损水量统计最新记录
     * 保存历史记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
@@ -462,7 +466,7 @@
    }
    /**
     * 得到控制器漏损水量统计历史记录中的最新记录
     * 得到符合条件的历史记录
     * @param id
     * @return
     */
@@ -470,32 +474,80 @@
        return rmIntakeAmountDayMapperDao.selectByPrimaryKey(id) ;
    }
    /////////////////////////////////////////////////
    //
    // 农户日用水量及花费统计功能
    //
    ////////////////////////////////////////////////
    /**
     * 得到最新记录
     * @param clientId
     * @return
     */
    public RmClientAmountDayLast getRmClientAmountLast(Long clientId){
        List<RmClientAmountDayLast> list = rmClientAmountDayLastMapperDao.selectByClientId(clientId) ;
        if(list != null && list.size() > 0){
            return list.get(0) ;
        }
        return null ;
    }
    /**
     * 保存最新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveRmClientAmountLast(RmClientAmountDayLast po){
        this.rmClientAmountDayLastMapperDao.insert(po) ;
    }
    /**
     * 保存记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveRmClientAmountDay(RmClientAmountDay po){
        this.rmClientAmountDayMapperDao.insert(po) ;
    }
    /**
     * 更新最新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRmClientAmountLast(RmClientAmountDayLast po){
        this.rmClientAmountDayLastMapperDao.updateByPrimaryKey(po) ;
    }
    /**
     * 更新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRmClientAmountDay(RmClientAmountDay po){
        this.rmClientAmountDayMapperDao.updateByPrimaryKey(po) ;
    }
    /**
     * 得到控制器漏损水量统计最新记录
     * 得到符合条件的历史记录
     * @param id
     * @return
     */
    public RmClientAmountDay getRmClientAmountDay(Long id){
        return rmClientAmountDayMapperDao.selectByPrimaryKey(id) ;
    }
    /**
     * 得到符合条件的历史记录
     * @param clientId
     * @param dt
     * @return
     */
    public RmIntakeAmountDay getRmIntakeAmountLastByDate(Date dt){
        List<RmIntakeAmountDay> list = rmIntakeAmountDayMapperDao.selectByDate(dt) ;
    public RmClientAmountDay getRmClientAmountByClientAndDate(Long clientId, Date dt){
        List<RmClientAmountDay> list = rmClientAmountDayMapperDao.selectByClientAndDate(clientId, dt) ;
        if(list != null && list.size() > 0){
            return list.get(0) ;
        }
        return null ;
    }
    /**
     * 得到控制器漏损水量统计历史记录中的某日记录
     * @param dt
     * @return
     */
    public RmIntakeAmountDay getRmIntakeAmountDayByDate(Date dt){
        List<RmIntakeAmountDay> list = rmIntakeAmountDayMapperDao.selectByDate(dt) ;
        if(list != null && list.size() > 0){
            return list.get(0) ;
        }
        return null ;
    }
    /////////////////////////////////////////////////
    //
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealClientAmountDay.java
New file
@@ -0,0 +1,343 @@
package com.dy.rtuMw.server.rtuData.p206V1_0_0;
import com.dy.common.mw.protocol.Data;
import com.dy.common.mw.protocol.p206V1_0_0.DataV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd83CloseVo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd83OpenVo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd84Vo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCdC0Vo;
import com.dy.common.util.DateTime;
import com.dy.pipIrrGlobal.pojoPr.PrController;
import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay;
import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast;
import com.dy.pipIrrGlobal.pojoRm.RmIntakeAmountDay;
import com.dy.pipIrrGlobal.pojoRm.RmIntakeAmountDayLast;
import com.dy.pipIrrGlobal.pojoSe.SeClient;
import com.dy.rtuMw.server.rtuData.TaskSurpport;
import com.dy.rtuMw.server.rtuData.dbSv.DbSv;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Date;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 10:00
 * @Description 农户日用水量统计
 */
public class TkDealClientAmountDay  extends TaskSurpport {
    private static final Logger log = LogManager.getLogger(TkDealClientAmountDay.class.getName());
    //类ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkDealClientAmountDay";
    /**
     * 执行节点任务: 取水口日用水量和漏损量
     *
     * @param data 需要处理的数据
     */
    @Override
    public void execute(Object data) {
        Data d = (Data) data;
        DataV1_0_1 dV1_0_1 = (DataV1_0_1) d.getSubData();//前面任务已经判断不为null
        Object cdObj = dV1_0_1.subData;
        if (cdObj != null && cdObj instanceof DataCd83CloseVo) {
            /*
            只能采用DataCd83CloseVo来计算农户日用水量的原因:
            1、如果采用DataCd84Vo来计算农户日用水量,必须采用本次累计流量减上次累流量的差值作为阶段农户用水量,
               然后各个阶段相加,得到本次农户用水量,这个用水量还没加到农户日用水量中,因为只有收不到DataCd83CloseVo
               上报数据时才能加到农户用水量中,否则就会重复计算,但什么时候及能否收到DataCd83CloseVo不可预知。
            2、如果农户有多张IC卡,同时在多个取水口取水,将会是更复杂的计算,许多情形更不可预测,且时间复杂度
               必然很高,这样程序运行时间更长,将会造成上行数据堵塞现象。
            3、所以只采用上报数据DataCd83CloseVo作为计算农户用水量的数据来源,这时必然会有漏报缺失情况发生,采用补报机制可以弥补一些。
             */
            /*
             补报DataCd83CloseVo处理方法:
             采用DataCd83CloseVo数据中的关阀时间closeDt计算出农户用水日期,不能用数据接收日期时间作为农户用水日期,
             但这种计算方法可能会有重复上报情况发生,即重复计算了,如果要判断重复,必然要增加一个关阀时间数据库表,增加时间
             复杂度,计算用时将会长,本系统假设只要RTU上报上来数据了,说明当前网络较好,必然能收到下行应答,不会发行重复补报。
             */
            Object[] objs = this.getTaskResults(TkPreGenObjs.taskId);
            DbSv sv = (DbSv) objs[0];
            PrController controller = (PrController) objs[1];
            SeClient clientVo = (SeClient)objs[3] ;//这个值对象中只有id和name会有值
            if(clientVo != null && clientVo.getId() != null)
            try {
                this.doDeal(sv, clientVo, controller, d.getRtuAddr(), dV1_0_1, (DataCd83CloseVo) cdObj);
            } catch (Exception e) {
                log.error("保存取水口日用水量和漏损量数据时发生异常", e);
            }
        }
    }
    /**
     * 业务处理
     *
     * @param sv         服务
     * @param clientVo   农户对象
     * @param controller 控制器对象
     * @param rtuAddr    控制器地址
     * @param dV1_0_1    上报数据
     * @param cdData     上报关阀数据对象
     */
    private void doDeal(DbSv sv, SeClient clientVo, PrController controller, String rtuAddr, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData) throws Exception {
        RmClientAmountDayLast poLast = sv.getRmClientAmountLast(clientVo.getId());
        if (poLast == null) {
            //数据库中不存在该农户的日取水量数据
            //首先生成最新数据及历史数据,并先保存
            poLast = this.newRmClientAmountLast(clientVo, dV1_0_1, cdData);
            this.newAndSaveHistoryDataDeal(sv, clientVo, dV1_0_1, cdData, poLast);
            sv.saveRmClientAmountLast(poLast);
        } else {
            if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt).equals(poLast.rtuDtLast)){
                //RTU时钟等于本地最新数据中的RTU时钟,重复上报数据,不进行任何处理
            }else if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt).after(poLast.rtuDtLast)){
                //RTU时钟晚于本地最新数据中的RTU时钟,是新上报数据
                Date upYmd = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
                if(upYmd.equals(poLast.dt)){
                    //同一天数据
                    poLast = this.updateRmClientAmountLastBySameDateNewData(clientVo, dV1_0_1, cdData, poLast);
                    RmClientAmountDay poHistory = null ;
                    if(poLast.lastHistoryId != null){
                        poHistory = sv.getRmClientAmountDay(poLast.lastHistoryId) ;
                    }
                    if(poHistory == null){
                        this.newAndSaveHistoryDataDeal(sv, clientVo, dV1_0_1, cdData, poLast);
                    }else{
                        poHistory = this.updateRmClientAmountBySameDateNewData(clientVo, poHistory, poLast, dV1_0_1, cdData);
                        sv.updateRmClientAmountDay(poHistory);
                    }
                    sv.saveRmClientAmountLast(poLast);
                }else if(upYmd.after(poLast.dt)){
                    //新的日期
                    poLast = this.updateRmClientAmountLastByNewDateNewData(clientVo, dV1_0_1, cdData, poLast);
                    this.newAndSaveHistoryDataDeal(sv, clientVo, dV1_0_1, cdData, poLast);
                    sv.saveRmClientAmountLast(poLast);
                }else{
                    //这种情况不存在
                }
                sv.updateRmClientAmountLast(poLast);
            }else{
                //RTU时钟早于本地最新数据中的RTU时钟,是补报数据
                Date upYmd = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
                RmClientAmountDay poHistory = sv.getRmClientAmountByClientAndDate(clientVo.getId(), upYmd) ;
                if(poHistory == null){
                    //无历史数据
                    this.newAndSaveHistoryDataDeal(sv, clientVo, dV1_0_1, cdData, null);
                }else{
                    poHistory = this.updateOldRmClientAmountBySupplyData(clientVo, poHistory, dV1_0_1, cdData);
                    sv.updateRmClientAmountDay(poHistory);
                }
            }
        }
    }
    /**
     * 生成新的控制器漏损日统计最新记录
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @return
     * @throws Exception
     */
    private RmClientAmountDayLast newRmClientAmountLast(SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData)throws Exception {
        RmClientAmountDayLast po = new RmClientAmountDayLast() ;
        po.clientId = clientVo.getId();
        po.amount = cdData.thisAmount ;
        po.money = cdData.thisMoney ;
        po.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
        po.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt);
        po.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt);
        po.thisAmountLast = cdData.thisAmount ;
        po.thisMoneyLast = cdData.thisMoney ;
        po.thisTimeLast = cdData.thisTime ;
        po.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        return po ;
    }
    /**
     * 生成新的控制器漏损日统计历史记录
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @return
     * @throws Exception
     */
    private RmClientAmountDay newRmClientAmountDay(SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData, RmClientAmountDayLast lastPo)throws Exception {
        RmClientAmountDay poHistory = new RmClientAmountDay() ;
        poHistory.clientId = clientVo.getId();
        if(lastPo != null){
            if(poHistory.amount != null){
                poHistory.amount += lastPo.amount ;
            }else{
                poHistory.amount = lastPo.amount ;
            }
            if(poHistory.money != null){
                poHistory.money += lastPo.money ;
            }else{
                poHistory.money = lastPo.money ;
            }
            poHistory.dt = lastPo.dt ;
            poHistory.openDtLast = lastPo.openDtLast ;
            poHistory.closeDtLast = lastPo.closeDtLast ;
            poHistory.thisAmountLast = lastPo.thisAmountLast ;
            poHistory.thisMoneyLast = lastPo.thisMoneyLast ;
            poHistory.thisTimeLast = lastPo.thisTimeLast ;
            poHistory.rtuDtLast = lastPo.rtuDtLast ;
        }else{
            poHistory.amount = cdData.thisAmount ;
            poHistory.money = cdData.thisMoney ;
            poHistory.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
            poHistory.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt);
            poHistory.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt);
            poHistory.thisAmountLast = cdData.thisAmount ;
            poHistory.thisMoneyLast = cdData.thisMoney ;
            poHistory.thisTimeLast = cdData.thisTime ;
            poHistory.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        }
        return poHistory ;
    }
    /**
     * 保存新的历史数据记录,并把ID赋值给最新记录的 lastHistoryId
     * @param sv
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @throws Exception
     * @return RmIntakeAmountDay
     */
    private RmClientAmountDay newAndSaveHistoryDataDeal(DbSv sv, SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData, RmClientAmountDayLast lastPo)throws Exception {
        RmClientAmountDay poHistory = this.newRmClientAmountDay(clientVo, dV1_0_1, cdData, lastPo) ;
        sv.saveRmClientAmountDay(poHistory);
        //由最新数据持有历史数据中的最新记录ID,以方便快速查询
        lastPo.lastHistoryId = poHistory == null ? null: poHistory.id ;
        return poHistory ;
    }
    /**
     * 更新最新数据
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @return
     * @throws Exception
     */
    private RmClientAmountDayLast updateRmClientAmountLastBySameDateNewData(SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData, RmClientAmountDayLast lastPo)throws Exception {
        lastPo.clientId = clientVo.getId();
        if(lastPo.amount != null){
            lastPo.amount += cdData.thisAmount ;
        }else{
            lastPo.amount = cdData.thisAmount ;
        }
       if(lastPo.money != null){
            lastPo.money += cdData.thisMoney ;
        }else{
            lastPo.money = cdData.thisMoney ;
        }
        lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
        lastPo.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt);
        lastPo.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt);
        lastPo.thisAmountLast = cdData.thisAmount ;
        lastPo.thisMoneyLast = cdData.thisMoney ;
        lastPo.thisTimeLast = cdData.thisTime ;
        lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        return lastPo ;
    }
    /**
     * 更新最新数据
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @return
     * @throws Exception
     */
    private RmClientAmountDayLast updateRmClientAmountLastByNewDateNewData(SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData, RmClientAmountDayLast lastPo)throws Exception {
        lastPo.clientId = clientVo.getId();
        lastPo.amount = cdData.thisAmount ;
        lastPo.money = cdData.thisMoney ;
        lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
        lastPo.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt);
        lastPo.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt);
        lastPo.thisAmountLast = cdData.thisAmount ;
        lastPo.thisMoneyLast = cdData.thisMoney ;
        lastPo.thisTimeLast = cdData.thisTime ;
        lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        return lastPo ;
    }
    /**
     * 更新最新数据
     * @param clientVo
     * @param poHistory
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @return
     * @throws Exception
     */
    private RmClientAmountDay updateRmClientAmountBySameDateNewData(SeClient clientVo, RmClientAmountDay poHistory, RmClientAmountDayLast lastPo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData)throws Exception {
        poHistory.clientId = clientVo.getId();
        if(poHistory.amount != null){
            poHistory.amount += cdData.thisAmount ;
        }else{
            poHistory.amount = cdData.thisAmount ;
        }
        if(poHistory.money != null){
            poHistory.money += cdData.thisMoney ;
        }else{
            poHistory.money = cdData.thisMoney ;
        }
        poHistory.dt = lastPo.dt ;
        poHistory.openDtLast = lastPo.openDtLast ;
        poHistory.closeDtLast = lastPo.closeDtLast ;
        poHistory.thisAmountLast = lastPo.thisAmountLast ;
        poHistory.thisMoneyLast = lastPo.thisMoneyLast ;
        poHistory.thisTimeLast = lastPo.thisTimeLast ;
        poHistory.rtuDtLast = lastPo.rtuDtLast ;
        return poHistory ;
    }
    /**
     * 更新最新数据
     * @param clientVo
     * @param poHistory
     * @param dV1_0_1
     * @param cdData
     * @return
     * @throws Exception
     */
    private RmClientAmountDay updateOldRmClientAmountBySupplyData(SeClient clientVo, RmClientAmountDay poHistory, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData)throws Exception {
        poHistory.clientId = clientVo.getId();
        if(poHistory.amount != null){
            poHistory.amount += cdData.thisAmount ;
        }else{
            poHistory.amount = cdData.thisAmount ;
        }
        if(poHistory.money != null){
            poHistory.money += cdData.thisMoney ;
        }else{
            poHistory.money = cdData.thisMoney ;
        }
        poHistory.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
        poHistory.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt) ;
        poHistory.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt) ;
        poHistory.thisAmountLast = cdData.thisAmount ;
        poHistory.thisMoneyLast = cdData.thisMoney ;
        poHistory.thisTimeLast = cdData.thisTime ;
        poHistory.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt) ;
        return poHistory ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealIntakeAmountDay.java
@@ -22,7 +22,7 @@
 */
public class TkDealIntakeAmountDay extends TaskSurpport {
    private static final Logger log = LogManager.getLogger(TkDealLoss.class.getName());
    private static final Logger log = LogManager.getLogger(TkDealIntakeAmountDay.class.getName());
    //类ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkDealIntakeAmountDay";
@@ -73,23 +73,40 @@
    private void doDeal(DbSv sv, PrController controller, String rtuAddr, DataV1_0_1 dV1_0_1, UpDataVo dataVo) throws Exception {
        RmIntakeAmountDayLast poLast = sv.getRmIntakeAmountLast(controller.getIntakeId());
        if (poLast == null) {
            //数据库中不存在该取水口的漏损数据
            //数据库中不存在该取水口的日取水量数据
            //首先生成最新数据及历史数据,并先保存
            poLast = this.newRmIntakeAmountLast(controller, rtuAddr, dV1_0_1, dataVo);
            this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV1_0_1, dataVo, poLast);
            sv.saveRmIntakeAmountLast(poLast);
        } else {
            if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataVo.rtuDt).before(poLast.rtuDtLast)){
                //RTU时钟早于本地RTU时钟,是补报,补报没法计算取水口日累计取水量,因为采用的是累计流量相差的计算方法
                //RTU时钟早于本地RTU时钟,是补报,不用补报来计算取水口日累计取水量,因为采用的是累计流量相差的计算方法,
                //其实补报的量值,基于前面上报数据已经计算包含了,只是量值归结的日期不正确罢了。
            }else if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataVo.rtuDt).equals(poLast.rtuDtLast)){
                //RTU时钟等于本地RTU时钟,重复上报数据,不进行任何处理
            }else{
                //上行数据中的日期时间符合可计算的条件
                //上行数据中的日期时间符合计算的条件
                if(!rtuAddr.equals(poLast.rtuAddrLast)){
                    //更换了控制器,只更换控制器地址,不进行水量计算
                    poLast = this.updateRmIntakeAmountLastByControllerChange(poLast, controller, rtuAddr, dV1_0_1, dataVo);
                    //因为上行数据中的日期时间是可进行计算的,所以新生成一个历史记录
                    this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV1_0_1, dataVo, poLast);
                    //更换了控制器,处理方法:只更换控制器地址,不进行水量计算
                    //因为上行数据中的日期时间是可进行计算的
                    if(DateTime.dateFrom_yyyy_MM_dd1(dV1_0_1.dt).equals(poLast.dt)){
                        //同一天数据
                        poLast = this.updateRmIntakeAmountLastByControllerChange(poLast, controller, rtuAddr, dV1_0_1, dataVo);
                        RmIntakeAmountDay poHistory = null ;
                        if(poLast.lastHistoryId != null){
                            poHistory = sv.getRmIntakeAmountDay(poLast.lastHistoryId) ;
                        }
                        if(poHistory == null){
                            this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV1_0_1, dataVo, poLast);
                        }else{
                            poHistory = this.updateRmIntakeAmountByControllerChange(poHistory, poLast, controller, rtuAddr, dV1_0_1, dataVo);
                            sv.updateRmIntakeAmountDay(poHistory);
                        }
                    }else{
                        //非同一天,所以新生成一个历史记录
                        poLast = this.updateRmIntakeAmountLastByControllerChange(poLast, controller, rtuAddr, dV1_0_1, dataVo);
                        this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV1_0_1, dataVo, poLast);
                    }
                    sv.saveRmIntakeAmountLast(poLast);
                }else{
                    //未更换控制器
@@ -117,6 +134,8 @@
                    }
                }
            }
            //更新最新数据
            sv.updateRmIntakeAmountLast(poLast);
        }
    }
@@ -164,14 +183,13 @@
        }else{
            po.amount = 0.0D ;
        }
        po.amount = lastPo==null?0.0D:lastPo.amount ;
        po.totalAmountLast = cdData.totalAmount ;
        return po ;
    }
    /**
     * 保存新的开阀上报历史数据记录,并把ID赋值给最新记录的 lastHistoryId
     * 保存新的历史数据记录,并把ID赋值给最新记录的 lastHistoryId
     * @param sv
     * @param controller
     * @param rtuAddr
@@ -206,7 +224,7 @@
        lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(dV1_0_1.dt);
        lastPo.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV1_0_1.dt);
        lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        //lastPo.amount = lastPo.amount ; //累计取水量不变
        //lastPo.amount = lastPo.amount ; //日累计取水量不变
        lastPo.totalAmountLast = cdData.totalAmount ;
        return lastPo ;
    }
@@ -231,12 +249,11 @@
        if(difference > 0){
            lastPo.amount = difference;
        }else{
            //po.amount = po.amount ; //累计取水量不变
            //po.amount = po.amount ; //日累计取水量不变
        }
        lastPo.totalAmountLast = cdData.totalAmount ;
        return lastPo ;
    }
    /**
     * 更新最新记录
@@ -265,6 +282,29 @@
    }
    /**
     * 生成新的控制器漏损日统计最新记录
     * @param controller
     * @param rtuAddr
     * @param dV1_0_1
     * @param cdData
     * @return
     * @throws Exception
     */
    private RmIntakeAmountDay updateRmIntakeAmountByControllerChange(RmIntakeAmountDay po, RmIntakeAmountDayLast lastPo, PrController controller, String rtuAddr, DataV1_0_1 dV1_0_1, UpDataVo cdData)throws Exception {
        po.intakeId = controller==null?null:controller.getIntakeId();
        po.controllerIdLast = controller==null?null:controller.getId();
        po.rtuAddrLast = rtuAddr;
        po.dt = lastPo.dt ;
        po.dtLast = lastPo.dtLast;
        po.rtuDtLast = lastPo.rtuDtLast;
        po.amount = lastPo.amount ;
        po.totalAmountLast = lastPo.totalAmountLast ;
        return po ;
    }
    /**
     * 更新历史记录
     * @param controller
     * @param rtuAddr
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealLoss.java
@@ -94,6 +94,7 @@
                    //这种情况不存在(RTU时钟早于本地记录中的RTU时钟(RTU穿越回过去了,可能时钟重置了),此种情况不处理)
                }
            }
            sv.updateRmLossLast(poLast);
        }
    }
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkPreGenObjs.java
@@ -7,6 +7,7 @@
import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.*;
import com.dy.pipIrrGlobal.pojoSe.SeClient;
import com.dy.rtuMw.server.ServerProperties;
import com.dy.rtuMw.server.rtuData.TaskSurpport;
import com.dy.rtuMw.server.rtuData.dbSv.DbSv;
import com.dy.common.mw.protocol.Data;
@@ -46,7 +47,7 @@
                controllerTramp = sv.getPrControllerTrampByRtuAddr(rtuAddr);
                if(controllerTramp == null){
                    //第一次发现
                    controllerTramp = new PrControllerTramp(null, rtuAddr, d.getProtocol(), new Date()) ;
                    controllerTramp = new PrControllerTramp(null, rtuAddr, d.getProtocol(), new Date(), ServerProperties.orgTag) ;
                    //第一次发现,下发清空RTU历史命令,以使其重新开始记录新地点的数据
                    this.sendClearCommand(rtuAddr, d.protocol);
                }
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V202404/TkPreGenObjsV202404.java
@@ -8,6 +8,7 @@
import com.dy.common.springUtil.SpringContextUtil;
import com.dy.pipIrrGlobal.pojoPr.PrController;
import com.dy.pipIrrGlobal.pojoPr.PrControllerTramp;
import com.dy.rtuMw.server.ServerProperties;
import com.dy.rtuMw.server.rtuData.TaskSurpport;
import com.dy.rtuMw.server.rtuData.dbSv.DbSv;
import com.dy.rtuMw.web.com.CommandCtrl;
@@ -45,7 +46,7 @@
                controllerTramp = sv.getPrControllerTrampByRtuAddr(rtuAddr);
                if(controllerTramp == null){
                    //第一次发现
                    controllerTramp = new PrControllerTramp(null, rtuAddr, d.getProtocol(), new Date()) ;
                    controllerTramp = new PrControllerTramp(null, rtuAddr, d.getProtocol(), new Date(), ServerProperties.orgTag) ;
                    //第一次发现,下发清空RTU历史命令,以使其重新开始记录新地点的数据
                    this.sendClearCommand(rtuAddr, d.protocol);
                }
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/RtuDataDealTree.xml
@@ -21,7 +21,8 @@
                            <task id="TkDealOpenValveReport" name="控制器开阀上报(功能码83)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealOpenValveReport" />
                            <task id="TkDealCloseValveReport" name="控制器关阀上报(功能码83)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealCloseValveReport" />
                            <task id="TkDealLoss" name="取水口日漏损量(功能码C0)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealLoss" />
                            <task id="TkDealIntakeAmountDay" name="取水口日用水量和漏损量(功能码84、功能码83、功能码C0)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealIntakeAmountDay" />
                            <task id="TkDealIntakeAmountDay" name="取水口日用水量(功能码84、功能码83、功能码C0)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealIntakeAmountDay" />
                            <task id="TkDealClientAmountDay" name="农户日用水量(功能码84、功能码83、功能码C0)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealClientAmountDay" />
                        </task>
                        <!-- 识别命令响应数据 -->
                        <task id="TkFindComResponse" name="识别响应命令数据" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkFindComResponse">
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/config.xml
@@ -3,6 +3,7 @@
        <server name="通信中间件" showStartInfo="true" company="http://www.dyjs.com"/>
        <!-- 
        基本配置
        orgTag 机构tag(对应机构tag,和数据源后缀)
        isLowPower: 是否为低功耗
        onlyOneProtocol:在支持多通信协议时,只有RTU上线了,才能识别出该RTU实际用的通信协议,进而用此协议解析上行数据及构造下行命令。
                         如果RTU未曾上线(通信中间件启动后该RTU未曾上线),那么在向它发送下行命令时,不能判断出其采用的协议,也不能构造命令,尤其是低功耗情况下,不上线是正常现象。
@@ -18,7 +19,8 @@
        cacheUpDownDataMaxCount:上下行数据缓存队列中缓存数据个数的最大值,这个与现实项目所接水表数相关
        disconnectedByNoUpDataMinutes:没有上行数据的分钟数,达到这个分钟数,认为RTU断网了,取值范围是2_100
         -->
        <base
        <base
            orgTag="ym"
            isLowPower="false"
            onlyOneProtocol="true"
            downComandMaxResendTimes="1"
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/MyThreadJob.java
@@ -14,6 +14,16 @@
    private static final Logger log = LogManager.getLogger(MyThreadJob.class) ;
    public static String icCardAddr = "3B7D1E1A" ;
    public static String icCardNo = "61181622830147821" ;
    public static String openValveDt = "240711163700" ;
    public static String cdC0 = "C0" ;
    public static String cd83Open = "83Open" ;
    public static String cd83Close = "83Close" ;
    public static String curCd = cdC0 ;//通过修改这个值,来改变上报数据类型
    public String rtuAddr;
    public String serverIp;
    public Integer serverPort;
@@ -44,7 +54,7 @@
                if(sendTimes <= ServerProperties.sendTimes){
                    log.info("RTU" + rtuAddr + "开始任务");
                    log.info("RTU" + rtuAddr + "将要执行" + ServerProperties.sendTimes + "轮次任务,当前轮次是" + sendTimes);
                    sendDataOfP206V1_0_0() ;
                    sendDataOfP206V1_0_0(curCd) ;
                }else{
                    if(ServerProperties.sendOverThenCloseConnect == 1){
                        log.info("RTU" + rtuAddr + "等待一会,以接收通信中间件下行数据");
@@ -64,11 +74,20 @@
        }
    }
    private void sendDataOfP206V1_0_0(){
    private void sendDataOfP206V1_0_0(String cd){
        try{
            if(heartbeatTimes > ServerProperties.heartbeatTimes){
                heartbeatTimes = 1 ;
                this.sendReportData() ;
                byte[] bs = null ;
                if(cd.equals(cdC0)){
                    bs = RtuUpData.createCdC0(this.rtuAddr) ;
                }else if(cd.equals(cd83Open)){
                    bs = RtuUpData.createCd83Open(this.rtuAddr, icCardAddr, icCardNo, openValveDt) ;
                }else if(cd.equals(cd83Close)){
                    bs = RtuUpData.createCd83Close(this.rtuAddr, icCardAddr, icCardNo, openValveDt) ;
                }
                this.session.write(bs) ;
                log.info("RTU" + rtuAddr + "发送了上行数据:" + ByteUtil.bytes2Hex(bs, false));
                TcpClUnit.clientSendData();
                sendTimes++ ;
            }else{
@@ -82,7 +101,7 @@
    }
    private void sendHeartbeat(){
        try{
            byte[] bs = this.createHeartbeat() ;
            byte[] bs = RtuUpData.createHeartbeat(this.rtuAddr) ;
            this.session.write(bs) ;
            log.info("RTU" + rtuAddr + "发送了心跳数据:" + ByteUtil.bytes2Hex(bs, false));
        }catch (Exception e){
@@ -90,15 +109,6 @@
        }
    }
    private void sendReportData(){
        try{
            byte[] bs = this.createReport() ;
            this.session.write(bs) ;
            log.info("RTU" + rtuAddr + "发送了上报数据:" + ByteUtil.bytes2Hex(bs, false));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private void jobOver(){
        if(ServerProperties.sendOverThenCloseConnect == 1){
@@ -108,128 +118,6 @@
        TcpClUnit.clientOver() ;
    }
    /**
     * 构造心跳数据
     * @return 字节数组
     * @throws Exception 异常
     */
    public byte[] createHeartbeat( ) 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)0x80, (byte)0) ;//控制域功能码:确认 认可
        index++ ;
        GlCreate.createRtuAddr(this.rtuAddr, bsHead, index);
        index += 5 ;
        ByteUtil.hex2Bytes("02", bsHead, index) ;
        byte[] bs = new byte[1] ;
        bs[0] = (byte)0xF2 ;//数据域: 1 个字节,F0 登录, F1 退出登录,F2 在线保持。
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        GlCreate.createLen(bytes);//长度放字节数组中
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
        return bytes ;
    }
    /**
     * 构造上报数据
     * @return 字节数组
     * @throws Exception 异常
     */
    public byte[] createReport( ) 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)0x80, (byte)3) ;//控制域功能码3:自报帧,流量(水量)参数
        index++ ;
        GlCreate.createRtuAddr(this.rtuAddr, bsHead, index);
        index += 5 ;
        ByteUtil.hex2Bytes("C0", bsHead, index) ;
        byte[] bs = new byte[2] ;
        bs[0] = (byte)0x04 ;//有流量数据
        bs[1] = (byte)0xE0 ;//有水压、电池电压、信号强度
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        bs = new byte[5] ;//瞬时流量
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (43)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (65)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[5] ;//累计流量
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (43)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (65)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (87)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[5] ;//损失流量
        bs[0] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (32)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (54)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//水压
        bs[0] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (32)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (4)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//电池电压
        bs[0] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (32)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (32)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[1] ;//信号强度
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[6] ;//时钟
        GlCreate.createTp(bs, 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-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/RtuUpData.java
New file
@@ -0,0 +1,287 @@
package com.dy.testClient.tcpClient;
import com.dy.common.mw.protocol.p206V1_0_0.CommonV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0;
import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlCreate;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
/**
 * @Author: liurunyu
 * @Date: 2024/7/11 13:55
 * @Description
 */
public class RtuUpData {
    private static byte[] creatHead(String rtuAddr, String code, byte ctrl)throws Exception {
        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] = ctrl; //控制域功能码
        index++ ;
        GlCreate.createRtuAddr(rtuAddr, bsHead, index);
        index += 5 ;
        ByteUtil.hex2Bytes(code, bsHead, index) ;
        return bsHead ;
    }
    /**
     * 构造心跳数据
     * @return 字节数组
     * @throws Exception 异常
     */
    public static byte[] createHeartbeat(String rtuAddr) throws Exception {
        byte[] bytes = creatHead(rtuAddr, "02", (byte)0xB0);
        byte[] bs = new byte[1] ;
        bs[0] = (byte)0xF2 ;//数据域: 1 个字节,F0 登录, F1 退出登录,F2 在线保持。
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        GlCreate.createLen(bytes);//长度放字节数组中
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
        return bytes ;
    }
    /**
     * 构造上报数据
     * @return 字节数组
     * @throws Exception 异常
     */
    public static byte[] createCd83Open(String rtuAddr, String icCardAddr, String icCardNo, String openValveDt) throws Exception {
        byte[] bytes = creatHead(rtuAddr, "83", (byte)0xB0);
        byte[] bs = new byte[1] ;
        bs[0] = (byte)0x01 ;//刷卡开阀
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[5] ;//累计流量
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (43)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[4] = ByteUtil.int2BCD_LE (0)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[8] ;//IC卡编号
        GlCreate.createIcCardNo(icCardNo, bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//IC卡地址
        ByteUtil.hex2Bytes_LE(icCardAddr, bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//用水户余额
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (43)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (0)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[6] ;//开阀时间
        GlCreate.createTp(openValveDt, bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[6] ;//控制器时钟
        GlCreate.createTp(bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        GlCreate.createLen(bytes);//长度放字节数组中
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
        return bytes ;
    }
    /**
     * 构造上报数据
     * @return 字节数组
     * @throws Exception 异常
     */
    public static byte[] createCd83Close(String rtuAddr, String icCardAddr, String icCardNo, String openValveDt) throws Exception {
        byte[] bytes = creatHead(rtuAddr, "83", (byte)0xB0);
        byte[] bs = new byte[1] ;
        bs[0] = (byte)0x02 ;//刷卡关阀
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[5] ;//累计流量
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (53)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[4] = ByteUtil.int2BCD_LE (0)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[8] ;//IC卡编号
        GlCreate.createIcCardNo(icCardNo, bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//IC卡地址
        ByteUtil.hex2Bytes_LE(icCardAddr, bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//用水户余额
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (33)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (0)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[6] ;//开阀时间
        GlCreate.createTp(openValveDt, bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[6] ;//关阀时间
        GlCreate.createTp(bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[5] ;//用水户本次用水量
        bs[0] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[4] = ByteUtil.int2BCD_LE (0)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//用水户本次消费金额
        bs[0] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (0)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[2] ;//用水户本次用水时长
        bs[0] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (0)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[1] ;//水价类型
        bs[0] = ByteUtil.int2BCD_LE (1)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[2] ;//水价
        bs[0] = ByteUtil.int2BCD_LE (0)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (1)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[6] ;//控制器时钟
        GlCreate.createTp(bs, 0);
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[1] ;//卡类型
        bs[0] = ByteUtil.int2BCD_LE (1)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        GlCreate.createLen(bytes);//长度放字节数组中
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
        return bytes ;
    }
    /**
     * 构造上报数据
     * @return 字节数组
     * @throws Exception 异常
     */
    public static byte[] createCdC0(String rtuAddr) 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)0x80, (byte)3) ;//控制域功能码3:自报帧,流量(水量)参数
        index++ ;
        GlCreate.createRtuAddr(rtuAddr, bsHead, index);
        index += 5 ;
        ByteUtil.hex2Bytes("C0", bsHead, index) ;
        byte[] bs = new byte[2] ;
        bs[0] = (byte)0x04 ;//有流量数据
        bs[1] = (byte)0xE0 ;//有水压、电池电压、信号强度
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        bs = new byte[5] ;//瞬时流量
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (43)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (65)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[5] ;//累计流量
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (43)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (65)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (87)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[5] ;//损失流量
        bs[0] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (32)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (54)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//水压
        bs[0] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (32)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (4)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[4] ;//电池电压
        bs[0] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[1] = ByteUtil.int2BCD_LE (32)[0] ;
        bs[2] = ByteUtil.int2BCD_LE (10)[0] ;
        bs[3] = ByteUtil.int2BCD_LE (32)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[1] ;//信号强度
        bs[0] = ByteUtil.int2BCD_LE (21)[0] ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        bs = new byte[6] ;//时钟
        GlCreate.createTp(bs, 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-mw/pipIrr-mwTest-client/src/main/resources/log4j2.xml
@@ -12,7 +12,7 @@
        /logs/testJgroups.log当前软件所在硬盘根目录 
        logs/testJgroups.log当前软件所在目录 
     -->
    <RollingFile name="File" fileName="logs/mwTestCl.log" filePattern="logs/aepTest-%d{yyyyMMdd}-%i.log">
    <RollingFile name="File" fileName="logs/mwTestCl.log" filePattern="logs/mwTestCl-%d{yyyyMMdd}-%i.log">
      <PatternLayout charset="UTF-8" pattern="%d %-5p [%t] (%class.%method:%L) - %m%n%throwable"/>
      <Policies>
        <TimeBasedTriggeringPolicy interval="7" />
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-server/src/main/java/com/dy/testServer/Server.java
@@ -105,8 +105,8 @@
            if(txt.startsWith("0")){
                throw new Exception("元素config.base的属性rtuAddrStart的数值不能以0开头!");
            }
            if(txt.length() != 10){
                throw new Exception("元素config.base的属性rtuAddrStart的数值长度必须为10位!");
            if(!(txt.length() == 10 || txt.length() == 12)){
                throw new Exception("元素config.base的属性rtuAddrStart的数值长度必须为10位或12位!");
            }
            ServerProperties.rtuAddrStart = Long.valueOf(txt) ;
            
@@ -121,8 +121,8 @@
            if(txt.startsWith("0")){
                throw new Exception("元素config.base的属性rtuAddrEnd的数值不能以0开头!");
            }
            if(txt.length() != 10){
                throw new Exception("元素config.base的属性rtuAddrEnd的数值长度必须为10位!");
            if(!(txt.length() == 10 || txt.length() == 12)){
                throw new Exception("元素config.base的属性rtuAddrEnd的数值长度必须为10位或12位!");
            }
            ServerProperties.rtuAddrEnd = Long.valueOf(txt) ;
            if(ServerProperties.rtuAddrEnd <= ServerProperties.rtuAddrStart){
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-server/src/main/resources/log4j2.xml
@@ -12,7 +12,7 @@
        /logs/testJgroups.log当前软件所在硬盘根目录 
        logs/testJgroups.log当前软件所在目录 
     -->
    <RollingFile name="File" fileName="logs/mwTestSv.log" filePattern="logs/aepTest-%d{yyyyMMdd}-%i.log">
    <RollingFile name="File" fileName="logs/mwTestSv.log" filePattern="logs/mwTestSv-%d{yyyyMMdd}-%i.log">
      <PatternLayout charset="UTF-8" pattern="%d %-5p [%t] (%class.%method:%L) - %m%n%throwable"/>
      <Policies>
        <TimeBasedTriggeringPolicy interval="7" />
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/.gitignore
New file
@@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/.mvn/wrapper/maven-wrapper.properties
New file
@@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/mvnw
New file
@@ -0,0 +1,259 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.2
#
# Optional ENV vars
# -----------------
#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
#   MVNW_REPOURL - repo url base for downloading maven distribution
#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
  native_path() { cygpath --path --windows "$1"; }
  ;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
  if [ -n "${JAVA_HOME-}" ]; then
    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
      JAVACCMD="$JAVA_HOME/jre/sh/javac"
    else
      JAVACMD="$JAVA_HOME/bin/java"
      JAVACCMD="$JAVA_HOME/bin/javac"
      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
        return 1
      fi
    fi
  else
    JAVACMD="$(
      'set' +e
      'unset' -f command 2>/dev/null
      'command' -v java
    )" || :
    JAVACCMD="$(
      'set' +e
      'unset' -f command 2>/dev/null
      'command' -v javac
    )" || :
    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
      return 1
    fi
  fi
}
# hash string like Java String::hashCode
hash_string() {
  str="${1:-}" h=0
  while [ -n "$str" ]; do
    char="${str%"${str#?}"}"
    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
    str="${str#?}"
  done
  printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
  printf %s\\n "$1" >&2
  exit 1
}
trim() {
  # MWRAPPER-139:
  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
  #   Needed for removing poorly interpreted newline sequences when running in more
  #   exotic environments such as mingw bash on Windows.
  printf "%s" "${1}" | tr -d '[:space:]'
}
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
  case "${key-}" in
  distributionUrl) distributionUrl=$(trim "${value-}") ;;
  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
  esac
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
  *)
    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
    distributionPlatform=linux-amd64
    ;;
  esac
  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
  ;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
  exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
  trap clean HUP INT TERM EXIT
else
  die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
  distributionUrl="${distributionUrl%.zip}.tar.gz"
  distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
  verbose "Found wget ... using wget"
  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
  verbose "Found curl ... using curl"
  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
  verbose "Falling back to use Java to download"
  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
  cat >"$javaSource" <<-END
    public class Downloader extends java.net.Authenticator
    {
      protected java.net.PasswordAuthentication getPasswordAuthentication()
      {
        return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
      }
      public static void main( String[] args ) throws Exception
      {
        setDefault( new Downloader() );
        java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
      }
    }
    END
  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
  verbose " - Compiling Downloader.java ..."
  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
  verbose " - Running Downloader.java ..."
  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
  distributionSha256Result=false
  if [ "$MVN_CMD" = mvnd.sh ]; then
    echo "Checksum validation is not supported for maven-mvnd." >&2
    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
    exit 1
  elif command -v sha256sum >/dev/null; then
    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
      distributionSha256Result=true
    fi
  elif command -v shasum >/dev/null; then
    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
      distributionSha256Result=true
    fi
  else
    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
    exit 1
  fi
  if [ $distributionSha256Result = false ]; then
    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
    exit 1
  fi
fi
# unzip and move
if command -v unzip >/dev/null; then
  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/mvnw.cmd
New file
@@ -0,0 +1,149 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements.  See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership.  The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License.  You may obtain a copy of the License at
@REM
@REM    https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied.  See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.2
@REM
@REM Optional ENV vars
@REM   MVNW_REPOURL - repo url base for downloading maven distribution
@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
  $VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
  "maven-mvnd-*" {
    $USE_MVND = $true
    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
    $MVN_CMD = "mvnd.cmd"
    break
  }
  default {
    $USE_MVND = $false
    $MVN_CMD = $script -replace '^mvnw','mvn'
    break
  }
}
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
if ($env:MAVEN_USER_HOME) {
  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
}
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
  exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
  if ($TMP_DOWNLOAD_DIR.Exists) {
    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
  }
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
  if ($USE_MVND) {
    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
  }
  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
  }
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
try {
  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
    Write-Error "fail to move MAVEN_HOME"
  }
} finally {
  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/pom.xml
New file
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>pipIrr-web</artifactId>
        <groupId>com.dy</groupId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <packaging>jar</packaging>
    <artifactId>pipIrr-mwTest-rtu</artifactId>
    <version>1.0.0</version>
    <name>pipIrr-mwTest-rtu</name>
    <description>模拟RTU(靳总协议)</description>
    <dependencies>
    </dependencies>
    <build>
        <plugins>
            <!-- 生成不包含依赖jar的可执行jar包
            <plugin>
                !- spring boot提供的maven打包插件 -
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        !-
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        -
                        <configuration>
                            !- 不加的话最终包名为: ${artifactId}-${version}.jar, 加了的话最终包名: ${artifactId}-${version}-${classifier}.jar  -
                            <classifier>execute</classifier>
                            !- 不指定生成路径的话, 默认保存在 ${build.directory} 下 -
                            <outputDirectory>${project.build.directory}/execute</outputDirectory>
                            <finalName>${artifactId}-${version}</finalName>
                            <layout>ZIP</layout>
                            <mainClass>com.dy.pipIrrBase.PipIrrBaseApplication</mainClass>
                            <includes>
                                <include>
                                    <groupId>com.dy</groupId>
                                    <artifactId>pipIrr-common</artifactId>
                                </include>
                                <include>
                                    <groupId>com.dy</groupId>
                                    <artifactId>pipIrr-global</artifactId>
                                </include>
                            </includes>
                            <excludes>
                                <exclude>
                                    <groupId>org.projectlombok</groupId>
                                    <artifactId>lombok</artifactId>
                                </exclude>
                            </excludes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            -->
            <!-- 拷贝依赖的jar包到lib目录-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <configuration>
                            <!-- 不加的话最终包名为: ${artifactId}-${version}.jar, 加了的话最终包名: ${artifactId}-${version}-${classifier}.jar
                            <classifier>execute</classifier>
                            -->
                            <!-- ${project.build.directory}是maven变量,内置的,表示target目录,如果不写,将在根目录下创建/lib -->
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                            <!-- excludeTransitive:是否不包含间接依赖包,比如我们依赖A,但是A又依赖了B,我们是否也要把B打进去 默认不打-->
                            <excludeTransitive>false</excludeTransitive>
                            <!-- 复制的jar文件去掉版本信息 -->
                            <stripVersion>false</stripVersion>
                            <finalName>${project.artifactId}-${project.version}</finalName>
                            <layout>ZIP</layout>
                            <mainClass>com.dy.rtuMw.PipIrrMwAcceptApplication</mainClass>
                            <includes>
                                <include>
                                    <groupId>com.dy</groupId>
                                    <artifactId>pipIrr-common</artifactId>
                                </include>
                                <include>
                                    <groupId>com.dy</groupId>
                                    <artifactId>pipIrr-global</artifactId>
                                </include>
                            </includes>
                            <excludes>
                                <exclude>
                                    <groupId>org.projectlombok</groupId>
                                    <artifactId>lombok</artifactId>
                                </exclude>
                            </excludes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <!-- 设置java编译版本,运行环境版本 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <!-- source: 源代码编译版本;target: 目标平台编译版本;encoding: 字符集编码。 -->
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <!-- 解决资源文件的编码问题 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>${encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <!-- maven里执行测试用例的插件 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <!-- 下面解决:当进行Maven Lifecycle package时报错:Could not find artifact org.apache.mina:mina-core:bundle:2.2.1 in maven (https://repo1.maven.org/maven2/)-->
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
</project>
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/AdapterImp_TcpClUnit.java
New file
@@ -0,0 +1,19 @@
package com.dy.pipIrrMwTestRtu;
import com.dy.pipIrrMwTestRtu.tcpClient.TcpClUnitAdapter;
import com.dy.pipIrrMwTestRtu.tcpClient.TcpClUnitConfigVo;
public class AdapterImp_TcpClUnit implements TcpClUnitAdapter {
    private TcpClUnitConfigVo configVo ;
    public TcpClUnitConfigVo getConfig() {
        return configVo;
    }
    public void setConfig(TcpClUnitConfigVo configVo){
        this.configVo = configVo ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/PipIrrMwTestRtuApplication.java
New file
@@ -0,0 +1,33 @@
package com.dy.pipIrrMwTestRtu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) //禁止启动数据库连接池
@ComponentScan(basePackages = {"com.dy.common", "com.dy.pipIrrGlobal", "com.dy.pipIrrMwTestRtu"},
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
                        com.dy.common.apiDoc.SpringApiConfig.class //一种排除类的方式
                }),
                @ComponentScan.Filter(type = FilterType.REGEX, pattern = {
                        //二种排除类的方式,写正则表达式,需要对目标类的完全限定名完全匹配,否则不生效
                        "com.dy.common.aop..*",
                        "com.dy.common.apiDoc..*",
                        "com.dy.common.multiDataSource..*",
                        "com.dy.common.mybatis..*",
                        "com.dy.common.singleDataSource..*",
                        "com.dy.common.webFilter..*",
                        "com.dy.common.webListener..*"
                })
        }
)
public class PipIrrMwTestRtuApplication{
    public static void main(String[] args) {
        SpringApplication.run(PipIrrMwTestRtuApplication.class, args);
    }
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalCodecFactory.java
New file
@@ -0,0 +1,35 @@
package com.dy.pipIrrMwTestRtu.tcpClient;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
public class LocalCodecFactory implements ProtocolCodecFactory {
    private ProtocolEncoder encoder;
    private ProtocolDecoder decoder;
    public LocalCodecFactory() {
        encoder = new LocalEncoder();
        decoder = new LocalDecoder();
    }
    /**
     * 得到协议编码器
     * @param ioSession 网络会话
     * @return 协议编码器
     */
    @Override
    public ProtocolEncoder getEncoder(IoSession ioSession) {
        return encoder;
    }
    /**
     * 得到协议解码器
     * @param ioSession 网络会话
     * @return 协议解码器
     */
    @Override
    public ProtocolDecoder getDecoder(IoSession ioSession) {
        return decoder;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalDecoder.java
New file
@@ -0,0 +1,37 @@
package com.dy.pipIrrMwTestRtu.tcpClient;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import java.io.IOException;
public class LocalDecoder extends CumulativeProtocolDecoder {
    private static final Logger log = LogManager.getLogger(LocalDecoder.class) ;
    private static final String DECODER_STATE_KEY = LocalDecoder.class.getName() + ".STATE";
    public static final int MAX_SIZE = 2147483647 ;
    /**
     * 对网络传输来的数据进行解码
     */
    protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws IOException, Exception{
        int remain = in.remaining() ;
        if(remain > 0){
            byte[] preByte = new byte[remain];
            in.get(preByte) ;
            in.position(0) ;
            log.info("收到中心下行数据:" + ByteUtil.bytes2Hex(preByte, true));
        }
        return true;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalEncoder.java
New file
@@ -0,0 +1,27 @@
package com.dy.pipIrrMwTestRtu.tcpClient;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import java.io.IOException;
public class LocalEncoder extends ProtocolEncoderAdapter {
    private static final Logger log = LogManager.getLogger(LocalEncoder.class) ;
    /**
     * 对数据进行编码,以备网络传输
     */
    public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws IOException, Exception{
        byte[] data = (byte[])message;
        log.info("下行数据:" + ByteUtil.bytes2Hex(data, true));
        out.write(IoBuffer.allocate((data==null?0:data.length), false).put(data).flip());
    }
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpClUnitAdapter.java
New file
@@ -0,0 +1,7 @@
package com.dy.pipIrrMwTestRtu.tcpClient;
import com.dy.common.mw.UnitAdapterInterface;
public interface TcpClUnitAdapter extends UnitAdapterInterface {
    public TcpClUnitConfigVo getConfig() ;
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpClUnitConfigVo.java
New file
@@ -0,0 +1,6 @@
package com.dy.pipIrrMwTestRtu.tcpClient;
public class TcpClUnitConfigVo {
    public String  mwServerIp ;
    public Integer  mwServerPort ;
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpConnect.java
New file
@@ -0,0 +1,62 @@
package com.dy.pipIrrMwTestRtu.tcpClient;
import com.dy.common.util.Callback;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import java.net.InetSocketAddress;
public class TcpConnect {
     /**
     * 判断会话是否有效
     * @param se 网络会话
     * @return 是否连接
     */
    public boolean isConnected(IoSession se) {
        return (se != null && se.isConnected());
    }
    /**
     * 创建新会话
     * @param host 服务器URI
     * @param port 服务器端口
     * @param connectTimeout 连接超时时长
     * @param handler 数据处理者
     * @param callback 回调
     * @return 网络会话
     */
    public void createSession(String host ,
                               int port ,
                               int connectTimeout ,
                               TcpHandler handler,
                               Callback callback) throws Exception{
        SocketConnector connector = new NioSocketConnector();
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new LocalCodecFactory()));
        connector.setHandler(handler);
        ConnectFuture connectFuture = connector.connect(new InetSocketAddress(host, port));
        connectFuture.awaitUninterruptibly(connectTimeout);
        IoSession se = connectFuture.getSession();
        callback.call(se) ;
    }
    /**
     * 关闭会话联接
     * @param se
     * @param connectTimeout
     */
    public void disconnect(IoSession se , int connectTimeout) {
        if (se != null) {
            try{
                se.closeNow().awaitUninterruptibly(connectTimeout);
            }catch(Exception e){
            }finally{
                se = null;
            }
        }
    }
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpHandler.java
New file
@@ -0,0 +1,77 @@
package com.dy.pipIrrMwTestRtu.tcpClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.FilterEvent;
public class TcpHandler extends IoHandlerAdapter {
    private static Logger log = LogManager.getLogger(TcpHandler.class.getName()) ;
    /**
     * {@inheritDoc}
     */
    @Override
    public void sessionCreated(IoSession session) throws Exception {
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void sessionOpened(IoSession session) throws Exception {
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void sessionClosed(IoSession session) throws Exception {
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void inputClosed(IoSession session) throws Exception {
        session.closeNow();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void event(IoSession session, FilterEvent event) throws Exception {
    }
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/Config.xml
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <server name="RTU模拟" showStartInfo="true" company="http://www.dyjs.com"/>
    <!--
    enable:是否启动
     -->
    <tcpCl mwServerIp="127.0.0.1" mwServerPort="60000" />
</config>
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/application.yml
New file
@@ -0,0 +1,29 @@
logging:
    charset:
        console: UTF-8
    config:
        classpath: log4j2.yml
#web服务端口,tomcat默认是8080
server:
    error:
        whitelabel:
            enabled: false
    port: 65534
    servlet:
        context-path: /rtu #web访问上下文路径
        encoding:
            #取消默认的字符集编码
            enabled: true
            #设置强制使用指定字符编码集
            force: true
            #使用的字符编码
            charset: utf-8
#禁止启动数据库连接池
spring:
    #autoconfigure:
    #    exclude:
    #        - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
    #        - org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
    #        - org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/log4j2.xml
New file
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="OFF">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout charset="GBK" pattern="%d %-5p [%t] (%F:%L) - %m%n%throwable"/>
    </Console>
    <!--
        fileName="${sys:user.home}/logs/aepTest.log" filePattern="${sys:user.home}/logs/aepTest-%d{yyyy-MM}-%i.log.gz"
        fileName="/logs/testJgroups.log" filePattern="/logs/testJgroups-%d{yyyyMMdd}-%i.log.gz"
        fileName="logs/testJgroups.log" filePattern="logs/testJgroups-%d{yyyyMMdd}-%i.log.gz"
        sys:user.home当前用户在操作系统中的文档目录
        /logs/testJgroups.log当前软件所在硬盘根目录
        logs/testJgroups.log当前软件所在目录
     -->
    <RollingFile name="File" fileName="logs/mwRtu.log" filePattern="logs/mwRtu-%d{yyyyMMdd}-%i.log">
      <PatternLayout charset="UTF-8" pattern="%d %-5p [%t] (%class.%method:%L) - %m%n%throwable"/>
      <Policies>
        <TimeBasedTriggeringPolicy interval="7" />
        <SizeBasedTriggeringPolicy size="10MB"/>
      </Policies>
      <DefaultRolloverStrategy max="50" />
    </RollingFile>
  </Appenders>
  <Loggers>
      <!--
      <Logger name="com.zhzc.jgTest" level="debug">
      <AppenderRef ref="Console"/>
    </Logger>
      <Logger name="org.jgroups" level="info">
      <AppenderRef ref="File"/>
    </Logger>
      -->
    <!-- Root与各个Logger同时起作用 -->
    <Root level="info">
      <AppenderRef ref="Console"/>
      <AppenderRef ref="File"/>
    </Root>
  </Loggers>
</Configuration>
pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/test/java/com/dy/pipIrrMwTestRtu/PipIrrMwTestRtuApplicationTests.java
New file
@@ -0,0 +1,13 @@
package com.dy.pipIrrMwTestRtu;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class PipIrrMwTestRtuApplicationTests {
    @Test
    void contextLoads() {
    }
}
pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/pom.xml
@@ -13,7 +13,7 @@
    <packaging>jar</packaging>
    <artifactId>pipIrr-mwTest-web</artifactId>
    <version>1.0.0</version>
    <name>pipIrr-mw-rtu</name>
    <name>pipIrr-mwTest-web</name>
    <description>通信中间件中心服务端下发命令测试</description>
    <dependencies>
pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/src/main/java/com/dy/pipIrrMwTestWeb/PipIrrMwTestWebApplication.java
@@ -28,9 +28,6 @@
)
public class PipIrrMwTestWebApplication{
    @Autowired
    private CommandP206V202404Ctrl test ;
    public static void main(String[] args) {
        SpringApplication.run(PipIrrMwTestWebApplication.class, args);
    }
pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/src/main/java/com/dy/pipIrrMwTestWeb/p206V1_0_0/ComSupportP206V1_0_0.java
@@ -23,7 +23,7 @@
    protected static String rtuAddr = "532328059995" ;
    protected static String rtuResultSendWebUrl = "http://127.0.0.1:65535/test/comRes/receive" ;
    protected static String vsIcCardNo = "7044010666" ;//虚拟IC卡编号(用户虚拟卡序列号)
    protected static String vsIcCardNo = "61181622830147822" ;//虚拟IC卡编号(用户虚拟卡序列号)
    @Autowired
pipIrr-platform/pipIrr-web/pom.xml
@@ -18,6 +18,7 @@
    <description>此模块为其他web模块的局部全局模块,只定义依赖</description>
    <modules>
        <module>pipIrr-mwTest-rtu</module>
        <module>pipIrr-mwTest-web</module>
        <module>pipIrr-web-sso</module>
        <module>pipIrr-web-base</module>