折腾:
【未解决】用Java代码解析104协议收到的数据
期间,自己的接收的示例数据
68 12 E6 B7 00 00 0F 81 05 00 05 00 01 0C 00 95 42 03 00 00
解析出错,抛出异常了:

68 12 E6 B7 00 00 0F 81 05 00 05 00 01 0C 00 95 42 03 00 00 --->>> 未知类型标识符 at com.iec.analysis.common.TypeIdentifier.getDescribe(TypeIdentifier.java:46) TypeIdentifier.java:46 at com.iec.analysis.protocol104.ASDU.ASDU_analysis(ASDU.java:15) ASDU.java:15 at com.iec.analysis.protocol104.Analysis.analysis(Analysis.java:48) Analysis.java:48 at com.iec.test.Analysis104Test.analysis(Analysis104Test.java:79) Analysis104Test.java:79 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) Method.java:498 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) ReflectiveCallable.java:12 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) FrameworkMethod.java:47 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) InvokeMethod.java:17 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) ParentRunner.java:325 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) BlockJUnit4ClassRunner.java:78 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) BlockJUnit4ClassRunner.java:57 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) ParentRunner.java:290 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) ParentRunner.java:71 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) ParentRunner.java:288 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) ParentRunner.java:58 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) ParentRunner.java:268 at org.junit.runners.ParentRunner.run(ParentRunner.java:363) ParentRunner.java:363 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
需要去深入研究104协议,以及解析协议的代码,调试看看为何会报错。
然后想办法解决掉,确保能正常解析数据
此处是 code=15
代码中没有定义
src/refer/java/iec_analysis/src/main/java/com/iec/analysis/common/TypeIdentifier.java
public enum TypeIdentifier {
SINGLE_POINT(1, "不带时标的单点信息"),
TWO_POINT(3, "不带时标的双点信息"),
NORMALIZED(9, "测量值,归一化值"),
SCALE(11, "测量值,标度化值"),
SHORT_FLOAT(13, "测量值,短浮点数"),
SINGLE_POINT_TIME(30, "带CP56Time2a时标的单点信息"),
TWO_POINT_TIME(31, "带CP56Time2a时标的双点信息"),
SINGLE_COMMAND(45, "单命令(遥控)"),
TWO_COMMAND(46, "双命令(遥控)"),
PRESETS_SINGLE_PARAmeter(48, "预置/激活单个参数命令"),
READ_SINGLE_PARAMETer(102, "读单个参数命令"),
END_OF_INITIALIZATIon(70, "初始化结束"),
CALL_COMMAND(100, "召唤命令"),
CLOCK_SYNCHRONIZATIon(103, "时钟同步/读取命令"),
TEST_COMMAND(104, "测试命令"),
RESET_PROCESS(105, "复位进程命令"),
READ_MULTIPLE_PARAMETERS(132, "读多个参数命令"),
PRESETS_MULTIPLE_PARAMETERS(136, "预置/激活多个参数命令");
private int code;
private String describe;
TypeIdentifier(int code, String describe) {
this.code = code;
this.describe = describe;
}
public static String getDescribe(int code) throws UnknownTypeIdentifierException {
for (TypeIdentifier value : TypeIdentifier.values()) {
if (value.code == code) return value.describe;
}
throw new UnknownTypeIdentifierException();
}
}
所以会报错。
然后去研究104协议,看看15是什么定义
以及之前的定义,是否还有需要优化的
src/refer/java/iec_analysis/src/main/java/com/iec/analysis/protocol104/ASDU.java
builder.append("类属性标识符[7 byte]:").append(TypeIdentifier.getDescribe(asdu[0])).append("\n");找找 类属性标识符 TypeIdentifier Type Identifier
【已解决】IEC 104协议中的Type Identifier的定义
看起来:15是:
M_IT_NA_1 15 0x0F Integrated totals
然后想办法,把代码完善,加进去这些定义。
无意间发现,另外文件中
src/refer/python/iec104/iec104/asdu.py
class InfoObj(object):
__metaclass__ = InfoObjMeta
def __init__(self, data):
self.ioa = data.read("int:16")
data.read("int:16")
print "IOA: ", self.ioa
class MSpNa1(SIQ):
type_id = 1
name = 'M_SP_NA_1'
description = 'Single-point information without time tag'
def __init__(self, data):
super(MSpNa1, self).__init__(data)
LOG.debug('Obj: M_SP_NA_1, Value: {}'.format(self.spi))
class MSpTa1(InfoObj):
type_id = 2
name = 'M_SP_TA_1'
description = 'Single-point information with time tag'
def __init__(self, data):
super(MSpTa1, self).__init__(data)
...
class FSgNa1(InfoObj):
type_id = 125
name = 'F_SG_NA_1'
description = 'Segment'
class FDrTa1(InfoObj):
type_id = 126
name = 'F_DR_TA_1'
description = 'Directory'基本上都已经定义好了这些类型
不过缺少了一段的定义
C_SC_TA_1 58 0x3A Single command with time tag CP56Time2a C_DC_TA_1 59 0x3B Double command with time tag CP56Time2a C_RC_TA_1 60 0x3C Regulating step command with time tag CP56Time2a C_SE_TA_1 61 0x3D Measured value, normalised value command with time tag CP56Time2a C_SE_TB_1 62 0x3E Measured value, scaled value command with time tag CP56Time2a C_SE_TC_1 63 0x3F Measured value, short floating point number command with time tag CP56Time2a C_BO_TA_1 64 0x40 Bitstring of 32 bit command with time tag CP56Time2a
需要抽空加进去
但是此处为何
src/refer/java/iec_analysis/src/main/java/com/iec/analysis/common/TypeIdentifier.java
没有加上这些定义?
是时间上来不及?还是另外有专门的考虑?
此处,还是先去看看基本的协议,再去决定,是否给此处TypeIdentifier加上定义
此处,故意用别的

