1、增加流浪控制器实体(和数据库表);
2、修改部分通信协议实现;
3、增加部分通信协议实现;
4、增加通信中间件RTU上行数据处理任务树部分节点。
16个文件已修改
18个文件已添加
1374 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CodeV1_0_1.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CommonV1_0_1.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd65Vo.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd81Vo.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd83CloseVo.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd83OpenVo.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd84Vo.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd97Vo.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd98Vo.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataV1_0_1.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/ProtocolConstantV206V1_0_0.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_21_Down.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_65_Down.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_65_Up.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_81_Down.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_81_Up.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_83_Up.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_84_Up.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_92_Down.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_93_Down.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Down.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Up.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Down.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Up.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_C0_Up.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrControllerTrampMapper.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrControllerTramp.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrControllerTrampMapper.xml 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/TkRtuData.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/dbSv/DbSv.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/p206V1_0_0/TkDealControllerTramp.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/p206V1_0_0/TkFindReport.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/p206V1_0_0/TkPreGenObjs.java 79 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/resources/RtuDataDealTree.xml 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CodeV1_0_1.java
@@ -6,12 +6,16 @@
    public static final String cd_10 = "10" ;//设置遥测站终端地址
    public static final String cd_21 = "21" ;//设置服务端IP和端口
    public static final String cd_50 = "50" ;//查询遥测站终端地址
    public static final String cd_65 = "65" ;//查询IP和端口
    public static final String cd_66 = "66" ;//查询阀门状态(靳总把该命令设计成召测83功能码数据的命令了,因为这个命令回执没有阀门状态数据域,所以这个命令只能作为召测命令用了)
    public static final String cd_71 = "71" ;//设置工作模式(李天赐制定的协议,当前未实现)
    public static final String cd_81 = "81" ;//随机自报报
    public static final String cd_83 = "83" ;//遥测站开关阀自报
    public static final String cd_84 = "84" ;//开阀工作报
    public static final String cd_92 = "92" ;//遥控启动阀门
    public static final String cd_93 = "93" ;//遥控关闭阀门
    public static final String cd_97 = "97" ;//APP远程开阀
    public static final String cd_98 = "98" ;//APP远程关阀
    public static final String cd_C0 = "C0" ;//遥测站自报实时数据
    public static String getCodeName(String code) {
@@ -19,14 +23,18 @@
            (code.equals(cd_10) ? "设置遥测站终端地址" :
            (code.equals(cd_21) ? "设置IP和端口" :
            (code.equals(cd_50) ? "查询遥测站终端地址" :
            (code.equals(cd_65) ? "查询IP和端口" :
            (code.equals(cd_66) ? "查询阀门状态" :
            (code.equals(cd_71) ? "设置工作模式" :
            (code.equals(cd_81) ? "随机自报" :
            (code.equals(cd_83) ? "开关阀自报" :
            (code.equals(cd_84) ? "开阀工作报" :
            (code.equals(cd_92) ? "遥控启动阀门" :
            (code.equals(cd_93) ? "遥控关闭阀门" :
            (code.equals(cd_97) ? "APP远程开阀" :
            (code.equals(cd_98) ? "PP远程关阀" :
            (code.equals(cd_C0) ? "自报实时数据" :
            ""))))))))))) ;
            ""))))))))))))))) ;
        return name ;
    }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CommonV1_0_1.java
