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
Was this page helpful?