news 2026/11/4 7:30:29

DLMS电能表通讯协议中文手册:HDLC链路层与AXDR编码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DLMS电能表通讯协议中文手册:HDLC链路层与AXDR编码解析

简介:《DMLS协议中文版》面向电能量数据采集终端研发、电能表通讯调试及IEC62056/DLMS协议入门人员,针对采集器与电能表之间通讯协议理解与实现的问题,提供一份中文说明手册。资源包共1个doc文件,约620KB,内容以协议分层讲解和请求数据实例为主:先梳理物理层、链路层、应用层的Client-Server模型,再展开HDLC链路层、ASN.1语法、BER与AXDR编码、AARQ/AARE连接帧及数据请求过程,并给出请求电量、瞬时量(电压、电流、功率)、负荷曲线和时间的报文范例,便于对照协议字段排查通讯问题。已有873人学习,适合作为开发联调时的案头参考与协议速查材料。

1. 一块电表怎么"开口说话":DMLS 协议到底是个什么东西

家里换了智能电表之后,有件事变得有点玄学:没人上门抄表,账单却月月准时送到。电表并不是偷偷连了网,它只是按一套约定好的格式,把数字打包递给采集设备,再由采集设备往上送。

DMLS 协议(业界更常见的写法是 DLMS)就是这套约定——一套面向电能表的数据通讯规则,规定了采集端怎么问、电表怎么答、答不上来时怎么重来、长数据怎么切块。这份中文手册把 DLMS 协议族在实际应用中最常遇到的部分翻成了中文,覆盖协议模型、物理层、HDLC 链路层、应用层,以及 ASN.1、BER、AXDR 这几个一听就头大的编码名词。搞懂它,你才能对着一串十六进制字节说出"这是在要上个月的电量",而不是把它当成黑匣子。

2. 三层楼与两次握手:DMLS 协议模型到底怎么运转

2.1 为什么电表通讯非要分成三层

把一次抄表想象成寄一份需要签收的快递。物理层是公路和货车,负责把东西真的挪过去;链路层是快递公司的分拣中心,负责核对地址、检查包装有没有破损、东西太大就拆成几箱;应用层才是包裹里那张纸,上面写着"我要上个月的电量"。

三层各管一段,好处是出问题时能定位到具体一层。线插错了是物理层的事,电表不回帧是链路层的事,回了帧但内容读不懂是应用层的事。如果所有逻辑糊在一起,一个字节对不上你就只能从头猜。

DLMS 协议模型确实就这三层:物理层、链路层、应用层。层与层之间用指定的服务通讯,上层不关心下层怎么实现。这个设计在二十多年前定下来,放到今天看依然实用——因为它把"怎么搬"和"搬什么"彻底分开了。

通讯双方是 Client-Server 结构。数据请求端(采集器)是 Client,数据提供端(电表)是 Server。这个方向不能反:电表从不主动找你,它永远等着被问。所以凡是遇到"我的设备一直收不到数据",第一件事不是怀疑电表坏了,而是确认自己到底有没有把请求发出去、发对了没有。

另外要留意,DLMS 并没有单独设一个"表示层"。编码、语法这些东西被并进了应用层,ASN.1、BER、AXDR 就是干这个活儿的。这也解释了为什么应用层看着最复杂——它一个人干了两层的事。

2.2 一次完整抄表要握几次手

一次完整的数据通讯,从插上线到挂断,一共要走六步:

  1. 建立物理层连接:打开端口、初始化底层硬件;
  2. 建立链路层连接:Client 发 SNRM 帧,Server 回 UA 帧;
  3. 建立应用层连接:Client 发 AARQ 帧,Server 回 AARE 帧;
  4. 进行数据通讯:Client 发数据请求帧,Server 回数据响应帧;
  5. 结束链路:先发 RR 帧确认,再发 DISC 帧,Server 回 UA 或 DM;
  6. 解除物理层连接:关闭物理端口。