中的示例数据:
"68 0E 4E 14 7C 00 65 01 0A 00 0C 00 00 00 00 05",
去测试,看看能否解析
结果code=101
也报错

-》看来就是代码写的不完整,无法解析其他的ASDU type Identifier
-》所以,先去加上再说。
所以再去:
【已解决】把IEC 104的ASDU Type Identifier的全部定义添加到com.iec.analysis的TypeIdentifier
再去调试看看,即可解决此处问题。至少此处id解析不会报错了:
(只不过后续会出现其他错误而已)

【总结】
此处,由于之前代码:
src/refer/java/iec_analysis/src/main/java/com/iec/analysis/common/TypeIdentifier.java
中的ASDU 的Type Identifier定义不够全,导致解析很多数据都报错。
现在自己参考官网定义,加上全部的定义后:
src/refer/java/iec_analysis/src/main/java/com/iec/analysis/common/TypeIdentifier.java
package com.iec.analysis.common;
import com.iec.analysis.exception.UnknownTypeIdentifierException;
/**
* 归一化值
*
* @Authorzhangyu
* @create2019/5/2716:59
*/
public enum TypeIdentifier {
// SINGLE_POINT(1, "不带时标的单点信息"),
// TWO_POINT(3, "不带时标的双点信息"),
// NORMALIZED(9, "测量值,归一化值"),
// SCALE(11, "测量值,标度化值"),
// SHORT_FLOAT(13, "测量值,短浮点数"),
// SINGLE_POINT_TIME(30, "带CP56Time2a时标的单点信息"),
// TWO_POINT_TIME(31, "带CP56Time2a时标的双点信息"),
// SINGLE_COMMAND(45, "单命令(遥控)"),
// TWO_COMMAND(46, "双命令(遥控)"),
// PRESETS_SINGLE_PARAmeter(48, "预置/激活单个参数命令"),
// READ_SINGLE_PARAMETer(102, "读单个参数命令"),
// END_OF_INITIALIZATIon(70, "初始化结束"),
// CALL_COMMAND(100, "召唤命令"),
// CLOCK_SYNCHRONIZATIon(103, "时钟同步/读取命令"),
// TEST_COMMAND(104, "测试命令"),
// RESET_PROCESS(105, "复位进程命令"),
// READ_MULTIPLE_PARAMETERS(132, "读多个参数命令"),
// PRESETS_MULTIPLE_PARAMETERS(136, "预置/激活多个参数命令");
M_SP_NA_1(1, "0x01", "Single-point information"),
M_SP_TA_1(2, "0x02", "Single-point information with time tag"),
M_DP_NA_1(3, "0x03", "Double-point information"),
M_DP_TA_1(4, "0x04", "Double-point information with time tag"),
M_ST_NA_1(5, "0x05", "Step position information"),
M_ST_TA_1(6, "0x06", "Step position information with time tag"),
M_BO_NA_1(7, "0x07", "Bitstring of 32 bit"),
M_BO_TA_1(8, "0x08", "Bitstring of 32 bit with time tag"),
M_ME_NA_1(9, "0x09", "Measured value, normalised value"),
M_ME_TA_1(10, "0x0A", "Measured value, normalized value with time tag"),
M_ME_NB_1(11, "0x0B", "Measured value, scaled value"),
M_ME_TB_1(12, "0x0C", "Measured value, scaled value wit time tag"),
M_ME_NC_1(13, "0x0D", "Measured value, short floating point number"),
M_ME_TC_1(14, "0x0E", "Measured value, short floating point number with time tag"),
M_IT_NA_1(15, "0x0F", "Integrated totals"),
M_IT_TA_1(16, "0x10", "Integrated totals with time tag"),
M_EP_TA_1(17, "0x11", "Event of protection equipment with time tag"),
M_EP_TB_1(18, "0x12", "Packed start events of protection equipment with time tag"),
M_EP_TC_1(19, "0x13", "Packed output circuit information of protection equipment with time tag"),
M_PS_NA_1(20, "0x14", "Packed single point information with status change detection"),
M_ME_ND_1(21, "0x15", "Measured value, normalized value without quality descriptor"),
M_SP_TB_1(30, "0x1E", "Single-point information with time tag CP56Time2a"),
M_DP_TB_1(31, "0x1F", "Double-point information with time tag CP56Time2a"),
M_ST_TB_1(32, "0x20", "Step position information with time tag CP56Time2a"),
M_BO_TB_1(33, "0x21", "Bitstring of 32 bit with time tag CP56Time2a"),
M_ME_TD_1(34, "0x22", "Measured value, normalised value with time tag CP56Time2a"),
M_ME_TE_1(35, "0x23", "Measured value, scaled value with time tag CP56Time2a"),
M_ME_TF_1(36, "0x24", "Measured value, short floating point number with time tag CP56Time2a"),
M_IT_TB_1(37, "0x25", "Integrated totals with time tag CP56Time2a"),
M_EP_TD_1(38, "0x26", "Event of protection equipment with time tag CP56Time2a"),
M_EP_TE_1(39, "0x27", "Packed start events of protection equipment with time tag CP56Time2a"),
M_EP_TF_1(40, "0x28", "Packed output circuit information of protection equipment with time tag CP56Time2a"),
C_SC_NA_1(45, "0x2D", "Single command"),
C_DC_NA_1(46, "0x2E", "Double command"),
C_RC_NA_1(47, "0x2F", "Regulating step command"),
C_SE_NA_1(48, "0x30", "Set-point Command, normalised value"),
C_SE_NB_1(49, "0x31", "Set-point Command, scaled value"),
C_SE_NC_1(50, "0x32", "Set-point Command, short floating point number"),
C_BO_NA_1(51, "0x33", "Bitstring 32 bit command"),
C_SC_TA_1(58, "0x3A", "Single command with time tag CP56Time2a"),
C_DC_TA_1(59, "0x3B", "Double command with time tag CP56Time2a"),
C_RC_TA_1(60, "0x3C", "Regulating step command with time tag CP56Time2a"),
C_SE_TA_1(61, "0x3D", "Measured value, normalised value command with time tag CP56Time2a"),
C_SE_TB_1(62, "0x3E", "Measured value, scaled value command with time tag CP56Time2a"),
C_SE_TC_1(63, "0x3F", "Measured value, short floating point number command with time tag CP56Time2a"),
C_BO_TA_1(64, "0x40", "Bitstring of 32 bit command with time tag CP56Time2a"),
M_EI_NA_1(70, "0x46", "End of Initialisation"),
C_IC_NA_1(100, "0x64", "Interrogation command"),
C_CI_NA_1(101, "0x65", "Counter interrogation command"),
C_RD_NA_1(102, "0x66", "Read command"),
C_CS_NA_1(103, "0x67", "Clock synchronisation command"),
C_TS_NA_1(104, "0x68", "Test command"),
C_RP_NA_1(105, "0x69", "Reset process command"),
C_CD_NA_1(106, "0x6A", "Delay acquisition command"),
C_TS_TA_1(107, "0x6B", "Test command with time tag CP56Time2a"),
P_ME_NA_1(110, "0x6E", "Parameter of measured values, normalized value"),
P_ME_NB_1(111, "0x6F", "Parameter of measured values, scaled value"),
P_ME_NC_1(112, "0x70", "Parameter of measured values, short floating point number"),
P_AC_NA_1(113, "0x71", "Parameter activation"),
F_FR_NA_1(120, "0x78", "File ready"),
F_SR_NA_1(121, "0x79", "Section ready"),
F_SC_NA_1(122, "0x7A", "Call directory, select file, call file, call section"),
F_LS_NA_1(123, "0x7B", "Last section, last segment"),
F_FA_NA_1(124, "0x7C", "ACK file, ACK section"),
F_SG_NA_1(125, "0x7D", "Segment"),
F_DR_TA_1(126, "0x7E", "Directory");
private int code;
private String hexStr;
private String describe;
TypeIdentifier(int code, String hexStr, String describe) {
this.code = code;
this.hexStr = hexStr;
this.describe = describe;
}
public static String getDescribe(int code) throws UnknownTypeIdentifierException {
for (TypeIdentifier value : TypeIdentifier.values()) {
if (value.code == code) return value.describe;
}
throw new UnknownTypeIdentifierException();
}
}即可正常解析,不会报错。
转载请注明:在路上 » 【已解决】java解析104数据出错异常:未知类型标识符 at com.iec.analysis.common.TypeIdentifier.getDescribe TypeIdentifier.java