折腾:
【未解决】用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