第 2 步和第 3 步是两回事,这点最容易让人困惑。链路层连接解决的是"两头能对上话"——地址对不对、帧长对不对、CRC 校验过不过。应用层连接解决的是"两头说的是不是同一套话"——版本号一致吗、最大能收多长的包、要不要认证。这个过程在协议里叫 Negotiation,字面意思就是协商。

只建了链路层就直接塞应用层数据过去,电表不会报错,它只会沉默。这种沉默比报错更难查,因为你手里没有任何错误码。

排错时顺序反过来用最省事:先看物理层有没有通,再看链路层有没有 UA 回应,最后才看应用层的 AARE 里 result 字段是不是 0。照着这个顺序走,九成的通讯问题在第二步之前就能揪出来。

还有一个血泪经验:请求完数据别急着挂断。手册里写得很明确,数据请求结束后还要再发一帧 RR,收到确认之后才可以发 DISC 结束链路。当然也可以什么都不发,靠 Server 端的超时挂断机制自己收尾,但手册建议用前者。少发那一帧 RR,某些固件会认为你还没收完,下一次连接时状态就乱了。

2.3 物理层为什么几乎被"跳过"

DLMS 可以跑在多种介质上:拨号 Modem、串行通道、网络口等等。物理层的功能很朴素——接收链路层的数据发到介质上,或者从介质上收数据交给链路层。规约层面它只规定几件事:打开端口、初始化端口、收发数据、关闭端口。

在嵌入式设备里,物理层基本对应系统的底层驱动,一般不受通讯规约控制。这份手册因此没有展开讨论物理层服务,理由也说得直白:不影响协议功能实现的部分,就不占篇幅。

打个比方,写快递单的人不需要懂发动机原理。但反过来要注意——发动机真坏了,单子写得再对也没用。拨号 Modem 的初始化参数配错、挂断没做干净,上层协议设计得再严密也会全体失效。所以物理层"被跳过",是指协议文档跳过,不是指调试时可以跳过。

3. HDLC 链路层:两个 0x7E 之间到底装了什么

3.1 帧格式拆解:为什么有的帧多出一段校验

链路层用的是 HDLC 高速链路控制协议,它由两个子层构成:LLC 子层和 MAC 子层。LLC 子层只做转发,把 MAC 子层的数据递给应用层,或者反过来,它不对数据做任何处理。MAC 子层才是干实事的,地址检查、CRC 校验、长帧的打包拆包都在这里。

先看帧的整体骨架。不携带应用层数据时,帧长这样:

顺序字段说明
10x7E固定帧头
2帧类型与帧长2 字节
3目的地址域变长
4源地址域变长
5控制域1 字节
6数据帧校验2 字节
70x7E固定帧尾

携带应用层数据时,中间会多出三项:帧头校验、LLC 帧头、用户数据信息。位置在控制域之后、数据帧校验之前。

多出来的第一项是帧头校验(HCS)。它对"帧类型与帧长 + 目的地址 + 源地址 + 控制域"这几段再算一次 CRC。为什么一个帧要校验两次?因为帧头里的长度字段一旦错位,接收端就会按错误的长度去切后面的数据,整帧彻底切歪,最后连帧尾的 0x7E 都对不上。先校验帧头,等于先把尺子校准,再去量东西。

第二项是 LLC 帧头,固定三个字节,而且带方向:Client 端发往 Server 的数据加 0xE6、0xE6、0x00;Server 端发往 Client 的数据加 0xE6、0xE7、0x00。抓包时这三个字节非常有用——一眼就能看出这帧是谁发的,不用先去解地址域。

第三项就是真正的应用层数据。默认情况下,用户数据信息最大 128 字节。注意这个 128 是默认值,不是硬上限,想要更长可以在 SNRM 帧里协商。

3.2 地址域:一个字节的最低比特位,决定了后面还有没有

