diff --git a/src/com/szpg/DSCTest.java b/src/com/szpg/DSCTest.java index a7bf684..bacf942 100644 --- a/src/com/szpg/DSCTest.java +++ b/src/com/szpg/DSCTest.java @@ -34,6 +34,8 @@ // 测试发送查询甲烷参数命令 dsc.testSendCH4Command(client); + +// System.out.println(Float.intBitsToFloat(Integer.parseInt("3F4054F5",16))); } private void testSendCH4Command(ACUClient client) { diff --git a/src/com/szpg/DSCTest.java b/src/com/szpg/DSCTest.java index a7bf684..bacf942 100644 --- a/src/com/szpg/DSCTest.java +++ b/src/com/szpg/DSCTest.java @@ -34,6 +34,8 @@ // 测试发送查询甲烷参数命令 dsc.testSendCH4Command(client); + +// System.out.println(Float.intBitsToFloat(Integer.parseInt("3F4054F5",16))); } private void testSendCH4Command(ACUClient client) { diff --git a/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java b/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java index 934f17e..50fc608 100644 --- a/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java +++ b/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java @@ -1,5 +1,6 @@ package com.szpg.plc.message.response.read; +import java.util.ArrayList; import java.util.List; import com.szpg.plc.message.CommandResponse; @@ -11,24 +12,31 @@ */ private static final long serialVersionUID = 6615138314462518854L; - private List jwnd; //甲烷浓度值 - private List jwldbjz; //甲烷联动报警值 + private List jwnd; //甲烷浓度值 + private List jwldbjz; //甲烷联动报警值 private List jwldsn; //甲烷联动使能 private List jwldbj; //甲烷联动报警 + + public ReadCH4ParamCommandResponse() { + jwnd = new ArrayList(); + jwldbjz = new ArrayList(); + jwldsn = new ArrayList(); + jwldbj = new ArrayList(); + } - public List getJwnd() { + public List getJwnd() { return jwnd; } - public void setJwnd(List jwnd) { + public void setJwnd(List jwnd) { this.jwnd = jwnd; } - public List getJwldbjz() { + public List getJwldbjz() { return jwldbjz; } - public void setJwldbjz(List jwldbjz) { + public void setJwldbjz(List jwldbjz) { this.jwldbjz = jwldbjz; } diff --git a/src/com/szpg/DSCTest.java b/src/com/szpg/DSCTest.java index a7bf684..bacf942 100644 --- a/src/com/szpg/DSCTest.java +++ b/src/com/szpg/DSCTest.java @@ -34,6 +34,8 @@ // 测试发送查询甲烷参数命令 dsc.testSendCH4Command(client); + +// System.out.println(Float.intBitsToFloat(Integer.parseInt("3F4054F5",16))); } private void testSendCH4Command(ACUClient client) { diff --git a/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java b/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java index 934f17e..50fc608 100644 --- a/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java +++ b/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java @@ -1,5 +1,6 @@ package com.szpg.plc.message.response.read; +import java.util.ArrayList; import java.util.List; import com.szpg.plc.message.CommandResponse; @@ -11,24 +12,31 @@ */ private static final long serialVersionUID = 6615138314462518854L; - private List jwnd; //甲烷浓度值 - private List jwldbjz; //甲烷联动报警值 + private List jwnd; //甲烷浓度值 + private List jwldbjz; //甲烷联动报警值 private List jwldsn; //甲烷联动使能 private List jwldbj; //甲烷联动报警 + + public ReadCH4ParamCommandResponse() { + jwnd = new ArrayList(); + jwldbjz = new ArrayList(); + jwldsn = new ArrayList(); + jwldbj = new ArrayList(); + } - public List getJwnd() { + public List getJwnd() { return jwnd; } - public void setJwnd(List jwnd) { + public void setJwnd(List jwnd) { this.jwnd = jwnd; } - public List getJwldbjz() { + public List getJwldbjz() { return jwldbjz; } - public void setJwldbjz(List jwldbjz) { + public void setJwldbjz(List jwldbjz) { this.jwldbjz = jwldbjz; } diff --git a/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java b/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java index ce15389..101eb07 100644 --- a/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java +++ b/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java @@ -6,11 +6,16 @@ import org.apache.log4j.Logger; +import com.szpg.db.dao.PgAcuRdcmdDao; +import com.szpg.db.dao.impl.PgAcuRdcmdDaoImpl; +import com.szpg.db.data.PgAcuRdcmd; import com.szpg.plc.message.AppMessage; +import com.szpg.plc.message.AppMessageConstants; import com.szpg.plc.message.UnKnownMessage; import com.szpg.plc.message.command.LinkCommand; import com.szpg.plc.message.command.read.ReadCH4ParamCommand; import com.szpg.plc.message.response.LinkCommandResponse; +import com.szpg.plc.message.response.read.ReadCH4ParamCommandResponse; import com.szpg.plc.protocol.DTProtocolInterface; import com.szpg.plc.protocol.fins.frame.FINSByteFrame; import com.szpg.plc.protocol.fins.frame.FINSByteFrameTool; @@ -48,11 +53,27 @@ // 读写命令的响应 if (commandStr.equalsIgnoreCase("00000002")) { - String commandType = FINSByteFrameTool.getFinsCommandCode(byteMessage); - if (commandType.equalsIgnoreCase("0101")) { - // 读内存命令响应 -// received = - } else if (commandType.equalsIgnoreCase("0102")) { + String commandCode = FINSByteFrameTool.getFinsCommandCode(byteMessage); + if (commandCode.equalsIgnoreCase("0101")) { + // 读内存命令响应的解析 + + // 1首先解析出消息的PLC端地址(即响应消息的源地址)和返回的内存内容的字数 + String dest = FINSByteFrameTool.getControlSour(byteMessage); //命令的目标地址即响应消息的源地址 + int count = FINSByteFrameTool.getDataWithoutEndCode(byteMessage).length; + + // 2查询数据中最近的有效的读内存命令,获取其读取的参数类型 + PgAcuRdcmdDao readCmdDao = new PgAcuRdcmdDaoImpl(); + PgAcuRdcmd readCmd = readCmdDao.findLatestCmdByDestAndCount(dest, count); + if (null != readCmd) { + String commandType = readCmd.getCmd_type(); + + // 3根据参数类型调用相应的方法进行解析 + switch(commandType) { + case AppMessageConstants.CMD_TYPE_READCH4PARAM: + received = bytesToReadCH4ParamCommand(finsFrame); + } + } + } else if (commandCode.equalsIgnoreCase("0102")) { // 写内存命令响应 } } @@ -236,7 +257,7 @@ } /** - * 将链路监测消息字节数组解析为消息对象AFN=02H + * 将握手响应字节数组转换为消息对象 * * @param byteMessage * @return @@ -261,34 +282,34 @@ return lcr; } -// /** -// * 将设置终端地址响应消息字节数组解析为消息对象AFN=10H -// * -// * @param byteMessage -// * @return -// */ -// private AppMessage bytesToSetAddressCommandResponse(GBByteFrame gbFrame) { -// byte[] data = GBByteFrameTool.getDataWithoutPwTp(gbFrame); // 获取数据域 -// String address = gbFrame.address; // 获取地址域 -// -// SetAddressCommandResponse sacr = new SetAddressCommandResponse(Calendar.getInstance(), address); -// if (data.length == 5) { -// sacr.setNewAddress(ByteUtil.bcdToString(new byte[] { data[0], data[1], data[2] }) + -// ByteUtil.binToHexString(new byte[] { data[4], data[3] })); -// if (sacr.getNewAddress().length() == 10) { -// sacr.setValid(true); -// sacr.setSuccess(true); -// } else { -// logger.error("设置终端地址响应消息解析错误"); -// sacr.setValid(false); -// } -// } else { -// logger.error("设置终端地址响应消息长度错误"); -// sacr.setValid(false); -// } -// -// return sacr; -// } + /** + * 将查询甲烷参数响应消息字节数组转换为消息对象 + * + * @param byteMessage + * @return + */ + private AppMessage bytesToReadCH4ParamCommand(FINSByteFrame finsFrame) { + ReadCH4ParamCommandResponse rcpcr = new ReadCH4ParamCommandResponse(); + + byte[] body = finsFrame.TEXT_DATA_BODY; + if (body[2] == 0x00 && body[3] == 0x00) { + // 正常返回 + byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存 + int chct = data.length / (2 * 2 * 2); //甲烷监测点的数量/每个甲烷点位的参数包括2个变量、每个变量占2个字,每个字占2个字节 + for (int i = 0; i < chct; i++) { + byte[] valueByte = new byte[] { data[i*8 + 2], data[i*8 + 3], data[i*8], data[i*8 + 1] }; + byte[] thresholdByte = new byte[] { data[i*8 + 6], data[i*8 + 7], data[i*8 + 4], data[i*8 + 5] }; + + float value = Float.intBitsToFloat(Integer.parseInt(ByteUtil.binToHexString(valueByte), 16)); //甲烷浓度值 + float threshold = Float.intBitsToFloat(Integer.parseInt(ByteUtil.binToHexString(thresholdByte), 16)); //甲烷报警阈值 + + rcpcr.getJwnd().add(value); + rcpcr.getJwldbjz().add(threshold); + } + } + + return rcpcr; + } // // /** // * 将查询终端地址响应消息字节数组解析为消息对象AFN=50H @@ -3461,7 +3482,9 @@ Bytes bytes = new Bytes(); bytes.append(byteMessage[i]).append(byteMessage[i + 1]).append(byteMessage[i + 2]).append(byteMessage[i + 3]); //FINS帧头 bytes.append(byteMessage[i + 4]).append(byteMessage[i + 5]).append(byteMessage[i + 6]).append(byteMessage[i + 7]); //FINS长度 - for (int j = 0; j < length + 8; j++) { + + // FINS的数据区 + for (int j = 0; j < length; j++) { bytes.append(byteMessage[i + 8 + j]); } @@ -3476,6 +3499,7 @@ } } } catch (Exception e) { + e.printStackTrace(); bytesList.clear(); bytesList.add(byteMessage); return bytesList; diff --git a/src/com/szpg/DSCTest.java b/src/com/szpg/DSCTest.java index a7bf684..bacf942 100644 --- a/src/com/szpg/DSCTest.java +++ b/src/com/szpg/DSCTest.java @@ -34,6 +34,8 @@ // 测试发送查询甲烷参数命令 dsc.testSendCH4Command(client); + +// System.out.println(Float.intBitsToFloat(Integer.parseInt("3F4054F5",16))); } private void testSendCH4Command(ACUClient client) { diff --git a/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java b/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java index 934f17e..50fc608 100644 --- a/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java +++ b/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java @@ -1,5 +1,6 @@ package com.szpg.plc.message.response.read; +import java.util.ArrayList; import java.util.List; import com.szpg.plc.message.CommandResponse; @@ -11,24 +12,31 @@ */ private static final long serialVersionUID = 6615138314462518854L; - private List jwnd; //甲烷浓度值 - private List jwldbjz; //甲烷联动报警值 + private List jwnd; //甲烷浓度值 + private List jwldbjz; //甲烷联动报警值 private List jwldsn; //甲烷联动使能 private List jwldbj; //甲烷联动报警 + + public ReadCH4ParamCommandResponse() { + jwnd = new ArrayList(); + jwldbjz = new ArrayList(); + jwldsn = new ArrayList(); + jwldbj = new ArrayList(); + } - public List getJwnd() { + public List getJwnd() { return jwnd; } - public void setJwnd(List jwnd) { + public void setJwnd(List jwnd) { this.jwnd = jwnd; } - public List getJwldbjz() { + public List getJwldbjz() { return jwldbjz; } - public void setJwldbjz(List jwldbjz) { + public void setJwldbjz(List jwldbjz) { this.jwldbjz = jwldbjz; } diff --git a/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java b/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java index ce15389..101eb07 100644 --- a/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java +++ b/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java @@ -6,11 +6,16 @@ import org.apache.log4j.Logger; +import com.szpg.db.dao.PgAcuRdcmdDao; +import com.szpg.db.dao.impl.PgAcuRdcmdDaoImpl; +import com.szpg.db.data.PgAcuRdcmd; import com.szpg.plc.message.AppMessage; +import com.szpg.plc.message.AppMessageConstants; import com.szpg.plc.message.UnKnownMessage; import com.szpg.plc.message.command.LinkCommand; import com.szpg.plc.message.command.read.ReadCH4ParamCommand; import com.szpg.plc.message.response.LinkCommandResponse; +import com.szpg.plc.message.response.read.ReadCH4ParamCommandResponse; import com.szpg.plc.protocol.DTProtocolInterface; import com.szpg.plc.protocol.fins.frame.FINSByteFrame; import com.szpg.plc.protocol.fins.frame.FINSByteFrameTool; @@ -48,11 +53,27 @@ // 读写命令的响应 if (commandStr.equalsIgnoreCase("00000002")) { - String commandType = FINSByteFrameTool.getFinsCommandCode(byteMessage); - if (commandType.equalsIgnoreCase("0101")) { - // 读内存命令响应 -// received = - } else if (commandType.equalsIgnoreCase("0102")) { + String commandCode = FINSByteFrameTool.getFinsCommandCode(byteMessage); + if (commandCode.equalsIgnoreCase("0101")) { + // 读内存命令响应的解析 + + // 1首先解析出消息的PLC端地址(即响应消息的源地址)和返回的内存内容的字数 + String dest = FINSByteFrameTool.getControlSour(byteMessage); //命令的目标地址即响应消息的源地址 + int count = FINSByteFrameTool.getDataWithoutEndCode(byteMessage).length; + + // 2查询数据中最近的有效的读内存命令,获取其读取的参数类型 + PgAcuRdcmdDao readCmdDao = new PgAcuRdcmdDaoImpl(); + PgAcuRdcmd readCmd = readCmdDao.findLatestCmdByDestAndCount(dest, count); + if (null != readCmd) { + String commandType = readCmd.getCmd_type(); + + // 3根据参数类型调用相应的方法进行解析 + switch(commandType) { + case AppMessageConstants.CMD_TYPE_READCH4PARAM: + received = bytesToReadCH4ParamCommand(finsFrame); + } + } + } else if (commandCode.equalsIgnoreCase("0102")) { // 写内存命令响应 } } @@ -236,7 +257,7 @@ } /** - * 将链路监测消息字节数组解析为消息对象AFN=02H + * 将握手响应字节数组转换为消息对象 * * @param byteMessage * @return @@ -261,34 +282,34 @@ return lcr; } -// /** -// * 将设置终端地址响应消息字节数组解析为消息对象AFN=10H -// * -// * @param byteMessage -// * @return -// */ -// private AppMessage bytesToSetAddressCommandResponse(GBByteFrame gbFrame) { -// byte[] data = GBByteFrameTool.getDataWithoutPwTp(gbFrame); // 获取数据域 -// String address = gbFrame.address; // 获取地址域 -// -// SetAddressCommandResponse sacr = new SetAddressCommandResponse(Calendar.getInstance(), address); -// if (data.length == 5) { -// sacr.setNewAddress(ByteUtil.bcdToString(new byte[] { data[0], data[1], data[2] }) + -// ByteUtil.binToHexString(new byte[] { data[4], data[3] })); -// if (sacr.getNewAddress().length() == 10) { -// sacr.setValid(true); -// sacr.setSuccess(true); -// } else { -// logger.error("设置终端地址响应消息解析错误"); -// sacr.setValid(false); -// } -// } else { -// logger.error("设置终端地址响应消息长度错误"); -// sacr.setValid(false); -// } -// -// return sacr; -// } + /** + * 将查询甲烷参数响应消息字节数组转换为消息对象 + * + * @param byteMessage + * @return + */ + private AppMessage bytesToReadCH4ParamCommand(FINSByteFrame finsFrame) { + ReadCH4ParamCommandResponse rcpcr = new ReadCH4ParamCommandResponse(); + + byte[] body = finsFrame.TEXT_DATA_BODY; + if (body[2] == 0x00 && body[3] == 0x00) { + // 正常返回 + byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存 + int chct = data.length / (2 * 2 * 2); //甲烷监测点的数量/每个甲烷点位的参数包括2个变量、每个变量占2个字,每个字占2个字节 + for (int i = 0; i < chct; i++) { + byte[] valueByte = new byte[] { data[i*8 + 2], data[i*8 + 3], data[i*8], data[i*8 + 1] }; + byte[] thresholdByte = new byte[] { data[i*8 + 6], data[i*8 + 7], data[i*8 + 4], data[i*8 + 5] }; + + float value = Float.intBitsToFloat(Integer.parseInt(ByteUtil.binToHexString(valueByte), 16)); //甲烷浓度值 + float threshold = Float.intBitsToFloat(Integer.parseInt(ByteUtil.binToHexString(thresholdByte), 16)); //甲烷报警阈值 + + rcpcr.getJwnd().add(value); + rcpcr.getJwldbjz().add(threshold); + } + } + + return rcpcr; + } // // /** // * 将查询终端地址响应消息字节数组解析为消息对象AFN=50H @@ -3461,7 +3482,9 @@ Bytes bytes = new Bytes(); bytes.append(byteMessage[i]).append(byteMessage[i + 1]).append(byteMessage[i + 2]).append(byteMessage[i + 3]); //FINS帧头 bytes.append(byteMessage[i + 4]).append(byteMessage[i + 5]).append(byteMessage[i + 6]).append(byteMessage[i + 7]); //FINS长度 - for (int j = 0; j < length + 8; j++) { + + // FINS的数据区 + for (int j = 0; j < length; j++) { bytes.append(byteMessage[i + 8 + j]); } @@ -3476,6 +3499,7 @@ } } } catch (Exception e) { + e.printStackTrace(); bytesList.clear(); bytesList.add(byteMessage); return bytesList; diff --git a/src/com/szpg/plc/protocol/fins/frame/FINSByteFrame.java b/src/com/szpg/plc/protocol/fins/frame/FINSByteFrame.java index 0ed7141..d319e9f 100644 --- a/src/com/szpg/plc/protocol/fins/frame/FINSByteFrame.java +++ b/src/com/szpg/plc/protocol/fins/frame/FINSByteFrame.java @@ -223,7 +223,8 @@ return false; } - if (byteMessage.length == FINSByteFrameTool.getFrameLength(byteMessage) + 8) { + if (byteMessage.length == ByteUtil.binToInt(FINSByteFrameTool.getFrameLength(byteMessage)) + 8) { + this.LENGTH = FINSByteFrameTool.getFrameLength(byteMessage); return true; } else { return false; diff --git a/src/com/szpg/DSCTest.java b/src/com/szpg/DSCTest.java index a7bf684..bacf942 100644 --- a/src/com/szpg/DSCTest.java +++ b/src/com/szpg/DSCTest.java @@ -34,6 +34,8 @@ // 测试发送查询甲烷参数命令 dsc.testSendCH4Command(client); + +// System.out.println(Float.intBitsToFloat(Integer.parseInt("3F4054F5",16))); } private void testSendCH4Command(ACUClient client) { diff --git a/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java b/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java index 934f17e..50fc608 100644 --- a/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java +++ b/src/com/szpg/plc/message/response/read/ReadCH4ParamCommandResponse.java @@ -1,5 +1,6 @@ package com.szpg.plc.message.response.read; +import java.util.ArrayList; import java.util.List; import com.szpg.plc.message.CommandResponse; @@ -11,24 +12,31 @@ */ private static final long serialVersionUID = 6615138314462518854L; - private List jwnd; //甲烷浓度值 - private List jwldbjz; //甲烷联动报警值 + private List jwnd; //甲烷浓度值 + private List jwldbjz; //甲烷联动报警值 private List jwldsn; //甲烷联动使能 private List jwldbj; //甲烷联动报警 + + public ReadCH4ParamCommandResponse() { + jwnd = new ArrayList(); + jwldbjz = new ArrayList(); + jwldsn = new ArrayList(); + jwldbj = new ArrayList(); + } - public List getJwnd() { + public List getJwnd() { return jwnd; } - public void setJwnd(List jwnd) { + public void setJwnd(List jwnd) { this.jwnd = jwnd; } - public List getJwldbjz() { + public List getJwldbjz() { return jwldbjz; } - public void setJwldbjz(List jwldbjz) { + public void setJwldbjz(List jwldbjz) { this.jwldbjz = jwldbjz; } diff --git a/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java b/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java index ce15389..101eb07 100644 --- a/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java +++ b/src/com/szpg/plc/protocol/fins/FINSDTProtocolImp.java @@ -6,11 +6,16 @@ import org.apache.log4j.Logger; +import com.szpg.db.dao.PgAcuRdcmdDao; +import com.szpg.db.dao.impl.PgAcuRdcmdDaoImpl; +import com.szpg.db.data.PgAcuRdcmd; import com.szpg.plc.message.AppMessage; +import com.szpg.plc.message.AppMessageConstants; import com.szpg.plc.message.UnKnownMessage; import com.szpg.plc.message.command.LinkCommand; import com.szpg.plc.message.command.read.ReadCH4ParamCommand; import com.szpg.plc.message.response.LinkCommandResponse; +import com.szpg.plc.message.response.read.ReadCH4ParamCommandResponse; import com.szpg.plc.protocol.DTProtocolInterface; import com.szpg.plc.protocol.fins.frame.FINSByteFrame; import com.szpg.plc.protocol.fins.frame.FINSByteFrameTool; @@ -48,11 +53,27 @@ // 读写命令的响应 if (commandStr.equalsIgnoreCase("00000002")) { - String commandType = FINSByteFrameTool.getFinsCommandCode(byteMessage); - if (commandType.equalsIgnoreCase("0101")) { - // 读内存命令响应 -// received = - } else if (commandType.equalsIgnoreCase("0102")) { + String commandCode = FINSByteFrameTool.getFinsCommandCode(byteMessage); + if (commandCode.equalsIgnoreCase("0101")) { + // 读内存命令响应的解析 + + // 1首先解析出消息的PLC端地址(即响应消息的源地址)和返回的内存内容的字数 + String dest = FINSByteFrameTool.getControlSour(byteMessage); //命令的目标地址即响应消息的源地址 + int count = FINSByteFrameTool.getDataWithoutEndCode(byteMessage).length; + + // 2查询数据中最近的有效的读内存命令,获取其读取的参数类型 + PgAcuRdcmdDao readCmdDao = new PgAcuRdcmdDaoImpl(); + PgAcuRdcmd readCmd = readCmdDao.findLatestCmdByDestAndCount(dest, count); + if (null != readCmd) { + String commandType = readCmd.getCmd_type(); + + // 3根据参数类型调用相应的方法进行解析 + switch(commandType) { + case AppMessageConstants.CMD_TYPE_READCH4PARAM: + received = bytesToReadCH4ParamCommand(finsFrame); + } + } + } else if (commandCode.equalsIgnoreCase("0102")) { // 写内存命令响应 } } @@ -236,7 +257,7 @@ } /** - * 将链路监测消息字节数组解析为消息对象AFN=02H + * 将握手响应字节数组转换为消息对象 * * @param byteMessage * @return @@ -261,34 +282,34 @@ return lcr; } -// /** -// * 将设置终端地址响应消息字节数组解析为消息对象AFN=10H -// * -// * @param byteMessage -// * @return -// */ -// private AppMessage bytesToSetAddressCommandResponse(GBByteFrame gbFrame) { -// byte[] data = GBByteFrameTool.getDataWithoutPwTp(gbFrame); // 获取数据域 -// String address = gbFrame.address; // 获取地址域 -// -// SetAddressCommandResponse sacr = new SetAddressCommandResponse(Calendar.getInstance(), address); -// if (data.length == 5) { -// sacr.setNewAddress(ByteUtil.bcdToString(new byte[] { data[0], data[1], data[2] }) + -// ByteUtil.binToHexString(new byte[] { data[4], data[3] })); -// if (sacr.getNewAddress().length() == 10) { -// sacr.setValid(true); -// sacr.setSuccess(true); -// } else { -// logger.error("设置终端地址响应消息解析错误"); -// sacr.setValid(false); -// } -// } else { -// logger.error("设置终端地址响应消息长度错误"); -// sacr.setValid(false); -// } -// -// return sacr; -// } + /** + * 将查询甲烷参数响应消息字节数组转换为消息对象 + * + * @param byteMessage + * @return + */ + private AppMessage bytesToReadCH4ParamCommand(FINSByteFrame finsFrame) { + ReadCH4ParamCommandResponse rcpcr = new ReadCH4ParamCommandResponse(); + + byte[] body = finsFrame.TEXT_DATA_BODY; + if (body[2] == 0x00 && body[3] == 0x00) { + // 正常返回 + byte[] data = FINSByteFrameTool.getDataWithoutEndCode(finsFrame); //获取返回的内存 + int chct = data.length / (2 * 2 * 2); //甲烷监测点的数量/每个甲烷点位的参数包括2个变量、每个变量占2个字,每个字占2个字节 + for (int i = 0; i < chct; i++) { + byte[] valueByte = new byte[] { data[i*8 + 2], data[i*8 + 3], data[i*8], data[i*8 + 1] }; + byte[] thresholdByte = new byte[] { data[i*8 + 6], data[i*8 + 7], data[i*8 + 4], data[i*8 + 5] }; + + float value = Float.intBitsToFloat(Integer.parseInt(ByteUtil.binToHexString(valueByte), 16)); //甲烷浓度值 + float threshold = Float.intBitsToFloat(Integer.parseInt(ByteUtil.binToHexString(thresholdByte), 16)); //甲烷报警阈值 + + rcpcr.getJwnd().add(value); + rcpcr.getJwldbjz().add(threshold); + } + } + + return rcpcr; + } // // /** // * 将查询终端地址响应消息字节数组解析为消息对象AFN=50H @@ -3461,7 +3482,9 @@ Bytes bytes = new Bytes(); bytes.append(byteMessage[i]).append(byteMessage[i + 1]).append(byteMessage[i + 2]).append(byteMessage[i + 3]); //FINS帧头 bytes.append(byteMessage[i + 4]).append(byteMessage[i + 5]).append(byteMessage[i + 6]).append(byteMessage[i + 7]); //FINS长度 - for (int j = 0; j < length + 8; j++) { + + // FINS的数据区 + for (int j = 0; j < length; j++) { bytes.append(byteMessage[i + 8 + j]); } @@ -3476,6 +3499,7 @@ } } } catch (Exception e) { + e.printStackTrace(); bytesList.clear(); bytesList.add(byteMessage); return bytesList; diff --git a/src/com/szpg/plc/protocol/fins/frame/FINSByteFrame.java b/src/com/szpg/plc/protocol/fins/frame/FINSByteFrame.java index 0ed7141..d319e9f 100644 --- a/src/com/szpg/plc/protocol/fins/frame/FINSByteFrame.java +++ b/src/com/szpg/plc/protocol/fins/frame/FINSByteFrame.java @@ -223,7 +223,8 @@ return false; } - if (byteMessage.length == FINSByteFrameTool.getFrameLength(byteMessage) + 8) { + if (byteMessage.length == ByteUtil.binToInt(FINSByteFrameTool.getFrameLength(byteMessage)) + 8) { + this.LENGTH = FINSByteFrameTool.getFrameLength(byteMessage); return true; } else { return false; diff --git a/src/com/szpg/plc/protocol/fins/frame/FINSByteFrameTool.java b/src/com/szpg/plc/protocol/fins/frame/FINSByteFrameTool.java index 54eb01f..1d0d324 100644 --- a/src/com/szpg/plc/protocol/fins/frame/FINSByteFrameTool.java +++ b/src/com/szpg/plc/protocol/fins/frame/FINSByteFrameTool.java @@ -13,14 +13,13 @@ * @param finsFrame * @return */ - public static int getFrameLength(byte[] finsFrame) { + public static byte[] getFrameLength(byte[] finsFrame) { if (finsFrame.length < 8) { - return 0; + return new byte[] {0x00, 0x00, 0x00, 0x00}; } byte[] lengthByte = new byte[] {finsFrame[4], finsFrame[5], finsFrame[6], finsFrame[7]}; - - return ByteUtil.binToInt(lengthByte); + return lengthByte; } /** @@ -127,7 +126,7 @@ byte[] text = getText(finsFrame); if (null != text && text.length > 10) - return ByteUtil.binToHexString(new byte[] {text[6], text[7], text[7]}); + return ByteUtil.binToHexString(new byte[] {text[6], text[7], text[8]}); else return ""; } @@ -158,9 +157,9 @@ public static byte[] getDataWithoutEndCode(byte[] finsFrame) { byte[] text = getText(finsFrame); - if (null != text && text.length > 22) { + if (null != text && text.length > 12) { Bytes dataBody = new Bytes(); - for (int i = 23; i < text.length; i++) { + for (int i = 14; i < text.length; i++) { dataBody.append(text[i]); } @@ -172,6 +171,25 @@ /** + * 获取读取的数据内容 + * 不包括END CODE + * + * @param finsFrame + * @return + */ + public static byte[] getDataWithoutEndCode(FINSByteFrame finsFrame) { + byte[] dataBody = finsFrame.TEXT_DATA_BODY; + + Bytes dataByte = new Bytes(); + for (int i = 4; i < dataBody.length; i++) { + dataByte.append(dataBody[i]); + } + + return dataByte.toBytes(); + } + + + /** * 获取包含END CODE在内的用户数据域 * * @param finsFrame