最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】java解析104数据出错异常:未知类型标识符 at com.iec.analysis.common.TypeIdentifier.getDescribe TypeIdentifier.java

Java crifan 810浏览 0评论
折腾:
【未解决】用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加上定义
此处,故意用别的
Description and analysis of IEC 104 Protocol Technical Report
中的示例数据:
"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

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
83 queries in 0.170 seconds, using 22.63MB memory