HDLC 用的是扩展编址技术,规则只有一条,但极其关键:某个地址字节的最低位如果是 0,说明这个地址域还没结束,后面还有字节;如果是 1,说明地址域到此为止。

换句话说,真正的地址值装在每个字节的高 7 位里,最低位被征用作"续接标志"。一个 N 字节的地址,实际能表示 7N 位的信息。

Client 端的地址永远是 1 个字节,最低位固定为 1,所以有效位只有 7 位,最多 128 个 Client 地址。这在采集场景里够用——一台采集终端就是一个 Client。

Server 端就复杂了。为了让一个物理地址能对应多个逻辑地址,它被拆成两部分:upper HDLC Address 表示逻辑地址,lower HDLC address 表示物理地址。upper 部分总是要有,lower 部分在确认不需要时可以省掉。常见的有三种结构:一字节(只有 upper)、两字节(upper 一字节 + lower 一字节)、四字节(upper 两字节 + lower 两字节)。

用一小段代码把解析逻辑写出来,比看文字描述直观:

def parse_hdlc_address(data, start): """从 data[start] 开始解析一个 HDLC 地址域 返回 (地址值, 占用的字节数) """ value = 0 offset = 0 while True: b = data[start + offset] # 低 7 位参与地址值拼接,最低位是"是否结束"的标志 value = (value << 7) | (b >> 1) offset += 1 if b & 0x01: # 最低位为 1,地址域结束 return value, offset

这段逻辑的含义是:每读一个字节,先把已有值左移 7 位,再把新字节的高 7 位拼进去;一旦发现最低位是 1,就停下来。函数返回两个值,一个是还原出的地址,一个是这个地址占了几字节——后者在定位后续字段时同样重要,因为地址长度不固定,你没算对字节数,控制域就会读错位置。

提示:某些三相电表在实际测试中只有四字节 Server 地址结构可用,一字节和两字节结构发过去得不到响应。协议允许不等于设备实现,这类差异只能靠实测确认。

还有一类特殊地址,被 HDLC 定为保留地址,其中比较重要的是广播地址。DLMS 协议族支持使用上述任一种地址结构,也支持特殊地址。

3.3 控制域:RRR 和 SSS 这对计数器到底在数什么

控制域负责两件事:帧计数和帧类型标识。

对应关系是这样的:RRR 是接收帧计数,SSS 是发送帧计数。链路层连接建立之后,第一次请求数据时(在 Client 端,包括发送 AARQ),RRR 置 0,SSS 置 0。Server 收到后回响应,RRR 变成 1,SSS 还是 0。Client 再请求时 RRR 加 1、SSS 加 1。Server 再响应时,RRR 加 1 变成 2,SSS 加 1。如此反复,直到 Client 拿到全部数据。

这套计数机制看着啰嗦,作用却很实在:它让双方能确认"这一帧是不是我期待的那一帧"。计数对不上,电表大概率直接不理你。这是现场最常见的"通讯静默"原因之一,比 CRC 错还隐蔽,因为 CRC 错至少你还能从抓包工具里看到红色标记。

控制域里还有两位:P/F,也就是 Poll/Final。Poll 位由 Client 发送,置 1 表示要求 Server 回应,置 0 表示不允许回应。Final 位由 Server 发送,置 1 表示一次数据帧发送结束,置 0 表示还没发完。Final 位只有在通讯窗口(window size)大于 1 时才有意义;窗口等于 1 时,Server 返回的每帧这一位都是 1。

帧类型方面,几种常见的帧各有分工:

帧类型名称用途
I信息传输帧搬运实际数据
RR准备接收表示准备好接收下一帧
RNR接收未就绪相当于忙帧
SNRM设置正常响应模式建立链路层连接
UA无编号确认对 SNRM 和 DISC 的响应
DISC结束链路主动断开
DM断开模式对 DISC 的响应
UI无编号信息保持链路,对链路控制无影响
FRMR拒绝接收因某种不确定原因拒收

