Getting Started

Installation

# PSEM (ANSI C12.18/C12.19) — serial or TCP meters
dotnet add package SharpMeter.Client

# DLMS/COSEM (IEC 62056) — smart meters
dotnet add package SharpMeter.Dlms

# Testing with built-in emulator
dotnet add package SharpMeter.Emulator

Requirements

  • .NET 9.0 or .NET 10.0
  • For serial communication: a USB-to-optical probe (e.g., ANSI Type 2 optical port)
  • For TCP: network access to the meter or collector

First PSEM Connection

using SharpMeter.Client;
using SharpMeter.Transport;
using Microsoft.Extensions.Logging.Abstractions;

// 1. Create a serial transport
var options = new TransportOptions
{
    PortName = "COM3",
    BaudRate = 9600
};
await using var transport = new SerialTransport(options, NullLogger<SerialTransport>.Instance);

// 2. Create the PSEM client
await using var client = new PsemClient(transport, NullLogger<PsemClient>.Instance);

// 3. Connect (identify → negotiate → logon → security)
byte[] password = new byte[20]; // your meter password
var result = await client.ConnectAsync(
    userId: 2,
    userName: "SharpMeter",
    password: password);

if (result.IsSuccess)
{
    // 4. Read a table
    var table = await client.ReadTableAsync(tableId: 1);
    if (table.IsSuccess)
        Console.WriteLine($"Read {table.Value.Length} bytes from {table.Value.DisplayName}");

    // 5. Disconnect gracefully
    await client.DisconnectAsync();
}
else
{
    Console.WriteLine($"Connection failed: {result.Error}");
}

First DLMS Connection

using SharpMeter.Dlms;
using SharpMeter.Dlms.Enums;
using SharpMeter.Transport;
using Microsoft.Extensions.Logging.Abstractions;

// 1. Create a TCP transport
var options = new TransportOptions { Host = "192.168.1.100", Port = 4059 };
await using var transport = new TcpTransport(options, NullLogger<TcpTransport>.Instance);

// 2. Create the DLMS client
var dlmsOptions = new DlmsClientOptions
{
    Authentication = AuthenticationMechanism.LowLevelSecurity,
    Password = "password"u8.ToArray()
};
await using var client = new DlmsClient(transport, dlmsOptions, NullLogger<DlmsClient>.Instance);

// 3. Connect (SNRM → AARQ)
await client.ConnectAsync();

// 4. Read active energy import
var result = await client.GetAttributeAsync(
    classId: 3,
    obisCode: ObisCode.ActiveEnergyImportTotal,
    attributeIndex: 2);

if (result.IsSuccess)
    Console.WriteLine($"Energy: {result.Value.Length} bytes");

// 5. Disconnect
await client.DisconnectAsync();

Using the Emulator

No hardware? Use the built-in emulator for development and testing:

using SharpMeter.Client;
using SharpMeter.Emulator;
using Microsoft.Extensions.Logging.Abstractions;

var config = new EmulatorConfiguration
{
    Manufacturer = "TEST",
    SerialNumber = "TESTMETER0000001"
};

var emulator = new MeterEmulator(config, NullLogger<MeterEmulator>.Instance);
await using var transport = new EmulatorTransport(emulator, NullLogger<EmulatorTransport>.Instance);
await using var client = new PsemClient(transport, NullLogger<PsemClient>.Instance);

// Use exactly like a real meter
await client.ConnectAsync(password: null);
var table = await client.ReadTableAsync(1);
await client.DisconnectAsync();
Last updated: 2026-04-08
Was this page helpful?