liurunyu
2023-11-22 429f9d85eddbb07081c149d7156964337ba688aa
通信中间件开发,阶段性提交
26个文件已修改
20个文件已删除
24个文件已添加
4 文件已重命名
4572 ■■■■ 已修改文件
pipIrr-platform/pipIrr-common/pipIrr-common.iml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/core/CoreThread.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Command.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Data.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Driver.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/DriverParserDataCallback.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultError.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultFromRtu.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultToRtu.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/OnLine.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/OnLineHandle.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/PrefixedDataAvailableHandleImp.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206/ProtocolConstantV206.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CodeV1_0_1.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CommonV1_0_1.java 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd02Vo.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCdC0Vo.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataV1_0_1.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DriverV1_0_1.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/OnLineV1_0_1.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/ParseParamsForDownV1_0_1.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/ParseParamsForUpV1_0_1.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/PrefixedDataAvailableV1_0_1.java 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/ProtocolConstantV206V1_0_0.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_02_Down.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_02_Up.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/CommonV1_0_1.java 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd01Vo.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd02Vo.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd03Vo.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd0405Vo.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd06Vo.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataV1_0_1.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DriverV1_0_1.java 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/ParseParamsForDownV1_0_1.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/ParseParamsForUpV1_0_1.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/ProtocolConstantV1_0_1.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_01_Up.java 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_02_Up.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_03_Up.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_0405_Up.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_06_Down.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_06_Up.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_XY_Down.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/说明.txt 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/support/SupportUnit.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/support/SupportUnitConfigVo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/queue/Queue.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/threadPool/ThreadPoolImp.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/threadPool/TreadPoolFactory.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/ByteUtil.java 414 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/Server.java 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/ServerProperties.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/AboutRtuNode.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/TcpUpDataCache.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/Task.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TaskConfig.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TaskPool.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TaskSurpport.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TkReceive.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TkRtuData.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/Tree.xml 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TreeConfig.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TreeParse.java 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/p206V1_0_0/TkFindP206V1_0_0.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/p206V1_0_0/TkPreGenObjs.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/forTcp/MidResultActionFromRtu.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/forTcp/MidResultActionToRtu.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/forTcp/TcpDownCommandCache.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/tasks/BusiConstantTask.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/tasks/RtuDownTask.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/tasks/RtuUpTask.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/tasks/ToRtuConstantTask.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/resources/config.xml 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/pipIrr-common.iml
@@ -105,5 +105,6 @@
    <orderEntry type="library" name="Maven: org.jdom:jdom2:2.0.6.1" level="project" />
    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.8.21" level="project" />
    <orderEntry type="library" name="Maven: org.apache.mina:mina-core:2.2.1" level="project" />
    <orderEntry type="library" name="Maven: org.quartz-scheduler:quartz-weblogic:2.1.7" level="project" />
  </component>
</module>
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/core/CoreThread.java
@@ -10,7 +10,7 @@
    
    private static CoreThread instance = new CoreThread() ;
    private static Long sleepBigBusy = 100L ;//大忙时(除了恒久任务,还是其他任务),核心线程暂停间隔
    private static Long sleepBigBusy = 100L ;//大忙时(除了恒久任务,还有其他任务),核心线程暂停间隔
    private static Long sleepSmallBusy = 500L ;//小忙时(只有恒久任务,无其他任务),核心线程暂停间隔
    
    private CoreThread(){
@@ -22,8 +22,8 @@
    
    /**
     * è®¾ç½®æš‚停时长
     * @param sleepWorking
     * @param sleepIdel
     * @param sleepBigBusy å¤§å¿™æ—¶ï¼ˆé™¤äº†æ’久任务,还有其他任务),核心线程暂停间隔
     * @param sleepSmallBusy å°å¿™æ—¶ï¼ˆåªæœ‰æ’久任务,无其他任务),核心线程暂停间隔
     */
    public void setSleep(Long sleepBigBusy, Long sleepSmallBusy){
        CoreThread.sleepBigBusy = sleepBigBusy ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Command.java
@@ -32,25 +32,7 @@
     * RTU åœ°å€
     */
    public String rtuAddr ;
    /**
     * æ°´è¡¨å·
     * åº”用电信平台时有效
     */
    public String meterNo ;
    /**
     * ç”µä¿¡å¹³å°ä¸Šçš„产品ID,当不在电信平台上运行时,为null
     * åº”用电信平台时有效
     */
    public Integer productId ;
    /**
     * ç”µä¿¡å¹³å°ä¸Šçš„设备ID,当不在电信平台上运行时,为null
     * åº”用电信平台时有效
     */
    public String deviceId ;
    /**
     * å‘½ä»¤ç±»åž‹:Rtu命令、针对监控中间件的命令
     * ç”±com.dy.common.mw.protocol.CommandType类定义
@@ -81,13 +63,6 @@
        String s = "命令id=" + id + "\n" ;
        s += (protocol == null ? "" : ("协议=" + protocol + "\n"));
        s += (rtuAddr == null ? "" : ("IMEI号=" + rtuAddr + "\n"));
        s += (meterNo == null ? "" : ("水表号=" + meterNo + "\n"));
        if(productId != null){
            s +=  "电信平台产品ID=" + productId + "\n" ;
        }
        if(deviceId != null && !deviceId.trim().equals("")){
            s +=  "电信平台设备ID=" + deviceId + "\n" ;
        }
        s += "命令类型=" + (type.equals(CommandType.innerCommand)?"内部命令":"终端命令") + "\n" ;
        s += (code == null ? "" : ("功能码=" + code + "\n")) ;
        s += "返回中间件对命令处理结果=" + (noRtMwDealRes == null?"返回":(noRtMwDealRes?"不返回":"返回") + "\n") ;
@@ -209,24 +184,6 @@
    }
    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }
    public String getMeterNo() {
        return meterNo;
    }
    public void setMeterNo(String meterNo) {
        this.meterNo = meterNo;
    }
    public Integer getProductId() {
        return productId;
    }
    public void setProductId(Integer productId) {
        this.productId = productId;
    }
    public String getDeviceId() {
        return deviceId;
    }
    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }
    public String getType() {
        return type;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Data.java
@@ -6,7 +6,6 @@
/**
 * æ•°æ®æ ¹
 * @author Administrator
 *
 */
public class Data  implements java.io.Serializable{
@@ -15,7 +14,6 @@
    private String commandId ;//命令ID,可能为null
    private String rtuAddr ;//终端地址
    private String meterNo ;//水表号
    private String protocol ;//数据所对应的协议名称
    private String code ;//数据所对应的功能码:
    private Object subData ;//对应各个功能码的具体数据
@@ -25,7 +23,6 @@
        StringBuilder sb = new StringBuilder() ;
        sb.append("上行报文(十六进制): ").append((hex == null?"":hex)).append("\n") ; //
        sb.append("IMEI号 : ").append((rtuAddr==null?"":rtuAddr)).append("\n") ;
        sb.append("水表号 : ").append((meterNo==null?"":meterNo)).append("\n") ;
        if(commandId != null){
            sb.append("命令ID : ").append(commandId).append("\n") ; //命令ID
        }
@@ -88,12 +85,6 @@
        this.rtuAddr = rtuAddr;
    }
    
    public String getMeterNo() {
        return meterNo;
    }
    public void setMeterNo(String meterNo) {
        this.meterNo = meterNo;
    }
    public String getCode() {
        return code;
    }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Driver.java
@@ -142,7 +142,7 @@
        return codeParse ;
    }
    /**
     * è§£æžä¸Šè¡Œæ•°æ®
     * è§£æžç”µä¿¡å¹³å°ä¸Šè¡Œæ•°æ®
     * @param isLowPower æ˜¯å¦åœ¨ä½ŽåŠŸè€—çŽ¯å¢ƒä¸‹è¿è¡Œ
     * @param rtuAddr æŽ§åˆ¶å™¨åœ°å€
     * @param upBuffer å­—节数组
@@ -151,18 +151,6 @@
     * @return MidResult[]
     */
    public abstract MidResult[] parseData(Boolean isLowPower, String rtuAddr, byte[] upBuffer, String upHex, DriverParserDataCallback callback, Object... params) ;
    /**
     * è§£æžç”µä¿¡å¹³å°ä¸Šè¡Œæ•°æ®
     * @param isLowPower æ˜¯å¦åœ¨ä½ŽåŠŸè€—çŽ¯å¢ƒä¸‹è¿è¡Œ
     * @param rtuAddr æŽ§åˆ¶å™¨åœ°å€
     * @param productId ç”µä¿¡å¹³å°äº§å“ID,当不在电信平台中运行时,为null
     * @param deviceId ç”µä¿¡å¹³å°è®¾å¤‡ID,当不在电信平台中运行时,为null
     * @param upBuffer å­—节数组
     * @param upHex å­—节数组16进制形式
     * @param callback å›žè°ƒ
     * @return MidResult[]
     */
    public abstract MidResult[] parseData(Boolean isLowPower, String rtuAddr, Integer productId, String deviceId, byte[] upBuffer, String upHex, DriverParserDataCallback callback, Object... params) ;
    
    /**
     * æž„造下行数据(命令)
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/DriverParserDataCallback.java
@@ -4,23 +4,19 @@
    /**
     * è§£æžä¸Šè¡Œæ•°æ®åŽå›žè°ƒ
     * @param rtuAddr ä¸Šè¡Œæ•°æ®åè®®å¤´ä¸­çš„IMEI号
     * @param meterNo ä¸Šè¡Œæ•°æ®åè®®å¤´ä¸­çš„æ°´è¡¨å·
     * @param rtuAddr ä¸Šè¡Œæ•°æ®åè®®å¤´ä¸­RtuAddr
     * @param code ä¸Šè¡Œæ•°æ® åŠŸèƒ½ç 
     * @param upHex ä¸Šè¡Œæ•°æ®
     * @param reportOrResponse_trueOrFalse ä¸Šè¡Œæ•°æ®æ˜¯ä¸»åŠ¨ä¸ŠæŠ¥è¿˜æ˜¯å‘½ä»¤ç»“æžœ
     * @param parseFail ä¸Šè¡Œæ•°æ®è§£æžæ˜¯å¦å¤±è´¥
     * @param rtuAddrInData ä¸Šè¡Œæ•°æ®ä¸­åœ¨åè®®æ•°æ®ä¸­çš„IMEI号,
     * @param meterNoInData ä¸Šè¡Œæ•°æ®ä¸­åœ¨åè®®æ•°æ®ä¸­çš„æ°´è¡¨å·ï¼Œ
     *     â€œä¿®æ”¹RTU终端管理配置参数”命令的返回数据,其协议头中的IMEI号与数据中的IMEI号不一样,
     *  å¦‚æžœRTU不能关闭网络,那么sessionCach中的IMEI号总是用修改前的IMEI号,使得以后上行数据的不能找到缓存中的Session
     */
    void callback(String rtuAddr,
            String meterNo,
            String code,
            String code,
            String upHex, 
            Boolean reportOrResponse_trueOrFalse, 
            boolean parseFail,
            String rtuAddrInData,
            String meterNoInData) ;
            String rtuAddrInData) ;
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultError.java
@@ -12,14 +12,12 @@
    public String protocolName ;//协议名称
    public String rtuAddr ;//IMEI号,注意rtuAddr可能为null
    public String meterNo ;//水表号,注意meterNo可能为null
    public String message ;//出错消息
    public Exception e ;//异常
    
    public MidResultError(String protocolName, String rtuAddr, String meterNo, String message, Exception e){
    public MidResultError(String protocolName, String rtuAddr, String message, Exception e){
        this.protocolName = protocolName ;
        this.rtuAddr = rtuAddr ;
        this.meterNo = meterNo ;
        this.message = message ;
        this.e = e ;
    }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultFromRtu.java
@@ -14,9 +14,6 @@
    
    public String protocolName ;//协议名称
    public String rtuAddr ;//IMEI号
    public String meterNo ;//水表号
    public Integer productId ;//电信平台产品ID,当不在电信平台运行时,为null
    public String deviceId ;//电信平台设备ID,当不在电信平台运行时,为null
    public String upCode ;//上行数据中的功能码
    public String upHex ;//上行数据十六进制形式
    public byte[] upBuffer ;//上行数据字节数组
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultToRtu.java
@@ -12,9 +12,6 @@
    public String protocolName ;//协议名称
    public String rtuAddr ;//IMEI号(电信平台IMEI)
    public String meterNo ;//水表号
    public Integer productId ;//电信平台产品ID
    public String deviceId ;//电信平台设备ID
    public String commandId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
    public String downCode ;//下行命令功能码;
    public byte[] downBuffer ;//下行命令数据
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/OnLine.java
@@ -17,12 +17,10 @@
        public int result ;//分析结果
        public String protocolName ;//协议名称
        public String rtuAddr ;//IMEI号
        public String meterNo ;//水表号
        public byte[] remoteData;//需要向Rtu回写的数据
        public OnLineResult(){
            result = OnLineAction_fail ;
            rtuAddr = null ;
            meterNo = null ;
            remoteData = null ;
        }
    }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/OnLineHandle.java
@@ -6,7 +6,7 @@
public class OnLineHandle {
    