在原始字节流里,非 I 帧的帧类型直接体现在控制域的取值上,带上 Poll 位后常见的是 SNRM 为 0x93、UA 为 0x73、DISC 为 0x53、DM 为 0x1F。I 帧则不同,它的控制域最高位为 0,剩下的位用来装 RRR 和 SSS。

3.4 长数据帧与 SNRM 参数协商:128 字节只是起跑线

链路层连接是靠 SNRM 帧建立的。Client 发 SNRM,Server 回 UA 表示连接已建立,回 DM 则表示链路断开、连接没建成。UA 帧里通常带着链路参数的配置信息——这正是它比一句"好的"信息量大的地方。

协商的参数主要有两个:WINDOW_SIZE 描述通讯双方一次能发几帧(HDLC 允许一次连发多帧);MAXIMUM_INFORMATION_FIELD_LENGTH 描述一个链路帧里用户数据能有多长。两者的默认值分别是 1 和 128 字节。落到帧里是四个具体参数:发送最大信息域长度、接收最大信息域长度、发送窗口大小、接收窗口大小。

把这四个参数塞进帧里是什么样子?看一段真实的 SNRM:

# 完整帧(空格分隔,便于逐字段对照) 7e a0 21 00 22 00 23 03 93 0b 14 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 65 5e 7e # 逐段拆解 # 7e 帧头 # a0 21 帧类型与帧长:类型 A(=1010),S 位 0,长度 0x021 = 33 字节 # 00 22 00 23 目的地址:四字节,Server 地址 # 03 源地址:一字节,Client 地址 # 93 控制域:SNRM # 0b 14 帧头校验 # 81 80 信息域起始标识 # 12 参数组长度 0x12 = 18 字节 # 05 01 80 参数 05(发送最大信息域长度),长 1,值 0x80 = 128 # 06 01 80 参数 06(接收最大信息域长度),长 1,值 128 # 07 04 00 00 00 01 参数 07(发送窗口大小),长 4,值 1 # 08 04 00 00 00 01 参数 08(接收窗口大小),长 4,值 1 # 65 5e 数据帧校验 # 7e 帧尾

数一下就能验证长度字段:帧类型 2 字节 + 目的地址 4 字节 + 源地址 1 字节 + 控制域 1 字节 = 8 字节;帧头校验 2 字节;信息域 21 字节;数据帧校验 2 字节。8 + 2 + 21 + 2 = 33,正好对上 0x21。这种"数一遍对一遍"的习惯,比任何调试工具都管用。

长数据帧的触发条件也在这里。一次请求、一次响应装不下全部数据时(受限于默认 128 字节的信息域),就要启动分片流程。分割时,帧类型与帧长字段里的 S 位(segmentation bit)会被置 1,接收端检测到这一位置位,就知道后面还有,于是发 RR 帧去要剩下的部分,直到收全。

注意:请求负荷曲线时一定是使用长数据帧。负荷曲线数据量大,想靠一帧搞定基本不可能。

至于数据完整性,HDLC 用的是 16 位 CRC,具体实现可以参考标准文档的附录。链路层本质上是个透明通道:它不解析用户数据,也不知道里面装的是电量还是时间戳,它只负责把东西完好地送到对面。就像快递公司不会拆你的包裹,只管送到。

4. 应用层的三种语言:ASN.1、BER 与 AXDR 是什么关系

4.1 ASN.1 只是一份语法说明书,本身不是数据

理解 DLMS 应用层,得先建立三个概念:ASN.1 语法、BER 编码、AXDR 编码。它们的关系不是并列,而是层层嵌套。

ASN.1 是一种抽象语法语言,专门用来描述数据帧的组成。DLMS 跟很多简单通讯协议最大的不同就在这里:它不用一堆表格和固定帧格式来描述,而是用这种抽象语言来定义。好处是抽象性和通用性极高,程序移植起来省事;坏处是第一次看会觉得像天书。

