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