    /**
     * è§£æžä¸Šçº¿æ•°æ®ï¼Œå¾—到IMEI号
     * è§£æžä¸Šçº¿æ•°æ®ï¼Œå¾—到RtuAddr
     * @param bs å­—节数组
     * @return OnLine.OnLineResult
     */
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/PrefixedDataAvailableHandleImp.java
@@ -35,13 +35,13 @@
                if(set.size() == 0){
                    throw new Exception("上线数据完整性检查时,得到的协议完整性检查类集合为空。") ;
                }
                int prority = ProtocolConstant.firstPriority ;
                int priority = ProtocolConstant.firstPriority ;
                while(true){
                    Object[] objs = this.getClassObjAndAnnotationVo(prority, set) ;
                    Object[] objs = this.getClassObjAndAnnotationVo(priority, set) ;
                    PrefixedDataAvailable pda = (PrefixedDataAvailable)objs[0] ;
                    if(pda == null && prority == ProtocolConstant.firstPriority){
                        throw new Exception("上线数据完整性检查时,未得到优先级为" + prority + "上线数据完整性检查类!") ;
                    if(pda == null && priority == ProtocolConstant.firstPriority){
                        throw new Exception("上线数据完整性检查时,未得到优先级为" + priority + "上线数据完整性检查类!") ;
                    }else if(pda == null){
                        //说明上线数据完整性检查类集合已经遍历完了。
                        break ;
@@ -53,7 +53,7 @@
                    if(pds == null){
                        //说明不是对应的协议数据,需要另外的协议来处理上线
                        //循环继续
                        prority++ ;
                        priority++ ;
                    }else{
                        //停止循环,返回结果
                        break ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206/ProtocolConstantV206.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CodeV1_0_1.java
File was renamed from pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/CodeV1_0_1.java
@@ -1,29 +1,27 @@
package com.dy.common.mw.protocol.pMeterV1_0_1;
package com.dy.common.mw.protocol.p206V1_0_0;
public class CodeV1_0_1 {
    //功能码为字符串,十六进制数据
    public static final String cd_01 = "01" ;//定时(周期)上报
    public static final String cd_02 = "02" ;//实时(触发)上报
    public static final String cd_02 = "02" ;//链路检测
    public static final String cd_03 = "03" ;//事件上报
    public static final String cd_04 = "04" ;//开阀
    public static final String cd_05 = "05" ;//关阀
    public static final String cd_06 = "06" ;//阀门动作结果
    public static String getCodeName(String code) {
        String name = (code.equals(cd_01) ? "定时上报 " :
            (code.equals(cd_02) ? "触发上报" :
            (code.equals(cd_03) ? "事件上报" :
        String name = (code.equals(cd_02) ? "链路检测" :
            (code.equals(cd_03) ? "事件上报" :
            (code.equals(cd_04) ? "开阀" : 
            (code.equals(cd_05) ? "关阀" : 
            (code.equals(cd_06) ? "阀门动作结果" : 
            "")))))) ;
            ""))))) ;
        return name ;
    }
    
    /**
     * æ˜¯å¦ä¸ºæœ‰æ•ˆåŠŸèƒ½ç 
     * @param code
     * @return
     * @param code åŠŸèƒ½ç 
     * @return æœ‰æ•ˆtrue,无效false
     */
    public static boolean isValid(String code){
        String name = getCodeName(code) ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CommonV1_0_1.java
New file
@@ -0,0 +1,156 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
public class CommonV1_0_1 {
    /**
     * æ£€æŸ¥å¤´
     * @param bs ä¸Šè¡Œå­—节数组
     * @return true是,false否
     * @throws Exception  å¼‚常
     */
    public Boolean isThisProtocolHead(byte[] bs) throws Exception{
        if(bs == null){
            return null ;
        }else if(bs.length >= (ProtocolConstantV206V1_0_0.ctrlIndex - 1)
                && bs[0] == ProtocolConstantV206V1_0_0.P_Head_Byte
                && bs[2] == ProtocolConstantV206V1_0_0.P_Head_Byte){
            //String vs = this.parseVersion(bs) ;
            //return vs.equals(ProtocolConstantV206V1_0_0.version);
            return true ;
        }else{
            return false ;
        }
    }
    /**
     * æ£€æŸ¥å¤´
     * @param bs ä¸Šè¡Œå­—节数组
     * @throws Exception å¼‚常
     */
    public void checkHead(byte[] bs) throws Exception{
        if(bs.length < 13 || bs[0] != ProtocolConstantV206V1_0_0.P_Head_Byte || bs[2] != ProtocolConstantV206V1_0_0.P_Head_Byte){
            throw new Exception("上行数据帧头不正确!") ;
        }
    }
    /**
     * æ£€æŸ¥å°¾
     * @param bs ä¸Šè¡Œå­—节数组
     * @throws Exception å¼‚常
     */
    public void checkTail(byte[] bs) throws Exception{
        if(bs.length < 1 || bs[bs.length - 1] != ProtocolConstantV206V1_0_0.P_Tail_Byte){
            throw new Exception("上行数据尾不正确!") ;
        }
    }
    /**
     * åˆ†æžæ•°æ®å­—节数
     * @param bs ä¸Šè¡Œå­—节数组
     * @return æ•°æ®é•¿åº¦
     * @throws Exception å¼‚常
     */
    public int parseDataLen(byte[] bs)throws Exception{
        return ByteUtilUnsigned.bytes2Short_BE(bs, ProtocolConstantV206V1_0_0.dataLenIndex) ;
    }
    /**
     * åˆ†æžIMEI号
     * @param bs ä¸Šè¡Œå­—节数组
     * @return æŽ§åˆ¶å™¨åœ°å€
     * @throws Exception å¼‚常
     */
    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() < 6){
            rtuAddrStr = "0" + rtuAddrStr ;
        }
        return rtuAddrBCD + rtuAddrStr ;
    }
    /**
     * åˆ†æžåŠŸèƒ½ç 
     * @param bs ä¸Šè¡Œå­—节数组
     * @return åŠŸèƒ½ç 
     */
    public String parseCode(byte[] bs){
        return ByteUtil.bytes2Hex(bs, false, ProtocolConstantV206V1_0_0.codeIndex, 1) ;
    }
    /**
     * æ ¡éªŒå’Œæ£€æŸ¥
     * @param bs ä¸Šè¡Œå­—节数组
     * @return é€šè¿‡true,未通过false
     */
    public boolean checkCrc(byte[] bs) {
        byte he = 0 ;
        for(int i = 0 ; i <= bs.length - 3 ; i++){
            he = (byte)(he + bs[i]) ;
        }
        return bs[bs.length - 2] == he ;
    }
    /**
     * æ ¡éªŒå’Œæ£€æŸ¥
     * @param bs  ä¸Šè¡Œå­—节数组
     * @return é€šè¿‡null,未通过返回原因
     * @throws Exception å¼‚常
     */
    public String checkCrc_str(byte[] bs) throws Exception {
        byte[] he = new byte[1] ;
        for(int i = 0 ; i <= bs.length - 3 ; i++){
            he[0] = (byte)(he[0] + bs[i]) ;
        }
        short hes = ByteUtilUnsigned.byte2Byte(he, 0);
        short heOrg = ByteUtilUnsigned.byte2Byte(bs, bs.length - 2);
        if(hes == heOrg){
            return null ;
        }else{
            return "计算校验和是:" + hes + ",上传校验和是" + heOrg ;
        }
    }
    /*
    æž„造控制域
    D7                  D6                  D5~D4            D3~D0
    ä¼ è¾“方向位 DIR        æ‹†åˆ†æ ‡å¿—位 DIV       å¸§è®¡æ•°ä½ FCB       åŠŸèƒ½ç 
    */
    public byte createCtrl(byte funcCode){
        byte b = 0 ;
        b = (byte)(b | funcCode) ;
        //FCB == 3
        b = (byte)(b | (byte)60) ;
        //DIV = 0
        //DIR = 0
        return b ;
    }
    /*
     * åˆ†æžç‰ˆæœ¬å·
     * @param bs  ä¸Šè¡Œå­—节数组
     * @return ç‰ˆæœ¬å·
     * @throws Exception å¼‚常
    public String parseVersion(byte[] bs)throws Exception{
        short ver = ByteUtilUnsigned.byte2Byte(bs, ProtocolConstantV206V1_0_0.versionIndex) ;
        char[] cs = ("" + ver).toCharArray() ;
        StringBuilder vs = new StringBuilder() ;
        for(byte i = 0 ; i < cs.length; i++){
            if(i == 0){
                vs.append(cs[i]) ;
            }else{
                vs.append(".").append(cs[i]) ;
            }
        }
        return vs.toString() ;
    }
    */
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCd02Vo.java
New file
@@ -0,0 +1,20 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import lombok.Data;
//链路检测
@Data
public class DataCd02Vo {
    public String status ;//F0 ç™»å½•,F1 é€€å‡ºç™»å½•,F2 åœ¨çº¿ä¿æŒ
    public String toString(){
        StringBuffer sb = new StringBuffer() ;
        sb.append("      é“¾è·¯æ£€æµ‹ : \n") ;
        sb.append("      è¯·æ±‚状态 : ") ;
        sb.append(status == null?"":(status.equals("F0")?"登录":(status.equals("F1")?"退出登录":(status.equals("F2")?"在线保持":status)))) ;
        sb.append("\n") ;
        return sb.toString() ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataCdC0Vo.java
New file
@@ -0,0 +1,7 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import lombok.Data;
@Data
public class DataCdC0Vo {
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DataV1_0_1.java
New file
@@ -0,0 +1,26 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import lombok.Data;
@Data
public class DataV1_0_1 implements java.io.Serializable{
    private static final long serialVersionUID = 202211271110001L;
    public String rtuAddr ;//RtuAddr
    public DataCd02Vo dataCd02Vo;//链路检测
    public DataCdC0Vo dataCdC0Vo;//终端自报实时数据
    public String dt ;//通信中间件产生发报时间(yyyy-MM-dd hh:mm:ss)
    public String toString(){
        StringBuffer sb = new StringBuffer() ;
        sb.append("   æŽ§åˆ¶å™¨åœ°å€ : " + (rtuAddr==null?"":rtuAddr) + "\n") ;
        sb.append("   ç»ˆç«¯æ•°æ®:\n") ;
        if(dataCd02Vo != null){
            sb.append(dataCd02Vo.toString()) ;
        }
        return sb.toString() ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/DriverV1_0_1.java
New file
@@ -0,0 +1,149 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import com.dy.common.mw.protocol.*;
import com.dy.common.util.DateTime;
import java.net.URI;
import java.net.URL;
@AnnotationDriver(name= ProtocolConstantV206V1_0_0.protocolName)
public class DriverV1_0_1 extends Driver {
    private static String scanRootPackage = "" ;
    //在Driver中是单例,随Driver的单例对象在单线程中运行
    private ParseParamsForUpV1_0_1 upCpParams ;
    private ParseParamsForDownV1_0_1 downCpParams ;
    private Boolean reportOrResponse_trueOrFalse = null ;
    private String rtuAddrInData = null ;
    public DriverV1_0_1(){
        upCpParams = new ParseParamsForUpV1_0_1() ;
        downCpParams = new ParseParamsForDownV1_0_1() ;
    }
    /**
     * æ‰«æè¯†åˆ«åŠŸèƒ½ç æ³¨è§£ç±»
     */
    @Override
    public void scanAnnotationCode() throws Exception{
        if(!scanRootPackage.endsWith(".")){
            scanRootPackage += "." ;
        }
        URL url = this.getClass().getResource("/" + scanRootPackage.replace('.', '/'));
        URI uri = new URI(url.toString());
        super.doScanAnnotationCode(this, ProtocolConstantV206V1_0_0.protocolName, uri, scanRootPackage) ;
    }
    /**
     * è§£æžä¸Šè¡Œæ•°æ®
     * @param isLowPower æ˜¯å¦åœ¨ä½ŽåŠŸè€—çŽ¯å¢ƒä¸‹è¿è¡Œ
     * @param rtuAddr
     * @param upBuffer
     * @param callback
     * @param upHex
     * @return
     */
    @Override
    public MidResult[] parseData(Boolean isLowPower, String rtuAddr, byte[] upBuffer, String upHex, DriverParserDataCallback callback, Object... params) {
        reportOrResponse_trueOrFalse = null ;
        boolean isFail = false ;
        String upCode = null ;
        try{
            CommonV1_0_1 cp = new CommonV1_0_1() ;
            cp.checkHead(upBuffer) ;
            cp.checkTail(upBuffer) ;
            String crcStr = cp.checkCrc_str(upBuffer) ;
            if(crcStr != null){
                return new MidResult[]{(new MidResultError(ProtocolConstantV206V1_0_0.protocolName, rtuAddr, "严重错误,上行数据CRC检查失败," + crcStr, null))} ;
            }
            rtuAddr = cp.parseRtuAddr(upBuffer) ;
            upCode = cp.parseCode(upBuffer) ;
            if(upCode == null){
                return new MidResult[]{(new MidResultError(ProtocolConstantV206V1_0_0.protocolName, rtuAddr, "严重错误,未能从上行数据中解析出功能码!", null))} ;
            }
            //Integer dataLen = cp.parseFrameLen(upBuffer) ;
            Data upData = new Data() ;
            upData.setRtuAddr(rtuAddr) ;
            upData.setProtocol(ProtocolConstantV206V1_0_0.protocolName);
            upData.setCode(upCode) ;
            upData.setHex(upHex) ;
            DataV1_0_1 dV1_0_1 = new DataV1_0_1() ;
            //dV1_0_1.version = cp.parseVersion(upBuffer) ;
            dV1_0_1.rtuAddr = rtuAddr ;
            dV1_0_1.dt = DateTime.yyyy_MM_dd_HH_mm_ss() ;
            upData.setSubData(dV1_0_1) ;
            this.upCpParams.clear();
            this.upCpParams.setValue(ProtocolConstantV206V1_0_0.protocolName,
                    rtuAddr,
                    upCode,
                    upHex,
                    upBuffer,
                    upData);
            CodeParse codeParse = this.getUpCodeParser(upCode) ;
            if(codeParse == null){
                return new MidResult[]{(new MidResultError(ProtocolConstantV206V1_0_0.protocolName, rtuAddr, "严重错误,未能得到上行数据功能码" + upCode + "处理类!", null))} ;
            }else{
                return codeParse.parse(isLowPower, this.upCpParams, new CodeParseCallback(){
                    @Override
                    public void callback(Boolean flag) {
                        reportOrResponse_trueOrFalse = flag ;
                        rtuAddrInData = dV1_0_1.getRtuAddr() ;
                    }
                });
            }
        } catch (Exception e) {
            isFail = true ;
            return new MidResult[]{(new MidResultError(ProtocolConstantV206V1_0_0.protocolName, rtuAddr, "严重错误,分析Rtu数据出错!数据为:" + upHex + (e.getMessage() == null?"":(",出错信息:" + e.getMessage())), e))} ;
        } finally{
            callback.callback(rtuAddr, upCode, upHex, reportOrResponse_trueOrFalse, isFail, rtuAddrInData);
        }
    }
    /**
     * æž„造下行数据(命令)
     * @param isLowPower æ˜¯å¦åœ¨ä½ŽåŠŸè€—çŽ¯å¢ƒä¸‹è¿è¡Œ
     * @param command å‘½ä»¤
     * @return
     */
    @Override
    public MidResult[] createCommand(Boolean isLowPower, Command command, Object... params) {
        String rtuAddr = command.getRtuAddr() ;
        if(rtuAddr == null){
            return new MidResult[]{(new MidResultError(ProtocolConstantV206V1_0_0.protocolName, null, "严重错误,命令中IMEI号为空,不能构建任何命令!", null))} ;
        }
        try {
            String commandCode = command.getCode() ;
            this.downCpParams.clear();
            this.downCpParams.setValue(
                    ProtocolConstantV206V1_0_0.protocolName,
                    rtuAddr,
                    command.getId(),
                    commandCode,
                    command.getParam(),
                    command.getAttachment());
            if(commandCode == null){
                return new MidResult[]{(new MidResultError(ProtocolConstantV206V1_0_0.protocolName, rtuAddr,  "严重错误,命令中功能码为空,不能构建任何命令!", null))} ;
            }else{
                CodeParse codeParse = this.getDownCodeParser(commandCode) ;
                if(codeParse == null){
                    return new MidResult[]{(new MidResultError(ProtocolConstantV206V1_0_0.protocolName, rtuAddr,  "严重错误,未能得到下行数据功能码" + commandCode + "处理类!", null))} ;
                }else{
                    return codeParse.parse(isLowPower, this.downCpParams, null);
                }
            }
        } catch (Exception e) {
            return new MidResult[]{(new MidResultError(ProtocolConstantV206V1_0_0.protocolName, rtuAddr,  "严重错误,构造下行数据出错!命令为:" + command.toString(), e))} ;
        }
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/OnLineV1_0_1.java
File was renamed from pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/OnLineV1_0_1.java
@@ -1,11 +1,12 @@
package com.dy.common.mw.protocol.pMeterV1_0_1;
package com.dy.common.mw.protocol.p206V1_0_0;
import com.dy.common.mw.protocol.AnnotationOnLine;
import com.dy.common.mw.protocol.OnLine;
@AnnotationOnLine(
        protocolName = ProtocolConstantV1_0_1.protocolName,
        priority = ProtocolConstantV1_0_1.priority)
        protocolName = ProtocolConstantV206V1_0_0.protocolName,
        priority = ProtocolConstantV206V1_0_0.priority)
@SuppressWarnings("unused")
public class OnLineV1_0_1 implements OnLine{
    /**
@@ -22,18 +23,15 @@
            //出错
            olr.result = OnLine.OnLineAction_fail ;
            olr.rtuAddr = null ;
            olr.meterNo = null ;
        }else if(!flag.booleanValue()){
            //不是本协议数据
            olr.result = OnLine.OnLineAction_success_noMe ;
            olr.rtuAddr = null ;
            olr.meterNo = null ;
        }else{
            //是本协议数据
            olr.result = OnLine.OnLineAction_success ;
            olr.rtuAddr = cp.parseRtuAddr(upBuf) ;
            olr.meterNo = cp.parseMeterNo(upBuf) ;
            olr.protocolName = ProtocolConstantV1_0_1.protocolName ;
            olr.protocolName = ProtocolConstantV206V1_0_0.protocolName ;
        }
        return olr;
    }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/ParseParamsForDownV1_0_1.java
New file
@@ -0,0 +1,40 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import com.dy.common.mw.protocol.CodeParseParams;
public class ParseParamsForDownV1_0_1 implements CodeParseParams{
    public String protocolName ;
    public String rtuAddr ;//控制器地址
    public String commandId ;
    public String commandCode ;
    public Object param ;
    public Object attachment ;
    public ParseParamsForDownV1_0_1(){}
    public void clear(){
        this.protocolName = null ;
        this.rtuAddr = null ;
        this.commandId = null ;
        this.commandCode = null ;
        this.param = null ;
        this.attachment = null ;
    }
    public void setValue(
            String protocolName,
            String rtuAddr,
            String commandId,
            String commandCode,
            Object param,
            Object attachment ){
        this.protocolName = protocolName ;
        this.rtuAddr = rtuAddr ;
        this.commandId = commandId ;
        this.commandCode = commandCode ;
        this.param = param ;
        this.attachment = attachment ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/ParseParamsForUpV1_0_1.java
New file
@@ -0,0 +1,39 @@
package com.dy.common.mw.protocol.p206V1_0_0;
import com.dy.common.mw.protocol.CodeParseParams;
import com.dy.common.mw.protocol.Data;
public class ParseParamsForUpV1_0_1 implements CodeParseParams{
    public String protocolName ;//协议名称
    public String rtuAddr ;//控制器址
    public String upCode ;//上行报文数据中的功能码
    public String upHex ;//行报文数据十六进制形式
    public byte[] upBuffer ;//行报文数据字节数组
    public Data data ;//解析后的数据
    public ParseParamsForUpV1_0_1(){}
    public void clear(){
        this.protocolName = null ;
        this.rtuAddr = null ;
        this.upCode = null ;
        this.upHex = null ;
        this.upBuffer = null ;
        this.data = null ;
    }
    public void setValue(String protocolName,
            String rtuAddr,
            String upCode,
            String upHex,
            byte[] upBuffer,
            Data data){
        this.protocolName = protocolName ;
        this.rtuAddr = rtuAddr ;
        this.upCode = upCode ;
        this.upHex = upHex ;
        this.upBuffer = upBuffer ;
        this.data = data ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/PrefixedDataAvailableV1_0_1.java
File was renamed from pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/PrefixedDataAvailableV1_0_1.java
@@ -1,36 +1,36 @@
package com.dy.common.mw.protocol.pMeterV1_0_1;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.core.buffer.BufferDataException;
import org.apache.mina.core.buffer.IoBuffer;
package com.dy.common.mw.protocol.p206V1_0_0;
import com.dy.common.mw.channel.tcp.PrefixedDataAvailableStatus;
import com.dy.common.mw.protocol.AnnotationPrefixedDataAvailable;
import com.dy.common.mw.protocol.PrefixedDataAvailable;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.core.buffer.BufferDataException;
import org.apache.mina.core.buffer.IoBuffer;
@AnnotationPrefixedDataAvailable(
        protocolName = ProtocolConstantV1_0_1.protocolName,
        priority = ProtocolConstantV1_0_1.priority,
        onLineDataMinLength = ProtocolConstantV1_0_1.onLineDataMinLength,
        headMinLength = ProtocolConstantV1_0_1.headMinLength)
public class PrefixedDataAvailableV1_0_1  implements PrefixedDataAvailable {
        protocolName = ProtocolConstantV206V1_0_0.protocolName,
        priority = ProtocolConstantV206V1_0_0.priority,
        onLineDataMinLength = ProtocolConstantV206V1_0_0.onLineDataMinLength,
        headMinLength = ProtocolConstantV206V1_0_0.headMinLength)
@SuppressWarnings("unused")
public class PrefixedDataAvailableV1_0_1 implements PrefixedDataAvailable {
    private static Logger log = LogManager.getLogger(PrefixedDataAvailableV1_0_1.class) ;
    private static final Logger log = LogManager.getLogger(PrefixedDataAvailableV1_0_1.class) ;
    
    private static String protocolName = ProtocolConstantV1_0_1.protocolName ;
    private static final String protocolName = ProtocolConstantV206V1_0_0.protocolName ;
    /**
     * åˆ†æžä¸Šçº¿æ•°æ®(网络连接后第一包数据)是否可获得
     * @param in
     * @param in IoBuffer
     * @param remain ä¸€å®šæ—¶å¤§äºŽ0的数据
     * @param minDataLength æœ€å°æ•°æ®é•¿åº¦
     * @param maxDataLength æœ€å¤§æ•°æ®é•¿åº¦ï¼Œè¾¾åˆ°æˆ–超过此长度,认为是垃圾数据。例如:数据头部是正确的,但合法数据结尾总不出现,认为此数据垃圾数据
     * @return ä¸æ˜¯æœ¬åè®®æ•°æ®æ—¶è¿”回空
     * @throws Exception
     * @throws Exception å¼‚常
     */
    public PrefixedDataAvailableStatus forOnLine(IoBuffer in, 
            int remain,
@@ -49,11 +49,12 @@
    /**
     * åˆ†æžä¸Šçº¿åŽ(网络连接后非第一包数据)是否可获得
     * @param in
     * @param protocolConf Rtu配置
     * @param maxDataLength
     * @return
     * @throws Exception
     * @param in IoBuffer
     * @param remain  å‰©ä½™
     * @param minDataLength æœ€å°æ•°æ®é•¿åº¦
     * @param maxDataLength æœ€å¤§æ•°æ®é•¿åº¦
     * @return PrefixedDataAvailableStatus
     * @throws Exception å¼‚常
     */
    @Override
    public PrefixedDataAvailableStatus forUpData(IoBuffer in, 
@@ -71,9 +72,11 @@
    }
    /**
     * è¿›è¡Œåˆ¤æ–­
     * @param preByte
     * @param maxDataLength
     * @return
     * @param preByte byte[]
     * @param minDataLength æœ€å°æ•°æ®é•¿åº¦
     * @param maxDataLength æœ€å¤§æ•°æ®é•¿åº¦
     * @return PrefixedDataAvailableStatus
     * @throws Exception å¼‚常
     */
    private PrefixedDataAvailableStatus doForData(byte[] preByte, int minDataLength, int maxDataLength) throws Exception{
        int remain = preByte.length ;
@@ -98,14 +101,14 @@
        }
        Integer dataLen = parseCommon.parseDataLen(preByte) ;
        String headHex = ByteUtil.bytes2Hex(preByte, true) ;
        if(dataLen == null){
            String headHex = ByteUtil.bytes2Hex(preByte, true) ;
            throw new BufferDataException("收到数据之帧前部:" + headHex + ",但严重错误,在进行断包与粘包检查时,未能得到数据帧的长度。");
        }
        
        if (dataLen <= 0 || dataLen > maxDataLength) {
            String headHex = ByteUtil.bytes2Hex(preByte, true) ;
            throw new BufferDataException("收到数据之帧前部:" + headHex + ",但严重错误,在进行断包与粘包检查时,数据帧的长度(" + dataLen + ")超出合法范围。");
        }
        
@@ -113,10 +116,12 @@
            //不断不粘
            return new PrefixedDataAvailableStatus().completed(dataLen) ;
        }else if(remain > dataLen){
            String headHex = ByteUtil.bytes2Hex(preByte, true) ;
            log.warn("收到数据之帧前部:" + headHex + ",但发生粘包现象。") ;
            return new PrefixedDataAvailableStatus().adjoined(dataLen) ;
        }else{
            // remain < dataLen
            String headHex = ByteUtil.bytes2Hex(preByte, true) ;
            log.warn("收到数据之帧前部:" + headHex + ",但发生断包现象。") ;
            return new PrefixedDataAvailableStatus().breaked() ;
        }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/ProtocolConstantV206V1_0_0.java
New file
@@ -0,0 +1,50 @@
package com.dy.common.mw.protocol.p206V1_0_0;
public class ProtocolConstantV206V1_0_0 {
    public static final String version = "1.0.1" ;
    public static final Byte versionByte = 101 ;
    /**
     * æ³¨è§£ç›¸å…³
     */
    public static final String protocolName = "p206V1_0_1" ;
    public static final int priority = 1 ;//优先级
    /**
     * RTU上线数据(上线后第一包数据)最小长度,设置该属性以备进行完整性检查,
     * å³æ–­åŒ…检查,使尽可能收全上线数据(取值范围1-100)
     */
    public static final int onLineDataMinLength = 30 ;//采用阀控回执(其长度最短)的字节数
    /**
     * RTU上报数据的头部最小长度,上报数据中,取这个最小长度的部分数据中,
     * è¦ä¸€å®šåŒ…含数据帧长度,以备取出数据帧长度来,进行完整性检查,
     * å³æ–­åŒ…与粘包检查(取值范围0-100,其中取值为0时,表示headMinLength数据无作用,由协议实现来控制)
     */
    public static final int headMinLength = 3 ;
    //帧起始
    public static final byte P_Head_Byte = (byte)0x68 ;
    public static final byte P_Tail_Byte = (byte)0x16 ;
    public static final String P_Head_Hex = "68" ;
    public static final String P_Tail_Hex = "16" ;
    public static final byte lenHead2Code = 10 ; //从头到功能码字节数组长度
    public static final byte lenTail = 2 ; //帧尾部字节数组长度
    /**
     * æ‰€åœ¨å­—节数组的位置(下标)
     */
    public static final int dataLenIndex = 1 ;//帧长度所在 å­—节数组起始下标
    public static final int ctrlIndex = 3 ;//控制域所在 å­—节数组起始下标
    public static final int rtuAddr1Index_start = 4 ;//控制器地址 å­—节数组开始下标
    public static final int rtuAddr1Index_end = 6 ;//控制器地址 å­—节数组开始下标
    public static final int rtuAddr2Index_start = 7 ;//控制器地址 å­—节数组截止下标
    public static final int rtuAddr2Index_end = 8 ;//控制器地址 å­—节数组截止下标
    public static final int codeIndex = 9 ;//功能码字节数组下标
    public static final int dataIndex = 10 ;//具体数据字节数组下标
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_02_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.*;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
import com.dy.common.util.CRC8_for_2_0;
import com.dy.common.util.DateTime;
@AnnotationCodeDown(ifAny={
        CodeV1_0_1.cd_06
})
public class Cd_02_Down  implements CodeParse {
    //private static Logger log = LogManager.getLogger(Cd_XY_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.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//IMEI号(电信平台设备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 = true ;//RTU不在线,命令是否缓存,低功耗时为true
        //对RTU上行数据的应答
        midRs.hasResponse = false ;//是否有应答
        midRs.maxSendTimes = 1 ;//对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) ;
        String rtuAddr = para.rtuAddr ;
        String rtuAddr1 = rtuAddr.substring(0, 6) ;
        String rtuAddr2 = rtuAddr.substring(6) ;
        index++ ;
        ByteUtil.string2BCD_BE(bsHead, rtuAddr1, index) ;
        index += 3 ;
        Integer rtuAddr2Int = Integer.parseInt(rtuAddr2) ;
        ByteUtilUnsigned.short2Bytes_BE(bsHead, rtuAddr2Int.shortValue(), index);
        index += 2 ;
        ByteUtil.hex2Bytes(para.commandCode, bsHead, index) ;
        byte[] bs = new byte[7] ;
        bs[0] = (byte)0xF2 ;
        ByteUtil.string2BCD_BE(bs, DateTime.yyMMddhhmmss(), 1) ;
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
        int len = bytes.length + ProtocolConstantV206V1_0_0.lenTail;
        bytes[ProtocolConstantV206V1_0_0.dataLenIndex] = (byte)len ;
        int crc = new CRC8_for_2_0().CRC8(bytes, ProtocolConstantV206V1_0_0.ctrlIndex, bytes.length -1) ;
        bs = new byte[ProtocolConstantV206V1_0_0.lenTail] ;
        bs[0] = (byte)crc ;
        bs[1] = ProtocolConstantV206V1_0_0.P_Tail_Byte ;
        bytes = ByteUtil.bytesMerge(bytes, bs) ;
        return bytes ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_02_Up.java
New file
@@ -0,0 +1,85 @@
package com.dy.common.mw.protocol.p206V1_0_0.parse;
import com.dy.common.mw.protocol.*;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.dy.common.mw.protocol.p206V1_0_0.*;
@AnnotationCodeUp(ifAny={
        CodeV1_0_1.cd_02
})
@SuppressWarnings("unused")
public class Cd_02_Up implements CodeParse{
    private static Logger log = LogManager.getLogger(Cd_02_Up.class);
    /**
     * åˆ†æžä¸Šè¡Œæ•°æ®
     */
    @Override
    public MidResult[] parse(Boolean isLowPower, CodeParseParams params, CodeParseCallback callback)throws Exception {
        ParseParamsForUpV1_0_1 para = (ParseParamsForUpV1_0_1)params ;
        int bsLen = new CommonV1_0_1().parseDataLen(para.upBuffer) ;
        if(bsLen > 0){
            this.doParse(para.upBuffer,
                    bsLen,
                    para.upCode,
                    para.data) ;
        }
        log.info("分析上行数据<" + CodeV1_0_1.getCodeName(para.upCode) + " RTU地址=" + para.rtuAddr + ">:\n" + para.data.toString());
        MidResultFromRtu midRs = new MidResultFromRtu() ;
        midRs.protocolName = para.protocolName ;//协议名称
        midRs.rtuAddr = para.rtuAddr ;//IMEI号
        midRs.upCode = para.upCode ;//上行数据中的功能码
        midRs.upHex = para.upHex ;//上行数据十六进制形式
        midRs.upBuffer = para.upBuffer ;//上行数据字节数组
        midRs.data = para.data ;//解析后的数据
        midRs.reportOrResponse_trueOrFalse = true ;//主动上报
        String confirmComCode = CodeV1_0_1.cd_02 ;
        ParseParamsForDownV1_0_1 downCpParams  = new ParseParamsForDownV1_0_1() ;
        downCpParams.setValue(
                ProtocolConstantV206V1_0_0.protocolName,
                para.rtuAddr,
                Command.defaultId,
                confirmComCode,
                null,
                null);
        //构造应答
        byte[] data = new Cd_02_Down().doParse(downCpParams) ;
        MidResultToRtu confirmCommand = new MidResultToRtu() ;
        confirmCommand.protocolName = para.protocolName ;//协议名称
        confirmCommand.rtuAddr = para.rtuAddr ;//IMEI号
        confirmCommand.commandId = Command.defaultId ;//命令ID,发起命令的客户端(web端)生成,以匹配命令结果
        confirmCommand.downCode = confirmComCode ;//下行命令功能码;
        confirmCommand.downBuffer = data ;//下行命令数据
        confirmCommand.downBufHex = ByteUtil.bytes2Hex(data, true) ;//下行命令数据十六进制形式
        confirmCommand.hasResponse = false ;//是否有应答
        confirmCommand.maxSendTimes = 1 ;//命令最大发送次数(当收不到应答时,将重发2次),如果不设置,命令缓存器进行补充设置
        confirmCommand.isSendFirst = true ;//确认命令,优先发送
        confirmCommand.isCachForOffLine = false ;//RTU不在线,命令是否缓存
        callback.callback(midRs.reportOrResponse_trueOrFalse);
        return new MidResult[]{midRs, confirmCommand} ;
    }
    /**
     * æ‰§è¡Œåˆ†æž
     * @param bs
     * @param bsLen å­—节长度(总包长,包括包头和包尾)
     * @param dataCode åŠŸèƒ½ç 
     * @param data æ•°æ®
     * @throws Exception å¼‚常
     */
    protected void doParse(byte[] bs, int bsLen, String dataCode, Data data) throws Exception {
        DataV1_0_1 dV1 = (DataV1_0_1)data.getSubData() ;
        DataCd02Vo cdData = new DataCd02Vo() ;
        dV1.dataCd02Vo = cdData ;
        cdData.status = ByteUtil.bytes2Hex(bs, false, ProtocolConstantV206V1_0_0.dataIndex, 1) ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/CommonV1_0_1.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd01Vo.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd02Vo.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd03Vo.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd0405Vo.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataCd06Vo.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DataV1_0_1.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/DriverV1_0_1.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/ParseParamsForDownV1_0_1.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/ParseParamsForUpV1_0_1.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/ProtocolConstantV1_0_1.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_01_Up.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_02_Up.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_03_Up.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_0405_Up.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_06_Down.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_06_Up.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/parse/Cd_XY_Down.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/pMeterV1_0_1/˵Ã÷.txt
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/support/SupportUnit.java
@@ -39,31 +39,36 @@
    public void start(UnitStartedCallbackInterface callback) throws Exception {
        if(!started){
            started = true ;
            if(confVo.enableThreadPool){
                TreadPoolFactory.initThreadPoolShort("短任务工作线程池",
                        this.confVo.short_maxThread,
                        this.confVo.short_minThread,
                        this.confVo.short_freeTimeout,
            if(confVo.enableShortThreadPool) {
                TreadPoolFactory.initThreadPoolShort("短任务工作线程池",
                        this.confVo.short_maxThread,
                        this.confVo.short_minThread,
                        this.confVo.short_freeTimeout,
                        this.confVo.short_busyTimeout);
                TreadPoolFactory.initThreadPoolLong("长任务工作线程池",
                        this.confVo.long_maxThread,
                        this.confVo.long_minThread,
                        this.confVo.long_freeTimeout,
                        this.confVo.long_busyTimeout);
                if(this.confVo.showStartInfo){
                    System.out.println("线程池模块成功启动");
                }
            }else{
                System.out.println("短线程池配置不启动");
            }
            callback.call(null);
            if(confVo.enableLongThreadPool) {
                TreadPoolFactory.initThreadPoolLong("长任务工作线程池",
                        this.confVo.long_maxThread,
                        this.confVo.long_minThread,
                        this.confVo.long_freeTimeout,
                        this.confVo.long_busyTimeout);
            }else{
                System.out.println("长线程池配置不启动");
            }
            if(this.confVo.showStartInfo){
                System.out.println("线程池模块成功启动");
            }
        }
        callback.call(null);
    }
    @Override
    public void stop(UnitStartedCallbackInterface callback) throws Exception {
    public void stop(UnitStartedCallbackInterface callback) {
    }
    
    /*
    public static void main(String[] args) throws Exception{
        SupportUnitConfigVo supVo = new SupportUnitConfigVo() ;
        //短工作时长线程池,线程负责用时较短的工作任务
@@ -82,8 +87,9 @@
            supVo.long_busyTimeout = -1 ;
        }
        
        supVo.enableThreadPool = true ;
        supVo.enableShortThreadPool = true ;
        supVo.enableLongThreadPool = true ;
        supVo.showStartInfo = true ;
        SupportUnit supUnit = SupportUnit.getInstance() ;
@@ -94,6 +100,7 @@
        supUnit.start(obj -> {
        });
    }
    private static class AdapterImp_SupportUnit implements SupportUnitAdapter {
        
        private SupportUnitConfigVo configVo = null ;
@@ -106,7 +113,6 @@
        public void setConfig(SupportUnitConfigVo configVo) {
            this.configVo = configVo;
        }
    }
    */
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/support/SupportUnitConfigVo.java
@@ -1,8 +1,10 @@
package com.dy.common.mw.support;
public class SupportUnitConfigVo {
    public boolean enableThreadPool ;
    public boolean enableShortThreadPool ;
    public boolean enableLongThreadPool ;
    //短任务线程池
    public int short_maxThread ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/queue/Queue.java
@@ -4,7 +4,7 @@
import org.apache.logging.log4j.Logger;
/**
 * é˜Ÿåˆ—,先进先出
 * é˜Ÿåˆ—,先进先出,非线程安全
 */
public class Queue {
    @SuppressWarnings("unfinal")
@@ -62,6 +62,7 @@
     */
    @SuppressWarnings("unused")
    public void pushHead(NodeObj obj)throws Exception{
        //两个线程环境,需要同步锁
        synchronized(synObj){
            if(obj == null){
                return ;
@@ -89,6 +90,7 @@
     * @param obj å…¥åˆ—的对象
     */
    public void pushTail(NodeObj obj)throws Exception{
        //两个线程环境,需要同步锁
        synchronized(synObj){
            if(obj == null){
                return ;
@@ -116,6 +118,7 @@
     * @return å‡ºåˆ—对象
     */
    public NodeObj pop(){
        //两个线程环境,需要同步锁
        synchronized(synObj){
            NodeObj obj = null ;
            if(this.size > 0){
@@ -139,11 +142,14 @@
     */
    @SuppressWarnings("unused")
    public Node getFirstNode(){
        Node node = this.head.next ;
        if(node != this.tail){
            return node ;
        //两个线程环境,需要同步锁
        synchronized(synObj) {
            Node node = this.head.next;
            if (node != this.tail) {
                return node;
            }
            return null;
        }
        return null ;
    }
    /**
     * å¾—到最后一个节点,但不把节点从队列中清除
@@ -151,11 +157,14 @@
     */
    @SuppressWarnings("unused")
    public Node getLastNode(){
        Node node = this.tail.pre ;
        if(node != this.head){
            return node ;
        //两个线程环境,需要同步锁
        synchronized(synObj) {
            Node node = this.tail.pre;
            if (node != this.head) {
                return node;
            }
            return null;
        }
        return null ;
    }
    
    /**
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/threadPool/ThreadPoolImp.java
@@ -75,36 +75,6 @@
         */
        private Logger log = LogManager.getLogger(MonitorThread.class.getName());
        
        /**
         * å¾—到默认唯一实例
         * @return
         */
//        public MyThreadPool getDefaultInstance(){
//            if(myPool == null){
//                myPool = new MyThreadPool(null, null, null, null, null) ;
//            }
//            return myPool ;
//        }
        /**
         * å¾—到唯一实例
         * @param poolName
         * @param maxNum
         * @param minNum
         * @param freeTimeout
         * @param busyTimeout
         * @return
         */
//        public MyThreadPool getInstance(
//                String poolName ,
//                Integer maxNum ,
//                Integer minNum ,
//                Long freeTimeout ,
//                Long busyTimeout){
//            if(myPool == null){
//                myPool = new MyThreadPool(poolName, maxNum, minNum, freeTimeout, busyTimeout) ;
//            }
//            return myPool ;
//        }
        /**
         * çº¿ç¨‹æ± æž„造方法
@@ -125,8 +95,8 @@
            }
            this.poolName = poolName ;
            
            if(maxNum == null || maxNum.intValue() <= 0){
                maxNum = -1 ;
            if(maxNum == null || maxNum.intValue() < 0){
                maxNum = 65535 ;
            }
            if(minNum == null || minNum.intValue() < 0){
                minNum = 0 ;
@@ -148,20 +118,19 @@
            }else{
                this.busyTimeout = busyTimeout ;    
            }
            this.busiThreads = new ArrayList<MyThread>();
            this.freeThreads = new ArrayList<MyThread>();
            //最小化线程池
            for (int i = 0; i < this.minNum ; i++) {
                MyThread t = new MyThread(this);
                t.start();
                this.freeThreads.add(t);
                this.currNum++;
            if(maxNum != 0){
                this.busiThreads = new ArrayList<>();
                this.freeThreads = new ArrayList<>();
                //最小化线程池
                for (int i = 0; i < this.minNum ; i++) {
                    MyThread t = new MyThread(this);
                    t.start();
                    this.freeThreads.add(t);
                    this.currNum++;
                }
                this.monitorThread = new MonitorThread(this) ;
                this.monitorThread.start() ;
            }
            this.monitorThread = new MonitorThread(this) ;
            this.monitorThread.start() ;
        }
        /**
@@ -171,6 +140,9 @@
         */
        @Override
        public void putJob(Job job) throws Exception {
            if(this.busiThreads == null || this.freeThreads == null){
                throw new Exception("线程池未启动") ;
            }
            synchronized(this.synObj) {
                //log.debug("工作任务分配到线程池中。") ;
                MyThread t = null ;
@@ -215,7 +187,10 @@
        /**
         * çº¿ç¨‹å·¥ä½œå®Œæˆï¼Œä»ŽbusiThreads回归freeThreads
         */
        protected void freeThread(MyThread t) {
        protected void freeThread(MyThread t) throws Exception {
            if(this.busiThreads == null || this.freeThreads == null){
                throw new Exception("线程池未启动") ;
            }
            synchronized (synObj) {
                busiThreads.remove(t);
                freeThreads.add(t);
@@ -236,7 +211,7 @@
            /**
             * 
             * @param pool
             * @param pool æ± 
             */
            public MonitorThread(MyThreadPool pool){
                this.pool = pool ;
@@ -302,6 +277,7 @@
                            }
                        }//end synchronized (pool.synObj)
                    }catch(Exception e){
                        e.printStackTrace();
                    }finally{
                        continue ;
                    }
@@ -354,7 +330,7 @@
        
        /**
         * è®¾ç½®çº¿ç¨‹å·¥ä½œå¯¹è±¡
         * @param job
         * @param job å·¥ä½œ
         */
        protected void putJob(Job job) throws Exception {
            if(job == null){
@@ -418,13 +394,19 @@
        }
        
        public void free(){
            //使本线程回归空闲线程池
            pool.freeThread(this);
            //空闲开始记时
            this.time = System.currentTimeMillis() ;
            // æ²¡æœ‰å¯åšçš„了
            this.canJob = false;
            log.debug("线程池(" + this.pool.poolName + ")中的线程回归空闲集合。");
            try{
                //使本线程回归空闲线程池
                pool.freeThread(this);
                //空闲开始记时
                this.time = System.currentTimeMillis() ;
                // æ²¡æœ‰å¯åšçš„了
                this.canJob = false;
                log.debug("线程池(" + this.pool.poolName + ")中的线程回归空闲集合。");
            }catch (Exception e){
                log.error("线程池(" + pool.poolName + ")的工作线程释放回归时发生异常:\n" + e.getMessage(), e);
                e.printStackTrace();
            }
        }
        /**
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/threadPool/TreadPoolFactory.java
@@ -8,9 +8,9 @@
    
    /**
     * åˆå§‹åŒ–线程池
     * @param threadPoolName çº¿ç¨‹æ± å’Œçº¿ç¨‹åç§°
     * @param maxThreadNum çº¿ç¨‹æ± æœ€å¤§çº¿ç¨‹æ•° ï¼Œè‹¥ä¸º-1,不受限制
     * @param minThreadNum çº¿ç¨‹æ± æœ€å°çº¿ç¨‹æ•°ï¼Œæˆ–初始线程数
     * @param poolName çº¿ç¨‹æ± å’Œçº¿ç¨‹åç§°
     * @param maxNum çº¿ç¨‹æ± æœ€å¤§çº¿ç¨‹æ•° ï¼Œè‹¥ä¸º-1,不受限制
     * @param minNum çº¿ç¨‹æ± æœ€å°çº¿ç¨‹æ•°ï¼Œæˆ–初始线程数
     * @param freeTimeout ç©ºé—²çº¿ç¨‹è¶…æ—¶æ—¶é•¿(秒)
     * @param busyTimeout å¿™ç¢Œçº¿ç¨‹è¶…æ—¶æ—¶é•¿(秒),若为-1,不受限制
     * @return çº¿ç¨‹æ± å®žä¾‹
@@ -30,9 +30,9 @@
    
    /**
     * åˆå§‹åŒ–线程池
     * @param threadPoolName çº¿ç¨‹æ± å’Œçº¿ç¨‹åç§°
     * @param maxThreadNum çº¿ç¨‹æ± æœ€å¤§çº¿ç¨‹æ•°ï¼Œè‹¥ä¸º-1,不受限制
     * @param minThreadNum çº¿ç¨‹æ± æœ€å°çº¿ç¨‹æ•°ï¼Œæˆ–初始线程数
     * @param poolName çº¿ç¨‹æ± å’Œçº¿ç¨‹åç§°
     * @param maxNum çº¿ç¨‹æ± æœ€å¤§çº¿ç¨‹æ•°ï¼Œè‹¥ä¸º-1,不受限制
     * @param minNum çº¿ç¨‹æ± æœ€å°çº¿ç¨‹æ•°ï¼Œæˆ–初始线程数
     * @param freeTimeout ç©ºé—²çº¿ç¨‹è¶…æ—¶æ—¶é•¿(秒)
     * @param busyTimeout å¿™ç¢Œçº¿ç¨‹è¶…æ—¶æ—¶é•¿(秒),若为-1,不受限制
     * @return çº¿ç¨‹æ± å®žä¾‹
@@ -51,8 +51,6 @@
    }
    /**
     * å¾—到唯一线程池实例
     * @param dataSourceName
     * @return
     * @throws Exception
     */
    public final static ThreadPool.Pool getThreadPoolShort()
@@ -64,9 +62,6 @@
    }
    /**
     * å¾—到唯一线程池实例
     * @param dataSourceName
     * @return
     * @throws Exception
     */
    public final static ThreadPool.Pool getThreadPoolLong()
        throws Exception {
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/ByteUtil.java
@@ -9,7 +9,7 @@
     * å°†å­—节数组合并到字节数组上
     * @param bGroup1 è¢«åˆå¹¶æ•°ç»„
     * @param bGroup2 åˆå¹¶æ•°ç»„
     * @return åˆå¹¶åŽæ•°ç»„
     * @return è¿”回 åˆå¹¶åŽæ•°ç»„
     */
    public static byte[] bytesMerge(byte[] bGroup1, byte[] bGroup2){
        if(bGroup1 == null && bGroup2 == null){
@@ -29,11 +29,11 @@
    /**
     * åˆ¤æ–­æ‰€æœ‰å­—节是否为0xFF
     * @param bs
     * @param index
     * @param len
     * @return
     * @throws Exception
     * @param bs å­—节数组
     * @param index ä¸‹æ ‡ä½
     * @param len é•¿åº¦
     * @return è¿”回 è¿”回
     * @throws Exception å¼‚常
     */
    public static boolean bytesIsAll0xFF(byte[] bs, int index, int len)throws Exception {
        int count = 0 ;
@@ -42,14 +42,14 @@
                count++ ;
            }
        }
        return count==len?true:false ;
        return count == len;
    }
    /**
     * äºŒè¿›åˆ¶è½¬åè¿›åˆ¶æ•°
     * @param str
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static int binary2Int(String str) throws Exception {
        int cnt=0;
@@ -69,13 +69,13 @@
        return sum;
    }
    /**
     * å­—节转存二进制
     *
     *
     * @param b byte
     * @throws Exception
     * @return String
     * @throws Exception å¼‚常
     * @return è¿”回 String
     */
    public static String byte2Binary(byte b) throws Exception {
        int n = (b + 256) % 256 + 256;
@@ -87,11 +87,11 @@
    }
    /**
     * å­—节转存8位二进制
     *
     *
     * @param b
     *            byte
     * @throws Exception
     * @return String
     * @throws Exception å¼‚常
     * @return è¿”回 String
     */
    public static String byte2bit8Binary(byte b) throws Exception {
        String s = byte2Binary(b);
@@ -101,13 +101,13 @@
        }
        return s;
    }
    /**
     * å­—节取bit
     * @param b
     * @param index
     * @throws Exception
     * @return String
     * @param b
     * @throws Exception å¼‚常
     * @return è¿”回 String
     */
    public static byte[] getBit(byte b) throws Exception {
        byte[] bs = new byte[8] ;
@@ -125,9 +125,9 @@
    /**
     * å­—节取bit
     * @param b
     * @param index
     * @throws Exception
     * @return String
     * @param index ä¸‹æ ‡ä½
     * @throws Exception å¼‚常
     * @return è¿”回 String
     */
    public static byte getBit(byte b, byte index) throws Exception {
        if(index == 0){
@@ -153,11 +153,11 @@
    /**
     * ä¸€ä¸ªå­—节转正整数
     *
     *
     * @param b
     *            byte
     * @throws Exception
     * @return String
     * @throws Exception å¼‚常
     * @return è¿”回 String
     */
    public static Short byte2PlusInt(byte b) throws Exception {
        short v = b ;
@@ -167,13 +167,13 @@
        return v ;
    }
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * double转换byte
     * @param bs byte[]
     * @param bs å­—节数组 byte[]
     * @param value double double类型的参数
     * @param from int
     * @param from å¼€å§‹ä½ int
     */
    public static void double2Bytes_BE(byte[] bs, double value, int from)throws Exception {
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 8);
@@ -188,9 +188,9 @@
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * double转换byte,字节顺序是倒的
     * @param bs byte[]
     * @param bs å­—节数组 byte[]
     * @param value double double类型的参数
     * @param from int
     * @param from å¼€å§‹ä½ int
     */
    public static void double2Bytes_LE(byte[] bs, double value, int from)throws Exception {
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 8);
@@ -205,8 +205,8 @@
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * byte转换double
     * @param bs byte[]
     * @param from int
     * @param bs å­—节数组 byte[]
     * @param from å¼€å§‹ä½ int
     */
    public static double bytes2Double_BE(byte[] bs, int from) throws Exception {
        long l = bytes2Long_BE(bs, from);
@@ -216,8 +216,8 @@
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * byte转换double,字节顺序是倒的
     * @param bs byte[]
     * @param from int
     * @param bs å­—节数组 byte[]
     * @param from å¼€å§‹ä½ int
     */
    public static double bytes2Double_LE(byte[] bs, int from) throws Exception {
        long l = bytes2Long_LE(bs, from);
@@ -306,7 +306,7 @@
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * è½¬æ¢long型为byte数组
     * è½¬æ¢long型为byte数组
     * @value bs byte[]
     * @value value long
     * @value from int
@@ -315,8 +315,8 @@
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 8);
        if (b) {
            for (int i = 0; i < 8; i++) {
                bs[from + i] = Long.valueOf(value & 0xff).byteValue();
                value = value >> 8;
                bs[from + i] = Long.valueOf(value & 0xff).byteValue();
                value = value >> 8;
            if(value == 0){
                break ;
            }
@@ -325,12 +325,12 @@
            throw new Exception("long2Bytes时数组越界");
        }
    }
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * 8位字节数组转换为长整型
     * @param bs byte[]
     * @return
     * @param bs å­—节数组 byte[]
     * @return è¿”回
     */
    public static long bytes2Long_BE(byte[] bs) {
        int len = bs.length ;
@@ -347,16 +347,16 @@
                l = l | ls[i] ;
            }
            return l;
        }
        }
        return 0L ;
    }
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * 8位字节数组转换为长整型
     * @param bs byte[]
     * @param from int
     * @return
     * @param bs å­—节数组 byte[]
     * @param from å¼€å§‹ä½ int
     * @return è¿”回
     */
    public static long bytes2Long_BE(byte[] bs, int from) throws Exception {
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 8);
@@ -388,10 +388,10 @@
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * 8位字节数组转换为长整型
     * @param bs byte[]
     * @param from int
     * @param bs å­—节数组 byte[]
     * @param from å¼€å§‹ä½ int
     * @param end int
     * @return
     * @return è¿”回
     */
    public static long bytes2Long_BE(byte[] bs, int from, int end) throws Exception {
        boolean b = isOutOfArrLength(bs.length, end);
@@ -414,13 +414,13 @@
        }
    }
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * 8位字节数组转换为长整型
     * @param bs byte[]
     * @return
     * @param bs å­—节数组 byte[]
     * @return è¿”回
     */
    public static long bytes2Long_LE(byte[] bs) {
        int len = bs.length ;
@@ -437,16 +437,16 @@
                l = l | ls[i] ;
            }
            return l;
        }
        }
        return 0L ;
    }
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * 8位字节数组转换为长整型
     * @param bs byte[]
     * @param from int
     * @return
     * 8位字节数组转换为长整型
     * @param bs å­—节数组 byte[]
     * @param from å¼€å§‹ä½ int
     * @return è¿”回
     */
    public static long bytes2Long_LE(byte[] bs, int from) throws Exception {
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 8);
@@ -479,10 +479,10 @@
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * 8位字节数组转换为长整型
     * @param bs byte[]
     * @param from int
     * @param bs å­—节数组 byte[]
     * @param from å¼€å§‹ä½ int
     * @param end int
     * @return
     * @return è¿”回
     */
    public static long bytes2Long_LE(byte[] bs, int from, int end) throws Exception {
        boolean b = isOutOfArrLength(bs.length, end);
@@ -551,8 +551,9 @@
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * 4位字节数组转换为整型
     * @param b
     * @return
     * @param bs å­—节数组
     * @param from å¼€å§‹ä½
     * @return è¿”回
     */
    public static int bytes2Int_BE(byte[] bs, int from) throws Exception {
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 4);
@@ -573,13 +574,13 @@
            throw new Exception("byte2Int时数组越界");
        }
    }
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * 4位字节数组转换为整型,字节顺序是倒的
     * @param b
     * @return
     * @param bs å­—节数组 å­—节数组
     * @return è¿”回
     */
    public static int bytes2Int_LE(byte[] bs, int from) throws Exception {
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 4);
@@ -600,7 +601,7 @@
            throw new Exception("byte2Int时数组越界");
        }
    }
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
@@ -674,14 +675,14 @@
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * 2位字节数组转换为短整型
     * @param b
     * @return
     * @param bs å­—节数组 å­—节数组
     * @return è¿”回
     */
    public static short bytes2Short_BE(byte[] bs, int from) throws Exception {
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 2);
        if (b) {
            int s = 0;
            int s0 = bs[from + 0] ;
            int s0 = bs[from + 0] ;
            int s1 = bs[from + 1] ;
            // s1不变
@@ -697,14 +698,14 @@
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * 2位字节数组转换为短整型,字节顺序是倒的
     * @param b
     * @return
     * @param bs å­—节数组 å­—节数组
     * @return è¿”回
     */
    public static short bytes2Short_LE(byte[] bs, int from) throws Exception {
        boolean b = isOutOfArrLength(bs.length, (from - 1) + 2);
        if (b) {
            int s = 0;
            int s0 = bs[from + 0] ;
            int s0 = bs[from + 0] ;
            int s1 = bs[from + 1] ;
            // s0不变
@@ -718,11 +719,11 @@
    }
    /**
     * å­—符到一字节转换
     *
     *
     * @value bs byte[]
     * @value ch char char类型的参数
     * @value index int
     * @return
     * @return è¿”回
     */
    public static void char2Bytes(byte[] bs, char ch, int index)throws Exception {
        boolean b = isOutOfArrLength(bs.length, index);
@@ -735,10 +736,9 @@
    /**
     * ä¸€å­—节转换为字符
     *
     * @param b
     * @param bs å­—节数组 å­—节数组
     * @value index int
     * @return
     * @return è¿”回
     */
    public static char bytes2Char(byte[] bs, int index) throws Exception {
        boolean b = isOutOfArrLength(bs.length, index);
@@ -751,13 +751,13 @@
    /**
     * å­—符串型数字转成byte
     *
     *
     * @param s
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static byte string2byte(String s) throws Exception {
        int n = 0;
        int n ;
        try {
            n = Integer.parseInt(s);
        } catch (Exception e) {
@@ -772,7 +772,7 @@
     * @value bs byte[]
     * @value str String
     * @value from int
     * @return
     * @return è¿”回
     * @throws java.io.UnsupportedEncodingException
     */
    public static int string2Bytes_BE(byte[] bs, String str, int from, int end)throws Exception {
@@ -798,7 +798,7 @@
     * @value bs byte[]
     * @value str String
     * @value from int
     * @return
     * @return è¿”回
     * @throws java.io.UnsupportedEncodingException
     */
    public static int string2Bytes_LE(byte[] bs, String str, int from, int end)throws Exception {
@@ -824,7 +824,7 @@
     * @value bs byte[]
     * @value str String
     * @value from int
     * @return
     * @return è¿”回
     * @throws java.io.UnsupportedEncodingException
     */
    public static int string2Bytes_BE(byte[] bs, String str, int from)throws Exception {
@@ -846,7 +846,7 @@
     * @value bs byte[]
     * @value str String
     * @value from int
     * @return
     * @return è¿”回
     * @throws java.io.UnsupportedEncodingException
     */
    public static int string2Bytes_LE(byte[] bs, String str, int from)throws Exception {
@@ -898,10 +898,10 @@
    /**
     * åˆ¤æ–­æ•°ç»„下标是否越界
     *
     *
     * @value bsLength æ•°ç»„总长度
     * @value toSite æ•°ç»„偏移量
     * @return
     * @return è¿”回
     */
    private static boolean isOutOfArrLength(int bsLength, int toSite) {
        if (bsLength > toSite) {
@@ -911,104 +911,104 @@
        }
    }
    /**
     * å­—节数组转换成十六进制的字符串
     *
     * @param b byte[]
     * å­—节数组转换成十六进制的字符串
     *
     * @param src byte[]
     * @param hasBlank 16进制是否用空格分隔
     * @return String
     * @return è¿”回 String
     */
    public static String bytes2Hex(byte[] src, boolean hasBlank){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String str = Integer.toHexString(v);
            if (str.length() < 2) {
    public static String bytes2Hex(byte[] src, boolean hasBlank){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String str = Integer.toHexString(v);
            if (str.length() < 2) {
                str = "0" + str;
            }
            }
            if (hasBlank) {
                if (i == 0) {
                    stringBuilder.append(str);
                    stringBuilder.append(str);
                } else {
                    stringBuilder.append(" " + str);
                    stringBuilder.append(" " + str);
                }
            } else {
                stringBuilder.append(str);
                stringBuilder.append(str);
            }
        }
        }
        return stringBuilder.toString().toUpperCase(Locale.US);
    }
    }
    /**
     * å­—节数组转换成十六进制的字符串
     *
     * @param b byte[]
     * å­—节数组转换成十六进制的字符串
     *
     * @param src byte[]
     * @param hasBlank 16进制是否用空格分隔
     * @param from
     * @param len
     * @return String
     * @param from å¼€å§‹ä½
     * @param len é•¿åº¦
     * @return è¿”回 String
     */
    public static String bytes2Hex(byte[] src, boolean hasBlank, int from, int len){
        if (src == null || src.length <= 0 || src.length < from + len) {
            return null;
        }
    public static String bytes2Hex(byte[] src, boolean hasBlank, int from, int len){
        if (src == null || src.length <= 0 || src.length < from + len) {
            return null;
        }
        byte[] bb = new byte[len];
        for (int i = 0 ; i < len; i++) {
            bb[i] = src[from + i];
        }
        return bytes2Hex(bb, hasBlank) ;
    }
    /**
    }
    /**
     * åå…­è¿›åˆ¶è½¬å­—节数组
     * @param hexString the hex string
     * @return byte[]
     */
    public static byte[] hex2Bytes(String hex) {
        if (hex == null || hex.equals("")) {
            return null;
        }
        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]));
        }
        return d;
    }
    /**
     * @param hex the hex string
     * @return è¿”回 byte[]
     */
    public static byte[] hex2Bytes(String hex) {
        if (hex == null || hex.equals("")) {
            return null;
        }
        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]));
        }
        return d;
    }
    /**
     * åå…­è¿›åˆ¶è½¬å­—节数组
     * @param hexString the hex string
     * @return byte[]
     */
    public static int hex2Bytes(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]));
     * @param hex the hex string
     * @return è¿”回 byte[]
     */
    public static int hex2Bytes(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[i] ;
        }
        return fromIndex ;
    }
        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进制字符串
     *
     * @param bytes å¾…转换byte[]
     * @return è½¬æ¢åŽçš„字符串
     * @return è¿”回 è½¬æ¢åŽçš„字符串
     */
    public static String bytesToHex(byte[] bytes) {
        //一个byte为8位,可用两个十六进制位标识
@@ -1032,7 +1032,7 @@
     * å°†16进制字符串转换为byte[]
     *
     * @param str å¾…转换字符串
     * @return è½¬æ¢åŽçš„byte[]
     * @return è¿”回 è½¬æ¢åŽçš„byte[]
     */
    public static byte[] hexToBytes(String str) {
        if (str == null || "".equals(str.trim())) {
@@ -1051,18 +1051,18 @@
    /**
     * Convert char to byte
     * @param c char
     * @return byte
     * @return è¿”回 byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
    }
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * æ•´å½¢è½¬æˆBCD编码
     * @param l
     * @return
     * @param i
     * @return è¿”回
     */
    public static byte[] int2BCD_BE(int i)throws Exception {
        String str = "" + i;
@@ -1079,8 +1079,8 @@
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * æ•´å½¢è½¬æˆBCD编码,字节顺序是倒的
     * @param l
     * @return
     * @param i
     * @return è¿”回
     */
    public static byte[] int2BCD_LE(int i)throws Exception {
        String str = "" + i;
@@ -1099,7 +1099,7 @@
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * é•¿æ•´å½¢è½¬æˆBCD编码
     * @param l
     * @return
     * @return è¿”回
     */
    public static byte[] long2BCD_BE(long l)throws Exception {
        String str = "" + l;
@@ -1118,7 +1118,7 @@
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * é•¿æ•´å½¢è½¬æˆBCD编码,字节顺序是倒的
     * @param l
     * @return
     * @return è¿”回
     */
    public static byte[] long2BCD_LE(long l) throws Exception {
        String str = "" + l;
@@ -1137,30 +1137,30 @@
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * å­—符串型数字转成BCD编码
     * @param s
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static byte[] string2BCD_BE(String s) throws Exception {
        byte[] b = null;
        byte[] b ;
        if (s.length() % 2 == 0) {
            b = new byte[s.length() / 2];
        } else {
            b = new byte[(s.length() / 2) + 1];
        }
        encodeBCD_BE(s, b, 0, b.length);
        return b ;
    }
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * å­—符串转换成byte数组
     * @value bs byte[]
     * @value str String
     * @value fromIndex int
     * @return
     * @throws java.io.Exception
     * @return è¿”回
     * @throws Exception å¼‚常 å¼‚常
     */
    public static int string2BCD_BE(byte[] bs, String str, int fromIndex)throws Exception {
        byte[] bb = string2BCD_BE(str);
@@ -1179,8 +1179,8 @@
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * å­—符串型数字转成BCD编码,字节顺序是倒的
     * @param s
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static byte[] string2BCD_LE(String s) throws Exception {
        byte[] b = null;
@@ -1193,15 +1193,15 @@
        return b;
    }
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * å­—符串转换成byte数组
     * @value bs byte[]
     * @value str String
     * @value fromIndex int
     * @return
     * @throws java.io.Exception
     * @return è¿”回
     * @throws Exception å¼‚常 å¼‚常
     */
    public static int string2BCD_LE(byte[] bs, String str, int fromIndex)throws Exception {
        byte[] bb = string2BCD_LE(str);
@@ -1221,10 +1221,8 @@
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * BCD编码转成整型
     * @param b
     * @param startIndex
     * @param endIndex
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static int BCD2Int_BE(byte b) throws Exception {
        String str = "";
@@ -1237,10 +1235,8 @@
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * BCD编码转成整型,字节顺序是倒的
     * @param b
     * @param startIndex
     * @param endIndex
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static int BCD2Int_LE(byte b) throws Exception {
        String str = "";
@@ -1255,8 +1251,8 @@
     * @param b
     * @param startIndex
     * @param endIndex
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static int BCD2Int_BE(byte[] b, int startIndex, int endIndex)throws Exception {
        String str = "";
@@ -1271,8 +1267,8 @@
     * @param b
     * @param startIndex
     * @param endIndex
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static int BCD2Int_LE(byte[] b, int startIndex, int endIndex)throws Exception {
        String str = "";
@@ -1287,8 +1283,8 @@
     * @param b
     * @param startIndex
     * @param endIndex
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static long BCD2Long_BE(byte[] b, int startIndex, int endIndex)throws Exception {
        String str = "";
@@ -1304,8 +1300,8 @@
     * @param b
     * @param startIndex
     * @param endIndex
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static long BCD2Long_LE(byte[] b, int startIndex, int endIndex)throws Exception {
        String str = "";
@@ -1320,8 +1316,8 @@
     * @param b
     * @param startIndex
     * @param endIndex
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static String BCD2String_BE(byte[] b, int startIndex, int endIndex) throws Exception {
        return decodeBCD_BE(b, startIndex, endIndex - startIndex + 1);
@@ -1333,8 +1329,8 @@
     * @param b
     * @param startIndex
     * @param endIndex
     * @return
     * @throws Exception
     * @return è¿”回
     * @throws Exception å¼‚常
     */
    public static String BCD2String_LE(byte[] b, int startIndex, int endIndex) throws Exception {
        return decodeBCD_LE(b, startIndex, endIndex - startIndex + 1);
@@ -1342,17 +1338,17 @@
    /**
     * å¤§ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„高字节》
     * ç¼–码BCD,例如1387编码成  13  87,顺序是正的
     * ç¼–码BCD,例如1387编码成  13  87,顺序是正的
     * @param value
     * @param dest
     * @param startIndex
     * @param length
     * @param length é•¿åº¦
     */
    private static void encodeBCD_BE(String value, byte[] dest, int startIndex, int length)throws Exception {
        if (value == null || !value.matches("\\d*")) {
            throw new Exception("数字转成BCD编码时出错,不是合法数字:" + value, null);
        }
        int[] tmpInts = new int[2 * length];
        int index = value.length() - 1;
        for (int i = tmpInts.length - 1; i >= 0 && index >= 0; i--, index--) {
@@ -1362,20 +1358,20 @@
            dest[i] = (byte) (tmpInts[2 * j] * 16 + tmpInts[2 * j + 1]);
        }
    }
    /**
     * å°ç«¯æ¨¡å¼ã€Šæ•°æ®ä½Žä½åœ¨æ•°ç»„低字节》
     * ç¼–码BCD,例如1387编码成  87  13,顺序是倒的
     * ç¼–码BCD,例如1387编码成  87  13,顺序是倒的
     * @param value
     * @param dest
     * @param startIndex
     * @param length
     * @param length é•¿åº¦
     */
    private static void encodeBCD_LE(String value, byte[] dest, int startIndex, int length)throws Exception {
        if (value == null || !value.matches("\\d*")) {
            throw new Exception("数字转成BCD编码时出错,不是合法数字:" + value, null);
        }
        int[] tmpInts = new int[2 * length];
        int index = value.length() - 1;
        for (int i = 0; i <= tmpInts.length - 1 && index >= 0; i++, index--) {
@@ -1393,8 +1389,8 @@
     * è§£ç BCD,顺序是正的
     * @param src
     * @param startIndex
     * @param length
     * @return
     * @param length é•¿åº¦
     * @return è¿”回
     */
    private static String decodeBCD_BE(byte[] src, int startIndex, int length)throws Exception {
        StringBuilder sb = new StringBuilder();
@@ -1415,8 +1411,8 @@
      * ç¼–码BCD,顺序是倒的
     * @param src
     * @param startIndex
     * @param length
     * @return
     * @param length é•¿åº¦
     * @return è¿”回
     */
    private static String decodeBCD_LE(byte[] src, int startIndex, int length)throws Exception {
        StringBuilder sb = new StringBuilder();
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/Server.java
@@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.List;
import com.dy.aceMw.server.tasks.BusiConstantTask;
import com.dy.common.mw.UnitInterface;
import com.dy.common.mw.UnitStartedCallbackInterface;
import com.dy.common.mw.channel.rmi.RmiConfigVo;
@@ -147,7 +148,14 @@
            ServerProperties.lastUpDataTimeLive = conf.getSetAttrPlusInt(doc, "config.base", "lastUpDataTimeLive", null, 0, 5, null) * 1000L ;
            //数据库数据id生成器的id后缀,0是默认的后缀,一般web系统应用,数据中间件id后缀大于等于1
            ServerProperties.dbDataIdSuffix = conf.getSetAttrInt(doc, "config.base", "dbDataIdSuffix", null, 1, 9, null);
            //上下行数据缓存队列中缓存数据个数的报警量,这个与现实项目所接水表数相关
            ServerProperties.cacheUpDownDataWarnCount = conf.getSetAttrPlusInt(doc, "config.base", "cacheUpDownDataWarnCount", null, 1, null, null) ;
            //上下行数据缓存队列中缓存数据个数的最大值,这个与现实项目所接水表数相关
            ServerProperties.cacheUpDownDataMaxCount = conf.getSetAttrPlusInt(doc, "config.base", "cacheUpDownDataMaxCount", null, 1, null, null) ;
            if(ServerProperties.cacheUpDownDataMaxCount <= ServerProperties.cacheUpDownDataWarnCount){
                throw new Exception("cacheUpDownDataMaxCount必须大于cacheUpDownDataWarnCount") ;
            }
            //设置ID生成器的后缀
            IDLongGenerator.setSuffix(ServerProperties.dbDataIdSuffix.intValue());
@@ -175,29 +183,42 @@
            //支持模块: springHibernate和 çº¿ç¨‹æ± 
            SupportUnitConfigVo supVo = new SupportUnitConfigVo() ;
            //短工作时长线程池,线程负责用时较短的工作任务
            supVo.short_maxThread = conf.getSetAttrPlusInt(doc, "config.support", "short_maxThread", null, 1, 1000, null) ;//池中最大线程数为所有CPU核数+1
            supVo.short_minThread = conf.getSetAttrPlusInt(doc, "config.support", "short_minThread", null, 1, 5, null) ;//池中最小线程数
            supVo.short_maxThread = conf.getSetAttrPlusInt(doc, "config.support", "short_maxThread", null, -1, 1000, null) ;//池中最大线程数为所有CPU核数+1
            if(supVo.short_maxThread < 0){
                supVo.short_maxThread = -1 ;
            }
            supVo.short_minThread = conf.getSetAttrPlusInt(doc, "config.support", "short_minThread", null, -1, 100, null) ;//池中最小线程数
            if(supVo.short_minThread < 0){
                supVo.short_minThread = -1 ;
            }
            supVo.short_freeTimeout = conf.getSetAttrPlusInt(doc, "config.support", "short_freeTimeout", null, 1, 90, null) * 1000 ;//线程数空闲时长,若池中线程数量大于minThread,且有的线程空闲时长超过freeTimeout,则清除该线程,为了不清除,把minThread与maxThread设置相等
            supVo.short_busyTimeout = conf.getSetAttrPlusInt(doc, "config.support", "short_busyTimeout", null, 1, 10, null) * 1000 ;//线程不间断工作时长(单位为秒)超时限,认为线程已经了崩溃,将强制清除,短工作时长设置为5秒
            if(supVo.short_maxThread == 0 || supVo.short_minThread == 0){
                supVo.enableShortThreadPool = false ;
            }else{
                supVo.enableShortThreadPool = true ;
            }
            //长工作时长线程池,线程负责用时较长的工作任务
            supVo.long_maxThread = conf.getSetAttrInt(doc, "config.support", "long_maxThread", null, -1, 1000, null)  ;//池中最大线程数,若为-1,不受限制
            if(supVo.long_maxThread < 0){
                supVo.long_maxThread = -1 ;
            }
            supVo.long_minThread = conf.getSetAttrPlusInt(doc, "config.support", "long_minThread", null, 0, 5, null) ;//池中最小线程数
            supVo.long_minThread = conf.getSetAttrPlusInt(doc, "config.support", "long_minThread", null, -1, 100, null) ;//池中最小线程数
            if(supVo.long_minThread < 0){
                supVo.long_minThread = -1 ;
            }
            supVo.long_freeTimeout = conf.getSetAttrPlusInt(doc, "config.support", "long_freeTimeout", null, 1, 90, null) * 1000 ;//线程数空闲时长,若池中线程数量大于minThread,且有的线程空闲时长超过freeTimeout,则清除该线程
            supVo.long_busyTimeout = conf.getSetAttrInt(doc, "config.support", "long_busyTimeout", null, -1, 10, null) ;//线程不间断工作时长(单位为秒)超时限,若为-1,不受限制
            if(supVo.long_busyTimeout < 0){
                supVo.long_busyTimeout = -1 ;
            }
            supVo.enableThreadPool = conf.getSetAttrBoolean(doc, "config.support", "enableThreadPool", null, null) ;
//            supVo.enableSpringHibernate = conf.getSetAttrBoolean(doc, "config.support", "enableSpringHibernate", null, null) ;
//            if(supVo.enableSpringHibernate){
//                supVo.springXmlFile = conf.getSetAttrTxt(doc, "config.support", "springXmlFile", null, false, null) ;
//            }
            if(supVo.long_maxThread == 0 || supVo.long_minThread == 0){
                supVo.enableLongThreadPool = false ;
            }else{
                supVo.enableLongThreadPool = true ;
            }
            supVo.showStartInfo = showStartInfo ;
            
            AdapterImp_SupportUnit supAdap = new AdapterImp_SupportUnit() ;
@@ -270,14 +291,15 @@
            CoreUnitConfigVo coreConfVo = new CoreUnitConfigVo();
            coreConfVo.sleepBigBusy = conf.getSetAttrPlusInt(doc, "config.core", "sleepBigBusy", null, 1, 200, null).longValue() ;
            coreConfVo.sleepSmallBusy = conf.getSetAttrPlusInt(doc, "config.core", "sleepSmallBusy", null, 2, 1000, null).longValue();
            coreConfVo.queueWarnSize = conf.getSetAttrPlusInt(doc, "config.core", "queueWarnSize", null, 500, 1000000, null) ;
            coreConfVo.queueMaxSize = conf.getSetAttrPlusInt(doc, "config.core", "queueMaxSize", null, 5000, 3000000, null)  ;
            coreConfVo.queueWarnSize = ServerProperties.cacheUpDownDataWarnCount ;
            coreConfVo.queueMaxSize = ServerProperties.cacheUpDownDataMaxCount ;
            coreConfVo.showStartInfo = showStartInfo ;
            AdapterImp_CoreUnit coreAdap = new AdapterImp_CoreUnit();
            coreAdap.setConfig(coreConfVo);
            CoreUnit coreUnit = CoreUnit.getInstance();
            coreUnit.setAdapter(coreAdap);
            CoreUnit.addConstantTask(new ToRtuConstantTask());
            CoreUnit.addConstantTask(new BusiConstantTask());
            coreUnit.start(new UnitStartedCallbackInterface(){
                @Override
                public void call(Object obj) {
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/ServerProperties.java
@@ -25,6 +25,12 @@
    public static Long lastUpDataTimeLive = 1000L ;
    
    //数据库数据id生成器的id后缀,0是默认的后缀,一般web系统应用,数据中间件id后缀大于等于1
    public static Integer dbDataIdSuffix = 1 ;
    public static Integer dbDataIdSuffix = 1 ;
    //上下行数据缓存队列中缓存数据个数的报警量,这个与实体项目所接水表数相关
    public static Integer cacheUpDownDataWarnCount = 1000000 ;
    //上下行数据缓存队列中缓存数据个数的最大值,这个与实体项目所接水表数相关
    public static Integer cacheUpDownDataMaxCount = 1100000 ;
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/AboutRtuNode.java
New file
@@ -0,0 +1,62 @@
package com.dy.aceMw.server.busi;
import com.dy.aceMw.server.busi.deal.TaskPool;
import com.dy.aceMw.server.busi.deal.TaskSurpport;
import com.dy.common.queue.NodeObj;
import com.dy.common.threadPool.ThreadPool;
import com.dy.common.threadPool.TreadPoolFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class AboutRtuNode implements NodeObj {
    private static final Logger log = LogManager.getLogger(AboutRtuNode.class.getName());
    public Object obj ;//数据
    public AboutRtuNode(Object obj){
        this.obj = obj ;
    }
    /**
     * è‡ªå·±å¤„理自己
     * @return
     */
    public boolean dealSelf(){
        try {
            ThreadPool.Pool pool = TreadPoolFactory.getThreadPoolLong() ;
            pool.putJob(new ThreadPool.Job() {
                public void execute() {
                    if(obj != null){
                        TaskSurpport t = null ;
                        try{
                            t = TaskPool.popTask() ;
                            if(t != null){
                                t.execute(obj);
                            }else{
                                log.error("未得到RTU主动上报数据处理任务!");
                            }
                        }catch(Exception e){
                            if(t != null){
                                //当有异常时,try catch中的代码可没有执行freeAndCleanTask
                                TaskPool.freeAndCleanTask(t);
                            }
                        }
                    }
                }
                @Override
                public void destroy(){
                }
                @Override
                public boolean isDestroy(){
                    return false ;
                }
            });
        } catch (Exception e) {
            log.error("在RtuDataNode内发生异常", e);
        }
        return true ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/TcpUpDataCache.java
New file
@@ -0,0 +1,70 @@
package com.dy.aceMw.server.busi;
import com.dy.aceMw.server.ServerProperties;
import com.dy.common.queue.Node;
import com.dy.common.queue.Queue;
public class TcpUpDataCache {
    //TCP下行命令缓存队列
    private static Queue cacheQueue = new Queue("tcpUpDataQueue") ;
    private static TcpUpDataCache instance = new TcpUpDataCache() ;
    private TcpUpDataCache(){
        cacheQueue.setLimit(ServerProperties.cacheUpDownDataWarnCount, ServerProperties.cacheUpDownDataMaxCount);
    }
    public static TcpUpDataCache getInstance(){
        return instance ;
    }
    /**
     * ç¼“存节点
     * @param reportOrResponse_trueOrFalse reportOrResponse_trueOrFalse
     * @param node node
     * @throws Exception å¼‚常
     */
    public static void cacheRtuUpData(boolean reportOrResponse_trueOrFalse, AboutRtuNode node) throws Exception{
        if(node != null && node.data != null){
            if(reportOrResponse_trueOrFalse){
                cacheQueue.pushHead(node);
            }else{
                cacheQueue.pushTail(node);
            }
        }
    }
    /**
     * å¾—到第一个节点
     * @return Node
     */
    public static Node getFirstQueueNode(){
        return cacheQueue.getFirstNode() ;
    }
    /**
     * å¾—到最后一个节点
     * @return Node
     */
    public static Node getLastQueueNode(){
        return cacheQueue.getLastNode() ;
    }
    /**
     * ç§»é™¤èŠ‚ç‚¹
     * @param node
     */
    public static void removeNode(Node node){
        cacheQueue.remove(node);
    }
    /**
     * ç¼“存的节点数
     * @Return ç¼“存节点数
     */
    public static Integer size(){
        return cacheQueue.size() ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/Task.java
New file
@@ -0,0 +1,46 @@
package com.dy.aceMw.server.busi.deal;
public interface Task {
    /**
     * ä»»åŠ¡é‡‡ç”¨å¯¹è±¡æ± ï¼Œä»¥ä¾¿é‡ç”¨ä»»åŠ¡å¯¹è±¡ï¼Œ
     * é‡ç”¨å‰è¦è¿›è¡Œå¯¹è±¡åˆå§‹åŒ–,清除上次执行任务时遗留的对象属性数据
     * åˆå§‹åŒ–本任务及所有子任务
     */
    public void cleanMeAndSubs() ;
    /**
     * æ‰§è¡ŒèŠ‚ç‚¹ä»»åŠ¡
     * @param data éœ€è¦å¤„理的数据
     */
    public void execute(Object data) ;
    /**
     * å¾—到本任务节点处理产生的中间结果,以供本节点所在树枝的下级任务节点及本树枝的左侧(根在上)所有树枝的节点应用本结果
     * @return
     */
    public Object[] getMyResults() ;
    /**
     * å¾—到指定任务节点处理产生的中间结果,以供本节点所在树枝的下级任务节点及本树枝的左侧(根在上)所有树枝的节点应用本结果
     * @param id æŒ‡å®šä»»åŠ¡ID
     * @return
     */
    public Object[] getTaskResults(String id);
    /**
     * è½¬ä¸‹çº§ä»»åŠ¡èŠ‚ç‚¹å¤„ç†ï¼Œé¦–å…ˆè¦å®žä½“åŒ–æ‰€æœ‰å­èŠ‚ç‚¹ã€‚
     * @param data éœ€è¦å¤„理的数据
     */
    public void toNextTasks(Object data) ;
    /**
     * è½¬ä¸‹çº§æŸä¸ªä»»åŠ¡èŠ‚ç‚¹å¤„ç†
     * @param data éœ€è¦å¤„理的数据
     * @param id æŒ‡å®šä»»åŠ¡ID
     */
    public void toNextOneTask(Object data, String id);
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TaskConfig.java
New file
@@ -0,0 +1,9 @@
package com.dy.aceMw.server.busi.deal;
public class TaskConfig {
    public String id ;
    public String name ;
    public Boolean enable ;//是否执行节点的数据处理任务任务
    public String clazz ;
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TaskPool.java
New file
@@ -0,0 +1,115 @@
package com.dy.aceMw.server.busi.deal;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TaskPool {
    private static Logger log = LogManager.getLogger(TaskPool.class.getName()) ;
    private static List<TaskSurpport> tasks = new ArrayList<TaskSurpport>() ;
    private static TreeConfig taskTreeConf ;
    public static void setTaskTreeCofig(TreeConfig conf){
        taskTreeConf = conf ;
    }
    /**
     * å¾—到任务
     * å¤šçº¿ç¨‹çŽ¯å¢ƒä¸‹è¿è¡Œ
     * @return
     */
    public static synchronized TaskSurpport popTask(){
        TaskSurpport t = (tasks.size() > 0)?tasks.get(0):null ;
        if(t != null){
            tasks.remove(0) ;
        }else{
            try {
                t = newTaskTree() ;
            } catch (Exception e) {
                log.error(e.getMessage() == null?"实例化上行数据处理任务对象树失败!" : e.getMessage(), e);
            } finally {
                if(t == null){
                    log.error("实例化上行数据处理任务对象失败!" );
                }
            }
        }
        return t ;
    }
    /**
     * æ”¾å›žä»»åŠ¡
     * å¤šçº¿ç¨‹çŽ¯å¢ƒä¸‹è¿è¡Œ
     * è¿™é‡Œéœ€è¦åŒæ­¥é”ï¼Œå› ä¸ºä¸Šé¢æ–¹æ³•中执行完tasks.get(0)且未执行tasks.remove(0)期间,本方法执行并且执行完,那么后期就会出乱子
     * @param t
     */
    public static synchronized void freeAndCleanTask(TaskSurpport t){
        if(t != null){
            boolean find = false ;
            for(TaskSurpport tin : tasks){
                if(tin == t){
                    find = true ;
                    break ;
                }
            }
            if(!find){
                t.cleanMeAndSubs();
                tasks.add(0, t) ;
            }
        }
    }
    /**
     * å®žä¾‹åŒ–任务对象树
     * @return
     * @throws Exception
     */
    private static TaskSurpport newTaskTree() throws Exception{
        TaskSurpport t = null ;
        if(taskTreeConf != null){
            t = newTask(null, taskTreeConf.taskConf, taskTreeConf.subTreeConfs) ;
        }
        return t ;
    }
    private static TaskSurpport newTask(TaskSurpport root, TaskConfig taskConf, TreeConfig[] subTreeConfs) throws Exception{
        TaskSurpport t = null ;
        if(taskConf != null){
            t = instanceTask(taskConf.clazz) ;
            if(t != null){
                t.conf = taskConf ;
                t.root = root ;
                if(root == null){
                    root = t ;
                }
                newSubTask(root, t, subTreeConfs);
            }
        }
        return t ;
    }
    private static void newSubTask(TaskSurpport root, TaskSurpport parent, TreeConfig[] treeConfs)throws Exception{
        if(parent != null && treeConfs != null && treeConfs.length > 0){
            parent.subTasks = new TaskSurpport[treeConfs.length] ;
            for(int i = 0 ; i < treeConfs.length; i++){
                parent.subTasks[i] = newTask(root, treeConfs[i].taskConf, treeConfs[i].subTreeConfs) ;
            }
        }
    }
    private static TaskSurpport instanceTask(String clazz)throws Exception{
        Class<?> c = Class.forName(clazz);
        if (c == null) {
            throw new Exception("实例化上行数据处理任务对象树失败!任务类为" + clazz + "!");
        }else{
            return (TaskSurpport)c.newInstance();
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TaskSurpport.java
New file
@@ -0,0 +1,132 @@
package com.dy.aceMw.server.busi.deal;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
 * éƒ¨åˆ†å®žçްTask
 */
public abstract class TaskSurpport implements Task {
    private static final Logger log = LogManager.getLogger(TaskSurpport.class.getName()) ;
    //当前所处理的上行数据所属RTU的地址
    public String rtuAddr_inRootTk ;//只在根root任务对象上会付此值
    //本节点配置
    protected TaskConfig conf ;
    //根任务
    protected TaskSurpport root ;
    //本任务的子任务
    protected TaskSurpport[] subTasks ;
    //本任务的处理结果
    protected Object[] taskResult ;
    /**
     * æ‰§è¡ŒèŠ‚ç‚¹ä»»åŠ¡
     * @param data éœ€è¦å¤„理的数据
     */
    @Override
    public abstract void execute(Object data) ;
    /**
     * ä»»åŠ¡é‡‡ç”¨å¯¹è±¡æ± ï¼Œä»¥ä¾¿é‡ç”¨ä»»åŠ¡å¯¹è±¡ï¼Œ
     * é‡ç”¨å‰è¦è¿›è¡Œå¯¹è±¡åˆå§‹åŒ–,清除上次执行任务时遗留的对象属性数据
     * åˆå§‹åŒ–本任务及所有子任务
     */
    @Override
    public void cleanMeAndSubs() {
        rtuAddr_inRootTk = null ;
        taskResult = null ;
        if(this.subTasks != null && this.subTasks.length > 0){
            for(int i = 0 ; i < this.subTasks.length; i++){
                this.subTasks[i].cleanMeAndSubs() ;
            }
        }
    }
    /**
     * å¾—到本任务节点处理产生的中间结果,以供本节点所在树枝的下级任务节点及本树枝的左侧(根在上)所有树枝的节点应用本结果
     * @return
     */
    @Override
    public Object[] getMyResults(){
        return taskResult ;
    }
    /**
     * å¾—到指定任务节点处理产生的中间结果,以供本节点所在树枝的下级任务节点及本树枝的左侧(根在上)所有树枝的节点应用本结果
     * @param id æŒ‡å®šä»»åŠ¡ID
     * @return
     */
    public Object[] getTaskResults(String id){
        if(root != null){
            return this.getTaskResults(root, id) ;
        }
        return null ;
    }
    private Object[] getTaskResults(TaskSurpport task, String id){
        if(task != null && task.conf != null && task.conf.id != null && task.conf.id.equals(id)){
            return task.getMyResults() ;
        }else{
            if(task.subTasks != null && task.subTasks.length > 0){
                Object[] rs = null ;
                for(int i = 0 ; i < task.subTasks.length; i++){
                    rs = getTaskResults(task.subTasks[i], id) ;
                    if(rs != null){
                        return rs ;
                    }
                }
            }
        }
        return null ;
    }
    /**
     * è½¬ä¸‹çº§ä»»åŠ¡èŠ‚ç‚¹å¤„ç†ï¼Œé¦–å…ˆè¦å®žä½“åŒ–æ‰€æœ‰å­èŠ‚ç‚¹ã€‚
     * @param data éœ€è¦å¤„理的数据
     */
    @Override
    public void toNextTasks(Object data) {
        try {
            if(subTasks != null && subTasks.length > 0){
                for(int i = 0 ; i < subTasks.length ; i++){
                    if(subTasks[i].conf.enable){
                        subTasks[i].execute(data) ;
                    }else{
                        //本节点不起作用,直接进入本节的子节点
                        subTasks[i].toNextTasks(data) ;
                    }
                }
            }
        } catch (Exception e) {
            log.error("向下级任务传递工作时出错," , e);
        }finally{
        }
    }
    /**
     * è½¬ä¸‹çº§æŸä¸ªä»»åŠ¡èŠ‚ç‚¹å¤„ç†
     * @param data éœ€è¦å¤„理的数据
     * @param id æŒ‡å®šä»»åŠ¡ID
     */
    public void toNextOneTask(Object data, String id){
        try {
            if(subTasks != null && subTasks.length > 0){
                for(int i = 0 ; i < subTasks.length ; i++){
                    if(subTasks[i].conf.id.equals(id)){
                        if(subTasks[i].conf.enable){
                            subTasks[i].execute(data) ;
                        }else{
                            //本节点不起作用,直接进入本节的子节点
                            subTasks[i].toNextTasks(data) ;
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("向指定子任务(" + id + ")传递任务时出错," , e);
        }finally{
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TkReceive.java
New file
@@ -0,0 +1,31 @@
package com.dy.aceMw.server.busi.deal;
import com.dy.common.mw.protocol.Data;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TkReceive extends TaskSurpport {
    private static final Logger log = LogManager.getLogger(TkReceive.class.getName()) ;
    //ç±»ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkReceive" ;
    /**
     * æ‰§è¡ŒèŠ‚ç‚¹ä»»åŠ¡
     * @param data éœ€è¦å¤„理的数据
     */
    @Override
    public void execute(Object data) {
        if(data == null){
            log.error("严重错误,RTU上行数据为空!" );
        }else{
            if(data instanceof Data){
                this.toNextTasks(data);
            }else{
                log.error("严重错误,该数据类型(" + data.getClass().getName() + "),接收数据任务还未实现!" );
            }
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TkRtuData.java
New file
@@ -0,0 +1,29 @@
package com.dy.aceMw.server.busi.deal;
import com.dy.common.mw.protocol.Data;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TkRtuData extends TaskSurpport {
    private static Logger log = LogManager.getLogger(TkRtuData.class.getName()) ;
    //ç±»ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkRtuData" ;
    /**
     * æ‰§è¡ŒèŠ‚ç‚¹ä»»åŠ¡
     * @param data éœ€è¦å¤„理的数据
     */
    @Override
    public void execute(Object data) {
        Data d = (Data)data ;
        String rtuAddr = d.getRtuAddr() ;
        if(rtuAddr == null){
            log.error("严重错误,RTU上行数据中无RTU地址!" );
        }else{
            this.toNextTasks(data);
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/Tree.xml
New file
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project>
<config>
    <!--
    id:与对应类中的静态成员变量taskId一致
    enable:标识本节点是否执行,若本节点不执行,则直接进入其子节点
    -->
    <task id="TkReceive" name="接收数据" enable="true" class="com.dy.aceMw.server.busi.deal.TkReceive">
        <task id="TkRtuData" name="接收RTU数据" enable="true" class="com.dy.aceMw.server.busi.deal.TkRtuData">
            <task id="TkFindP206V1_0_0" name="识别P206V1_0_0数据" enable="true" class="com.dy.aceMw.server.busi.deal.p206V1_0_0.TkFindP206V1_0_0">
                <task id="TkPreGenObjs" name="预先准备各对象" enable="true" class="com.dy.aceMw.server.busi.deal.p206V1_0_0.TkPreGenObjs">
                    <!-- è¯†åˆ«æµæµªè€…RTU,数据库中没有或数据库存在但未分配置供水机构 -->
                    <task id="TkDealRtuTramp" name="识别流浪者RTU" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.TkDealRtuTramp" />
                    <!-- éžæµæµªè€…RTU,必须放在TkDealRtuTramp后面 -->
                    <task id="TkDealNoRtuTramp" name="非流浪者RTU" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.TkDealNoRtuTramp">
                        <!-- è¯†åˆ«ä¸»åŠ¨ä¸ŠæŠ¥æ•°æ® -->
                        <task id="TkFindAutoReport" name="识别主动上报及触发上报数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.TkFindAutoReport">
                            <!-- æ£€æŸ¥æ—¶é—´ç­‰ä¸æ­£ç¡®çš„上报数据 -->
                            <task id="TkCheckAutoReport" name="检查时间等不正确的上报数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkCheckAutoReport">
                                <!-- æ£€æŸ¥é‡å¤ä¸ŠæŠ¥æ•°æ® -->
                                <task id="TkCheckRepeatReport" name="检查重复上报数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkCheckRepeatReport">
                                    <!-- Mn运维系统 -->
                                    <task id="TkMnRtuDealAutoReportLastAlarm" name="运维RTU上报最新报警" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkMnRtuDealAutoReportLastAlarm" />
                                    <!-- RTU主动上报数据必须在RTU主动上报报警任务的下面,以备主动上报数据中记录是否有报警-->
                                    <task id="TkMnRtuDealAutoReportLastData" name="运维RTU主动上报最新数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkMnRtuDealAutoReportLastData" />
                                    <!-- RTU实时(触发)上报数据必须在RTU主动上报报警任务的下面,以备主动上报数据中记录是否有报警-->
                                    <task id="TkMnRtuDealRealReportLastData" name="运维RTU实时(触发)上报最新数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkMnRtuDealRealReportLastData" />
                                    <!-- Org供水机构系统 -->
                                    <task id="TkOrgRtuDealAutoReportLastAlarm" name="供水机构RTU主动上报最新报警" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealAutoReportLastAlarm">
                                        <task id="TkOrgRtuDealAutoReportAlarm" name="供水机构RTU主动上报报警" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealAutoReportAlarm" />
                                        <task id="TkOrgRtuDealReportValveOpResult" name="供水机构RTU主动上报开关阀结果" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealReportValveOpResult" />
                                    </task>
                                    <!-- RTU主动上报数据必须在RTU主动上报报警任务的下面,以备主动上报数据中记录是否有报警-->
                                    <task id="TkOrgRtuDealDayAmountAlarm" name="供水机构RTU日结累计流量报警" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealDayAmountAlarm" >
                                        <task id="TkOrgRtuDeal48HourNoAmount" name="供水机构RTU48小时未用水" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDeal48HourNoAmount" >
                                            <task id="TkOrgRtuDealAutoReportLastData" name="供水机构RTU主动上报最新数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealAutoReportLastData">
                                                <task id="TkOrgRtuDealAutoReportData" name="供水机构RTU主动上报数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealAutoReportData" />
                                                <task id="TkOrgRtuDealCycleData" name="供水机构RTU主动上报周期采集数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealCycleData">
                                                    <task id="TkOrgRtuDealCycleLongSmallAmountAlarm" name="供水机构RTU主动上报周期采集数据长流水分析" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealCycleLongSmallAmountAlarm" />
                                                </task>
                                                <task id="TkOrgRtuDealAmountCost" name="供水机构RTU主动上报计算日水量、月水量、及水费" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealAmountCost" >
                                                    <task id="TkOrgRtuDealPayCost" name="供水机构用水户水表电子钱包支付水费" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealPayCost" />
                                                </task>
                                            </task>
                                        </task>
                                    </task>
                                    <!-- RTU实时(触发)上报数据必须在RTU主动上报报警任务的下面,以备主动上报数据中记录是否有报警-->
                                    <task id="TkOrgRtuDealRealReportLastData" name="供水机构RTU实时(触发)上报最新数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealRealReportLastData">
                                        <task id="TkOrgRtuDealRealReportData" name="供水机构RTU实时(触发)上报数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.autoReport.TkOrgRtuDealRealReportData" />
                                    </task>
                                </task>
                            </task>
                        </task>
                        <!-- è¯†åˆ«å‘½ä»¤å“åº”数据 -->
                        <task id="TkFindComResponse" name="识别响应命令数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.TkFindComResponse">
                            <task id="TkRtuDealCommandResponse" name="RTU响应命令数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.comResponse.TkRtuDealCommandResponse" >
                                <task id="TkRtuDealSetParamComResponse" name="RTU响应设置参数命令数据" enable="true" class="com.dy.busi.server.rtuData.meterV1_0.comResponse.TkRtuDealSetParamComResponse" />
                            </task>
                        </task>
                    </task>
                </task>
            </task>
            <task id="TkFindHAC_NBhV2_5" name="识别HAC_NBhV2_5数据" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.TkFindHAC_NBhV2_5">
                <task id="TkPipPreGenObjs" name="预先准备各对象" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.TkPipPreGenObjs">
                    <!-- è¯†åˆ«æµæµªè€…管网水表,数据库中没有或数据库存在但未分配置供水机构 -->
                    <task id="TkPipDealRtuTramp" name="识别流浪者管网水表" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.TkPipDealRtuTramp" />
                    <!-- éžæµæµªè€…管网水表,必须放在TkDealRtuTramp后面 -->
                    <task id="TkPipDealNoRtuTramp" name="非流浪者管网水表" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.TkPipDealNoRtuTramp">
                        <!-- è¯†åˆ«ä¸»åŠ¨ä¸ŠæŠ¥æ•°æ® -->
                        <task id="TkPipFindAutoReport" name="识别主动上报及触发上报数据" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.TkPipFindAutoReport">
                            <!-- æ£€æŸ¥æ—¶é—´ç­‰ä¸æ­£ç¡®çš„上报数据 -->
                            <task id="TkPipCheckAutoReport" name="检查时间等不正确的上报数据" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipCheckAutoReport">
                                <task id="TkPipCheckRepeatAutoReport" name="检查重复上报数据" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipCheckRepeatAutoReport">
                                    <!-- Mn运维系统 -->
                                    <task id="TkPipMnRtuDealAutoReportLastAlarm" name="运维管网水表上报最新报警" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipMnRtuDealAutoReportLastAlarm" />
                                    <!-- RTU主动上报数据必须在RTU主动上报报警任务的下面,以备主动上报数据中记录是否有报警-->
                                    <task id="TkPipMnRtuDealAutoReportLastData" name="运维管网水表主动上报最新数据" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipMnRtuDealAutoReportLastData" />
                                    <!-- Org供水机构系统 -->
                                    <task id="TkPipOrgRtuDealAutoReportLastAlarm" name="供水机构管网水表主动上报最新报警" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipOrgRtuDealAutoReportLastAlarm">
                                        <task id="TkPipOrgRtuDealAutoReportAlarm" name="供水机构管网水表主动上报报警" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipOrgRtuDealAutoReportAlarm" />
                                    </task>
                                    <!-- RTU主动上报数据必须在RTU主动上报报警任务的下面,以备主动上报数据中记录是否有报警-->
                                    <task id="TkPipOrgRtuDealAutoReportLastData" name="供水机构管网水表主动上报最新数据" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipOrgRtuDealAutoReportLastData">
                                        <task id="TkPipOrgRtuDealAutoReportData" name="供水机构管网水表主动上报数据" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipOrgRtuDealAutoReportData" />
                                        <task id="TkPipOrgRtuDealAmount" name="供水机构管网水表月流量统计" enable="true" class="com.dy.busi.server.rtuData.HAC_NBhV2_5.autoReport.TkPipOrgRtuDealAmount" />
                                    </task>
                                </task>
                            </task>
                        </task>
                    </task>
                </task>
            </task>
        </task>
    </task>
</config>
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TreeConfig.java
New file
@@ -0,0 +1,6 @@
package com.dy.aceMw.server.busi.deal;
public class TreeConfig {
    public TaskConfig taskConf ;
    public TreeConfig[] subTreeConfs ;//所有子节点
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/TreeParse.java
New file
@@ -0,0 +1,172 @@
package com.dy.aceMw.server.busi.deal;
import java.net.URL;
import java.util.*;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
public class TreeParse {
    public List<String> ids ;
    public List<String> classes ;
//    public static void main(String args[]) {
//        TreeParse o = new TreeParse();
//        TreeConfig conf = o.parseConfig();
//    }
    public TreeParse(){
        ids = new ArrayList<String>() ;
        classes = new ArrayList<String>() ;
    }
    /**
     * è§£æžå¤„理器配置
     * @return
     */
    protected TreeConfig parseConfig() {
        try {
            URL configFileURL = TreeParse.class.getResource("Tree.xml");
            return this.parse(this.createDom(configFileURL)) ;
        } catch (Exception e) {
            System.out.println("系统启动时,初始上行数据处理任务配置出错 !");
            System.out.println(e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
    /**
     *
     * @return
     */
    private Document createDom(URL configFileURL) throws Exception {
        if (configFileURL == null) {
            throw new Exception("未得到上行数据处理任务配置文件!", null);
        }
        Document doc = null;
        try {
            SAXBuilder sb = new SAXBuilder();
            doc = sb.build(configFileURL);
            if (doc == null) {
                throw new Exception("未生成上行数据处理任务配置文件的DOM对象!", null);
            }
        } catch (Exception e) {
            throw new Exception("生成上行数据处理任务配置文件的DOM对象失败!", e);
        }
        return doc;
    }
    /**
     * åˆ†æž
     * @return ArrayList<String>
     * @throws Exception
     */
    private TreeConfig parse(Document doc) throws Exception {
        Element root = doc.getRootElement();
        if (root == null) {
            throw new Exception("未得到上行数据处理任务配置文件根元素config!");
        }
        List<Element> rootTasks = root.getChildren("task") ;
        if(rootTasks == null || rootTasks.size() == 0){
            throw new Exception("未得到上行数据处理任务配置文件根任务task!");
        }
        if(rootTasks.size() > 1){
            throw new Exception("未得到上行数据处理任务配置文件根任务task必须只有一个!");
        }
        TreeConfig tree = new TreeConfig() ;
        tree.taskConf = new TaskConfig() ;
        this.parseNode(rootTasks.get(0), tree, tree.taskConf) ;
        return tree ;
    }
    private void parseNode(Element taskEle, TreeConfig me, TaskConfig taskConf)throws Exception {
//        <task id="task2.1" name="构造数据" enable="true" class="" />
        if(taskEle == null){
            throw new Exception("分析上行数据处理任务配置文件出错!");
        }
        String id = taskEle.getAttributeValue("id") ;
        if(id == null || id.trim().equals("")){
            throw new Exception("上行数据处理任务配置文件中id必须配置!");
        }
        id = id.trim() ;
        if(ids.contains(id)){
            throw new Exception("上行数据处理任务配置文件中id=" + id + "重复配置!");
        }
        taskConf.id = id ;
        ids.add(id) ;
        String name = taskEle.getAttributeValue("name") ;
        if(name == null || name.trim().equals("")){
            throw new Exception("上行数据处理任务配置文件中name必须配置!");
        }
        name = name.trim() ;
        taskConf.name = name ;
        String enable = taskEle.getAttributeValue("enable") ;
        if(enable == null || !(enable.trim().equals("true") || enable.trim().equals("false"))){
            throw new Exception("上行数据处理任务配置文件中enable必须配置,并且值只能为true或false!");
        }
        if(enable.trim().equals("true")){
            taskConf.enable = true ;
        }
        if(enable.trim().equals("false")){
            taskConf.enable = false ;
        }
        String clazz = taskEle.getAttributeValue("class") ;
        if(clazz == null || clazz.trim().equals("")){
            throw new Exception("上行数据处理任务配置文件中class必须配置!");
        }
        clazz = clazz.trim() ;
        if(classes.contains(clazz)){
            throw new Exception("上行数据处理任务配置文件中class=" + clazz + "重复配置!");
        }
        taskConf.clazz = clazz ;
        classes.add(clazz) ;
        this.checkClass(taskConf.clazz) ;
        this.parseSubNode(taskEle, me) ;
    }
    private void parseSubNode(Element ele, TreeConfig parent)throws Exception {
        List<?> list = ele.getChildren("task") ;
        if(list != null && list.size() > 0){
            parent.subTreeConfs = new TreeConfig[list.size()] ;
            Iterator<?> it = list.iterator();
            Element e = null;
            int count = 0 ;
            TreeConfig me ;
            while(it.hasNext()){
                e = (Element) it.next();
                me = new TreeConfig() ;
                me.taskConf = new TaskConfig() ;
                parent.subTreeConfs[count++] = me ;
                parseNode(e, me, me.taskConf) ;
            }
        }
    }
    private void checkClass(String clazz)throws Exception {
        Class<?> c = Class.forName(clazz);
        if (c == null) {
            throw new Exception("上行数据处理任务配置文件中不能实例化class=" + clazz + "!");
        }else{
            Object o = c.newInstance();
            if(o instanceof Task){
            }else{
                throw new Exception("上行数据处理任务配置文件中class=" + clazz + "必须实现Task接口!");
            }
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/p206V1_0_0/TkFindP206V1_0_0.java
New file
@@ -0,0 +1,27 @@
package com.dy.aceMw.server.busi.deal.p206V1_0_0;
import com.dy.aceMw.server.busi.deal.TaskSurpport;
import com.dy.common.mw.protocol.Data;
import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0;
public class TkFindP206V1_0_0 extends TaskSurpport {
    //ç±»ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkFindP206V1_0_0" ;
    /**
     * æ‰§è¡ŒèŠ‚ç‚¹ä»»åŠ¡
     * @param data éœ€è¦å¤„理的数据
     */
    @Override
    public void execute(Object data) {
        Data d = (Data)data ;
        if(d.getProtocol() != null && d.getProtocol().equals(ProtocolConstantV206V1_0_0.protocolName)){
            this.toNextTasks(data);
        }else{
            //不是本协议的数据
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/busi/deal/p206V1_0_0/TkPreGenObjs.java
New file
@@ -0,0 +1,82 @@
package com.dy.aceMw.server.busi.deal.p206V1_0_0;
import com.dy.aceMw.server.busi.deal.TaskSurpport;
import com.dy.common.mw.protocol.Data;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TkPreGenObjs extends TaskSurpport {
    private static final Logger log = LogManager.getLogger(TkPreGenObjs.class.getName()) ;
    //ç±»ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkPreGenObjs" ;
    /**
     * æ‰§è¡ŒèŠ‚ç‚¹ä»»åŠ¡
     * @param data éœ€è¦å¤„理的数据
     */
    @Override
    public void execute(Object data) {
        Data d = (Data)data ;
        String rtuAddr = d.getRtuAddr() ;
        //得到本地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, meterNo) ;
                        //可能未查询到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, meterNo) ;
                    if(rtuTramp == null){
                        rtuTramp = new SyRtuTramp(imei, meterNo) ;
                    }
                    this.taskResult = new Object[]{baseBusi, orgBusi, nbRtu, rtuTramp, null} ;
                    this.toNextOneTask(data, TkDealRtuTramp.taskId);
                }
            }else{
                //数据库中未查询到NB产品(RTU实体)
                //流浪者RTU
                rtuTramp = DbSyBuzi.getSyRtuTramp(baseBusi, imei, meterNo) ;
                if(rtuTramp == null){
                    rtuTramp = new SyRtuTramp(imei, meterNo) ;
                }
                this.taskResult = new Object[]{baseBusi, orgBusi, nbRtu, rtuTramp, null} ;
                this.toNextOneTask(data, TkDealRtuTramp.taskId);
            }
        }else{
            log.error("严重错误,未能得到BaseBusi对象");
        }
        */
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/forTcp/MidResultActionFromRtu.java
@@ -1,5 +1,7 @@
package com.dy.aceMw.server.forTcp;
import com.dy.aceMw.server.busi.AboutRtuNode;
import com.dy.aceMw.server.busi.TcpUpDataCache;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -23,33 +25,33 @@
                //此处实现,与以前不一样,
                //以前实现:匹配命令是从后向前匹配,
                //当前实现,匹配命令是从前向后匹配,原因:举例,当批量下发补召命令,如果从后匹配,则前面命令会下发多次,即一个上报次数据会补召多次
                MidResultToRtu resToRtu = TcpDownCommandCach.matchFromHead(resFromRtu) ;
                MidResultToRtu resToRtu = TcpDownCommandCache.matchFromHead(resFromRtu) ;
                if(resToRtu != null){
                    //匹配到下发的命令
                    resFromRtu.setCommandId(resToRtu.commandId) ;
                    this.sendResult(false, resFromRtu);
                    this.nextDeal(false, resFromRtu);
                }else{
                    this.sendResult(false, resFromRtu);
                    this.nextDeal(false, resFromRtu);
                    //未匹配到下发的命令,命令在缓存因超时被清除了
                    RtuStatusDealer.commandFail2Success(resFromRtu.rtuAddr) ;
                }
            }else{
                //主动上报数据
                this.sendResult(true, resFromRtu);
                this.nextDeal(true, resFromRtu);
            }
        }
    }
    private void sendResult(boolean reportOrResponse_trueOrFalse, MidResultFromRtu resFromRtu){
    /**
     * è¿›å…¥å¤šçº¿ç¨‹çŽ¯å¢ƒä¸­è¿è¡Œ
     * @param reportOrResponse_trueOrFalse
     * @param resFromRtu
     */
    private void nextDeal(boolean reportOrResponse_trueOrFalse, MidResultFromRtu resFromRtu){
        try{
            String json = resFromRtu.data.toJson() ;
//            if(reportOrResponse_trueOrFalse){
//                ToMqMessageCach.cachObj(MessageType.RtuAutoReport, json);
//            }else{
//                ToMqMessageCach.cachObj(MessageType.RtuCmdResponse, json);
//            }
            TcpUpDataCache.cacheRtuUpData(reportOrResponse_trueOrFalse, new AboutRtuNode(resFromRtu.data));
        }catch(Exception e){
            log.error(e.getMessage(), e);
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/forTcp/MidResultActionToRtu.java
@@ -15,7 +15,7 @@
        if(result != null && result instanceof MidResultToRtu){
            try {
                MidResultToRtu resToRtu = (MidResultToRtu)result ;
                TcpDownCommandCach.cachCommand(resToRtu);
                TcpDownCommandCache.cacheCommand(resToRtu);
                log.info("下行命令(toRtu)" + resToRtu.downCode + "中间结果已经放入下行命令缓存中");
            } catch (Exception e) {
                log.error(e);
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/forTcp/TcpDownCommandCache.java
File was renamed from pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/forTcp/TcpDownCommandCach.java
@@ -10,18 +10,18 @@
/**
 * éžçº¿ç¨‹å®‰å…¨çš„,只能在单线程中运行
 */
public class TcpDownCommandCach {
public class TcpDownCommandCache {
    
    //TCP下行命令缓存队列
    private static Queue cachQueue = new Queue("tcpDownComandQueue") ;
    private static Queue cacheQueue = new Queue("tcpDownCommandQueue") ;
    
    private static TcpDownCommandCach instance = new TcpDownCommandCach() ;
    private static TcpDownCommandCache instance = new TcpDownCommandCache() ;
    
    private TcpDownCommandCach(){
        cachQueue.setLimit(990000, 1000000);
    private TcpDownCommandCache(){
        cacheQueue.setLimit(ServerProperties.cacheUpDownDataWarnCount, ServerProperties.cacheUpDownDataMaxCount);
    }
    
    public static TcpDownCommandCach getInstance(){
    public static TcpDownCommandCache getInstance(){
        return instance ;
    }
@@ -30,16 +30,16 @@
     * @param result
     * @throws Exception
     */
    public static void cachCommand(MidResultToRtu result) throws Exception{
    public static void cacheCommand(MidResultToRtu result) throws Exception{
        if(result != null){
            if(result.maxSendTimes == null){
                //设置最大发送次数
                result.maxSendTimes = ServerProperties.downComandMaxResendTimes ;
            }
            if(result.isSendFirst){
                cachQueue.pushHead(new TcpDownCommandObj(result));
                cacheQueue.pushHead(new TcpDownCommandObj(result));
            }else{
                cachQueue.pushTail(new TcpDownCommandObj(result));
                cacheQueue.pushTail(new TcpDownCommandObj(result));
            }
        }
    }
@@ -52,7 +52,7 @@
    public static MidResultToRtu matchFromHead(MidResultFromRtu rsFromRtu){
        MidResultToRtu res = null ;
        TcpDownCommandObj obj = null ;
        Node node = cachQueue.getFirstNode() ;
        Node node = cacheQueue.getFirstNode() ;
        while(node != null && node.obj != null){
            obj = (TcpDownCommandObj)node.obj;
            res = obj.result ;
@@ -77,7 +77,7 @@
    public static MidResultToRtu matchFromTail(MidResultFromRtu rsFromRtu){
        MidResultToRtu res = null ;
        TcpDownCommandObj obj = null ;
        Node node = cachQueue.getLastNode() ;
        Node node = cacheQueue.getLastNode() ;
        while(node != null && node.obj != null){
            obj = (TcpDownCommandObj)node.obj;
            res = obj.result ;
@@ -99,7 +99,7 @@
     * @return
     */
    public static Node getFirstQueueNode(){
        return cachQueue.getFirstNode() ;
        return cacheQueue.getFirstNode() ;
    }
    
    /**
@@ -107,7 +107,7 @@
     * @return
     */
    public static Node getLastQueueNode(){
        return cachQueue.getLastNode() ;
        return cacheQueue.getLastNode() ;
    }
    
    /**
@@ -115,15 +115,15 @@
     * @param node
     */
    public static void removeNode(Node node){
        cachQueue.remove(node);
        cacheQueue.remove(node);
    }
    /**
     * ç¼“存的节点数
     * @param node
     * @Return ç¼“存节点数
     */
    public static Integer size(){
        return cachQueue.size() ;
        return cacheQueue.size() ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/tasks/BusiConstantTask.java
New file
@@ -0,0 +1,74 @@
package com.dy.aceMw.server.tasks;
import com.dy.aceMw.server.busi.AboutRtuNode;
import com.dy.aceMw.server.busi.TcpUpDataCache;
import com.dy.common.mw.core.CoreTask;
import com.dy.common.queue.Node;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
 * å¯¹RTU上行数据进行业务处理
 */
public class BusiConstantTask  extends CoreTask {
    private static final Logger log = LogManager.getLogger(BusiConstantTask.class.getName());
    /**
     * åœ¨å•线程环境中运行
     */
    @Override
    public Integer excute() {
        try{
            return dealRtuUpdata() ;
        }catch(Exception e){
            log.error(e);
        }
        return null ;
    }
    /**
     * å¤„理上行数据
     */
    public Integer dealRtuUpdata() {
        Node first = TcpUpDataCache.getFirstQueueNode() ;
        if(first != null){
            Integer count = TcpUpDataCache.size() ;
            Node last = TcpUpDataCache.getLastQueueNode() ;
            this.doDealRtuUpdata(first, last);
            return count ;
        }
        return null ;
    }
    /**
     * å¤„理缓存的上行数据节点
     * @param first ç¬¬ä¸€ä¸ªèŠ‚ç‚¹
     * @param last æœ€åŽä¸€ä¸ªèŠ‚ç‚¹
     */
    private void doDealRtuUpdata(Node first, Node last){
        if(last != null){
            //在dealNode方法中,可能要把last从队列中移除,这时last.pre为空,所以提前把last.pre取出来
            Node pre = last.pre ;
            dealNode(last) ;
            if(first != null && first != last){
                doDealRtuUpdata(first, pre) ;
            }else if(first != null && first == last){
                //停止
            }else if(first == null){
                //这种情况不会存在
                doDealRtuUpdata(null, pre) ;
            }
        }
    }
    /**
     * å¤„理一个节点
     * @param node èŠ‚ç‚¹
     */
    private void dealNode(Node node){
        AboutRtuNode obj = (AboutRtuNode)node.obj ;
        obj.dealSelf() ;
        TcpUpDataCache.removeNode(node);
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/tasks/RtuDownTask.java
@@ -34,8 +34,7 @@
    
    /**
     * å¤„理命令
     * @param webJgroupName
     * @param com
     * @param com å‘½ä»¤
     * @throws Exception
     */
    private void deal(Command com) throws Exception{
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/tasks/RtuUpTask.java
@@ -150,7 +150,7 @@
        }else{
            MidResult[] midRs = dri.parseData(ServerProperties.isLowPower, rtuAddrAtHead, upBuf, upHex, new DriverParserDataCallback(){
                @Override
                public void callback(String rtuAddrAtHead, String meterNoAtHead, String code, String upHex, Boolean reportOrResponse_trueOrFalse, boolean parseFail, String rtuAddrInData, String meterNoInData) {
                public void callback(String rtuAddrAtHead, String code, String upHex, Boolean reportOrResponse_trueOrFalse, boolean parseFail, String rtuAddrInData) {
                    //更新终端状态
                    if(rtuAddrInData != null && !rtuAddrInData.equals(rtuAddrAtHead)){
                        //数据头中的RTU地址与数据中的RTU地址不一致,更换成数据中的RTU地址
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/java/com/dy/aceMw/server/tasks/ToRtuConstantTask.java
@@ -5,7 +5,7 @@
import com.dy.common.queue.Node;
import com.dy.common.mw.core.CoreTask;
import com.dy.aceMw.server.forTcp.TcpDownCommandCach;
import com.dy.aceMw.server.forTcp.TcpDownCommandCache;
import com.dy.aceMw.server.forTcp.TcpDownCommandObj;
import com.dy.aceMw.server.forTcp.TcpSessionCach;
@@ -40,16 +40,12 @@
     * å¤„理下行命令
     */
    public Integer dealDownCommand(Long now) {
        try{
            Node first = TcpDownCommandCach.getFirstQueueNode() ;
            if(first != null){
                Integer count = TcpDownCommandCach.size() ;
                Node last = TcpDownCommandCach.getLastQueueNode() ;
                this.doDealDownCommand(now, first, last);
                return count ;
            }
        }catch(Exception e){
            log.error(e);
        Node first = TcpDownCommandCache.getFirstQueueNode() ;
        if(first != null){
            Integer count = TcpDownCommandCache.size() ;
            Node last = TcpDownCommandCache.getLastQueueNode() ;
            this.doDealDownCommand(now, first, last);
            return count ;
        }
        return null ;
    }
@@ -57,9 +53,9 @@
     * å¤„理缓存的下行命令节点
     * @param now å½“前时刻
     * @param first ç¬¬ä¸€ä¸ªèŠ‚ç‚¹
     * @param last æ˜¯åŽä¸€ä¸ªèŠ‚ç‚¹
     * @param last æœ€åŽä¸€ä¸ªèŠ‚ç‚¹
     */
    private void doDealDownCommand(Long now, Node first, Node last){
    private void doDealDownCommand1(Long now, Node first, Node last){
        if(first != null){
            //在dealNode方法中,可能要把first从队列中移除,这时first.next为空,所以提前把first.next取出来
            Node next = first.next ;
@@ -74,6 +70,28 @@
            }
        }
    }
    /**
     * å¤„理缓存的下行命令节点
     * @param now å½“前时刻
     * @param first ç¬¬ä¸€ä¸ªèŠ‚ç‚¹
     * @param last æœ€åŽä¸€ä¸ªèŠ‚ç‚¹
     */
    private void doDealDownCommand(Long now, Node first, Node last){
        if(last != null){
            //在dealNode方法中,可能要把last从队列中移除,这时last.pre为空,所以提前把last.pre取出来
            Node pre = last.pre ;
            dealNode(now, last) ;
            if(first != null && first != last){
                doDealDownCommand(now, first, pre) ;
            }else if(first != null && first == last){
                //停止
            }else if(first == null){
                //这种情况不会存在
                doDealDownCommand(now, null, pre) ;
            }
        }
    }
    
    /**
     * å¤„理一个节点
@@ -84,7 +102,7 @@
        TcpDownCommandObj obj = (TcpDownCommandObj)node.obj ;
        boolean removeNode = obj.dealSelf(now) ;
        if(removeNode){
            TcpDownCommandCach.removeNode(node);
            TcpDownCommandCache.removeNode(node);
        }
    }
pipIrr-platform/pipIrr-mw/pipIrr-mw-accept/src/main/resources/config.xml
@@ -14,6 +14,8 @@
        offLineCachTimeout: ä¸åœ¨çº¿ç¼“存的命令最大缓存时长(秒)
        lastUpDataTimeLive: TCP上行数据时刻缓存时长(秒),当达到时长时,TCP上行数据时刻被清空,采用TCP上行数据时刻目的是,阻止上行数据同时下发数据,因为RTU处理不过来(经初次实验,1秒还是有问题,2秒无问题)
        dbDataIdSuffix:数据库数据id生成器的id后缀,0是默认的后缀,一般web系统应用,数据中间件id后缀大于等于1 
        cacheUpDownDataWarnCount:上下行数据缓存队列中缓存数据个数的报警量,这个与现实项目所接水表数相关
        cacheUpDownDataMaxCount:上下行数据缓存队列中缓存数据个数的最大值,这个与现实项目所接水表数相关
         -->
        <base 
            isLowPower="false"
@@ -24,6 +26,8 @@
            offLineCachTimeout="86400"
            lastUpDataTimeLive="1"
            dbDataIdSuffix="1"
            cacheUpDownDataWarnCount="100000"
            cacheUpDownDataMaxCount="110000"
        />
        
        <!-- 
@@ -53,27 +57,28 @@
        <!-- 
        æ”¯æŒæ¨¡å—
        çŸ­å·¥ä½œæ—¶é•¿çº¿ç¨‹æ± ï¼Œçº¿ç¨‹è´Ÿè´£ç”¨æ—¶è¾ƒçŸ­çš„工作任务
        short_maxThread: æ± ä¸­æœ€å¤§çº¿ç¨‹æ•°ä¸ºæ‰€æœ‰CPU核数+1
        short_minThread: æ± ä¸­æœ€å°çº¿ç¨‹æ•°
        short_maxThread: æ± ä¸­æœ€å¤§çº¿ç¨‹æ•°ä¸ºæ‰€æœ‰CPU核数+1(short池与long池各分一半),若为-1,不受限制 ï¼Œè®¾ç½®ä¸º0,表示不启动线程池
        short_minThread: æ± ä¸­æœ€å°çº¿ç¨‹æ•°ï¼Œè‹¥ä¸º-1,不受限制,设置为0,表示不启动线程池
        short_freeTimeout: çº¿ç¨‹æ•°ç©ºé—²æ—¶é•¿ï¼Œè‹¥æ± ä¸­çº¿ç¨‹æ•°é‡å¤§äºŽminThread,且有的线程空闲时长超过freeTimeout,则清除该线程,为了不清除,把minThread与maxThread设置相等
        short_busyTimeout:线程不间断工作时长(单位为秒)超时限,认为线程已经了崩溃,将强制清除,短工作时长设置为5秒 
        é•¿å·¥ä½œæ—¶é•¿çº¿ç¨‹æ± ï¼Œçº¿ç¨‹è´Ÿè´£ç”¨æ—¶è¾ƒé•¿çš„工作任务,例如从Redis中取缓存的RTU上行数据
        long_maxThread: æ± ä¸­æœ€å¤§çº¿ç¨‹æ•°,若为-1,不受限制
        long_minThread: æ± ä¸­æœ€å°çº¿ç¨‹æ•°
        é•¿å·¥ä½œæ—¶é•¿çº¿ç¨‹æ± ï¼Œçº¿ç¨‹è´Ÿè´£ç”¨æ—¶è¾ƒé•¿çš„工作任务,例如数据库存取操作
        long_maxThread: æ± ä¸­æœ€å¤§çº¿ç¨‹æ•°ä¸ºæ‰€æœ‰CPU核数+1(short池与long池各分一半),若为-1,不受限制,设置为0,表示不启动线程池
        long_minThread: æ± ä¸­æœ€å°çº¿ç¨‹æ•°ï¼Œè‹¥ä¸º-1,不受限制,设置为0,表示不启动线程池
        long_freeTimeout: çº¿ç¨‹æ•°ç©ºé—²æ—¶é•¿ï¼Œè‹¥æ± ä¸­çº¿ç¨‹æ•°é‡å¤§äºŽminThread,且有的线程空闲时长超过freeTimeout,则清除该线程
        long_busyTimeout:线程不间断工作时长(单位为秒)超时限,若为-1,不受限制 
        enableThreadPool:是否启用线程池
         -->
        <!-- å½“前实现,写rtu日志、RMI数据处理用到了短线程池  -->
        <!-- å½“前实现,rtu上行数据处理(读写数据)用到了第线程池  -->
        <support
            short_maxThread="100"
            short_minThread="5"
            short_maxThread="6"
            short_minThread="6"
            short_freeTimeout="60"
            short_busyTimeout="5"
            long_maxThread="200"
            long_minThread="0"
            long_maxThread="6"
            long_minThread="6"
            long_freeTimeout="60"
            long_busyTimeout="-1"
            enableThreadPool="true"
        />
            
        <!-- 
@@ -105,14 +110,10 @@
        <!--
        sleepBigBusy:主线程大忙时每次执行间隔时长(毫秒)
        sleepSmallBusy:主线程小忙时每次执行间隔时长(毫秒)
        queueWarnSize: ç¼“存队列节点数警告数量
        queueMaxSize: ç¼“存队列节点数最大数量
         -->
        <core
            sleepBigBusy="100"
            sleepSmallBusy="500"
            queueWarnSize="100000"
            queueMaxSize="300000"
        />
        
        <!--