打个比方,ASN.1 是乐谱,BER 和 AXDR 是两种不同的演奏方式。乐谱本身不发出声音,但你得先有乐谱,才知道该演奏什么。

一段典型的 ASN.1 描述长这样:

Name ::= [tag] IMPLICIT/EXPLICIT DataType { null-data [0] IMPLICIT NULL, item1 [1] IMPLICIT DataType A1 OPTIONAL, item2 [2] IMPLICIT DataType A2 OPTIONAL, item3 [3] DataType ... }

拆开看几个关键部位。Name 是这个数据帧的名字。Tag 包含两部分:class type 和一个数字。class type 有四种取值,含义差别很大:

  • Universal:这个数据帧在所有 DLMS 应用里含义唯一;
  • Application:含义跟具体应用有关;
  • Private:只在某厂家自定义范围内有效;
  • Context-specific:含义取决于上下文,在不同结构里可能是不同的东西。

Tag 里那个数字是帧的标号,作为句柄出现在应用数据单元中。

IMPLICIT 和 EXPLICIT 描述的是子帧与父帧的关系。IMPLICIT 会改变父帧的 Tag,EXPLICIT 不改变。不注明的一律按 EXPLICIT 处理。

数据类型大多是顾名思义,常见的几个是:INTEGER 编号 2(十六进制 02)、BIT STRING 是 3(03)、OCTET STRING 是 4(04)、NULL 是 5(05)、OBJECT IDENTIFIER 是 6(06)、SEQUENCE 是 16(10)、SET 是 17(11)、PrintableString 是 19(13)、T61String 是 20(14)、IA5String 是 22(16)、UTCTime 是 23(17)。

大括号里的每一项就是数据帧中的一个数据项,每项后面的数字是它的标识。一个数据帧通常是对其他数据帧的组合,所以结构可以一层套一层。

两种复合类型值得单独讲。SEQUENCE 表示内容是顺序排列的,比如请求数据时常用的 Get-Request-Normal:里面依次是 invoke-id-and-priority、cosem-attribute-descriptor,还有一个可选的 access-selection-parameters。CHOICE 则表示从几个类型里选一个,比如 GET-Request 只能填 get-request-normal、get-request-next、get-request-with-list 三者之一。

OPTIONAL 这个关键字说明该项在需要时可以省略。别小看这个"可选",它正是 DLMS 帧千变万化的来源——同样的帧名,实际字节流可能差出一大截。

4.2 BER 编码:标识、长度、内容的三段式

ASN.1 只是语法,要写进数据帧还得转换成一个个字节,这就需要编码。分工是这样的:用 ASN.1 描述的 DLMS 协议用 BER 编码实现,用 ASN.1 描述的 XDLMS 协议用 AXDR 编码实现。

BER 的基本结构是三段式:数据标识、数据长度、数据内容。内容部分还可以再嵌套另一层 BER 结构,套娃式地往下走。

数据标识的构成值得单独说。一个 BER 标识里包含三块信息:

位段字段含义
bit15-14datatype classesUniversal(00) / Application(01) / Context-specific(10) / Private(11)
bit13Data typePrimitive(0) 简单类型 / Constructed(1) 复合类型
bit12-0data length数据内容的字节长度

这套设计让一个字节就同时说清了"这是哪一类""是简单还是复合""有多长",非常紧凑。

拿一个真实收到的 AARE 帧开头做例子,逐字节读一遍:

61 # AARE 的 tag,对应 [APPLICATION 1] 42 # AARE 的长度 0x42 = 66 字节 a1 # application-context-name 的 tag 09 # 该项长度 9 06 # 数据类型:OBJECT IDENTIFIER(Universal) 07 # 长度 7 60 85 74 05 08 01 01 # 应用上下文标识的具体内容 a2 03 02 01 00 # Association-result,结果值 0 表示接受 a3 05 a1 03 02 01 00 # Associate-source-diagnostic,诊断来源