@@ -82,7 +82,7 @@
    public String parseRtuAddr(byte[] bs)throws Exception{
        String rtuAddrBCD = "" + ByteUtil.BCD2Long_BE(bs, ProtocolConstantV206V1_0_0.rtuAddr1Index_start, ProtocolConstantV206V1_0_0.rtuAddr1Index_end) ;
        String rtuAddrStr = "" + ByteUtilUnsigned.bytes2Short_BE(bs, ProtocolConstantV206V1_0_0.rtuAddr2Index_start) ;
        while(rtuAddrStr.length() < 4){
        while(rtuAddrStr.length() < 5){
            rtuAddrStr = "0" + rtuAddrStr ;
        }
        return rtuAddrBCD + rtuAddrStr ;
@@ -99,7 +99,7 @@
    public String parseRtuAddr(byte[] bs, int index)throws Exception{
        String rtuAddrBCD = "" + ByteUtil.BCD2Long_BE(bs, index, index + 2) ;
        String rtuAddrStr = "" + ByteUtilUnsigned.bytes2Short_BE(bs, index + 3) ;
        while(rtuAddrStr.length() < 4){
        while(rtuAddrStr.length() < 5){
            rtuAddrStr = "0" + rtuAddrStr ;
        }
        return rtuAddrBCD + rtuAddrStr ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd65Vo.java
New file
@@ -0,0 +1,21 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import lombok.Data;
@Data
public class DataCd65Vo {
    public String ip ;//IP地址
    public Integer port ;//端口号
    public String toString(){
        StringBuilder sb = new StringBuilder() ;
        sb.append("   查询IP地址和端口:\n");
        sb.append("      IP地址:");
        sb.append(ip);
        sb.append("\n");
        sb.append("      端口号:");
        sb.append(port==null?"":port);
        sb.append("\n");
        return sb.toString() ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd81Vo.java
New file
@@ -0,0 +1,23 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import lombok.Data;
@Data
public class DataCd81Vo {
    public DataAlarmVo alarmVo ;//报警
    public DataStateVo stateVo ;//状态
    public String toString(){
        StringBuilder sb = new StringBuilder() ;
        sb.append("   终端随机自报数据:\n");
        if(alarmVo != null){
            sb.append(alarmVo.toString());
            sb.append("\n");
        }
        if(stateVo != null){
            sb.append(stateVo.toString());
            sb.append("\n");
        }
        return sb.toString() ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd83CloseVo.java
@@ -9,7 +9,7 @@
    // 6、流量计故障关阀;7、紧急关阀;8、用户远程开阀;9、用户远程关阀;
    public Byte type ;
    public Double totalAmount; //累计流量:5字节BCD码,取值范围0~9999999999,单位为m3。
    public String clientNum ;//农户编号
    public String cardNo ;//IC卡编号
    public String icAddr ;//ic卡地址
    public Double remainMoney ;//剩余金额:用户余额4字节BCD码,取值范围0.00~999999.99,单位为元
    public String openDt ;//用水户用水开始时间:6字节BCD码,顺序是年月日时分秒,其中公元年=2000+年。
@@ -28,8 +28,8 @@
        sb.append("      累计流量:");
        sb.append(totalAmount==null?"":totalAmount);
        sb.append("\n");
        sb.append("      农户编号:");
        sb.append(clientNum);
        sb.append("      IC卡编号:");
        sb.append(cardNo);
        sb.append("\n");
        sb.append("      ic卡地址:");
        sb.append(icAddr);
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd83OpenVo.java
@@ -11,7 +11,7 @@
    // 16,用户开阀后管道内没有水,自动关阀。管道不出水自动关阀
    public Byte type ;
    public Double totalAmount; //累计流量:5字节BCD码,取值范围0~9999999999,单位为m3。
    public String clientNum ;//农户编号
    public String cardNo ;//IC卡编号
    public String icAddr ;//ic卡地址
    public Double remainMoney;//剩余金额:用户余额4字节BCD码,取值范围0.00~999999.99,单位为元
    public String openDt ;//用水户开阀时间:6字节BCD码,顺序是年月日时分秒,其中公元年=2000+年。
@@ -26,8 +26,8 @@
        sb.append("      累计流量:");
        sb.append(totalAmount==null?"":totalAmount);
        sb.append("\n");
        sb.append("      农户编号:");
        sb.append(clientNum);
        sb.append("      IC卡编号:");
        sb.append(cardNo);
        sb.append("\n");
        sb.append("      ic卡地址:");
        sb.append(icAddr);
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd84Vo.java
@@ -4,7 +4,7 @@
@Data
public class DataCd84Vo {
    public String clientNum ;//农户编号
    public String cardNo ;//IC卡编号
    public Double remainMoney ;//剩余金额:用户余额4字节BCD码,取值范围0.00~999999.99,单位为元
    public Double totalAmount; //累计流量:5字节BCD码,取值范围0~9999999999,单位为m3。
    public Double instantAmount; //瞬时流量:5字节BCD码,取值范围0~9999999.999,单位为m3/h。
@@ -13,8 +13,8 @@
    public String toString(){
        StringBuilder sb = new StringBuilder() ;
        sb.append("   终端开阀工作报:\n");
        sb.append("      农户编号:");
        sb.append(clientNum);
        sb.append("      IC卡编号:");
        sb.append(cardNo);
        sb.append("\n");
        sb.append("      剩余金额(元):");
        sb.append(remainMoney==null?"":remainMoney);
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd97Vo.java
New file
@@ -0,0 +1,27 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import lombok.Data;
/**
 * @Author liurunyu
 * @Date 2024/01/13 10:08
 * @LastEditTime 2024/01/13 10:08
 * @Description
 */
@Data
public class DataCd97Vo {
    public String cardNo ;//虚拟卡号
    public boolean success;
    public String toString(){
        StringBuilder sb = new StringBuilder() ;
        sb.append("   APP远程开阀应答:\n");
        sb.append("      虚拟卡号:");
        sb.append(cardNo);
        sb.append("      结果:");
        sb.append(success?"执行":"失败");
        sb.append("\n");
        return sb.toString() ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd98Vo.java
New file
@@ -0,0 +1,27 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import lombok.Data;
/**
 * @Author liurunyu
 * @Date 2024/01/13 10:08
 * @LastEditTime 2024/01/13 10:08
 * @Description
 */
@Data
public class DataCd98Vo {
    public String cardNo ;//虚拟卡号
    public boolean success;
    public String toString(){
        StringBuilder sb = new StringBuilder() ;
        sb.append("   APP远程开阀应答:\n");
        sb.append("      虚拟卡号:");
        sb.append(cardNo);
        sb.append("      结果:");
        sb.append(success?"执行":"失败");
        sb.append("\n");
        return sb.toString() ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataV1_0_1.java
@@ -12,12 +12,16 @@
    public DataCd02Vo dataCd02Vo;//链路检测
    public DataCd10Vo dataCd10Vo;//设置RTU地址
    public DataCd21Vo dataCd21Vo;//设置IP地址
    public DataCd65Vo dataCd65Vo;//查询IP地址和端口
    public DataCd71Vo dataCd71Vo;//查询阀门状态
    public DataCd81Vo dataCd81Vo;//随机自报报
    public DataCd83OpenVo dataCd83OpenVo;//开阀自报
    public DataCd83CloseVo dataCd83CloseVo;//关阀自报
    public DataCd84Vo dataCd84Vo;//开阀工作报
    public DataCd92Vo dataCd92Vo;//开阀应答
    public DataCd93Vo dataCd93Vo;//关阀应答
    public DataCd97Vo dataCd97Vo;//APP远程开阀应答
    public DataCd98Vo dataCd98Vo;//APP远程关阀应答
    public DataCdC0Vo dataCdC0Vo;//终端自报实时数据
    public String dt ;//通信中间件产生发报时间(yyyy-MM-dd hh:mm:ss)
@@ -35,8 +39,14 @@
        if(dataCd21Vo != null){
            sb.append(dataCd21Vo.toString()) ;
        }
        if(dataCd65Vo != null){
            sb.append(dataCd65Vo.toString()) ;
        }
        if(dataCd71Vo != null){
            sb.append(dataCd71Vo.toString()) ;
        }
        if(dataCd81Vo != null){
            sb.append(dataCd81Vo.toString()) ;
        }
        if(dataCd83OpenVo != null){
            sb.append(dataCd83OpenVo.toString()) ;
@@ -53,6 +63,12 @@
        if(dataCd93Vo != null){
            sb.append(dataCd93Vo.toString()) ;
        }
        if(dataCd97Vo != null){
            sb.append(dataCd97Vo.toString()) ;
        }
        if(dataCd98Vo != null){
            sb.append(dataCd98Vo.toString()) ;
        }
        if(dataCdC0Vo != null){
            sb.append(dataCdC0Vo.toString()) ;
        }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/ProtocolConstantV206V1_0_0.java
@@ -28,7 +28,8 @@
    public static final byte P_Head_Byte = (byte)0x68 ;
    public static final byte P_Tail_Byte = (byte)0x16 ;
    public static final byte P_Default_mode = (byte)0x0F ;//默认工作模式
    //00H时遥测终端在兼容工作状态;01H时遥测终端在自报工作状态;02H时遥测终端在查询/应答工作状态;03H时遥测终端在调试/维修状态。
    public static final byte P_Default_mode = (byte)0x00 ;//默认工作模式
    public static final String P_Head_Hex = "68" ;
    public static final String P_Tail_Hex = "16" ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_21_Down.java
@@ -73,6 +73,9 @@
        ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ;
        /*
        参数格式: ip1,ip2,ip3,ip4,port
         */
        if(para.param == null){
            throw new Exception("未提供命令参数数据,不能构造功能码为" + CodeV1_0_1.cd_21 + "的下行命令") ;
        }else{
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_65_Down.java
New file
@@ -0,0 +1,88 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.CodeV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.CommonV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ParseParamsForDownV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0;
import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlCreate;
import com.dy.common.util.ByteUtil;
/**
 * @Author liurunyu
 * @Date 2024/01/13 10:47
 * @LastEditTime 2024/01/13 10:47
 * @Description
 */
@AnnotationCodeDown(ifAny={
        CodeV1_0_1.cd_65
})
public class Cd_65_Down implements CodeParse {
    //private static Logger log = LogManager.getLogger(Cd_66_Down.class);
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback) throws Exception {
        ParseParamsForDownV1_0_1 para = (ParseParamsForDownV1_0_1) params ;
        byte[] bs = this.doParse(para) ;
        MidResultToRtu midRs = new MidResultToRtu() ;
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;//rtu返回命令结果 发向目的地web URL
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址(电信平台设备IMEI)
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downBuffer = bs ;//下行命令数据
        midRs.downBufHex = ByteUtil.bytes2Hex(bs, true) ;//下行命令数据十六进制形式
        midRs.hasResponse = true ;//是否有应答
        midRs.maxSendTimes = null ;//命令最大发送次数(当收不到应答时,将重发),如果不设置,命令缓存器进行补充设置
        midRs.isCachForOffLine = false ;//RTU不在线,命令是否缓存,低功耗时为true
        if(isLowPower != null && isLowPower.booleanValue()){
            //低功耗时,尽快发送
            midRs.isQuickSend = true ;
        }
        return new MidResult[]{midRs} ;
    }
    /**
     * 构造下行数据
     * @param para 参数
     * @return 字节数组
     * @throws Exception 异常
     */
    public byte[] doParse(ParseParamsForDownV1_0_1 para) throws Exception {
        CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ;
        byte[] bytes ;
        byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ;
        byte index = 0 ;
        bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ;
        index++ ;
        bsHead[index] = 0 ;//帧长度
        index++ ;
        bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ;
        index++ ;
        bsHead[index] = commonV1_0_1.createCtrl((byte)0, (byte)0) ;
        index++ ;
        GlCreate.createRtuAddr(para.rtuAddr, bsHead, index);
        index += 5 ;
        ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ;
        bytes = bsHead ;
        GlCreate.createLen(bytes);//长度放字节数组中
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
        return bytes ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_65_Up.java
New file
@@ -0,0 +1,75 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.*;
import com.dy.common.util.ByteUtilUnsigned;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
 * @Author liurunyu
 * @Date 2024/01/13 10:40
 * @LastEditTime 2024/01/13 10:40
 * @Description
 */
@AnnotationCodeUp(ifAny={
        CodeV1_0_1.cd_65
})
@SuppressWarnings("unused")
public class Cd_65_Up implements CodeParse {
    private static final Logger log = LogManager.getLogger(Cd_65_Up.class);
    /**
     * 分析上行数据
     */
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback)throws Exception {
        ParseParamsForUpV1_0_1 para = (ParseParamsForUpV1_0_1)params ;
        int bsLen = new CommonV1_0_1().parseDataLen(para.upBuffer) ;
        if(bsLen > 0){
            this.doParse(para.upBuffer,
                    bsLen,
                    para.upCode,
                    para.data) ;
        }
        log.info("分析命令应答数据<" + CodeV1_0_1.getCodeName(para.upCode) + " RTU地址=" + para.rtuAddr + ">:\n" + para.data.toString());
        MidResultFromRtu midRs = new MidResultFromRtu() ;
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.upCode = para.upCode ;//上行数据中的功能码
        midRs.upHex = para.upHex ;//上行数据十六进制形式
        midRs.upBuffer = para.upBuffer ;//上行数据字节数组
        midRs.data = para.data ;//解析后的数据
        midRs.reportOrResponse_trueOrFalse = false ;//命令应答
        callback.callback(midRs.reportOrResponse_trueOrFalse);
        return new MidResult[]{midRs} ;
    }
    /**
     * 执行分析
     * @param bs 字节数组
     * @param bsLen 字节长度(总包长,包括包头和包尾)
     * @param dataCode 功能码
     * @param data 数据
     * @throws Exception 异常
     */
    protected void doParse(byte[] bs, int bsLen, String dataCode, Data data) throws Exception {
        DataV1_0_1 dV1 = (DataV1_0_1)data.getSubData() ;
        DataCd65Vo cdData = new DataCd65Vo() ;
        dV1.dataCd65Vo = cdData ;
        short index = ProtocolConstantV206V1_0_0.dataIndex ;
        String ip1 = "" + ByteUtilUnsigned.byte2Byte(bs, index++) ;
        String ip2 = "" +ByteUtilUnsigned.byte2Byte(bs, index++) ;
        String ip3 = "" +ByteUtilUnsigned.byte2Byte(bs, index++) ;
        String ip4 = "" +ByteUtilUnsigned.byte2Byte(bs, index++) ;
        cdData.ip = ip1 + "." + ip2 + "." + ip3 + "." + ip4 ;
        String port = "" +ByteUtilUnsigned.bytes2Short_LE(bs, index++) ;
        cdData.port = Integer.parseInt(port) ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_81_Down.java
New file
@@ -0,0 +1,89 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.CodeV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.CommonV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ParseParamsForDownV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0;
import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlCreate;
import com.dy.common.util.ByteUtil;
@AnnotationCodeDown(ifAny={
        CodeV1_0_1.cd_81
})
public class Cd_81_Down implements CodeParse {
    //private static Logger log = LogManager.getLogger(Cd_C0_Down.class);
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback) throws Exception {
        ParseParamsForDownV1_0_1 para = (ParseParamsForDownV1_0_1) params ;
        byte[] bs = this.doParse(para) ;
        MidResultToRtu midRs = new MidResultToRtu() ;
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;//rtu返回命令结果 发向目的地web URL
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址(电信平台设备IMEI)
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downBuffer = bs ;//下行命令数据
        midRs.downBufHex = ByteUtil.bytes2Hex(bs, true) ;//下行命令数据十六进制形式
        midRs.hasResponse = false ;//是否有应答
        midRs.maxSendTimes = 1 ;//命令最大发送次数(当收不到应答时,将重发),如果不设置,命令缓存器进行补充设置
        midRs.isCachForOffLine = false ;//RTU不在线,命令是否缓存,低功耗时为true
        midRs.isSendFirst = true ;//命令应答,首先发送,防止RTU重新上报
        if(isLowPower != null && isLowPower.booleanValue()){
            //低功耗时,尽快发送
            midRs.isQuickSend = true ;
        }
        return new MidResult[]{midRs} ;
    }
    /**
     * 构造下行数据
     * @param para 参数
     * @return 字节数组
     * @throws Exception 异常
     */
    public byte[] doParse(ParseParamsForDownV1_0_1 para) throws Exception {
        CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ;
        byte[] bytes ;
        byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ;
        byte index = 0 ;
        bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ;
        index++ ;
        bsHead[index] = 0 ;//帧长度
        index++ ;
        bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ;
        index++ ;
        bsHead[index] = commonV1_0_1.createCtrl((byte)0, (byte)0) ;
        index++ ;
        GlCreate.createRtuAddr(para.rtuAddr, bsHead, index);
        index += 5 ;
        ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ;
        byte[] bs = new byte[1] ;
        //确认帧的数据域用于遥测终端工作模式的确认或转换。数据为 1 个字节 HEX,00H 时遥测终
        //端在兼容工作状态; 01H 时遥测终端在自报工作状态; 02H 时遥测终端在查询/应答工作
        //状态; 03H 时遥测终端在调试/维修状态。
        bs[0] = ProtocolConstantV206V1_0_0.P_Default_mode;//数据域
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        GlCreate.createLen(bytes);//长度放字节数组中
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
        return bytes ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_81_Up.java
New file
@@ -0,0 +1,99 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.*;
import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlParse;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@AnnotationCodeUp(ifAny={
        CodeV1_0_1.cd_81
})
@SuppressWarnings("unused")
public class Cd_81_Up implements CodeParse {
    private static final Logger log = LogManager.getLogger(Cd_81_Up.class);
    /**
     * 分析上行数据
     */
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback)throws Exception {
        ParseParamsForUpV1_0_1 para = (ParseParamsForUpV1_0_1)params ;
        int bsLen = new CommonV1_0_1().parseDataLen(para.upBuffer) ;
        if(bsLen > 0){
            this.doParse(para.upBuffer,
                    bsLen,
                    para.upCode,
                    para.data) ;
        }
        log.info("分析上行数据<" + CodeV1_0_1.getCodeName(para.upCode) + " RTU地址=" + para.rtuAddr + ">:\n" + para.data.toString());
        MidResultFromRtu midRs = new MidResultFromRtu() ;
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.upCode = para.upCode ;//上行数据中的功能码
        midRs.upHex = para.upHex ;//上行数据十六进制形式
        midRs.upBuffer = para.upBuffer ;//上行数据字节数组
        midRs.data = para.data ;//解析后的数据
        midRs.reportOrResponse_trueOrFalse = true ;//主动上报
        String confirmComCode = para.upCode ;
        ParseParamsForDownV1_0_1 downCpParams  = new ParseParamsForDownV1_0_1() ;
        downCpParams.setValue(
                null,
                ProtocolConstantV206V1_0_0.protocolName,
                para.rtuAddr,
                Command.defaultId,
                confirmComCode,
                null,
                null);
        //构造应答
        byte[] data = new Cd_81_Down().doParse(downCpParams) ;
        MidResultToRtu confirmCommand = new MidResultToRtu() ;
        confirmCommand.protocolName = para.protocolName ;//协议名称
        confirmCommand.rtuAddr = para.rtuAddr ;//Rtu地址
        confirmCommand.commandId = Command.defaultId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        confirmCommand.downCode = confirmComCode ;//下行命令功能码;
        confirmCommand.downBuffer = data ;//下行命令数据
        confirmCommand.downBufHex = ByteUtil.bytes2Hex(data, true) ;//下行命令数据十六进制形式
        confirmCommand.hasResponse = false ;//是否有应答
        confirmCommand.maxSendTimes = 1 ;//命令最大发送次数(当收不到应答时,将重发2次),如果不设置,命令缓存器进行补充设置
        confirmCommand.isCachForOffLine = false ;//RTU不在线,命令是否缓存
        confirmCommand.isSendFirst = true ;//确认命令,优先发送
        if(isLowPower != null && isLowPower.booleanValue()){
            //低功耗时,尽快发送
            confirmCommand.isQuickSend = true ;
        }
        callback.callback(midRs.reportOrResponse_trueOrFalse);
        return new MidResult[]{midRs, confirmCommand} ;
    }
    /**
     * 执行分析
     * @param bs 字节数组
     * @param bsLen 字节长度(总包长,包括包头和包尾)
     * @param dataCode 功能码
     * @param data 数据
     * @throws Exception 异常
     */
    protected void doParse(byte[] bs, int bsLen, String dataCode, Data data) throws Exception {
        DataV1_0_1 dV1 = (DataV1_0_1)data.getSubData() ;
        DataCd81Vo cdData = new DataCd81Vo() ;
        dV1.dataCd81Vo = cdData ;
        short index = ProtocolConstantV206V1_0_0.dataIndex ;
        //报警数据
        cdData.alarmVo = GlParse.parseAlarm(bs, index) ;
        index += 2 ;
        //状态数据
        cdData.stateVo = GlParse.parseState(bs, index) ;
        index += 2 ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_83_Up.java
@@ -116,11 +116,11 @@
        cdData.totalAmount += tpInt * 100000000.0 ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.clientNum = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        index += 5 ;
        //IC卡号格式:4字节HEX码低位在前高位在后。
        cdData.clientNum = ByteUtil.bytesToHex(bs, index, index + 3) ;
        cdData.cardNo = ByteUtil.bytesToHex(bs, index, index + 3) ;
        index += 4 ;
        //用水户余额:用户余额4字节BCD码,取值范围0.00~999999.99,单位为元。
@@ -174,11 +174,11 @@
        cdData.totalAmount += tpInt * 100000000.0 ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.clientNum = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        index += 5 ;
        //IC卡号格式:4字节HEX码低位在前高位在后。
        cdData.clientNum = ByteUtil.bytesToHex(bs, index, index + 3) ;
        cdData.cardNo = ByteUtil.bytesToHex(bs, index, index + 3) ;
        index += 4 ;
        //用水户余额:用户余额4字节BCD码,取值范围0.00~999999.99,单位为元。
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_84_Up.java
@@ -88,7 +88,7 @@
        short index = ProtocolConstantV206V1_0_0.dataIndex ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.clientNum = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        index += 5 ;
        //用水户余额:用户余额4字节BCD码,取值范围0.00~999999.99,单位为元。
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_92_Down.java
@@ -72,18 +72,14 @@
        ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ;
        if(para.param == null){
            throw new Exception("未提供命令参数数据,不能构造功能码为" + CodeV1_0_1.cd_92 + "的下行命令") ;
        }else{
            index = 0 ;
            byte[] bs = new byte[9] ;
            bs[index++] = (byte)0xF0 ;
            GlCreate.createPw(bs, index);
            index += 2 ;
            GlCreate.createTp(bs, index);
        byte index1 = 0 ;
        byte[] bs = new byte[9] ;
        bs[index1++] = (byte)0xF0 ;
        GlCreate.createPw(bs, index1);
        index1 += 2 ;
        GlCreate.createTp(bs, index1);
            bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        }
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        GlCreate.createLen(bytes);//长度放字节数组中
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_93_Down.java
@@ -72,18 +72,14 @@
        ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ;
        if(para.param == null){
            throw new Exception("未提供命令参数数据,不能构造功能码为" + CodeV1_0_1.cd_93 + "的下行命令") ;
        }else{
            index = 0 ;
            byte[] bs = new byte[9] ;
            bs[index++] = (byte)0xF0 ;
            GlCreate.createPw(bs, index);
            index += 2 ;
            GlCreate.createTp(bs, index);
        byte index1 = 0 ;
        byte[] bs = new byte[9] ;
        bs[index1++] = (byte)0xF0 ;
        GlCreate.createPw(bs, index1);
        index1 += 2 ;
        GlCreate.createTp(bs, index1);
            bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        }
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        GlCreate.createLen(bytes);//长度放字节数组中
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Down.java
New file
@@ -0,0 +1,111 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.CodeV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.CommonV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ParseParamsForDownV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0;
import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlCreate;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
/**
 * @Author liurunyu
 * @Date 2024/01/12 14:49
 * @LastEditTime 2024/01/12 14:49
 * @Description
 */
@AnnotationCodeDown(ifAny={
        CodeV1_0_1.cd_97
})
public class Cd_97_Down implements CodeParse {
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback) throws Exception {
        ParseParamsForDownV1_0_1 para = (ParseParamsForDownV1_0_1) params ;
        byte[] bs = this.doParse(para) ;
        MidResultToRtu midRs = new MidResultToRtu() ;
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;//rtu返回命令结果 发向目的地web URL
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址(电信平台设备IMEI)
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downBuffer = bs ;//下行命令数据
        midRs.downBufHex = ByteUtil.bytes2Hex(bs, true) ;//下行命令数据十六进制形式
        midRs.hasResponse = true ;//是否有应答
        midRs.maxSendTimes = null ;//命令最大发送次数(当收不到应答时,将重发),如果不设置,命令缓存器进行补充设置
        midRs.isCachForOffLine = false ;//RTU不在线,命令是否缓存,低功耗时为true
        if(isLowPower != null && isLowPower.booleanValue()){
            //低功耗时,尽快发送
            midRs.isQuickSend = true ;
        }
        return new MidResult[]{midRs} ;
    }
    /**
     * 构造下行数据
     * @param para 参数
     * @return 字节数组
     * @throws Exception 异常
     */
    public byte[] doParse(ParseParamsForDownV1_0_1 para) throws Exception {
        CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ;
        byte[] bytes ;
        byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ;
        byte index = 0 ;
        bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ;
        index++ ;
        bsHead[index] = 0 ;//帧长度
        index++ ;
        bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ;
        index++ ;
        bsHead[index] = commonV1_0_1.createCtrl((byte)0, (byte)0) ;
        index++ ;
        GlCreate.createRtuAddr(para.rtuAddr, bsHead, index);
        index += 5 ;
        ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ;
        /*
        参数格式:  虚拟卡号,电子钱包余额,水价
         */
        String param = (String)para.param ;
        if(param == null || param.trim().equals("")){
            throw new Exception("未提供命令参数数据,不能构造功能码为" + CodeV1_0_1.cd_97 + "的下行命令") ;
        }else{
            String[] params = ((String)para.param).split(",") ;
            if(params == null || params.length != 3){
                throw new Exception("命令参数数据不正确,不能构造功能码为" + CodeV1_0_1.cd_97 + "的下行命令") ;
            }else{
                byte index1 = 0 ;
                byte[] bs = new byte[11] ;
                ByteUtil.string2BCD_LE(bs, params[0], 0) ;
                Integer money = (Double.valueOf(Double.parseDouble(params[1]) * 100)).intValue() ;
                ByteUtilUnsigned.int2Bytes_LE(bs, money, 4);
                Short price = (Double.valueOf(Double.parseDouble(params[2]) * 100)).shortValue() ;
                ByteUtilUnsigned.short2Bytes_LE(bs, price, 8);
                bytes = ByteUtil.bytesMerge(bsHead, bs) ;
            }
        }
        GlCreate.createLen(bytes);//长度放字节数组中
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
        return bytes ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Up.java
New file
@@ -0,0 +1,71 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.*;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
 * @Author liurunyu
 * @Date 2024/01/13 8:49
 * @LastEditTime 2024/01/13 8:49
 * @Description
 */
@AnnotationCodeUp(ifAny={
        CodeV1_0_1.cd_97
})
@SuppressWarnings("unused")
public class Cd_97_Up implements CodeParse {
    private static final Logger log = LogManager.getLogger(Cd_97_Up.class);
    /**
     * 分析上行数据
     */
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback)throws Exception {
        ParseParamsForUpV1_0_1 para = (ParseParamsForUpV1_0_1)params ;
        int bsLen = new CommonV1_0_1().parseDataLen(para.upBuffer) ;
        if(bsLen > 0){
            this.doParse(para.upBuffer,
                    bsLen,
                    para.upCode,
                    para.data) ;
        }
        log.info("分析上行数据<" + CodeV1_0_1.getCodeName(para.upCode) + " RTU地址=" + para.rtuAddr + ">:\n" + para.data.toString());
        MidResultFromRtu midRs = new MidResultFromRtu() ;
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.upCode = para.upCode ;//上行数据中的功能码
        midRs.upHex = para.upHex ;//上行数据十六进制形式
        midRs.upBuffer = para.upBuffer ;//上行数据字节数组
        midRs.data = para.data ;//解析后的数据
        midRs.reportOrResponse_trueOrFalse = false ;//主动上报
        callback.callback(midRs.reportOrResponse_trueOrFalse);
        return new MidResult[]{midRs} ;
    }
    /**
     * 执行分析
     * @param bs 字节数组
     * @param bsLen 字节长度(总包长,包括包头和包尾)
     * @param dataCode 功能码
     * @param data 数据
     * @throws Exception 异常
     */
    protected void doParse(byte[] bs, int bsLen, String dataCode, Data data) throws Exception {
        DataV1_0_1 dV1 = (DataV1_0_1)data.getSubData() ;
        DataCd97Vo cdData = new DataCd97Vo() ;
        dV1.dataCd97Vo = 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.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
New file
@@ -0,0 +1,97 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.CodeV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.CommonV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ParseParamsForDownV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0;
import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlCreate;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
/**
 * @Author liurunyu
 * @Date 2024/01/12 14:49
 * @LastEditTime 2024/01/12 14:49
 * @Description
 */
@AnnotationCodeDown(ifAny={
        CodeV1_0_1.cd_98
})
public class Cd_98_Down implements CodeParse {
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback) throws Exception {
        ParseParamsForDownV1_0_1 para = (ParseParamsForDownV1_0_1) params ;
        byte[] bs = this.doParse(para) ;
        MidResultToRtu midRs = new MidResultToRtu() ;
        midRs.rtuResultSendWebUrl = para.rtuResultSendWebUrl ;//rtu返回命令结果 发向目的地web URL
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址(电信平台设备IMEI)
        midRs.commandId = para.commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        midRs.downCode = para.commandCode ;//下行命令功能码;
        midRs.downBuffer = bs ;//下行命令数据
        midRs.downBufHex = ByteUtil.bytes2Hex(bs, true) ;//下行命令数据十六进制形式
        midRs.hasResponse = true ;//是否有应答
        midRs.maxSendTimes = null ;//命令最大发送次数(当收不到应答时,将重发),如果不设置,命令缓存器进行补充设置
        midRs.isCachForOffLine = false ;//RTU不在线,命令是否缓存,低功耗时为true
        if(isLowPower != null && isLowPower.booleanValue()){
            //低功耗时,尽快发送
            midRs.isQuickSend = true ;
        }
        return new MidResult[]{midRs} ;
    }
    /**
     * 构造下行数据
     * @param para 参数
     * @return 字节数组
     * @throws Exception 异常
     */
    public byte[] doParse(ParseParamsForDownV1_0_1 para) throws Exception {
        CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ;
        byte[] bytes ;
        byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ;
        byte index = 0 ;
        bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ;
        index++ ;
        bsHead[index] = 0 ;//帧长度
        index++ ;
        bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ;
        index++ ;
        bsHead[index] = commonV1_0_1.createCtrl((byte)0, (byte)0) ;
        index++ ;
        GlCreate.createRtuAddr(para.rtuAddr, bsHead, index);
        index += 5 ;
        ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ;
         /*
        参数格式:  虚拟卡号
         */
        if(para.param == null ||((String)para.param).trim().equals("")){
            throw new Exception("未提供命令参数数据,不能构造功能码为" + CodeV1_0_1.cd_98 + "的下行命令") ;
        }else{
            byte[] bs = new byte[5] ;
            ByteUtil.string2BCD_LE(bs, ((String)para.param).trim(), 0) ;
            bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        }
        GlCreate.createLen(bytes);//长度放字节数组中
        byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中
        bytes = ByteUtil.bytesMerge(bytes, bsTail) ;
        return bytes ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Up.java
New file
@@ -0,0 +1,71 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.*;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
 * @Author liurunyu
 * @Date 2024/01/13 8:49
 * @LastEditTime 2024/01/13 8:49
 * @Description
 */
@AnnotationCodeUp(ifAny={
        CodeV1_0_1.cd_98
})
@SuppressWarnings("unused")
public class Cd_98_Up implements CodeParse {
    private static final Logger log = LogManager.getLogger(Cd_98_Up.class);
    /**
     * 分析上行数据
     */
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback)throws Exception {
        ParseParamsForUpV1_0_1 para = (ParseParamsForUpV1_0_1)params ;
        int bsLen = new CommonV1_0_1().parseDataLen(para.upBuffer) ;
        if(bsLen > 0){
            this.doParse(para.upBuffer,
                    bsLen,
                    para.upCode,
                    para.data) ;
        }
        log.info("分析上行数据<" + CodeV1_0_1.getCodeName(para.upCode) + " RTU地址=" + para.rtuAddr + ">:\n" + para.data.toString());
        MidResultFromRtu midRs = new MidResultFromRtu() ;
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//Rtu地址
        midRs.upCode = para.upCode ;//上行数据中的功能码
        midRs.upHex = para.upHex ;//上行数据十六进制形式
        midRs.upBuffer = para.upBuffer ;//上行数据字节数组
        midRs.data = para.data ;//解析后的数据
        midRs.reportOrResponse_trueOrFalse = false ;//主动上报
        callback.callback(midRs.reportOrResponse_trueOrFalse);
        return new MidResult[]{midRs} ;
    }
    /**
     * 执行分析
     * @param bs 字节数组
     * @param bsLen 字节长度(总包长,包括包头和包尾)
     * @param dataCode 功能码
     * @param data 数据
     * @throws Exception 异常
     */
    protected void doParse(byte[] bs, int bsLen, String dataCode, Data data) throws Exception {
        DataV1_0_1 dV1 = (DataV1_0_1)data.getSubData() ;
        DataCd98Vo cdData = new DataCd98Vo() ;
        dV1.dataCd98Vo = 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.success = true ;
        }else{
            cdData.success = false ;
        }
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_C0_Up.java
@@ -51,7 +51,7 @@
                null,
                null);
        //构造应答
        byte[] data = new Cd_02_Down().doParse(downCpParams) ;
        byte[] data = new Cd_C0_Down().doParse(downCpParams) ;
        MidResultToRtu confirmCommand = new MidResultToRtu() ;
        confirmCommand.protocolName = para.protocolName ;//协议名称
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrControllerTrampMapper.java
New file
@@ -0,0 +1,65 @@
package com.dy.pipIrrGlobal.daoPr;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoPr.PrControllerTramp;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * @Author liurunyu
 * @Date 2024/1/15 15:27
 * @LastEditTime 2024/1/15 15:27
 * @Description
 */
@Mapper
public interface PrControllerTrampMapper extends BaseMapper<PrControllerTramp> {
    /**
     * 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(PrControllerTramp record);
    /**
     * insert record to table selective
     * @param record the record
     * @return insert count
     */
    int insertSelective(PrControllerTramp record);
    /**
     * select by primary key
     * @param id primary key
     * @return object by primary key
     */
    PrControllerTramp selectByPrimaryKey(Long id);
    /**
     * select by RtuAddr
     * @param rutAddr 控制器地址
     * @return object by 控制器地址
     */
    List<PrControllerTramp> selectPrControllerTrampByRtuAddr(String rutAddr);
    /**
     * update record selective
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKeySelective(PrControllerTramp record);
    /**
     * update record
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKey(PrControllerTramp record);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrControllerTramp.java
New file
@@ -0,0 +1,64 @@
package com.dy.pipIrrGlobal.pojoPr;
/**
 * @Author liurunyu
 * @Date 2024/1/15 15:00
 * @LastEditTime 2024/1/15 15:00
 * @Description
 */
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 io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.*;
import org.hibernate.validator.constraints.Length;
/**
 * 流浪控制器
 */
@TableName(value="pr_controller_tramp", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "流浪控制器")
public class PrControllerTramp implements BaseEntity {
    public static final long serialVersionUID = 2024011502001L;
    /**
     * 主键
     */
    @JSONField(serializeUsing= ObjectWriterImplToString.class)
    @TableId(type = IdType.INPUT)
    @Schema(description = "实体id", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    public Long id;
    /**
     * 通讯协议
     */
    @Schema(description = "控制器地址", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "控制器地址不能为空")
    @Length(message = "控制器地址必须{max}位",min = 11, max = 11)
    public String rtuAddr;
    /**
     * 通讯协议
     */
    @Schema(description = "通讯协议", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "通讯协议不能为空")
    @Length(message = "通讯协议不大于{max}字",max = 25)
    public String protocol;
    /**
     * 通讯协议
     */
    @Schema(description = "发现时间", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotBlank(message = "发现时间不能为空")
    public String findDt;//发现时间( yyyy-mm-dd HH:MM:SS)
}
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrControllerTrampMapper.xml
New file
@@ -0,0 +1,98 @@
<?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.daoPr.PrControllerTrampMapper">
  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoPr.PrControllerTramp">
    <!--@mbg.generated-->
    <!--@Table pr_controller_tramp-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="rtuAddr" jdbcType="VARCHAR" property="rtuAddr" />
    <result column="protocol" jdbcType="VARCHAR" property="protocol" />
    <result column="findDt" jdbcType="VARCHAR" property="findDt" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, rtuAddr, protocol, findDt
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from pr_controller_tramp
    where id = #{id,jdbcType=BIGINT}
  </select>
  <select id="selectPrControllerTrampByRtuAddr" parameterType="java.lang.String" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from pr_controller_tramp
    where rtuAddr = #{rtuAddr,jdbcType=VARCHAR}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from pr_controller_tramp
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoPr.PrControllerTramp">
    <!--@mbg.generated-->
    insert into pr_controller_tramp (id, rtuAddr, protocol,
      findDt)
    values (#{id,jdbcType=BIGINT}, #{rtuAddr,jdbcType=VARCHAR}, #{protocol,jdbcType=VARCHAR},
      #{findDt,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrControllerTramp">
    <!--@mbg.generated-->
    insert into pr_controller_tramp
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="rtuAddr != null">
        rtuAddr,
      </if>
      <if test="protocol != null">
        protocol,
      </if>
      <if test="findDt != null">
        findDt,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="rtuAddr != null">
        #{rtuAddr,jdbcType=VARCHAR},
      </if>
      <if test="protocol != null">
        #{protocol,jdbcType=VARCHAR},
      </if>
      <if test="findDt != null">
        #{findDt,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrControllerTramp">
    <!--@mbg.generated-->
    update pr_controller_tramp
    <set>
      <if test="rtuAddr != null">
        rtuAddr = #{rtuAddr,jdbcType=VARCHAR},
      </if>
      <if test="protocol != null">
        protocol = #{protocol,jdbcType=VARCHAR},
      </if>
      <if test="findDt != null">
        findDt = #{findDt,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoPr.PrControllerTramp">
    <!--@mbg.generated-->
    update pr_controller_tramp
    set rtuAddr = #{rtuAddr,jdbcType=VARCHAR},
      protocol = #{protocol,jdbcType=VARCHAR},
      findDt = #{findDt,jdbcType=VARCHAR}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/TkRtuData.java
@@ -19,10 +19,15 @@
    public void execute(Object data) {
        Data d = (Data)data ;
        String rtuAddr = d.getRtuAddr() ;
        if(rtuAddr == null){
        if(rtuAddr == null || rtuAddr.trim().equals("")){
            log.error("严重错误,RTU上行数据中无RTU地址!" );
        }else{
            this.toNextTasks(data);
            String protocol = d.getProtocol() ;
            if(protocol == null || protocol.trim().equals("")){
                log.error("严重错误,RTU上行数据中无协议名称!" );
            }else{
                this.toNextTasks(data);
            }
        }
    }
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/dbSv/DbSv.java
New file
@@ -0,0 +1,64 @@
package com.dy.aceMw.server.rtuData.dbSv;
import com.dy.pipIrrGlobal.daoPr.PrControllerMapper;
import com.dy.pipIrrGlobal.daoPr.PrControllerTrampMapper;
import com.dy.pipIrrGlobal.pojoPr.PrController;
import com.dy.pipIrrGlobal.pojoPr.PrControllerTramp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * @Author liurunyu
 * @Date 2024/1/13 10:57
 * @LastEditTime 2024/1/13 10:57
 * @Description
 */
@Service()
public class DbSv {
    @Autowired
    private PrControllerTrampMapper prControllerTrampMapperDao;//流浪控制器DAO
    @Autowired
    private PrControllerMapper prControllerMapperDao ;//控制器DAO
    @Autowired
    @Lazy
    private DbSv sv ;
    /**
     * 通过控制器地址从数据库表中查询控制器
     * @param rtuAddr 控制器地址
     * @return 控制器
     */
    public PrController getPrControllerByRtuAddr(String rtuAddr){
        List<PrController> list = this.prControllerMapperDao.selectPrControllerByRtuAddr(rtuAddr) ;
        if(list != null && list.size() > 0){
            return list.get(0) ;
        }
        return null ;
    }
    /**
     * 通过控制器地址从数据库表中查询流浪控制器
     * @param rtuAddr 控制器地址
     * @return 流浪控制器
     */
    public PrControllerTramp getPrControllerTrampByRtuAddr(String rtuAddr){
        List<PrControllerTramp> list = this.prControllerTrampMapperDao.selectPrControllerTrampByRtuAddr(rtuAddr) ;
        if(list != null && list.size() > 0){
            return list.get(0) ;
        }
        return null ;
    }
    /**
     * 保存流浪控制器
     * @param po
     */
    public void savePrConctrollerTramp(PrControllerTramp po){
        this.prControllerTrampMapperDao.insert(po) ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/p206V1_0_0/TkDealControllerTramp.java
New file
@@ -0,0 +1,37 @@
package com.dy.aceMw.server.rtuData.p206V1_0_0;
import com.dy.aceMw.server.rtuData.TaskSurpport;
import com.dy.aceMw.server.rtuData.dbSv.DbSv;
import com.dy.pipIrrGlobal.pojoPr.PrControllerTramp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
 * @Author liurunyu
 * @Date 2024/1/15 16:29
 * @LastEditTime 2024/1/15 16:29
 * @Description
 */
/**
 * 处理流浪控制器
 */
public class TkDealControllerTramp extends TaskSurpport {
    private static final Logger log = LogManager.getLogger(TkDealControllerTramp.class.getName()) ;
    //类ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkDealControllerTramp" ;
    /**
     * 执行节点任务
     * @param data 需要处理的数据
     */
    @Override
    public void execute(Object data) {
        Object[] objs = this.getTaskResults(TkPreGenObjs.taskId) ;
        DbSv sv = (DbSv)objs[0] ;
        PrControllerTramp rtuTramp = (PrControllerTramp)objs[2] ;
        sv.savePrConctrollerTramp(rtuTramp);
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/p206V1_0_0/TkFindReport.java
New file
@@ -0,0 +1,42 @@
package com.dy.aceMw.server.rtuData.p206V1_0_0;
import com.dy.aceMw.server.rtuData.TaskSurpport;
import com.dy.common.mw.protocol.Data;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
 * @Author liurunyu
 * @Date 2024/1/15 17:15
 * @LastEditTime 2024/1/15 17:15
 * @Description
 */
/**
 * 识别非命令应答
 */
public class TkFindReport extends TaskSurpport {
    private static final Logger log = LogManager.getLogger(TkFindReport.class.getName()) ;
    //类ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkFindReport" ;
    /**
     * 执行节点任务
     * @param data 需要处理的数据
     */
    @Override
    public void execute(Object data) {
        if(data instanceof Data){
            Data d = (Data)data ;
            if(d.getCommandId() == null || d.getCommandId().trim().equals("")){
                //无命令ID
                this.toNextTasks(data);
            }
        }
        //Object[] objs = this.getTaskResults(TkPreGenObjs.taskId) ;
        //DbSv sv = (DbSv)objs[0] ;
        //PrController controller = (PrController)objs[1] ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/rtuData/p206V1_0_0/TkPreGenObjs.java
@@ -1,9 +1,12 @@
package com.dy.aceMw.server.rtuData.p206V1_0_0;
import com.dy.aceMw.server.rtuData.TaskSurpport;
import com.dy.aceMw.server.rtuData.dbSv.RtuSv;
import com.dy.aceMw.server.rtuData.dbSv.DbSv;
import com.dy.common.mw.protocol.Data;
import com.dy.common.springUtil.SpringContextUtil;
import com.dy.common.util.DateTime;
import com.dy.pipIrrGlobal.pojoPr.PrController;
import com.dy.pipIrrGlobal.pojoPr.PrControllerTramp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -21,69 +24,25 @@
    @Override
    public void execute(Object data) {
        Data d = (Data)data ;
        String rtuAddr = d.getRtuAddr() ;
        log.info("RTU" + rtuAddr + "数据到此,进行数据库存储测试");
        RtuSv sv = (RtuSv)SpringContextUtil.getBean(RtuSv.class) ;
        sv.save(d) ;
        //得到本地RTU 数据,以备后面节点应用
        /*
        BuziInterface baseBusi = BuziGeter.getBaseBusi() ;
        BuziInterface orgBusi = null ;
        SyRtu nbRtu = null ;
        SyRtuTramp rtuTramp = null ;
        if(baseBusi != null){
            nbRtu = DbSyBuzi.getRtu(baseBusi, imei) ;
            if(nbRtu != null){
                //数据库中查询到NB产品(RTU实体)
                if(nbRtu.orgTag != null && !nbRtu.orgTag.trim().equals("")){
                    orgBusi = BuziGeter.getBusi(nbRtu.orgTag) ;
                    if(orgBusi == null){
                        log.error("严重错误,未能得到标签为" + nbRtu.orgTag + "的供水机构数据库业务Busi");
                    }else{
                        BaMeter meter = DbOrgBuzi.getMeterByImeiAndNo(orgBusi, imei, rtuAddr) ;
                        //可能未查询到meter,即仍是流浪者RTU,但仍要后续处理:(1)、仍能识别出流浪者RTU,(2)、仍要记录其上报数据
                        if(meter != null){
                            String protocol = d.getProtocol() ;
                            if(protocol != null){
                                protocol = protocol.trim();
                                if(!protocol.equals("")){
                                    if(meter.protocol == null
                                            || meter.protocol.trim().equals("")
                                            || !meter.protocol.trim().equals(protocol)){
                                        //需要更新协议名称
                                        DbOrgBuzi.updateMeter4Protocol(orgBusi, meter.id, protocol);
                                    }
                                }
                            }
                        }
                        this.taskResult = new Object[]{baseBusi, orgBusi, nbRtu, null, meter} ;
                        this.toNextTasks(data);
                    }
                }else{
                    //NB产品(RTU实体)未分配给具体的供水机构
                    //流浪者RTU
                    rtuTramp = DbSyBuzi.getSyRtuTramp(baseBusi, imei, rtuAddr) ;
                    if(rtuTramp == null){
                        rtuTramp = new SyRtuTramp(imei, rtuAddr) ;
                    }
                    this.taskResult = new Object[]{baseBusi, orgBusi, nbRtu, rtuTramp, null} ;
                    this.toNextOneTask(data, TkDealRtuTramp.taskId);
                }
            }else{
                //数据库中未查询到NB产品(RTU实体)
                //流浪者RTU
                rtuTramp = DbSyBuzi.getSyRtuTramp(baseBusi, imei, rtuAddr) ;
        String rtuAddr = d.getRtuAddr() ;//TkRtuData里判断了rtuAddr为空
        DbSv sv = (DbSv)SpringContextUtil.getBean(DbSv.class) ;
        if(sv != null){
            PrController controller = sv.getPrControllerByRtuAddr(rtuAddr) ;
            if(controller == null){
                //数据库中未查询到控制器(RTU实体)
                //流浪者控制器
                PrControllerTramp rtuTramp = sv.getPrControllerTrampByRtuAddr(rtuAddr);
                if(rtuTramp == null){
                    rtuTramp = new SyRtuTramp(imei, rtuAddr) ;
                    rtuTramp = new PrControllerTramp(null, rtuAddr, d.getProtocol(), DateTime.yyyy_MM_dd_HH_mm_ss()) ;
                    this.taskResult = new Object[]{sv, null, rtuTramp} ;
                    this.toNextOneTask(data, TkDealControllerTramp.taskId);
                }
                this.taskResult = new Object[]{baseBusi, orgBusi, nbRtu, rtuTramp, null} ;
                this.toNextOneTask(data, TkDealRtuTramp.taskId);
            }
            //不论是否为流浪控制器(RTU实体),都要进行下步工作
            this.taskResult = new Object[]{sv, controller, null} ;
            this.toNextTasks(data);
        }else{
            log.error("严重错误,未能得到BaseBusi对象");
            log.error("严重错误,未能得到DbSv对象");
        }
        */
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/resources/RtuDataDealTree.xml
@@ -8,9 +8,20 @@
    <task id="TkReceive" name="接收数据" enable="true" class="com.dy.aceMw.server.rtuData.TkReceive">
        <task id="TkRtuData" name="接收RTU数据" enable="true" class="com.dy.aceMw.server.rtuData.TkRtuData">
            <task id="TkFindP206V1_0_0" name="识别P206V1_0_0数据" enable="true" class="com.dy.aceMw.server.rtuData.p206V1_0_0.TkFindP206V1_0_0">
                <task id="TkPreGenObjs" name="预先准备各对象" enable="true" class="com.dy.aceMw.server.rtuData.p206V1_0_0.TkPreGenObjs">
                <task id="TkPreGenObjs" name="预先准备各对象并识别流浪控制器" enable="true" class="com.dy.aceMw.server.rtuData.p206V1_0_0.TkPreGenObjs">
                    <!-- 处理流浪控制器 -->
                    <task id="TkDealControllerTramp" name="处理流浪控制器" enable="true" class="com.dy.aceMw.server.rtuData.p206V1_0_0.TkDealControllerTramp" />
                    <!-- 非流浪者RTU,必须放在TkDealControllerTramp后面 -->
                    <!-- 识别主动上报数据 -->
                    <task id="TkFindReport" name="识别上报数据" enable="true" class="com.dy.aceMw.server.rtuData.p206V1_0_0.TkFindReport">
                    </task>
                    <!-- 识别命令响应数据 -->
                    <task id="TkFindComResponse" name="识别响应命令数据" enable="true" class="com.dy.aceMw.server.rtuData.p206V1_0_0.TkFindComResponse">
                        <task id="TkRtuDealCommandResponse" name="RTU响应命令数据" enable="true" class="com.dy.aceMw.server.rtuData.p206V1_0_0.TkRtuDealCommandResponse" >
                        </task>
                    </task>
                </task>
            </task>
        </task>
    </task>
</project>