dlms cosem basics
TRANSCRIPT
The DLMS communication survival kit
This page shortly describes the basic concepts of the DLMS/COSEM model and
protocols. It is certainly very incomplete and somewhat over simplified. Still, the
presented information and the practical examples should give the minimal necessary
knowledge needed to be able to read metering data from a compliant device. It is
needless to say that the definitive reference about the COSEM/DLMS model and
protocols remains the ''colored books'' (Green Book, Blue Book) of the DLMS User
Association.
The Problem
We want to write a program able to read the value of the active energy register of an
electricity-meter of this kind...
... and the DLMS/COSEM protocol.
The problem is not trivial, and to be able to design a solution, we first need to know
more about some of the main concepts of the COSEM/DLMS standard.
The Physical Device
The Physical device, is our meter, it supports one or more communication profiles.
Currently, the Standard specifies two profiles: the 3-layer, connection oriented
HDLC-based profile, and the TCP-UDP/IP based profile. Our device, like many
others, uses the HDLC-based profile, it also has a physical address.
The Logical Device
A physical device hosts one or several Logical Devices. A logical device models a
specific functionality of the physical device. For example, in a multi-energy meter, one
logical device could be an electricity meter, another, a gas-meter etc. Each logical
device has an address, called the logical device address.
...using a serial line...
Page 1 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
According to the Standard, all physical devices have to host a special logical device
called the management logical device, with the predefined address 1. The
management logical device itself may contain a lot of information, but, at the
minimum, it has to contain a description of all the logical devices available in the
physical meter, with their logical addresses and names.
A physical device hosting 3 logical devices, with addresses 1,2 and 3
So, how do we read the value of the active energy out of the logical devices?
The COSEM Classes and object instances
A logical device is a container for COSEM objects. A COSEM object is simply a
structured piece of information with attributes and methods. For the moment, we
will ignore the methods and just focus on the attributes since they contain the values
that we are interested in. All objects that share the same structure are of the same
COSEM class. There are many COSEM classes (about 50) because there are many
different objects kinds. Since a logical device may contain many objects of different
classes, then how do we identify the information that we are interested in? This is
possible because, by definition, the first attribute of each object is its Logical Name.
The Logical Name
A logical name consists of a string of 6 values defined according to a system called
OBIS for Object Identification System. OBIS allows to uniquely identify each of the
many data items used in the energy metering equipment. The list of all possible OBIS
codes (OBIS code is another name for logical name) is published by the DLMS Users
Association on their web site in a dense Excel document. Fortunately, we have a
simple tool, called OBISHelper, able to find and identify the OBIS codes in a more
comfortable way. Then, what is the logical name of the active energy ''object''?
Using OBISHelper, we search for codes with ''active power'' and ''time integral'':
Page 2 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
It appears that the required OBIS code should be (in the standard notation)
1.x.1.8.0.255, for example 1.1.1.8.0.255. How can we know if such an object exists
in our electricity-meter?
The Association object
Each logical device contains at least one object of class Association LN or
Association SN. We will come back later to these strange names. For the moment it
suffices to say that the association object has an attribute (attribute 2) called the
object list containing the list of all objects available in the logical device.
Furthermore, the association object has the predefined logical name 0.0.40.0.0.255.
Therefore, we can find out what objects are available in a logical device just by
reading its object list.
The mandatory elements of devices
To summarize: several mandatory elements allow us to get the necessary information
about the content of a physical device:
� Each physical device has a management logical device, at address 1.
� A management logical device hosts a list of all the available logical devices in the
physical device. This list is the second attribute of the object of class SAP
Assignment , with the predefined name 0.0.41.0.0.255. Each list item consists of
the name and the address of a logical device.
� Each logical device hosts a list of all its available objects. This list is the second
attribute of the object of class Association, with the predefined name
0.0.40.0.0.255. Each list item consists (among others) of the logical name and
the class of an object.
So finally, how do we read the active energy register?
The Client-Server model
Page 3 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
The data exchange between our program and the meter uses the client-server model.
Our application is the client and the meter plays the role of server. The client sends
requests and the server answers responses. For example, our application would
send something like ''read the object 1.0.1.8.0.255'' and the server would answer
''1789.8 kWh''. Still, before being able to send such requests, the client has first to
establish a connection with the other side. But, as we have seen, the other side is
not just a physical device but a collection of logical devices, therefore an addressing
system is needed.
The addressing
In the COSEM/DLMS communication framework, each side of the connection has an
address. By definition, the client address is a byte value. Furthermore, the value of
the client address determines also the real nature of the client. The Standard states
that a client with address 16 (decimal) is a public client. There can be other kind of
clients, for example a Data Collection System, a Manufacturer, a Consumer, though,
the addresses of those clients are not defined in the Standard.
The server address is the doublet:
{
address of the logical device,
address of the physical device
}.
The Access Rights
Of course, not everybody is allowed to read or write any value in a meter. There are
several mechanisms to control the access rights. The simplest one is based on the
following rule: your access rights depend on who you are. The meter knows you by
your client address and, according to that address, it will present you (via the
Association object) just the objects that you are allowed to read (or write). If you are
not a public client, then, you will have more privileges, but you will also have to
provide somewhere a password or even more complex security elements.
Nevertheless, a public client is always authorized to access the logical
management device. Some manufacturers allow public clients to read many
objects, others are far more restrictive. In some cases, if you don't have the required
credentials, you will not even be authorized to read the active energy!
Connecting the layers
We assume that our meter implements the 3-layer, connection-oriented, HDLC-
based profile. According to the Open Systems Interconnection (OSI) model, each of
client's layer exchanges data with the peer server's layer. The 3 layers of the HDLC
profile are the Physical layer, the HDLC layer and the Application layer.
The physical layer
Page 4 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
The lowest layer is the physical layer, it is the layer 1 in the OSI model. In our
practical example, it boils down to a simple (3-wires) serial cable between a COM port
of our PC and the appropriate connector of our meter. The connection between the
two peers layers is accomplished...by mechanically connecting the two sides.
The HDLC layer
The next layer is the HDLC layer, it corresponds to the layers 2 to 4 of the OSI model.
The HDLC layer is connection oriented. It means that the peer HDLC layers must
first build a logical connection with each other by exchanging and negotiating some
connection parameters. Then, they can exchange data, as long as needed and finally
they close the connection. The data elements exchanged by the HDLC peer layers are
called HDLC-frames.
The whole ''two ways alternate'' HDLC layer traffic is rather complex: the HDLC layer
is able to segment long data into information frames (I-Frame) and reassemble
information frames into long data, it verifies the sequencing of frames, it checks the
frames integrity using CRCs, it monitors various timeouts. We will not go into the
details of the HDLC exchanges. Instead, in our target program, we will use our ezhdlc
library, that implements the whole HDLC traffic and just exposes three routines:
Establishes an HDLC connection with the peer layer.
Sends data to the peer layer and receives the response from the peer layer.
Closes the connection.
There are several parameters to set before calling the HDLC routines, the most
important are the HDLC-addresses (also called MAC addresses). The client MAC
address is a byte value, it identifies the client. We will use 16 (decimal) which means
public client.
The server (or meter) MAC address is divided in two parts, the upper part is the
logical device address, and the lower part is the physical device address. In
some cases, the lower part can be omitted. For example, in a point-to-point
configuration with a single meter, we don't care about the physical address of the
meter. Note, however, that this feature is not implemented by all manufacturers.
From here...
...
...
...to there.
HDLCConnect();
HDLCSendReceive(DataToSend, DataReceived);
HDLCDisconnect();
Page 5 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
To summarize: on the HDLC layer, the client address is always a byte, the server
address consists of two parts and there are three variants:
� One byte addressing. There is just an upper address. It is a byte value.
� Two bytes addressing. There is an upper address on 1 byte and a lower
address on 1 byte.
� Four bytes addressing. There is an upper address on 2 bytes and a lower
address on two bytes.
Note that not all manufacturers support the three variants.
Here is an example of the HDLC-layer parameters as set in the XmlDemo application:
In XmlDemo, when we click ''Connect'', the library routine HDLCConnect sends a
SNRM-frame to the server. The server responds with an UA-frame. The next picture
shows the resulting frame exchange. The green frame is the SNRM-frame and the red
is the UA-frame:
The connection of the peer HDLC-Layers
This frame exchange establishes the HDLC layer connection. From now on, data
frames (I-Frame) can be exchanged between the two sides.
The Application layer
The last layer of the 3-layers profile is the Application layer. After having connected
the physical layer and the HDLC layer, we have to connect the Application layer. In
the OSI terminology, this kind of connection is called an Association. Therefore, to
establish an association, we send an Association request and we expect an
Association response. Then, if the association has been correctly established, we
continue to send requests and receive responses until we are finished. Finally, we
release the association by disconnecting the HDLC-Layer.
All the requests and their corresponding responses are defined in the Standard using
XMLDemo parameters, One byte addressing
We set 10 (hexa) for the
client address (public client)
and 1 for the logical device
address (management
logical device). The lower
address is not specified (one
byte addressing).
Page 6 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
the ASN.1 notation. However, in our tools and libraries, the specific instances of
requests and responses are presented in a XML notation, like in the following:
This is a ReadRequest element. How can we send such a request to the meter? Of
course, the XML lines cannot be sent directly. They must be first encoded into a byte
sequence known as a protocol data unit (PDU), according to the rules specified in
the Standard. We will not go into the details of the encoding. Instead, in our target
program, we will use our xmlpdu library, that implements the encoding and decoding
procedures. The library exposes two routines:
Encodes a sequence of XML lines into a PDU
Decodes the PDU into a sequence of XML lines.
For example, the encoded PDU of the above ReadRequest is this bytes sequence...
...that we send to the meter using the HDLC layer, by calling HDLCSendReceive()
and pass the bytes sequence as parameter. Then, when the meter responds with
another bytes sequence, we translate it back to XML with PduToXml(). Finally, we
parse the received XML using any appropriate method. To summarize: all
request/response exchanges follow these five steps:
� Have the XML of a request.
� Encode the XML to PDU using XmlToPdu().
� Send the PDU to the other side and get a response PDU, using
HDLCSendReceive().
� Decode the response PDU into XML with PduToXml().
� Finally, parse the XML of the response.
<ReadRequest Qty="0001" >
<ParameterisedAccess>
<VariableName Value="60E8" />
<Selector Value="01" />
<Parameter>
<Structure Qty="0004" >
<Structure Qty="0004" >
<LongUnsigned Value="0008" />
<OctetString Value="0000010000FF" />
<Integer Value="02" />
<LongUnsigned Value="0000" />
</Structure>
<OctetString Value="07D8021DFF0C130DFF8000FF" />
<OctetString Value="07D90A1DFF0B3622FF8000FF" />
<Array Qty="0000" >
</Array>
</Structure>
</Parameter>
</ParameterisedAccess>
</ReadRequest>
XmlToPdu(XmlLines, Pdu);
PduToXml(Pdu, XmlLines);
05 01 04 60 E8 01 02 04 02 04 12 00 08 09 06 00 00 01 00 00 FF 0F 02 12 00 00 09 0C
07 D8 02 1D FF 0C 13 0D FF 80 00 FF 09 0C 07 D9 0A 1D FF 0B 36 22 FF 80 00 FF 01 00
Page 7 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
To come back to the problem: what requests will we have to send and what responses
will we expect, if we want to read the energy register?
The AssociationRequest
The AssociationRequest is the first request that we have to send in order to
establish the Association. It looks like this:
The application context name
The exchanges with the meter can take place in two flavors called ''contexts'', that
differ in the way the data is addressed (or referenced). In the logical name
reference context (or LN) the data is referenced by the logical name (OBIS code).
In the short name reference context (or SN) the data is referenced (addressed) by
a unique 16 bit integer. Furthermore, the services used to access the data are
different in each context. In LN context, the relevant services are Get (to read data)
and Set (to write data) and in SN context the services are Read and Write. The
context cannot be freely chosen by the client. Rather, it is fixed by the meter's
manufacturer, it is a characteristic of its implementation. Therefore, the meter's
context must be known beforehand.
The Proposed Dlms Version Number
This value is currently fixed to 6, it is the version number of the DLMS protocol.
The Proposed Conformance
This is a list of capabilities that we are expecting the meter to have. In our example,
since we are in SN context, we are expecting the following capabilities:
� Read : to support the read service.
� Write: to support the write service.
� MultipleReferences: to be able to handle several reads (or writes) at once.
� ParametrizedAccess: to allow to read subsets of large attributes.
For a LN meter we would have used this kind of AssociationRequest:
<AssociationRequest>
<ApplicationContextName Value="SN" />
<InitiateRequest>
<ProposedDlmsVersionNumber Value="06" />
<ProposedConformance>
<ConformanceBit Name="ParametrizedAccess" />
<ConformanceBit Name="MultipleReferences" />
<ConformanceBit Name="Write" />
<ConformanceBit Name="Read" />
</ProposedConformance>
<ProposedMaxPduSize Value="FFFF" />
</InitiateRequest>
</AssociationRequest>
<AssociationRequest>
<ApplicationContextName Value="LN" />
<InitiateRequest>
<ProposedDlmsVersionNumber Value="06" />
<ProposedConformance>
<ConformanceBit Name="Action" />
Page 8 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
As a LN meter supports different service than a SN meter, then the requested
capabilities are different. Otherwise the two requests are the same.
The Proposed MaxPdu Size
is the size of the longest PDU that the client is able to store. The value "FFFF" means
"no limits".
The AssociationResponse
The meter's response to an AssociationRequest is an AssociationResponse. For
example, a SN meter would send this response:
The Association Result
A value of zero indicates that the request succeeded. Any other value indicates a
failure.
The Negotiated Conformance
The negotiated conformance is a list of capabilities that the meter implements. It
contains all the capabilities that we have requested in the negotiated conformance of
the AssociationRequest except the capabilities which are NOT supported by the
meter.
The Negotiated MaxPdu Size
<ConformanceBit Name="EventNotification" />
<ConformanceBit Name="SelectiveAccess" />
<ConformanceBit Name="Set" />
<ConformanceBit Name="Get" />
<ConformanceBit Name="BlockTransferWithAction" />
<ConformanceBit Name="BlockTransferWithSet" />
<ConformanceBit Name="BlockTransferWithGet" />
<ConformanceBit Name="Attribute0SupportedWithGet" />
<ConformanceBit Name="PriorityMgmtSupported" />
<ConformanceBit Name="Attribute0SupportedWithSet" />
</ProposedConformance>
<ProposedMaxPduSize Value="FFFF" />
</InitiateRequest>
</AssociationRequest>
<AssociationResponse>
<ApplicationContextName Value="SN" />
<AssociationResult Value="00" />
<ResultSourceDiagnostic>
<AcseServiceUser Value="00" />
</ResultSourceDiagnostic>
<InitiateResponse>
<NegotiatedDlmsVersionNumber Value="06" />
<NegotiatedConformance>
<ConformanceBit Name="ParametrizedAccess" />
<ConformanceBit Name="MultipleReferences" />
<ConformanceBit Name="Write" />
<ConformanceBit Name="Read" />
</NegotiatedConformance>
<NegotiatedMaxPduSize Value="0960" />
<VaaName Value="FA00" />
</InitiateResponse>
</AssociationResponse>
Page 9 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
is the size of the longest PDU that the meter is able to store. A client should never
send a PDU longer than this value.
The VaaName
is the short name of the (current) association object. We will ignore it.
If the association fails, then the response will look like this:
The association result is not null. The value of the AcseServiceUser element is an
error code.
How to read data from a SN meter
The service used to read data from a short name referencing meter is the
ReadRequest. This is a very simple service. Here is an example:
A ReadRequest allows to read several attributes at once, still, in the example, we
just want to read one single attribute, therefore "Qty" is set to 1. The (short name)
reference of the attribute we want to read is the value of the element "VariableName".
Our goal is to read the value of the object with logical name 1.1.1.8.0.255, then, how
do we know the relationship (mapping) between the logical names and the short
names?
The mapping between SN and LN
The mapping information between the short names and the logical names is directly
available from the meter itself, it is called the Object List and it is also the second
attribute of the (current) Association object. In fact, the object list doesn't really
contain the short name of all attributes but rather one single base name for each
object instance. But what is then the base name of the Association object itself?
Fortunately, this name is defined as ''FA00''.
<AssociationResponse>
<ApplicationContextName Value="LN" />
<AssociationResult Value="01" />
<ResultSourceDiagnostic>
<AcseServiceUser Value="0B" />
</ResultSourceDiagnostic>
<InitiateResponse>
<NegotiatedDlmsVersionNumber Value="06" />
<NegotiatedConformance>
<ConformanceBit Name="Action" />
<ConformanceBit Name="SelectiveAccess" />
<ConformanceBit Name="Set" />
<ConformanceBit Name="Get" />
<ConformanceBit Name="BlockTransferWithGet" />
<ConformanceBit Name="Attribute0SupportedWithGet" />
</NegotiatedConformance>
<NegotiatedMaxPduSize Value="2134" />
<VaaName Value="0007" />
</InitiateResponse>
</AssociationResponse>
<ReadRequest Qty="0001" >
<VariableName Value="2BC8" />
</ReadRequest>
Page 10 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
From the base name to the short name
By definition, the base name of an object instance is also the short name of its first
attribute. Then, for example, the following request...
...causes this response:
By definition, the first attribute (attribute 1) of any object instance is its logical name.
Therefore, the responded OctetString is simply the logical name of the current
Association:
What are the short names of the other attributes? By definition, the short name of
attribute N is given by:
ShortNameOfAttributeN = BaseName + 8 * (N-1)
According to the standard, the object list is the attribute 2 of the current association.
Therefore its short name is FA00 + 8 = FA08. Let's read the object list:
Here is the response:
<ReadRequest Qty="0001" >
<VariableName Value="FA00" />
</ReadRequest>
<ReadResponse Qty="0001" >
<Data>
<OctetString Value="0000280000FF" />
</Data>
</ReadResponse>
<ReadRequest Qty="0001" >
<VariableName Value="FA08" />
</ReadRequest>
<ReadResponse Qty="0001" >
<Data>
<Array Qty="00F0" >
<Structure Qty="0004" >
<Long Value="00C8" />
<LongUnsigned Value="2716" />
<Unsigned Value="00" />
<OctetString Value="0000F00D00FF" />
</Structure>
....
Page 11 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
The object list is an array of 240 (F0) entries. Each entry describes one object
instance using a structure of 4 elements. Let's consider the item in blue:
� The first element is the base name of the object instance: "1770"
� The second element is the class identifier of the object instance. There are
many classes in COSEM. Class 3 is the Register Class.
� The third element is the class version of the class of the object instance, here it
is version 0.
� Finally, the fourth element is the logical name of the object instance:
"0101010800FF"
Thanks to the object list, we know that the active energy (OBIS 1.1.1.8.0.255) is an
object instance of class 3 with a base name of 1770. The COSEM/DLMS Blue Book
shows us that the layout of the Register Class is:
This tells us that the value attribute is attribute 2, therefore the short name of the
active energy value is 1770 + 8 = 1778. Let's read the value:
The response gives the ''digits'' of value of the active energy,17D (hexa) or 381 (dec),
but we still don't have the ''real'' value. We also need to read the third attribute
(scaler_unit):
<Structure Qty="0004" >
<Long Value="1770" />
<LongUnsigned Value="0003" />
<Unsigned Value="00" />
<OctetString Value="0101010800FF" />
</Structure>
....
</Array>
</Data>
</ReadResponse>
<ReadRequest Qty="0001" >
<VariableName Value="1778" />
</ReadRequest>
<ReadResponse Qty="0001" >
<Data>
<Long64 Value="000000000000017D" />
</Data>
</ReadResponse>
<ReadRequest Qty="0001" >
<VariableName Value="1780" />
</ReadRequest>
<ReadResponse Qty="0001" >
<Data>
Page 12 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
The scaler-unit is a structure of two elements. The first element is an integer power of
10 (scaler). The second element gives the measuring unit. Therefore, scaler = -1, unit
= 1E = Wh (according to the Blue Book). Finally, we have it: the value of the active
energy is:
ActiveEnergy = 381 * 10-1 = 38.1 Wh = 0.0381kWh
Since our meter supports ''MultipleReferences'', we can also read the attributes 2 and
3 at once:
How to read data from a LN meter
In logical name referencing, we use the Get service to read the data. There are
several variants of GetRequest, the simplest is the GetRequestNormal. Here it is:
InvokeIdAndPriority
is a byte value. The bit 7 selects the priority, 1 means high priority. The bit 6 selects
the service class and will be set to 1. The remaining bits are an unsigned value
identifying this particular invocation of GetRequestNormal. In our examples, we will
always set InvokeIdAndPriority to "C1".
AttributeDescriptor
This 3 elements structure identifies the object instance and the attribute that we want
<Structure Qty="0002" >
<Integer Value="FF" />
<Enum Value="1E" />
</Structure>
</Data>
</ReadResponse>
<ReadRequest Qty="0002" >
<VariableName Value="1778" />
<VariableName Value="1780" />
</ReadRequest>
<ReadResponse Qty="0002" >
<Data>
<Long64 Value="000000000000017D" />
</Data>
<Data>
<Structure Qty="0002" >
<Integer Value="FF" />
<Enum Value="1E" />
</Structure>
</Data>
</ReadResponse>
<GetRequest>
<GetRequestNormal>
<InvokeIdAndPriority Value="C1" />
<AttributeDescriptor>
<ClassId Value="0003" />
<InstanceId Value="0101010800FF" />
<AttributeId Value="02" />
</AttributeDescriptor>
</GetRequestNormal>
</GetRequest>
Page 13 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
to read:
� ClassId is the class identifier of the object that hosts the attribute we want to
read.
� InstanceId is the logical name of that object read.
� AttributeId is the attribute number of the attribute we want to read.
The AttributeId can be found in the Blue Book. The ClassId and the InstanceId
can be found in the object list. According to the Blue Book, the object list is the
attribute 2 of the object 0.0.40.0.0.255, and, the ClassId is 15 (Association LN).
Therefore, the GetRequestNormal to read the object list looks like this:
The response can be a GetResponseNormal, as here:
This object list is very small. It has only two entries. Each entry describes one object
instance using a structure of 4 elements. However, when the meter has many objects,
a GetResponseNormal would result in a very long PDU. Therefore, provided that the
<GetRequest>
<GetRequestNormal>
<InvokeIdAndPriority Value="C1" />
<AttributeDescriptor>
<ClassId Value="000E" />
<InstanceId Value="0000280000FF" />
<AttributeId Value="02" />
</AttributeDescriptor>
</GetRequestNormal>
</GetRequest>
<GetResponse>
<GetResponsenormal>
<InvokeIdAndPriority Value="C1" />
<Result>
<Data>
<Array Qty="0002" >
<Structure Qty="0004" >
<LongUnsigned Value="0001" />
<Unsigned Value="00" />
<OctetString Value="00002A0000FF" />
<Structure Qty="0002" >
<Array Qty="0002" >
<Structure Qty="0003" >
<Integer Value="01" />
<Enum Value="01" />
<NullData />
</Structure>
<Structure Qty="0003" >
<Integer Value="02" />
<Enum Value="01" />
<NullData />
</Structure>
</Array>
<Array Qty="0000" >
</Array>
</Structure>
</Structure>
....
</Array>
</Data>
</Result>
</GetResponsenormal>
</GetResponse>
Page 14 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
meter has the capability BlockTransferWithGet (which is listed in the
NegotiatedConformance of the AssociationResponse), it will send the data in
several blocks rather than in one large single chunk. This feature is called ''block
transfer'', it is indeed a data segmentation mechanism supported in the application
layer and we have to handle it in details.
LN Block Transfer
When a LN meter receives a GetRequestNormal (for example to read the object list)
it may decide to respond with a GetResponseNormal or it may rather switch to
block transfer and respond with a GetResponseWithDataBlock. In that case the
response will be:
The element InvokeIdAndPriority is the same as in the request. The outer Result is a
structure of 3 elements:
� LastBlock is a boolean which indicates if this block is the last block of the block
transfer (00 = false).
� BlockNumber is an unsigned value and is the number of this block.
� Finally, the RawData (in the inner Result) is an octet string containing the first n
bytes of our data.
Having the first block, we save the RawData, say T, and ask for the next block using
GetRequestForNextDataBlock:
InvokeIdAndPriority stays the same. BlockNumber is the number of the last block that
we have received. The response to this request will be another
GetResponseWithDataBlock (BlockNumber 2) and we will right-concatenate its
RawData to the T:
T := T + RawData
Then, we will repeat the process until we have received the last block (LastBlock =
true):
<GetResponse>
<GetResponsewithDataBlock>
<InvokeIdAndPriority Value="C1" />
<Result>
<LastBlock Value="00" />
<BlockNumber Value="00000001" />
<Result>
<RawData Value="018201B3020412...6020002031601000100" />
</Result>
</Result>
</GetResponsewithDataBlock>
</GetResponse>
<GetRequest>
<GetRequestForNextDataBlock>
<InvokeIdAndPriority Value="C1" />
<BlockNumber Value="00000001" />
</GetRequestForNextDataBlock>
</GetRequest>
<GetResponse>
<GetResponsewithDataBlock>
<InvokeIdAndPriority Value="81" />
Page 15 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
Here again, we right-concatenate the RawData to the data received so far.
T := T + RawData
The final data T will be a very long PDU. To convert T to XML we left-concatenate it
with the byte FF:
T := FF + T
and pass it to PduToXml.
The resulting XML will look like this:
The resulting data is an array with (possibly) many elements. There is one array entry
for each object instance. Each entry is a structure of 4 elements:
<Result>
<LastBlock Value="01" />
<BlockNumber Value="00000006" />
<Result>
<RawData Value="02041200071...601000100" />
</Result>
</Result>
</GetResponsewithDataBlock>
</GetResponse>
<Data>
<Array Qty="01B3" >
....
<Structure Qty="0004" >
<LongUnsigned Value="0003" />
<Unsigned Value="00" />
<OctetString Value="0101010800FF" />
<Structure Qty="0002" >
<Array Qty="0003" >
<Structure Qty="0003" >
<Integer Value="01" />
<Enum Value="01" />
<NullData />
</Structure>
<Structure Qty="0003" >
<Integer Value="02" />
<Enum Value="01" />
<NullData />
</Structure>
<Structure Qty="0003" >
<Integer Value="03" />
<Enum Value="01" />
<NullData />
</Structure>
</Array>
<Array Qty="0000" >
</Array>
</Structure>
</Structure>
....
</Array>
</Data>
Page 16 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
� The first element (LongUnsigned) is the ClassId of the instance.
� The second element (Unsigned) is the version number of the class of the instance.
� The third element is the logical name of the instance.
� Finally, the fourth element lists the access rights of the attributes and methods of
the instance.
Finally, as we know the parameters, we can send a GetRequestNormal to read the
''digits'' of the energy register:
Here is the response:
We read the scaler with this request:
And the response is:
Finally the active energy is:
<GetRequest>
<GetRequestNormal>
<InvokeIdAndPriority Value="C1" />
<AttributeDescriptor>
<ClassId Value="0003" />
<InstanceId Value="0101010800FF" />
<AttributeId Value="02" />
</AttributeDescriptor>
</GetRequestNormal>
</GetRequest>
<GetResponse>
<GetResponsenormal>
<InvokeIdAndPriority Value="C1" />
<Result>
<Data>
<DoubleLongUnsigned Value="000007D3" />
</Data>
</Result>
</GetResponsenormal>
</GetResponse>
<GetRequest>
<GetRequestNormal>
<InvokeIdAndPriority Value="C1" />
<AttributeDescriptor>
<ClassId Value="0003" />
<InstanceId Value="0101010800FF" />
<AttributeId Value="03" />
</AttributeDescriptor>
</GetRequestNormal>
</GetRequest>
<GetResponse>
<GetResponsenormal>
<InvokeIdAndPriority Value="C1" />
<Result>
<Data>
<Structure Qty="0002" >
<Integer Value="FE" />
<Enum Value="1E" />
</Structure>
</Data>
</Result>
</GetResponsenormal>
</GetResponse>
Page 17 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html
ActiveEnergy = 2003 * 10-2 = 20.03 Wh = 0.02003kWh
icube software
route d'Eclagnens 5
1376 Goumoens-la-Ville
Switzerland
Home
Page 18 of 18The DLMS communication survival
6/28/2011http://www.icube.ch/DLMSSurvivalKit/dsk1.html