读法很机械:看到 tag 就看后面跟的长度,按长度取内容,内容里如果还是复合类型,就继续往下拆。第一次看可能觉得枯燥,拆过三五个帧之后就会发现它其实相当规整。

4.3 AXDR 编码:为什么它能省掉一大半字节

AXDR 是对 XDR(外部数据表示法)的扩展。它和 BER 的差别,用一个具体例子最清楚:把 0x1234 和 0x5678 两个数编成一个序列。

用 BER 编码,结果大致是这样:

30 # SEQUENCE 标识 08 # 序列长度 8 字节 02 02 12 34 # INTEGER,长度 2,值 0x1234 02 02 56 78 # INTEGER,长度 2,值 0x5678

用 AXDR 编码,两个数的值直接排进去就行,省掉了每个元素的"类型标识 + 长度"这两字节开销。同样的内容,BER 要 10 个字节,AXDR 只要 4 个。

这不是抠门,是场景决定的。电能表通讯跑在现场总线上,带宽和时间都紧张,能省一个字节就省一个。BER 的可读性和自描述性更好,但在这个场景里属于奢侈品。

有一个界限必须说清楚:DLMS 里只有 AARQ 与 AARE 这两个帧的部分内容是用 DLMS 协议(即 BER 编码)的,绝大多数的应用层数据通讯走的是 XDLMS,也就是 AXDR 编码。所以"DLMS 和 XDLMS"不是两套并列的协议,而是应用层里用不同编码的两块内容。

4.4 AARQ 与 AARE:应用层那次握手到底在谈什么

AARQ 和 AARE 是两个特殊的数据帧,专门用来构筑 Client 与 Server 之间的应用层连接。连接请求由 Client 发起,Client 发 AARQ,Server 用 AARE 响应。

这两个帧之所以特殊,是因为它们不属于普通的数据请求,它们干的是"先把规则谈好"这件事。谈的内容包括协议版本、双方能接收的最大 PDU 长度、并发能力、认证方式等等。谈成了,后面才谈得上要数据。

AARE 里有两个字段值得盯着,排错时全靠它们。一个是 Association-result,值为 0 表示接受,非 0 就是拒绝。另一个是 Associate-source-diagnostic,说明拒绝的原因出在谁身上。抓到一帧 AARE,先看这两个字段,比盲猜快得多。

很多人第一次对接电表时会卡在这里:SNRM 发出去有 UA 回来,说明链路通了,但发 AARQ 之后对方回了个拒绝,或者干脆不回。前者去读 AARE 里的诊断字段,后者八成是 AARQ 本身的编码有问题——毕竟这是少数几个用 BER 编码的帧,跟后面用 AXDR 的数据帧写法完全不一样,很容易搞混。

4.5 请求数据:class id 和 OBIS 怎么把一条数据揪出来

连接建好之后就是常规的数据请求。Client 发数据请求帧,Server 以数据响应。请求不同的数据时,要用那类数据独有的 class id 和 OBIS 来标识。

这两个标识的分工可以这样理解:class id 说明"这是哪一类对象",OBIS 说明"是这一类里的哪一个"。少了任何一个都定位不到具体数据。

手册里给出的请求实例有四类:请求电量、请求瞬时量(电压、电流、功率)、请求负荷曲线、请求时间。这四类覆盖了抄表场景的绝大多数需求。其中负荷曲线是唯一被明确点名要用长数据帧的——它的数据量摆在那儿,一帧装不下。

请求帧的语法结构前面提过,是 SEQUENCE,依次是 invoke-id-and-priority、cosem-attribute-descriptor,以及可选的 access-selection-parameters。第三个字段"可选"意味着你可以按时间范围、按通道号去筛选数据,不用把整条曲线全拉回来。

5. 常见误区:DMLS、DLMS、COSEM、XDLMS 到底谁是谁

