DLMS/COSEM
SharpMeter implements the DLMS/COSEM protocol suite per IEC 62056 for smart meter communication. This is the dominant protocol for electricity, gas, and water meters worldwide.
Architecture
| Layer | Standard | Implementation |
|---|---|---|
| Application | DLMS (IEC 62056-53) | DlmsClient — GET/SET/ACTION services |
| Data Model | COSEM (IEC 62056-62) | ObisCode — object identification |
| Encoding | A-XDR (IEC 62056-53) | AxdrEncoder — data serialization |
| Data Link | HDLC (IEC 62056-46) | HdlcFrame — frame encoding/decoding |
| Transport | Serial / TCP | ITransport — pluggable |
OBIS Codes
OBIS (Object Identification System) uses 6-byte codes in the format A-B:C.D.E*F:
// Well-known codes
var energy = ObisCode.ActiveEnergyImportTotal; // 1.0.1.8.0.255
var voltage = ObisCode.VoltageL1; // 1.0.32.7.0.255
var clock = ObisCode.Clock; // 0.0.1.0.0.255
// Parse from string
var custom = ObisCode.Parse("1-0:1.8.0*255");
// Create directly
var code = new ObisCode(1, 0, 1, 8, 0, 255);
GET — Reading Attributes
// Read active energy import (Register class, attribute 2 = value)
var result = await client.GetAttributeAsync(
classId: 3, // Register
obisCode: ObisCode.ActiveEnergyImportTotal,
attributeIndex: 2); // value attribute
Batch Read
var descriptors = new[]
{
(classId: (ushort)3, obis: ObisCode.ActiveEnergyImportTotal, attr: (byte)2),
(classId: (ushort)3, obis: ObisCode.VoltageL1, attr: (byte)2),
(classId: (ushort)3, obis: ObisCode.CurrentL1, attr: (byte)2),
};
await foreach (var result in client.GetAttributeListAsync(descriptors))
{
// Process each result
}
SET — Writing Attributes
var value = AxdrEncoder.EncodeDoubleLongUnsigned(12345);
var result = await client.SetAttributeAsync(
classId: 3,
obisCode: ObisCode.ActiveEnergyImportTotal,
attributeIndex: 2,
value: value);
ACTION — Invoking Methods
var result = await client.ActionAsync(
classId: 8, // Clock class
obisCode: ObisCode.Clock,
methodIndex: 1, // adjust_to_quarter
parameters: AxdrEncoder.EncodeNull());
A-XDR Encoding
The AxdrEncoder handles DLMS data type encoding/decoding:
// Encoding
byte[] encoded = AxdrEncoder.EncodeDoubleLongUnsigned(42000);
byte[] str = AxdrEncoder.EncodeVisibleString("Hello");
byte[] octets = AxdrEncoder.EncodeOctetString(new byte[] { 0x01, 0x02 });
// Decoding
uint value = AxdrEncoder.DecodeDoubleLongUnsigned(data);
byte[] bytes = AxdrEncoder.DecodeOctetString(data, out int consumed);
Authentication
var options = new DlmsClientOptions
{
// No authentication
Authentication = AuthenticationMechanism.None,
// Low Level Security (password)
Authentication = AuthenticationMechanism.LowLevelSecurity,
Password = "mypassword"u8.ToArray(),
// High Level Security (challenge-response)
Authentication = AuthenticationMechanism.HighLevelSecurityGmac,
Password = encryptionKey,
};
HDLC Framing
The HDLC layer handles connection establishment, data transfer, and disconnection:
- SNRM — Set Normal Response Mode (connection)
- UA — Unnumbered Acknowledge
- I-frames — Information transfer with sequence numbering
- DISC — Disconnect
All framing is handled automatically by DlmsClient.
Last updated: 2026-04-08