文章目录
前言
适合阅读人员:电力行业、电表行业的软件工程师
本文是对蓝、绿皮书的大致解读
一、DLMS/COSEM规范是什么?
1. COSEM(Companion Specification for Energy Metering)(电能计量配套规范):
定义了设备(如电表)数据的结构和类型,包括对象模型、数据类型和方法,用于智能计量设备的数据对象建模,方便数据在不同厂家制造的设备之间的传递。
1.1 对象模型
对象模型首先分接口类,再分OBIS。先列举些常用的接口类
接口类名 | 类标识 | 类含义 |
---|---|---|
Data 数据 | 1 | 配置数据和参数,测量值如电流、电压、功率 |
Register 寄存器 | 3 | 对过程或状态值进行建模, “寄存器”对象知道进程或状态值的性质 |
Demand registe 需量寄存器 | 5 | 需量即平均功率及其相关的比例、单位、状态和时间信息进行建模。 |
Register activation 寄存器激活 | 6 | 管理费率结构 ,定义不同的激活掩码和寄存器组来实现对多种计费结构的灵活管理 |
Profile generic 曲线 | 7 | 允许存储、排序和访问称为捕获对象的数据组或数据系列 |
Clock 时钟 | 8 | 对器件时钟进行建模,管理与日期和时间相关的所有信息,包括由于时区和夏令时方案导致的本地时间与通用时间参考 (UTC) 的偏差。该 IC 还提供各种调整时钟的方法。 |
Script table 脚本表 | 9 | 用 execute(数据)方法执行脚本来对一系列动作的触发进行建模 |
Schedule 日历 | 10 | 与特殊日期表一起使用,在设备内对时间和日期驱动的活动进行建模 |
Special days table 特殊日期表 | 11 | 指定给定日期的特殊日期标识符。 该日期可能具有通配符,用于重复特殊日期(如圣诞节) |
Association LN class 关联逻辑名类 | 15 | 使用逻辑名引用在COSEM上下文中建立应用链接 |
Image transfer 图像传输 | 18 | 传输二进制文件(称为 Images 到 COSEM 服务器)的过程进行建模,传输升级包 |
Activity calendar 活动日历 | 20 | 对电表中各种费率结构的处理进行建模,如8:00~12:00时用费率1 |
Push setup 推送设置 | 40 | 要推送的 COSEM 对象属性的引用列表。它还包含推送目标和方法,以及通信时间窗口和重试处理。 |
Compact data 紧凑的数据 | 62 | 捕获由 capture_objects 属性确定的 COSEM 对象属性的值,如每日结算数据 |
Security setup 安全设置 | 64 | 正在使用的安全套件的必要信息,以及客户端和服务器之间适用的安全策略 |
Disconnect control 断开控制 | 70 | 管理电表的内部或外部断开单元(例如继电器、燃气阀) |
Limiter 限幅器 | 71 | 定义一组操作,当被监控对象“数据”、“寄存器”、“扩展寄存器”、“需求寄存器”等的值超过阈值至少持续最短时间时,将执行这些操作。 |
数据类(Data)对象,该类对象的标识class_id = 1,即类1标识数据对象。
该接口类允许对各种数据进行建模,例如配置数据和参数。
数据类对象有属性1(logical_name),数据类型为octet-string,含义为逻辑名即OBIS的16进制表示,
有属性2(value),数据类型为CHOICE的复合数据类型,类似C中的枚举类型,可选的数据类型如图。
该类无方法
OBject Identification System(OBIS)定义了计量设备中常用数据项的识别代码,OBIS为计量设备内的所有数据提供唯一标识符,不仅包括测量值,还包括用于配置或获取有关计量设备行为信息的抽象值。
OBIS采用层次结构,使用六个值组A到F,结构为A.B.C.D.E.F 共6个部分,由规范定义各OBIS代表的意义,如果想知道某OBIS的含义,请自行查阅《Companion Specification for Energy Metering》即Blue Book Edition 12.。
每种对象模型有1个类号,叫class_id, class_id和OBIS这2部分标识1种符合该对象模型的数据项,class表示同1类相似的数据,OBIS是对象标识系统的意思,class+OBIS共同标识1个数据,可以理解为1个数据分配1个编号;1个数据项可以有多个属性,属性1返回OBIS的16进制表示值
1.2 数据类型
表 2 包含可用于 COSEM 对象属性的数据类型列表。tag为数据类型的标签,15表示数据类型为integer即单字节表示的整数
数据表示第一个是数据类型。按一个字节。第二个是数据长度。按一个字节。
1.3 例子
如何表示电压有效值220V?
COSEM规范定义了class1为数据类,用于表示普通数据,假如规范里电压为OBIS为1.1.1.8.0.255标识A相电压(三相表)或电压(单相表),即{1 - 1.1.1.8.0.255}标识数据对象中的电压对象,该对象的属性1为其OBIS的16进制表示,即0x0101010800FF,属性2为电压的值为long类型,即0x00DC。
换句话说,class=1,OBIS=1.1.1.8.0.255,表示电压对象,该对象属性2为电压值,因为属性2数据类型是long,所以是2字节表示,attr2=0x00DC
2. DLMS(Device Language Message Specification)(设备语言消息规范):
是一种用于智能计量设备的标准通信协议,主要用于智能计量设备(如电表、水表、气表等)之间的通信,支持多种传输媒介,如串行通信、网络协议等,用于将对象模型映射到应用程序协议数据单元 (APDU) ,在 Green Book, DLMS UA 1中描述。
2.1 DLMS概述
DLMS协议分为应用层,中间层和物理层,DLMS既可以是面向连接的(request、response),也可以是无连接的
每个物理设备上有唯一命名的标识,DLMS称为系统标题,类似以太网物理设备的MAC地址
每个物理设备上可以有多个逻辑设备,其标识称为逻辑设备名称 (LDN),类似ip的端口号
每个逻辑设备里运行对象模型的一个实例
2.2 DLMS物理层
物理层可以使用RS232、以太网、PPP、红外光口等,此处以光口为例讲解。
2.3 DLMS链路层
DLMS链路层使用HDLC协议,负责封装成帧、差错检测、可靠传输
2.3.1封装成帧
LLC层
MAC子层
Flag标志字段为0x7E(0b01111110)
帧格式字段的长度为两个字节。它由三个子字段组成,称为格式类型子字段(4 位)、分割位(S,1 位)和帧长度子字段(11 位),如图 51 所示:格式类型子字段的值为 1010(二进制),用于标识该HDLC帧的帧格式类型为 3,如Figure 49。分割位为1,表示应用层数据分片传输,后面还有信息帧携带应用层一包的部分数据
此帧中正好有两个地址字段:目标地址字段和源地址字段。
地址采用各字节的LSB表示地址结束,位为1代表没有下1字节
这些是保留地址,有特殊用途
控制字段的长度为一个字节。它指示命令或响应的类型,并在适当的情况下包含序列号(帧 I、RR 和 RNR)。
RRR 是接收序列号 N(R),SSS 是发送序列号 N(S),P/F 是轮询/最终位。
P位(Poll):1 表示发送方希望接收方进行回应。
F位(Final):0 表示接收方的回应不是最终的,接收方可以继续发送更多的响应帧。1表示最后1帧
- 设置正常响应模式 (SNRM) 命令
控制字段用于指示该帧的类型,控制字段的含义如Table 8,帧可分为SNRM帧,SNRM(Set Normal Response Mode)帧是用于设置通信链路为正常应答模式的控制帧,用于配置和初始化数据链路,在正常应答模式下,接收方会发送确认帧(I帧、RR帧或REJ帧)来确认接收到的数据帧。
-
接收就绪 (RR) 命令和响应
a) 表示它已准备好接收 I 帧;和
b) 确认以前收到的编号不超过 N(R) - 1(含 N(R) - 1) 的 I 帧。 -
接收未就绪 (RNR) 命令和响应
Receive not ready (RNR) 帧来指示繁忙情况,即暂时无法接受后续 I 帧。编号不超过 N(R) – 1(含)的 I 帧应被视为已确认。 -
信息命令和响应帧(I 帧)
执行信息传输。I 帧控制字段应包含两个序列号:
a) N(S),表示与 I 帧关联的序列号
b) N(R),应表示下一个预期接收的 I 帧的序列号(截至传输时),因此应表明编号到 N(R) – 1(含)的 I 帧已被正确接收。 -
断开连接 (DISC) 命令
DISC 命令应用于终止先前由命令设置的操作或初始化模式。
从站应使用 未编号确认 (UA) 响应来确认接收和接受 SNRM 和 DISC 命令。
帧头检查序列 (HCS) 字段,HCS 字段的长度为两个字节。此检查序列仅适用于帧头
信息字段,内容参考应用层
2.3.2 可靠传输
红外口通信时可以有一个协商波特率的过程,图中的Z代表协商的波特率,如9600,用的是字符串明文协商,Device adress是设备地址,如0x01010102,协商好后进入HDLC帧
2.4 DLMS应用层
2.4.1 原语
上图第一列表示原语,列出的是应用层服务中应该所带的一些数据类型,.request列表示请求链接服务可以携带的原语,M表示必须要的参数,U表示用户可选参数。
DLMS应用层中使用了ISO/IEC 15954:1999 定义的一些应用层协议数据单元(APDU)的结构。
ISO/IEC 15954:1999中APDU(Application Protocol Data Unit)的编码遵循ASN.1(Abstract Syntax Notation One)语法标准和BER(Basic Encoding Rules)编码规则。
2.4.2 ASN.1
ASN表示抽象语法记号,即类似如下表示的结构,描述了数据的格式
COSEMpdu ::= CHOICE {
-- standardized DLMS PDUs used in COSEM
-- DLMS PDUs (no encryption selected30)
initiateRequest [1] IMPLICIT InitiateRequest,
readRequest [5] IMPLICIT ReadRequest,
writeRequest [6] IMPLICIT WriteRequest,
initiateResponse [8] IMPLICIT InitiateResponse,
readResponse [12] IMPLICIT ReadResponse,
writeResponse [13] IMPLICIT WriteResponse,
confirmedServiceError [14] ConfirmedServiceError,
unconfirmedWriteRequest [22] IMPLICIT UnconfirmedWriteRequest,
informationReportRequest [24] IMPLICIT InformationReportRequest,
-- the two ACSE APDUs
aarq AARQ-apdu
aare AARE-apdu,
-- APDUs used for data communication servicesusing LN referencing
get-request [192] IMPLICIT GET-Request,
set-request [193] IMPLICIT SET-Request,
event-notification-request [194] IMPLICIT EVENT-NOTIFICATION-Request,
action-request [195] IMPLICIT ACTION-Request,
get-response [196] IMPLICIT GET-Response,
set-response [197] IMPLICIT SET-Response,
action-response [199] IMPLICIT ACTION-Response,
-- global ciphered pdus
glo-get-request [200] IMPLICITOCTET STRING,
glo-set-request [201] IMPLICITOCTET STRING,
glo-event-notification-request [202] IMPLICIT OCTET STRING,
glo-action-request [203] IMPLICITOCTET STRING,
glo-get-response [204] IMPLICITOCTET STRING,
glo-set-response [205] IMPLICITOCTET STRING,
glo-action-response [207] IMPLICITOCTET STRING,
-- dedicated ciphered pdus
ded-get-request [208] IMPLICITOCTET STRING,
ded-set-request [209] IMPLICITOCTET STRING,
ded-event-notification-request [210] IMPLICIT OCTET STRING,
ded-actionRequest [211] IMPLICITOCTET STRING,
ded-get-response [212] IMPLICITOCTET STRING,
ded-set-response [213] IMPLICITOCTET STRING,
ded-action-response [215] IMPLICITOCTET STRING
}
上式是一个 ASN.1(抽象语法标记语言)定义,其定义了一个名为 COSEMpdu的 CHOICE 类型的结构,
COSEMpdu是自定义标识符,内部类型标识符全部大写,如BOOLEAN,INTEGER,类似C中的bool,int,
::=是赋值符号,-- 是注释符号,
CHOICE 用于定义一个数据类型,可以是多种不同类型中的一种,表示数据包可以是 {}里的任意1行,
ENUMERATED:用于定义一个具有有限个预定义值的枚举类型。
[1]中的数字1为该应用数据类型的显示标签(tag),如果没有指定,默认自动从第一行
依次给字段赋[0],[1],[2]...,
[1]表示这个字段在定义中的标签是1,
[1] IMPLICIT InitiateRequest表示该字段优先使用内部类型标识符InitiateRequest,
防止有重名的自定义标识符
当未指定标签时,即 IMPLICIT STRING,会用内部类型标识符STRING的tag(12)当做定义中的tag
在 BER(Basic Encoding Rules)中,基本数据类型的标签(tag)定义如下:
BOOLEAN: 1
INTEGER: 2
BIT STRING: 3
OCTET STRING: 4
NULL: 5
OBJECT IDENTIFIER: 6
Object Descriptor: 7
EXTERNAL: 8
REAL: 9
ENUMERATED: 10
UTF8String: 12
Sequence: 16
Sequence of: 16
Set: 17
Set of: 17
PrintableString: 19
T61String: 20
VideotexString: 21
IA5String: 22
GraphicString: 25
VisibleString: 26
GeneralString: 27
UniversalString: 28
CharacterString: 29
BMPString: 30
initiateRequest: 在 ASN.1 语法中,initiateRequest 是标识符,用于指定特定的选择类型(如CHOICE)中的一个选项。 这是一个字段名称或标记,通常在定义中出现。
InitiateRequest: 这是一个类型名称,用于指定 ASN.1 模式中某个特定的数据结构。它代表一个具体的数据类型定义。
每种APDU都有其特定的标签(tag)用于标识其类型和功能。具体的标签(tag)和详细的编码格式可以在标准文档中找到
2.4.3 BER编码
以Data定义的编码为例,上图结合1.2 数据类型可知,
01 // Array
3c // Array的Value占据的length(字节数)
02 // Structure
04 // Structure的Length ,表示结构体里有4个元素
12 // Unsigned16,因为长度固定,无length
00 08 // Unsigned16的数据值
09 //Octet String数据类型的标签
06 //Octet String为边长数据类型,有Length表Value的长度
00 00 01 00 00 ff //表8位元组,类似字符串
0f // int8
02
12 //int16
00 00
类型(type):每个字段的ASN.1类型都有一个唯一的标签,可以是数据类型或数据包类型的tag。
长度(Length):Value字段的长度(以字节为单位),当Tag可以推断出长度时,该项常常省略。
值(Value):字段的实际数据。
Type(定长) | Length(变长) | Value(变长) |
---|---|---|
0b00000011 | 0x01 | 0x01 |
Type占1字节,分3部分含义,如下表
标签类Class | P/C(私有/构造类) | 标签编号Tag |
---|---|---|
7 6 | 5 | 4 3 2 1 0 |
0b00 | 0b0 | 0b00011 |
-
类Class占2bit,
00:通用类(Universal),表示ASN协议已定义的基本数据类型
01:应用类(Application)
10:上下文特定类(Context-specific)
11:私有类(Private)
通用数据类型type=0b00后的tag见下图
- 通用类数据类型如Table2,这是一个定义 Data 类型的 ASN.1 模块,使用了 CHOICE 构造来定义不同的数据类型,为属性值的可选数据类型标签,与ASN.1自带的相同基本数据类型的全局tag效果一样。
在本质上,定义的 boolean [3] IMPLICIT BOOLEAN 与 ASN.1 的标准 BOOLEAN(0x01) 类型都是表示布尔值,但它们的上下文和使用场景有所不同。一个是特定于Data数据结构中的选项,另一个则是通用的基本类型。
-
应用类数据类型
应用关联请求(AARQ)Tag: 0x60 :用于发起一个应用关联请求,包含请求建立应用关联所需的信息。 应用关联释放响应(AARE)Tag: 0x61 :用于响应应用关联释放请求,确认或拒绝释放应用关联的请求。 应用关联释放请求(RLRQ)Tag: 0x62 :用于请求释放已经建立的应用关联。 应用关联释放确认(RLRE)Tag: 0x63 :用于确认应用关联释放请求的处理结果。
[APPLICATION 0] == [ 60H ] = [ 96 ],APPLICATION 0 即0b01100000=[ 60H ]
常用应用类数据类型 | APDU type | 描述 |
---|---|---|
AARQ | 0x60 | 在应用层协议中用于建立通信会话的一个消息类型 |
AARE | 0x61 | 确认或拒绝AARQ请求 |
RLRQ | 0x62 | 释放应用关联: 发出释放会话的请求,通常意味着要结束当前的通信会话或资源分配 |
RLRE | 0x63 | 释放响应消息,确认释放请求并结束会话 |
GET | 0xC0 | GET 服务是客户端用来请求服务器返回一个或多个属性的值 |
SET | 0xC1 | SET服务是客户端用来请求服务器替换一个或多个属性的内容 |
ACT | 0xC4 | 客户端使用 ACTION 服务来请求服务器调用一个或多个方法。调用方法可能意味着发送方法调用参数和接收返回参数 |
下面是Get的相关数据类型定义,CHOICE表选择,Get-Request的标签后接1表示是Get-Request-Normal类
以请求反向有功为例:
S: 7e a0 1c 00 22 00 23 03 54 bd 5e e6 e6 00 c0 01 81 00 03 01 01 02 08 00 ff 02 00 9f 36 7e
解释:
7e a0 1c 00 22 00 23 03 54 bd 5e e6 e6 00 //Hdlchead
c0 // get-request Cosemapdu[192]
01 //Request Nomal
81 // invoke-id and priority
00 03//Class id 3
01 01 02 08 00 ff //反向总有功 OBIS
02 //反向总有功的属性2
00 //Access Selector: 0
9f 36 7e //HDLC Tail
例2:Get请求:
7e a0 19 03 21 dc 1f d6 e6 e6 00 c0 01 c1 00 0f 00 00 28 00 00 ff 07 00 29 2d 7e
解析:
7e // Flag
a0 19 // Frame Format
// 1010 .... .... .... = Type: 10
// .... 0... .... .... = Segmentation: 0
// .... .000 0001 1001 = Length: 25
03 // Destination Address
// 0000 001. = Upper HDLC Address: 1
21 // Source Address
// 0010 000. = Upper HDLC Address: 16
dc // Control
// .... ...0 = Frame: I (Information) (0)
// ...1 .... = Poll/Final: 1
// 110. .... = Receive Sequence Number: 6
// .... 110. = Send Sequence Number: 6
1f d6 // Header Check Sequence
e6 e6 00 // LLC Header
c0 // APDU: get-request (192)
01 // Get Request: get-request-normal (1)
c1 // Invoke Id And Priority
// .... 0001 = Invoke Id: 1
// .1.. .... = Service Class: confirmed (1)
// 1... .... = Priority: high (1)
00 0f // Class Id: association_ln (15)
00 00 28 00 00 ff // Instance Id: Current association (0.0.40.0.0.255)
07 // Attribute Id: secret (7)
00 // Selective Access Descriptor,
// Access Selector: 0
29 2d // Frame Check Sequence
7e // Flag
Get请求的回复:
上下文特定类数据类型 | APDU type | 描述 |
---|---|---|
authentication functional unit 、group identifie | 0x80 | 最高位置1其余的为unused bits |
format identifie | 0x81 | SNRM中表示协商窗口大小等参数 |
未知 | 0x88 | |
未知 | 0x89 | |
acse-requirements | 0x8A | |
mechanism-name | 0x8B | |
application-context-name | 0xA1 | |
result | 0xA2 | |
result-source-diagnostic | 0xA3 | |
calling-AP-title-field | 0xA6 | |
未知 | 0xAA | |
Authentication-value | 0xAC | |
user-information | 0xBE |
所有的DLMS应用数据包APDU都有1个type,标识1种特定格式的数据结构体,如0xC0 = 192,表示该应用类数据按 get-request的ASN格式解析,get-request类似于C中自定义的结构体,其最终由一些基本数据结构组成
- P/C构造类型(Constructed/Primitive)占1bit,
0:原始类型(Primitive)
1:构造类型(Constructed),只有数据类型为容器类(SEQUENCE 、CHOICE 、SET)时置为1
标签号(Tag Number)占5bit
若标签号小于 31(即 0-30),则直接使用这些位表示标签号。
若标签号大于等于 31,则这些位全为 1,并且标签号在后续字节中同Length表示方式编码。
-
BER 允许对数据的长度进行编码,有固定长度和变长两种编码方式
Length字节中的MSB为0表示固定长度,长为LSB0~6; MSB为1表示可变长度,长为各字节的LSB6~0依次拼起来,最后1字节MSB为0,表示无后续长度字节
在客户端/服务器模型中,请求由客户端发送,响应由服务器发送。允许客户端在收到对前一个请求的响应之前发送多个请求。因此,为了能够确定哪个响应对应于每个请求,有必要在请求中包含引用。Invoke_Id 参数用于此目的。此参数的值由客户端分配,以便每个请求都带有不同的Invoke_Id。服务器应将Invoke_Id复制到相应的响应中。
应用连接的建立
二、历史背景
DLMS协议最早由智能计量标准化组织(DLMS User Association)提出和维护。它在1990年代起步,旨在实现不同制造商设备之间的互操作性。
三、结构和组成
DLMS协议通常包括以下几个主要组成部分:
DLMS/COSEM通信协议:
定义了设备与外部系统之间的通信规则,包括数据传输、数据封装和命令解析等。
应用层协议:
实现具体的应用功能,如读取计量数据、设置设备参数、远程控制等。
参考文档
DLMS UA 1000-1 Ed. 12.1,Companion Specification for Energy Metering即Blue Book Edition 12.
DLMS UA 1000-2 Ed. 8.0 ,DLMS/COSEM Architecture and Protocols, Eighth Edition即Green book Edition 8.
GB/T 16263.1-2006/ISO/IEC 8825-1:2002, 信息技术 ASN.1编码规则 第 1部分 :基本编码规则(BER)正则 编码规 则 (CER)和非典型编码规则(DER)规范