5.1 易混点:DMLS 和 DLMS 是两个协议吗

为什么混:这两个词只差一个字母,而且都在中文资料里大量出现。有的文档标题写 DMLS,正文写 DLMS;有的同一份材料里前后不一致。第一次接触的人很容易以为这是两套不同的东西,甚至去搜"两者的区别"。

怎么区分:它们是同一个东西。DLMS 是 Device Language Message Specification 的缩写,指的是一整套面向电能表等设备的数据通讯协议族,对应标准编号为 IEC 62056 的那一系列文档。中文资料里的 DMLS 基本是笔误或排版顺序颠倒,不影响含义。判断标准很简单:看上下文是不是在讲电能表通讯、三层模型、HDLC、OBIS,如果是,那就是同一个协议族,不用纠结拼写。

真要说区别,只有一个:正式的标准文本和英文技术资料里用 DLMS,中文转述材料里偶有 DMLS。对实际开发没有任何影响。

5.2 易混点:DLMS 和 XDLMS 是两套平行的协议吗

为什么混:名字上看起来像"基础版"和"扩展版",而且两者确实用不同的编码方式,很容易被理解成两代产品或者两个独立规范。

怎么区分:它们不是并列关系,而是同一层里用不同编码的两块内容。用 ASN.1 描述的 DLMS 协议用 BER 编码实现,用 ASN.1 描述的 XDLMS 协议用 AXDR 编码实现。更关键的一条界限是:DLMS 里只有 AARQ 与 AARE 这两个帧的部分内容使用 DLMS 协议,绝大多数应用层数据通讯用的是 XDLMS。

所以实际开发中你的体感是:握手阶段小心翼翼对付 BER 编码,握手完之后基本都是 AXDR 的地盘。看到一帧里既有 0x61 这种 BER 味道的标识、又有裸露的数值字节,不用怀疑自己抓错了包,那就是设计如此。

5.3 易混点:COSEM 是 DLMS 里的某一层吗

为什么混:这两个词几乎总是成对出现,标准文档里也经常连着写,加上缩写风格接近,很容易被当成同一套东西的两种叫法。

怎么区分:COSEM 管的是"有什么数据",DLMS 管的是"数据怎么搬"。前者是一套接口对象与标识系统,定义了电能表里应该有哪些对象、每个对象有哪些属性、用什么编号去访问;后者是通讯协议,定义了这些访问请求怎么打包、怎么传输、怎么确认。

用图书馆打比方:COSEM 是书目分类法和索书号体系,DLMS 是借书处那套流程——怎么填单子、怎么递进去、怎么等回复。你可以只懂流程不懂分类,但那样你填不出索书号。反过来只懂分类不懂流程,书也借不出来。这也是为什么请求数据时必须同时给出 class id 和 OBIS——那是 COSEM 定下的地址体系。

5.4 易混点:class id 和 OBIS 是不是一回事

为什么混:两者都出现在请求帧里,都是数字,都能"标识数据",初学者很容易认为随便填一个就能取到值。

怎么区分:class id 标识的是对象的类别,OBIS 标识的是类别下的具体对象。举个具体点的例子:class id 决定"你要找的是不是这一类东西",OBIS 决定"这一类里你要哪一个"。两个都对上,才能取到值。

这也解释了为什么会出现"OBIS 填对了但读不出数"的情况——class id 错了。反过来同样成立。排查时建议把两个值一起核对,别只盯着其中一个。

5.5 易混点:128 字节是协议规定的最大长度吗

为什么混:手册里写"用户数据信息的最大长度,默认为 128 字节",这个"默认"两个字很容易被读漏。而且大多数抓包看到的帧确实都不超过这个数。

怎么区分:128 是默认值,不是硬上限。想要更长的字节数,可以在 SNRM 帧里协商。同样,WINDOW_SIZE 默认是 1,也不代表协议只能一帧一帧地发——HDLC 本来就允许一次发送多帧,只是默认配置保守。

