pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlCreate.java
@@ -28,6 +28,10 @@ ByteUtil.string2BCD_LE(bs, DateTime.yyMMddhhmmss(), index) ; } public static void createTp(String yyMMddhhmmss, byte[] bs, int index) throws Exception { ByteUtil.string2BCD_LE(bs, yyMMddhhmmss, index) ; } public static void createLen(byte[] bsNoTail) throws Exception { int len = bsNoTail.length - ProtocolConstantV206V1_0_0.lenHead2ctrl; bsNoTail[ProtocolConstantV206V1_0_0.dataLenIndex] = (byte)len ; pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/ByteUtil.java
@@ -1035,6 +1035,31 @@ return fromIndex ; } /** * 十六进制转字节数组 * @param hex the hex string * @return 返回 byte[] */ public static int hex2Bytes_LE(String hex, byte[] bs, int fromIndex) { if (hex == null || hex.equals("")) { return fromIndex; } hex = hex.toUpperCase(Locale.ENGLISH); int length = hex.length() / 2; char[] hexChars = hex.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } for(int i = 0 ; i < d.length; i++){ bs[fromIndex++] = d[(d.length - 1) - i] ; } return fromIndex ; } private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; // /** // * 将byte[]转换为16进制字符串 pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml
@@ -134,7 +134,10 @@ #protocol: DYJS_2023,DYJS_2024 mw: #命令发送地址 comSendUrl: "http://127.0.0.1:8070/rtuMw/com/send" ym: comSendUrl: "http://127.0.0.1:8070/rtuMw/com/send" sp: comSendUrl: "http://127.0.0.1:8071/rtuMw/com/send" #监测控制模块回调地址 rtuCallbackUrl_rm: "http://127.0.0.1:8081/remote/comRes/receive" #微信小程序回调地址 pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealClientAmountDay.java
@@ -170,8 +170,16 @@ RmClientAmountDay poHistory = new RmClientAmountDay() ; poHistory.clientId = clientVo.getId(); if(lastPo != null){ poHistory.amount += lastPo.amount ; poHistory.money += lastPo.money ; if(poHistory.amount != null){ poHistory.amount += lastPo.amount ; }else{ poHistory.amount = lastPo.amount ; } if(poHistory.money != null){ poHistory.money += lastPo.money ; }else{ poHistory.money = lastPo.money ; } poHistory.dt = lastPo.dt ; poHistory.openDtLast = lastPo.openDtLast ; poHistory.closeDtLast = lastPo.closeDtLast ; @@ -278,8 +286,16 @@ */ private RmClientAmountDay updateRmClientAmountBySameDateNewData(SeClient clientVo, RmClientAmountDay poHistory, RmClientAmountDayLast lastPo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData)throws Exception { poHistory.clientId = clientVo.getId(); poHistory.amount += lastPo.amount ; poHistory.money += lastPo.money ; if(poHistory.amount != null){ poHistory.amount += cdData.thisAmount ; }else{ poHistory.amount = cdData.thisAmount ; } if(poHistory.money != null){ poHistory.money += cdData.thisMoney ; }else{ poHistory.money = cdData.thisMoney ; } poHistory.dt = lastPo.dt ; poHistory.openDtLast = lastPo.openDtLast ; poHistory.closeDtLast = lastPo.closeDtLast ; pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/MyThreadJob.java
@@ -14,6 +14,16 @@ private static final Logger log = LogManager.getLogger(MyThreadJob.class) ; public static String icCardAddr = "3B7D1E1A" ; public static String icCardNo = "61181622830147821" ; public static String openValveDt = "240711163700" ; public static String cdC0 = "C0" ; public static String cd83Open = "83Open" ; public static String cd83Close = "83Close" ; public static String curCd = cdC0 ;//通过修改这个值,来改变上报数据类型 public String rtuAddr; public String serverIp; public Integer serverPort; @@ -44,7 +54,7 @@ if(sendTimes <= ServerProperties.sendTimes){ log.info("RTU" + rtuAddr + "开始任务"); log.info("RTU" + rtuAddr + "将要执行" + ServerProperties.sendTimes + "轮次任务,当前轮次是" + sendTimes); sendDataOfP206V1_0_0() ; sendDataOfP206V1_0_0(curCd) ; }else{ if(ServerProperties.sendOverThenCloseConnect == 1){ log.info("RTU" + rtuAddr + "等待一会,以接收通信中间件下行数据"); @@ -64,11 +74,20 @@ } } private void sendDataOfP206V1_0_0(){ private void sendDataOfP206V1_0_0(String cd){ try{ if(heartbeatTimes > ServerProperties.heartbeatTimes){ heartbeatTimes = 1 ; this.sendReportData() ; byte[] bs = null ; if(cd.equals(cdC0)){ bs = RtuUpData.createCdC0(this.rtuAddr) ; }else if(cd.equals(cd83Open)){ bs = RtuUpData.createCd83Open(this.rtuAddr, icCardAddr, icCardNo, openValveDt) ; }else if(cd.equals(cd83Close)){ bs = RtuUpData.createCd83Close(this.rtuAddr, icCardAddr, icCardNo, openValveDt) ; } this.session.write(bs) ; log.info("RTU" + rtuAddr + "发送了上行数据:" + ByteUtil.bytes2Hex(bs, false)); TcpClUnit.clientSendData(); sendTimes++ ; }else{ @@ -82,7 +101,7 @@ } private void sendHeartbeat(){ try{ byte[] bs = this.createHeartbeat() ; byte[] bs = RtuUpData.createHeartbeat(this.rtuAddr) ; this.session.write(bs) ; log.info("RTU" + rtuAddr + "发送了心跳数据:" + ByteUtil.bytes2Hex(bs, false)); }catch (Exception e){ @@ -90,15 +109,6 @@ } } private void sendReportData(){ try{ byte[] bs = this.createReport() ; this.session.write(bs) ; log.info("RTU" + rtuAddr + "发送了上报数据:" + ByteUtil.bytes2Hex(bs, false)); }catch (Exception e){ e.printStackTrace(); } } private void jobOver(){ if(ServerProperties.sendOverThenCloseConnect == 1){ @@ -108,128 +118,6 @@ TcpClUnit.clientOver() ; } /** * 构造心跳数据 * @return 字节数组 * @throws Exception 异常 */ public byte[] createHeartbeat( ) throws Exception { CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ; byte[] bytes ; byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ; byte index = 0 ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = 0 ;//帧长度 index++ ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = commonV1_0_1.createCtrl((byte)0x80, (byte)0) ;//控制域功能码:确认 认可 index++ ; GlCreate.createRtuAddr(this.rtuAddr, bsHead, index); index += 5 ; ByteUtil.hex2Bytes("02", bsHead, index) ; byte[] bs = new byte[1] ; bs[0] = (byte)0xF2 ;//数据域: 1 个字节,F0 登录, F1 退出登录,F2 在线保持。 bytes = ByteUtil.bytesMerge(bsHead, bs) ; GlCreate.createLen(bytes);//长度放字节数组中 byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中 bytes = ByteUtil.bytesMerge(bytes, bsTail) ; return bytes ; } /** * 构造上报数据 * @return 字节数组 * @throws Exception 异常 */ public byte[] createReport( ) throws Exception { CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ; byte[] bytes ; byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ; byte index = 0 ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = 0 ;//帧长度 index++ ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = commonV1_0_1.createCtrl((byte)0x80, (byte)3) ;//控制域功能码3:自报帧,流量(水量)参数 index++ ; GlCreate.createRtuAddr(this.rtuAddr, bsHead, index); index += 5 ; ByteUtil.hex2Bytes("C0", bsHead, index) ; byte[] bs = new byte[2] ; bs[0] = (byte)0x04 ;//有流量数据 bs[1] = (byte)0xE0 ;//有水压、电池电压、信号强度 bytes = ByteUtil.bytesMerge(bsHead, bs) ; bs = new byte[5] ;//瞬时流量 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bs[1] = ByteUtil.int2BCD_LE (43)[0] ; bs[2] = ByteUtil.int2BCD_LE (65)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ;//累计流量 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bs[1] = ByteUtil.int2BCD_LE (43)[0] ; bs[2] = ByteUtil.int2BCD_LE (65)[0] ; bs[3] = ByteUtil.int2BCD_LE (87)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ;//损失流量 bs[0] = ByteUtil.int2BCD_LE (10)[0] ; bs[1] = ByteUtil.int2BCD_LE (32)[0] ; bs[2] = ByteUtil.int2BCD_LE (54)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//水压 bs[0] = ByteUtil.int2BCD_LE (10)[0] ; bs[1] = ByteUtil.int2BCD_LE (32)[0] ; bs[2] = ByteUtil.int2BCD_LE (4)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//电池电压 bs[0] = ByteUtil.int2BCD_LE (10)[0] ; bs[1] = ByteUtil.int2BCD_LE (32)[0] ; bs[2] = ByteUtil.int2BCD_LE (10)[0] ; bs[3] = ByteUtil.int2BCD_LE (32)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[1] ;//信号强度 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[6] ;//时钟 GlCreate.createTp(bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; GlCreate.createLen(bytes);//长度放字节数组中 byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中 bytes = ByteUtil.bytesMerge(bytes, bsTail) ; return bytes ; } pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/RtuUpData.java
New file @@ -0,0 +1,287 @@ package com.dy.testClient.tcpClient; import com.dy.common.mw.protocol.p206V1_0_0.CommonV1_0_1; import com.dy.common.mw.protocol.p206V1_0_0.ProtocolConstantV206V1_0_0; import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlCreate; import com.dy.common.util.ByteUtil; import com.dy.common.util.ByteUtilUnsigned; /** * @Author: liurunyu * @Date: 2024/7/11 13:55 * @Description */ public class RtuUpData { private static byte[] creatHead(String rtuAddr, String code, byte ctrl)throws Exception { byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ; byte index = 0 ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = 0 ;//帧长度 index++ ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = ctrl; //控制域功能码 index++ ; GlCreate.createRtuAddr(rtuAddr, bsHead, index); index += 5 ; ByteUtil.hex2Bytes(code, bsHead, index) ; return bsHead ; } /** * 构造心跳数据 * @return 字节数组 * @throws Exception 异常 */ public static byte[] createHeartbeat(String rtuAddr) throws Exception { byte[] bytes = creatHead(rtuAddr, "02", (byte)0xB0); byte[] bs = new byte[1] ; bs[0] = (byte)0xF2 ;//数据域: 1 个字节,F0 登录, F1 退出登录,F2 在线保持。 bytes = ByteUtil.bytesMerge(bytes, bs) ; GlCreate.createLen(bytes);//长度放字节数组中 byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中 bytes = ByteUtil.bytesMerge(bytes, bsTail) ; return bytes ; } /** * 构造上报数据 * @return 字节数组 * @throws Exception 异常 */ public static byte[] createCd83Open(String rtuAddr, String icCardAddr, String icCardNo, String openValveDt) throws Exception { byte[] bytes = creatHead(rtuAddr, "83", (byte)0xB0); byte[] bs = new byte[1] ; bs[0] = (byte)0x01 ;//刷卡开阀 bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ;//累计流量 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bs[1] = ByteUtil.int2BCD_LE (43)[0] ; bs[2] = ByteUtil.int2BCD_LE (0)[0] ; bs[3] = ByteUtil.int2BCD_LE (0)[0] ; bs[4] = ByteUtil.int2BCD_LE (0)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[8] ;//IC卡编号 GlCreate.createIcCardNo(icCardNo, bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//IC卡地址 ByteUtil.hex2Bytes_LE(icCardAddr, bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//用水户余额 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bs[1] = ByteUtil.int2BCD_LE (43)[0] ; bs[2] = ByteUtil.int2BCD_LE (0)[0] ; bs[3] = ByteUtil.int2BCD_LE (0)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[6] ;//开阀时间 GlCreate.createTp(openValveDt, bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[6] ;//控制器时钟 GlCreate.createTp(bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; GlCreate.createLen(bytes);//长度放字节数组中 byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中 bytes = ByteUtil.bytesMerge(bytes, bsTail) ; return bytes ; } /** * 构造上报数据 * @return 字节数组 * @throws Exception 异常 */ public static byte[] createCd83Close(String rtuAddr, String icCardAddr, String icCardNo, String openValveDt) throws Exception { byte[] bytes = creatHead(rtuAddr, "83", (byte)0xB0); byte[] bs = new byte[1] ; bs[0] = (byte)0x02 ;//刷卡关阀 bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ;//累计流量 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bs[1] = ByteUtil.int2BCD_LE (53)[0] ; bs[2] = ByteUtil.int2BCD_LE (0)[0] ; bs[3] = ByteUtil.int2BCD_LE (0)[0] ; bs[4] = ByteUtil.int2BCD_LE (0)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[8] ;//IC卡编号 GlCreate.createIcCardNo(icCardNo, bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//IC卡地址 ByteUtil.hex2Bytes_LE(icCardAddr, bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//用水户余额 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bs[1] = ByteUtil.int2BCD_LE (33)[0] ; bs[2] = ByteUtil.int2BCD_LE (0)[0] ; bs[3] = ByteUtil.int2BCD_LE (0)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[6] ;//开阀时间 GlCreate.createTp(openValveDt, bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[6] ;//关阀时间 GlCreate.createTp(bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ;//用水户本次用水量 bs[0] = ByteUtil.int2BCD_LE (0)[0] ; bs[1] = ByteUtil.int2BCD_LE (10)[0] ; bs[2] = ByteUtil.int2BCD_LE (0)[0] ; bs[3] = ByteUtil.int2BCD_LE (0)[0] ; bs[4] = ByteUtil.int2BCD_LE (0)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//用水户本次消费金额 bs[0] = ByteUtil.int2BCD_LE (0)[0] ; bs[1] = ByteUtil.int2BCD_LE (10)[0] ; bs[2] = ByteUtil.int2BCD_LE (0)[0] ; bs[3] = ByteUtil.int2BCD_LE (0)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[2] ;//用水户本次用水时长 bs[0] = ByteUtil.int2BCD_LE (10)[0] ; bs[1] = ByteUtil.int2BCD_LE (0)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[1] ;//水价类型 bs[0] = ByteUtil.int2BCD_LE (1)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[2] ;//水价 bs[0] = ByteUtil.int2BCD_LE (0)[0] ; bs[1] = ByteUtil.int2BCD_LE (1)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[6] ;//控制器时钟 GlCreate.createTp(bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[1] ;//卡类型 bs[0] = ByteUtil.int2BCD_LE (1)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; GlCreate.createLen(bytes);//长度放字节数组中 byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中 bytes = ByteUtil.bytesMerge(bytes, bsTail) ; return bytes ; } /** * 构造上报数据 * @return 字节数组 * @throws Exception 异常 */ public static byte[] createCdC0(String rtuAddr) throws Exception { CommonV1_0_1 commonV1_0_1 = new CommonV1_0_1() ; byte[] bytes ; byte[] bsHead = new byte[ProtocolConstantV206V1_0_0.lenHead2Code] ; byte index = 0 ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = 0 ;//帧长度 index++ ; bsHead[index] = ProtocolConstantV206V1_0_0.P_Head_Byte ; index++ ; bsHead[index] = commonV1_0_1.createCtrl((byte)0x80, (byte)3) ;//控制域功能码3:自报帧,流量(水量)参数 index++ ; GlCreate.createRtuAddr(rtuAddr, bsHead, index); index += 5 ; ByteUtil.hex2Bytes("C0", bsHead, index) ; byte[] bs = new byte[2] ; bs[0] = (byte)0x04 ;//有流量数据 bs[1] = (byte)0xE0 ;//有水压、电池电压、信号强度 bytes = ByteUtil.bytesMerge(bsHead, bs) ; bs = new byte[5] ;//瞬时流量 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bs[1] = ByteUtil.int2BCD_LE (43)[0] ; bs[2] = ByteUtil.int2BCD_LE (65)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ;//累计流量 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bs[1] = ByteUtil.int2BCD_LE (43)[0] ; bs[2] = ByteUtil.int2BCD_LE (65)[0] ; bs[3] = ByteUtil.int2BCD_LE (87)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[5] ;//损失流量 bs[0] = ByteUtil.int2BCD_LE (10)[0] ; bs[1] = ByteUtil.int2BCD_LE (32)[0] ; bs[2] = ByteUtil.int2BCD_LE (54)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//水压 bs[0] = ByteUtil.int2BCD_LE (10)[0] ; bs[1] = ByteUtil.int2BCD_LE (32)[0] ; bs[2] = ByteUtil.int2BCD_LE (4)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[4] ;//电池电压 bs[0] = ByteUtil.int2BCD_LE (10)[0] ; bs[1] = ByteUtil.int2BCD_LE (32)[0] ; bs[2] = ByteUtil.int2BCD_LE (10)[0] ; bs[3] = ByteUtil.int2BCD_LE (32)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[1] ;//信号强度 bs[0] = ByteUtil.int2BCD_LE (21)[0] ; bytes = ByteUtil.bytesMerge(bytes, bs) ; bs = new byte[6] ;//时钟 GlCreate.createTp(bs, 0); bytes = ByteUtil.bytesMerge(bytes, bs) ; GlCreate.createLen(bytes);//长度放字节数组中 byte[] bsTail = GlCreate.createCrcTail(bytes) ;//CRC和尾叠加字节数组中 bytes = ByteUtil.bytesMerge(bytes, bsTail) ; return bytes ; } } pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/resources/log4j2.xml
@@ -12,7 +12,7 @@ /logs/testJgroups.log当前软件所在硬盘根目录 logs/testJgroups.log当前软件所在目录 --> <RollingFile name="File" fileName="logs/mwTestCl.log" filePattern="logs/aepTest-%d{yyyyMMdd}-%i.log"> <RollingFile name="File" fileName="logs/mwTestCl.log" filePattern="logs/mwTestCl-%d{yyyyMMdd}-%i.log"> <PatternLayout charset="UTF-8" pattern="%d %-5p [%t] (%class.%method:%L) - %m%n%throwable"/> <Policies> <TimeBasedTriggeringPolicy interval="7" /> pipIrr-platform/pipIrr-mw/pipIrr-mwTest-server/src/main/java/com/dy/testServer/Server.java
@@ -105,8 +105,8 @@ if(txt.startsWith("0")){ throw new Exception("元素config.base的属性rtuAddrStart的数值不能以0开头!"); } if(txt.length() != 10){ throw new Exception("元素config.base的属性rtuAddrStart的数值长度必须为10位!"); if(!(txt.length() == 10 || txt.length() == 12)){ throw new Exception("元素config.base的属性rtuAddrStart的数值长度必须为10位或12位!"); } ServerProperties.rtuAddrStart = Long.valueOf(txt) ; @@ -121,8 +121,8 @@ if(txt.startsWith("0")){ throw new Exception("元素config.base的属性rtuAddrEnd的数值不能以0开头!"); } if(txt.length() != 10){ throw new Exception("元素config.base的属性rtuAddrEnd的数值长度必须为10位!"); if(!(txt.length() == 10 || txt.length() == 12)){ throw new Exception("元素config.base的属性rtuAddrEnd的数值长度必须为10位或12位!"); } ServerProperties.rtuAddrEnd = Long.valueOf(txt) ; if(ServerProperties.rtuAddrEnd <= ServerProperties.rtuAddrStart){ pipIrr-platform/pipIrr-mw/pipIrr-mwTest-server/src/main/resources/log4j2.xml
@@ -12,7 +12,7 @@ /logs/testJgroups.log当前软件所在硬盘根目录 logs/testJgroups.log当前软件所在目录 --> <RollingFile name="File" fileName="logs/mwTestSv.log" filePattern="logs/aepTest-%d{yyyyMMdd}-%i.log"> <RollingFile name="File" fileName="logs/mwTestSv.log" filePattern="logs/mwTestSv-%d{yyyyMMdd}-%i.log"> <PatternLayout charset="UTF-8" pattern="%d %-5p [%t] (%class.%method:%L) - %m%n%throwable"/> <Policies> <TimeBasedTriggeringPolicy interval="7" /> pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/AdapterImp_TcpClUnit.java
New file @@ -0,0 +1,19 @@ package com.dy.pipIrrMwTestRtu; import com.dy.pipIrrMwTestRtu.tcpClient.TcpClUnitAdapter; import com.dy.pipIrrMwTestRtu.tcpClient.TcpClUnitConfigVo; public class AdapterImp_TcpClUnit implements TcpClUnitAdapter { private TcpClUnitConfigVo configVo ; public TcpClUnitConfigVo getConfig() { return configVo; } public void setConfig(TcpClUnitConfigVo configVo){ this.configVo = configVo ; } } pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalCodecFactory.java
New file @@ -0,0 +1,35 @@ package com.dy.pipIrrMwTestRtu.tcpClient; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFactory; import org.apache.mina.filter.codec.ProtocolDecoder; import org.apache.mina.filter.codec.ProtocolEncoder; public class LocalCodecFactory implements ProtocolCodecFactory { private ProtocolEncoder encoder; private ProtocolDecoder decoder; public LocalCodecFactory() { encoder = new LocalEncoder(); decoder = new LocalDecoder(); } /** * 得到协议编码器 * @param ioSession 网络会话 * @return 协议编码器 */ @Override public ProtocolEncoder getEncoder(IoSession ioSession) { return encoder; } /** * 得到协议解码器 * @param ioSession 网络会话 * @return 协议解码器 */ @Override public ProtocolDecoder getDecoder(IoSession ioSession) { return decoder; } } pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalDecoder.java
New file @@ -0,0 +1,37 @@ package com.dy.pipIrrMwTestRtu.tcpClient; import com.dy.common.util.ByteUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.CumulativeProtocolDecoder; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import java.io.IOException; public class LocalDecoder extends CumulativeProtocolDecoder { private static final Logger log = LogManager.getLogger(LocalDecoder.class) ; private static final String DECODER_STATE_KEY = LocalDecoder.class.getName() + ".STATE"; public static final int MAX_SIZE = 2147483647 ; /** * 对网络传输来的数据进行解码 */ protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws IOException, Exception{ int remain = in.remaining() ; if(remain > 0){ byte[] preByte = new byte[remain]; in.get(preByte) ; in.position(0) ; log.info("收到中心下行数据:" + ByteUtil.bytes2Hex(preByte, true)); } return true; } } pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/LocalEncoder.java
New file @@ -0,0 +1,27 @@ package com.dy.pipIrrMwTestRtu.tcpClient; import com.dy.common.util.ByteUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolEncoderAdapter; import org.apache.mina.filter.codec.ProtocolEncoderOutput; import java.io.IOException; public class LocalEncoder extends ProtocolEncoderAdapter { private static final Logger log = LogManager.getLogger(LocalEncoder.class) ; /** * 对数据进行编码,以备网络传输 */ public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws IOException, Exception{ byte[] data = (byte[])message; log.info("下行数据:" + ByteUtil.bytes2Hex(data, true)); out.write(IoBuffer.allocate((data==null?0:data.length), false).put(data).flip()); } } pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpClUnitAdapter.java
New file @@ -0,0 +1,7 @@ package com.dy.pipIrrMwTestRtu.tcpClient; import com.dy.common.mw.UnitAdapterInterface; public interface TcpClUnitAdapter extends UnitAdapterInterface { public TcpClUnitConfigVo getConfig() ; } pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpClUnitConfigVo.java
New file @@ -0,0 +1,6 @@ package com.dy.pipIrrMwTestRtu.tcpClient; public class TcpClUnitConfigVo { public String mwServerIp ; public Integer mwServerPort ; } pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpConnect.java
New file @@ -0,0 +1,62 @@ package com.dy.pipIrrMwTestRtu.tcpClient; import com.dy.common.util.Callback; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.transport.socket.SocketConnector; import org.apache.mina.transport.socket.nio.NioSocketConnector; import java.net.InetSocketAddress; public class TcpConnect { /** * 判断会话是否有效 * @param se 网络会话 * @return 是否连接 */ public boolean isConnected(IoSession se) { return (se != null && se.isConnected()); } /** * 创建新会话 * @param host 服务器URI * @param port 服务器端口 * @param connectTimeout 连接超时时长 * @param handler 数据处理者 * @param callback 回调 * @return 网络会话 */ public void createSession(String host , int port , int connectTimeout , TcpHandler handler, Callback callback) throws Exception{ SocketConnector connector = new NioSocketConnector(); connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new LocalCodecFactory())); connector.setHandler(handler); ConnectFuture connectFuture = connector.connect(new InetSocketAddress(host, port)); connectFuture.awaitUninterruptibly(connectTimeout); IoSession se = connectFuture.getSession(); callback.call(se) ; } /** * 关闭会话联接 * @param se * @param connectTimeout */ public void disconnect(IoSession se , int connectTimeout) { if (se != null) { try{ se.closeNow().awaitUninterruptibly(connectTimeout); }catch(Exception e){ }finally{ se = null; } } } } pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/java/com/dy/pipIrrMwTestRtu/tcpClient/TcpHandler.java
New file @@ -0,0 +1,77 @@ package com.dy.pipIrrMwTestRtu.tcpClient; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.FilterEvent; public class TcpHandler extends IoHandlerAdapter { private static Logger log = LogManager.getLogger(TcpHandler.class.getName()) ; /** * {@inheritDoc} */ @Override public void sessionCreated(IoSession session) throws Exception { } /** * {@inheritDoc} */ @Override public void sessionOpened(IoSession session) throws Exception { } /** * {@inheritDoc} */ @Override public void sessionClosed(IoSession session) throws Exception { } /** * {@inheritDoc} */ @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { } /** * {@inheritDoc} */ @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { } /** * {@inheritDoc} */ @Override public void messageReceived(IoSession session, Object message) throws Exception { } /** * {@inheritDoc} */ @Override public void messageSent(IoSession session, Object message) throws Exception { } /** * {@inheritDoc} */ @Override public void inputClosed(IoSession session) throws Exception { session.closeNow(); } /** * {@inheritDoc} */ @Override public void event(IoSession session, FilterEvent event) throws Exception { } } pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/Config.xml
New file @@ -0,0 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <config> <server name="RTU模拟" showStartInfo="true" company="http://www.dyjs.com"/> <!-- enable:是否启动 --> <tcpCl mwServerIp="127.0.0.1" mwServerPort="60000" /> </config> pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/application.yml
New file @@ -0,0 +1,29 @@ logging: charset: console: UTF-8 config: classpath: log4j2.yml #web服务端口,tomcat默认是8080 server: error: whitelabel: enabled: false port: 65534 servlet: context-path: /rtu #web访问上下文路径 encoding: #取消默认的字符集编码 enabled: true #设置强制使用指定字符编码集 force: true #使用的字符编码 charset: utf-8 #禁止启动数据库连接池 spring: #autoconfigure: # exclude: # - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration # - org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration # - org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration pipIrr-platform/pipIrr-web/pipIrr-mwTest-rtu/src/main/resources/log4j2.xml
New file @@ -0,0 +1,39 @@ <?xml version="1.0" encoding="UTF-8"?> <Configuration status="OFF"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout charset="GBK" pattern="%d %-5p [%t] (%F:%L) - %m%n%throwable"/> </Console> <!-- fileName="${sys:user.home}/logs/aepTest.log" filePattern="${sys:user.home}/logs/aepTest-%d{yyyy-MM}-%i.log.gz" fileName="/logs/testJgroups.log" filePattern="/logs/testJgroups-%d{yyyyMMdd}-%i.log.gz" fileName="logs/testJgroups.log" filePattern="logs/testJgroups-%d{yyyyMMdd}-%i.log.gz" sys:user.home当前用户在操作系统中的文档目录 /logs/testJgroups.log当前软件所在硬盘根目录 logs/testJgroups.log当前软件所在目录 --> <RollingFile name="File" fileName="logs/mwRtu.log" filePattern="logs/mwRtu-%d{yyyyMMdd}-%i.log"> <PatternLayout charset="UTF-8" pattern="%d %-5p [%t] (%class.%method:%L) - %m%n%throwable"/> <Policies> <TimeBasedTriggeringPolicy interval="7" /> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <DefaultRolloverStrategy max="50" /> </RollingFile> </Appenders> <Loggers> <!-- <Logger name="com.zhzc.jgTest" level="debug"> <AppenderRef ref="Console"/> </Logger> <Logger name="org.jgroups" level="info"> <AppenderRef ref="File"/> </Logger> --> <!-- Root与各个Logger同时起作用 --> <Root level="info"> <AppenderRef ref="Console"/> <AppenderRef ref="File"/> </Root> </Loggers> </Configuration> pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/pom.xml
@@ -13,7 +13,7 @@ <packaging>jar</packaging> <artifactId>pipIrr-mwTest-web</artifactId> <version>1.0.0</version> <name>pipIrr-mw-rtu</name> <name>pipIrr-mwTest-web</name> <description>通信中间件中心服务端下发命令测试</description> <dependencies> pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/src/main/java/com/dy/pipIrrMwTestWeb/PipIrrMwTestWebApplication.java
@@ -28,9 +28,6 @@ ) public class PipIrrMwTestWebApplication{ @Autowired private CommandP206V202404Ctrl test ; public static void main(String[] args) { SpringApplication.run(PipIrrMwTestWebApplication.class, args); } pipIrr-platform/pipIrr-web/pom.xml
@@ -18,6 +18,7 @@ <description>此模块为其他web模块的局部全局模块,只定义依赖</description> <modules> <module>pipIrr-mwTest-rtu</module> <module>pipIrr-mwTest-web</module> <module>pipIrr-web-sso</module> <module>pipIrr-web-base</module>