DLMS/COSEM 蓝皮书解读(一):先搞懂 DLMS 协议与蓝皮书

发布时间:2026/9/29 4:35:16
DLMS/COSEM 蓝皮书解读(一):先搞懂 DLMS 协议与蓝皮书 DLMS/COSEM 蓝皮书解读一先搞懂 DLMS 协议与蓝皮书系列说明本系列基于 DLMS User Association 发布的《Blue Book蓝皮书第 16 版 · 第 2 部分 —— COSEM interface classes》按一个接口类class写一篇的节奏带你把这套电能/公用事业计量数据交换标准啃透。本篇是总览不展开任何具体 class只做一件事给你装上三张地图协议地图、文档地图、模型地图。从下一篇起进入具体 class。0. 为什么你要懂 DLMS/COSEM如果你做智能电表、水气热表、AMI高级量测体系、HESHead End System主站或任何表计 ↔ 系统的数据采集几乎一定会撞上 DLMS/COSEM。它是IEC 62056 系列电能计量数据交换的核心实现全球主流电表、采集器、主站厂商都支持它的设计哲学是“面向对象 标准化对象模型”—— 而不是简单的发一条指令读一个寄存器。先看一个对比感受它的不一样假设要读正向有功总电能在两种协议里分别是这样的Modbus 风格读寄存器主站读保持寄存器 40001长度 2 从站0x30 0x39 12345问题来了12345是什么多少度电小数点在哪答案是 ——看点表。点表是厂商给的 Excel换一款表就得重新对一遍字段含义、字节序、倍率全靠人工约定。DLMS/COSEM 风格读对象主站GET ( class_id 3, logical_name 1-0:1.8.0, attribute_index 2 ) 从站12345再看这个对象自己的描述Register 对象 1-0:1.8.0 ├─ logical_name 1-0:1.8.0 ← 我是正向有功总电能 ├─ value 12345 ← 当前值 └─ scaler_unit { scaler -1, unit 30 (Wh) } ← 单位瓦时×10⁻¹主站不需要任何外部点表读完value再读scaler_unit自己就能算出12345 × 10⁻¹ 1234,5 Wh。这就是 DLMS 的核心卖点语义随数据一起传输。表计不仅告诉你数是多少还告诉你这是什么量、什么单位。代价是 —— 概念多、文档厚、上手慢。本系列就是来把这个门槛削平的。1. DLMS/COSEM 到底是什么DLMSDevice Language Message Specification设备语言报文规范COSEMCompanion Specification for Energy Metering能源计量配套规范两者通常合称DLMS/COSEM由DLMS User AssociationDLMS UA总部瑞士楚格维护。它最初为电能表设计如今已扩展到水、气、热等**多公用事业multi-utility**场景。一句话定位DLMS/COSEM 规定了一台计量设备对外应当暴露哪些对象、每个对象有哪些属性/方法、以及主站用什么服务去访问它们—— 至于底层走 HDLC、TCP/IP、PLC 还是 RF它都能适配。2. 蓝皮书是什么DLMS UA 文档家族DLMS UA 的规范按颜色书组织最关键的几本颜色书内容类比Blue Book蓝皮书COSEM 接口类与对象模型本系列解读的就是它的第 2 部分“有哪些对象、长什么样”Green Book绿皮书传输层、网络层、应用层协议报文怎么封装、怎么握手“报文怎么传”Yellow Book黄皮书M-Bus、802.15.4 等外部总线的适配封装“怎么搭别的总线”White Paper白皮书概览与导读“入门介绍”我们手里的这份Blue-Book-Ed-16-part-2就是第 16 版蓝皮书第 2 部分。Edition 16表示它已迭代到第 16 版文档版权页标注 1997–2023里面定义了97 个接口类class_id从 1 一直编到 162中间有空号从最简单的Dataclass_id 1到复杂的Profile genericclass_id 7、Association LNclass_id 15、Security setupclass_id 64等。为什么第 2 部分最值得先读因为绿皮书讲怎么传但你得先知道传的是什么。对象模型是整套体系的地基。3. 通信模型一次抄表到底发生了什么3.1 客户端 / 服务器DLMS/COSEM 是**主从客户端-服务器**模型COSEM 服务器Server 表计 / 采集器被读的一方COSEM 客户端Client 主站 / HES / 手持终端读的一方3.2 应用关联AA—— 带身份的一次会话双方要通信必须先建立一个应用关联Application Association, AA。可以理解为一次带身份的会话。AA 定义了三件事AA 定义的内容说明应用上下文Application context用 LN 还是 SN 寻址、是否启用加密/压缩等认证机制Authentication无认证 / 口令 / 对称密钥GMAC/ 公钥证书等xDLMS 上下文哪些对象可见、能读还是能写权限视图AA 本身也是用专门的接口类建模的Association LNclass_id 15用于逻辑名寻址Association SNclass_id 12用于短名寻址。也就是说会话本身也是一个对象—— 这是 COSEM一切皆对象的体现。3.3 xDLMS 服务会话建好之后访问对象靠xDLMS 服务最常用四个服务作用类比GET读取属性值读数据readSET写入属性值写配置writeACTION调用方法复位、执行脚本…invokeEVENT服务器主动上报事件通知notify3.4 【举例】一次完整抄表交互把上面串起来主站读一次正向有功总电能的完整过程① 建立物理连接 串口/光口 → HDLC或 网口 → TCP 连接Wrapper ② 建立应用关联AA 客户端 → AARQ含认证信息如口令或 GMAC 密钥 服务器 → AARE接受 / 拒绝并确认应用上下文 ③ 读数据可多次 客户端 → GET.request ( class_id3, 1-0:1.8.0.255, attribute_index2 ) # value 服务器 → GET.response ( 12345 ) 客户端 → GET.request ( class_id3, 1-0:1.8.0.255, attribute_index3 ) # scaler_unit 服务器 → GET.response ( structure { scaler-1, unit30 } ) ④ 主站换算 12345 × 10^(-1) 1234,5 Wh ⑤ 释放 RLQ / 断开连接或保持长连接继续读其他对象实操提示步骤 ③ 里两个GET可以合并优化 —— 用一条GET with list一次读多个属性把value和scaler_unit一起取回通信轮次减半。这在抄表量大时对效率影响显著。3.5 底层传输与蓝皮书解耦蓝皮书第 2 部分只关心对象长什么样不绑定物理通道。常见传输方式方式标准场景HDLCIEC 62056-46串口 / 光口老表计、手持终端常用TCP/UDP WrapperIEC 62056-47IP 网络现代主站主流PLC / RFYellow Book 封装电力线载波、微功率无线M-BusYellow Book 封装水气热表3.6 数据编码A-XDR报文最终以DLMS A-XDRBER 编码的抽象语法封装在 APDU 里。它的关键特点是每个值前面都带一个数据类型标签tag接收方无需先验知识就能知道接下来这个数是什么类型。举几个实际编码tag 就是本系列后面反复出现的 CHOICE 方括号数字数据类型tag编码字节12345long-unsigned[18]0x1212 30 390x3039 12345ABCvisible-string[10]0x0A0A 03 41 42 43TRUEboolean[3]0x0303 01{ -1, 30 }structure{integer, enum}[2]0x0202 02 0F FF 16 1E最后一行展开02structure 标签022 个元素0F FFinteger[15]值 −116 1Eenum[22]值 30 Wh。这正是scaler_unit在报文里的样子 —— 后面第 3 篇会详细拆。4. 核心思想对象模型与接口类这是蓝皮书最该记住的一句话计量设备 一堆COSEM 对象的集合每个对象都是某个接口类Interface Class, IC的实例接口类用class_id标识。4.1 四个核心概念概念含义例子接口类IC一类对象的模板定义有哪些属性和方法Register类专门建模带量纲的寄存器COSEM 对象实例IC 的具体化正向有功总电能和反向有功总电能是Register类的两个实例class_id接口类的编号Data 1、Register 3、Profile generic 7logical_name每个对象的第一个属性它的身份证符合OBIS编码1-0:1.8.0蓝皮书原文Clause 4的精确表述“An object is a collection of attributes and methods. … The first attribute of any object is the logical_name. … Objects that share common characteristics are generalized as an interface class, identified with a class_id.”4.2 属性引用怎么写用**逻辑名LN**寻址时引用一个属性写成三元组( class_id, logical_name, attribute_index )例如读正向有功总电能的当前值( 3, 1-0:1.8.0, 2 ) │ │ └─ attribute_index 2 → Register 的第 2 个属性 value │ └──────────── logical_nameOBIS 正向有功总电能 └──────────────── class_id 3 → Register方法引用类似只是第三个字段是方法索引。例如复位某个RegisterACTION ( 3, 1-0:1.8.0, 1 ) # 1 该类的第 1 个方法 reset可选方法4.3 属性索引的通用约定对所有接口类都成立attribute_index含义1logical_name永远是第一个属性2, 3, …该类定义的第 2、第 3 个属性依类而异必须查该类的蓝图0所有公开属性批量读取/捕获时用如Profile generic的 capture_objects⚠️ 千万不要跨类套用属性索引。Register的 2 号属性是value但Demand register的 2 号属性是current_average_valueProfile generic的 2 号属性是buffer。属性索引只在某个类内部有意义。5. 三层服务器模型蓝皮书把一台物理设备抽象成三层Level 1: 物理设备 (Physical device) —— 一块真实的表 Level 2: 逻辑设备 (Logical device) —— 设备内部的虚拟分区 Level 3: COSEM 对象 (Objects) —— 真正的属性/方法【举例】一台多能源表假设一块四表合一设备同时计量电、水、气它的内部可能是物理设备一块表 │ ├─ 管理逻辑设备Management Logical Device地址通常为 1 │ └─ 暴露设备结构LDN、逻辑设备清单、当前关联、事件对象… │ ├─ 逻辑设备 #2电 │ ├─ Register 1-0:1.8.0正向有功总电能 │ ├─ Register 1-0:15.7.0有功功率 │ └─ Profile generic 1-0:99.1.0负荷曲线 │ ├─ 逻辑设备 #3水 │ └─ Register 8-0:1.8.0累计水量m³ │ └─ 逻辑设备 #4气 └─ Register 7-0:1.8.0累计气量m³关键要点一台物理设备里可以有多个逻辑设备把电、水、气分别建模互不干扰每个物理设备必须包含一个管理逻辑设备地址固定通常为 1并对公共客户端public client开放**最低安全级别无认证**的访问 —— 作用是让主站能在不知道任何密钥的情况下先读出设备内部结构逻辑设备用LDNLogical Device Name唯一标识。蓝皮书原文对 LDN 的说明“Each COSEM logical device can be identified by its unique COSEM LDN. The LDN is defined as a string ofup to 16 octets.”且原文 NOTE“Administered by the DLMS User Association, in cooperation with the FLAG Association.”LDN 的常见构成前 3 字节是厂商代码FLAG 分配的三字母厂商 ID 的 ASCII 编码其后是厂商自定义的序列号。另有manufacturer_id由 IEC 62056-21 的三字母厂商 ID 按公式计算为 2 字节。6. 两种寻址方式LN 与 SN寻址全称特点适用LNLogical Name逻辑名用logical_nameOBISclass_id寻址语义清晰、可扩展复杂设备、现代系统主流SNShort Name短名每个属性/方法映射成一个13 位整数报文更短简单 / 资源受限设备【举例】同一个电能值在两种寻址下的写法读Register对象1-0:1.8.0的valueLN 寻址 GET ( class_id 3, logical_name 1-0:1.8.0, attribute_index 2 ) → 报文里要带完整 6 字节 OBIS SN 寻址 该对象的基名 x示例0x0100 value 的短名 x 0x08 0x0108 GET ( short_name 0x0108 ) → 报文里只是一个 13 位整数偏移是固定的、按类定义的Data的value是x 0x08Register的value也是x 0x08但Register还多一个scaler_unit在x 0x10方法reset在x 0x28。本系列每篇都会给出该类的Short name 偏移表无论你用 LN 还是 SN 都能对上。7. 本系列路线图蓝皮书第 2 部分定义了97 个接口类。本系列按class_id由小到大逐篇推进每篇一个类含多版本的合并到一篇class_id接口类一句话用途状态1Data最通用的数据容器配置、参数、字符串…第 2 篇3Register带量纲的数值电能、功率…第 3 篇4Extended register扩展寄存器带状态、采集时刻第 4 篇5Demand register需量寄存器自己算平均功率第 5 篇6Register activation费率结构切换哪些寄存器生效第 6 篇7Profile generic曲线/日志负荷曲线、事件记录第 7 篇8Clock时钟全表时间基准计划中9Script table脚本表一组可执行动作计划中10Schedule调度何时执行计划中11Special days table特殊日表节假日费率计划中15Association LN逻辑名方式的应用关联含 4 个版本计划中20Activity calendar活动日历费率时段切换的总调度计划中21Register monitor寄存器监视器越限告警计划中22Single action schedule单次动作调度计划中64Security setup安全配置密钥、加密套件含 2 个版本计划中71Limiter限流器负荷控制计划中…另有通信类G3-PLC、PRIME、LoRaWAN、NB-IoT 等、计费类Account、Credit、Token gateway等计划中阅读建议不必按顺序死磕。如果你做抄表优先看Data/Register/Profile generic做费率看Register activation/Activity calendar/Script table做安全看Association LN/Security setup。8. 小结 下期预告本篇建立了三张地图协议地图DLMS/COSEM 是客户端-服务器模型靠AA 会话xDLMS 服务GET/SET/ACTION访问对象底层可走 HDLC / IP / PLC / RF数据用带类型标签的A-XDR编码文档地图蓝皮书定义对象长什么样绿皮书定义报文怎么传模型地图物理设备 → 逻辑设备 → COSEM 对象对象 接口类的实例靠class_idlogical_name 属性索引定位。再记住三个反直觉的点一切皆对象—— 连会话本身都是对象Association LN属性索引不跨类通用——Register的 2 号是value别的类不一定语义随数据走—— 单位unit和倍率scaler在对象里不在主站的配置文件里。下一篇第 2 篇从最简单的class_id 1的Data类讲起 —— 它只有两个属性、零个方法却是理解整个对象模型的最小完备样本。我们会把logical_name的OBIS 编码逐字节拆开1-0:1.8.0每个数字到底什么意思讲清value背后那张CHOICE 数据类型母表后面所有类都在复用它并用序列号、配置参数、布尔标志、复杂结构等真实例子说明为什么没有单位反而是它最大的优势。参考资料DLMS UA《Blue Book Ed.16 Part 2 – COSEM interface classes》Clause 4Basic principles / The COSEM server model / Overview of the COSEM interface classes含 LDN 定义与 NOTE。文中 class_id 与接口类名称均取自该文档接口类清单。