反过来说,正因为默认值是 128,超过这个长度的数据(比如负荷曲线)必须走分片流程,S 位置 1,接收端发 RR 去要后续部分。看到 S 位是 1 就以为出错了,那是另一个常见的误判。

6. 什么时候该翻这份手册:三个信号和两个劝退理由

判断要不要花时间读一份协议中文手册,我习惯看三件事:手上有没有真实的字节流要解释、有没有一个必须打通的对端设备、有没有一个说不清原因的失败现象。三条里占两条,就值得读;只占一条,多半用不上。

你的处境建议原因
要对接电能表,抓到了十六进制报文但看不懂重点读链路层与应用层帧格式和编码规则能直接对上手里的字节
链路能建、数据读不出先看 AARE 的 result 与诊断字段

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 7:28:28

PLSQL Developer 连接 Oracle 实战:instantclient_11_2 配置与排错指南

简介&#xff1a;这份资源面向需要在本机连接远程 Oracle 数据库的开发者与运维人员&#xff0c;尤其适合不想完整安装 Oracle 客户端、希望轻量部署的初中级用户。包内为 instantclient_11_2 轻量客户端套件&#xff0c;共 45 个文件&#xff0c;以 20 个 dll 动态链接库为核心…

作者头像 李华
网站建设 2026/11/4 7:28:02

鲲鹏云Hadoop集群启动失败的四大根因与排错路径

简介&#xff1a;本资源是一份面向大数据初学者与鲲鹏云平台实践者的Hadoop集群部署实验报告&#xff0c;聚焦华为云环境下基于ARM架构&#xff08;鲲鹏&#xff09;的大数据基础设施搭建全流程。报告完整覆盖ECS服务器与OBS对象存储的开通配置、AK/SK密钥获取、多节点&#xf…

作者头像 李华
网站建设 2026/11/4 7:27:59

自动驾驶仿真技术PonyWorld 2.0的突破与应用

1. 自动驾驶仿真技术的突破性进展上周业内最重磅的消息莫过于小马智行正式发布了PonyWorld世界模型2.0版本。作为自动驾驶领域的老兵&#xff0c;我第一时间拿到了技术白皮书仔细研读。这个看似只是版本号升级的产品&#xff0c;实际上代表着自动驾驶仿真技术的一次重大突破。记…

作者头像 李华
网站建设 2026/11/4 7:27:57

法律可计算性与司法AI系统的可信赖设计

1. 数字法学变革的底层逻辑当裁判文书上网率突破90%、全国法院收案量连续五年超过3000万件时&#xff0c;传统法学研究范式正面临根本性挑战。去年参与某省高院智能审判系统评估时&#xff0c;我亲眼目睹了这样的场景&#xff1a;法官助理输入案由关键词后&#xff0c;系统在3秒…

作者头像 李华
网站建设 2026/11/4 7:27:50

深入解析SqlTools服务层:VS Code SQL工具链的底层机制与集成实践

简介&#xff1a;这份资源面向在 VS Code 中使用 SQL Server (mssql) 扩展却无法连接数据库的开发者&#xff0c;核心解决扩展依赖的 Microsoft.SqlTools.ServiceLayer 默认从 GitHub 拉取、国内网络难以完成下载的问题。压缩包共 823 个文件&#xff0c;约 76.46MB&#xff0c…

作者头像 李华
网站建设 2026/11/4 7:27:35

哈希表在四数相加与赎金信问题中的高效应用

1. 算法训练营第六天内容概览今天要啃的两道题目在哈希表应用中非常典型——454题考察哈希表在多元组统计中的高效性&#xff0c;383题则展现了哈希表作为字符频次计数器的优势。这两道题在真实业务场景中出现频率极高&#xff0c;比如四数之和的变种常见于多维数据分析&#x…

作者头像 李华