Skip to content

DLMS Meter

The dlms_meter component connects to smart meters which use the DLMS/COSEM protocol in PUSH mode over UART. These smart meters are widely deployed globally.

The component does not transmit data to the meter. The meter periodically broadcasts frames. ESPHome listens, decodes (and decrypts if necessary), and updates the configured sensors as data arrives.

NOTE

An adapter (like an M-Bus to UART module) is required to connect the EspHome board to the smart meter.

For encrypted meters, you must request a 32-character hexadecimal decryption key from your energy provider.

Smart meter with M-Bus adapter board to ESP32

This component requires a UART bus to be configured.

TIP

The UART configuration depends on your specific meter hardware. Be sure to consult your provider or meter’s specifications.

dlms_meter:
id: dlms_meter_hub
uart_id: uart_dlms_bus
sensor:
- platform: dlms_meter
dlms_meter_id: dlms_meter_hub
obis_code: "1.0.1.7.0.255"
name: "Active power taken from grid"
  • id (Optional, ID): The ID of the dlms_meter component.
  • uart_id (Optional, ID): The ID of the UART component that is connected to the smart meter.
  • decryption_key (Optional, string): Specify if your smart meter uses encryption. You should request this key from your electricity provider (32 hex characters, case-insensitive).
  • auth_key (Optional, string): Authentication key. Specify if your smart meter uses encryption with authentication. You should request this key from your electricity provider. Used for General-GLO-Ciphering and General-DED-Ciphering APDUs.
  • skip_crc (Optional, boolean): Skip CRC check. Some smart meters use the wrong polynomial to calculate CRC. In such cases, you can use this flag as a workaround. Defaults to false.
  • custom_patterns (Optional, list): While the dlms_meter natively supports most devices, some meters use unique payload structures. If your meter’s data isn’t being read correctly, use this field to define a custom AXDR descriptor pattern that tells the system how to parse the incoming data.

All platforms (sensor, text_sensor, binary_sensor) support dynamic mapping using the obis_code property. This allows you to decode nearly any property your meter emits.

  • dlms_meter_id (Optional, ID): Manually specify the ID of the dlms_meter hub if you have multiple.
  • obis_code (Required, string): The OBIS code of the value you want to read. The code supports flexible formats like 1-0:32.7.0 or 1.0.32.7.0.255.

When defining your sensors, it is recommended to include standard ESPHome sensor properties such as unit_of_measurement, accuracy_decimals, device_class, and state_class. The exact configuration will vary depending on the specific value you are reading (e.g., energy vs. power vs. voltage).

Here is an example of how to configure an energy sensor so it displays correctly with Home Assistant’s Energy Dashboard:

sensor:
- platform: dlms_meter
dlms_meter_id: dlms_meter_hub
obis_code: "1.0.1.8.0.255"
name: "Energy Consumed"
unit_of_measurement: "kWh"
accuracy_decimals: 3
device_class: energy
state_class: total_increasing

Before using this method, it is highly recommended to check your meter’s manual or your energy provider’s documentation for a list of supported OBIS codes.

If you are configuring your meter for the first time and do not know which OBIS codes it broadcasts, you can temporarily increase the logging level to VERBOSE. The component will print all successfully parsed OBIS codes and their values to the ESPHome log.

logger:
level: VERBOSE
initial_level: DEBUG
logs:
dlms_meter: VERBOSE

In this configuration, the global level is set to VERBOSE because ESPHome will otherwise exclude lower-severity log messages at compile time (any log message with a lower severity will not be shown).

To prevent your console from being flooded with verbose messages from every component, initial_level restores the standard default of DEBUG dynamically at run time, while the logs mapping manually sets the specific dlms_meter tag to remain at VERBOSE.

WARNING

Increasing the log level severity can impact the performance of your ESP application and increase memory size. Always revert to default log levels for daily use.

TIP

If you are building custom patterns or need to capture the raw hex payload for troubleshooting, change the dlms_meter log level to VERY_VERBOSE. This will output the full raw buffer and the decrypted AXDR payload.

For more details, refer to the Logger Component.

For backwards compatibility, the legacy predefined keys from earlier versions are still fully supported and mapped automatically to their respective OBIS codes. Add only the ones you need. All support standard options from their respective platform domains.

sensor:
- platform: dlms_meter
dlms_meter_id: dlms_meter_hub
voltage_l1:
name: "Voltage Phase 1"
voltage_l2:
name: "Voltage Phase 2"
text_sensor:
- platform: dlms_meter
dlms_meter_id: dlms_meter_hub
meternumber:
name: "Meter Number"

Sensors:

  • voltage_l1 (1.0.32.7.0.255): Voltage Phase 1.
  • voltage_l2 (1.0.52.7.0.255): Voltage Phase 2.
  • voltage_l3 (1.0.72.7.0.255): Voltage Phase 3.
  • current_l1 (1.0.31.7.0.255): Current Phase 1.
  • current_l2 (1.0.51.7.0.255): Current Phase 2.
  • current_l3 (1.0.71.7.0.255): Current Phase 3.
  • active_power_plus (1.0.1.7.0.255): Active power taken from grid.
  • active_power_minus (1.0.2.7.0.255): Active power put into grid.
  • active_energy_plus (1.0.1.8.0.255): Cumulative active energy taken from grid.
  • active_energy_minus (1.0.2.8.0.255): Cumulative active energy exported to grid.
  • reactive_energy_plus (1.0.3.8.0.255): Reactive energy taken from grid.
  • reactive_energy_minus (1.0.4.8.0.255): Reactive energy exported to grid.
  • power_factor (1.0.13.7.0.255): Power factor.

Text Sensors:

  • timestamp (0.0.1.0.0.255): Timestamp included in the received frame.
  • meternumber (0.0.96.1.0.255): Meter number reported by the device.

This example demonstrates how to use the optional configuration variables for encrypted meters or those requiring custom parsing patterns.

dlms_meter:
id: dlms_meter_hub
uart_id: uart_dlms_bus
decryption_key: "00112233445566778899AABBCCDDEEFF"
auth_key: "00112233445566778899AABBCCDDEEFF"
skip_crc: false
custom_patterns:
- pattern: "TO, TV"
name: "flat OBIS + value pairs"
priority: 15
default_obis: "1.0.96.1.0.255"

You can define a custom pattern simply by passing its pattern string, or by defining an object with additional properties:

  • pattern (Required, string): The DSL-based pattern string (e.g., "TO, TV").
  • name (Optional, string): A name for the pattern.
  • priority (Optional, int): The priority of the pattern (lower number is tried first). Defaults to 0.
  • default_obis (Optional, string): The fallback OBIS code to use if the pattern captures no OBIS code. Requires name to be set. Formatted like 1-0:96.1.0 or 1.0.96.1.0.255.

The dlms_meter component loads several built-in patterns by default. Your custom patterns will be evaluated alongside these based on their configured priority.

NamePriorityTypical use
T110class ID, tagged OBIS, scaler, value
T220tagged OBIS, value, scaler-unit structure
T330value first, class ID, scaler-unit, OBIS
ADV40untagged ZPA/Aidon-style layouts

Here are some common structures you might encounter on less standard meters:

dlms_meter:
# ...
custom_patterns:
- pattern: "TC, TO, TDTM"
name: "datetime value"
- pattern: "C, O, A, V, TS, TU"
name: "untagged flat"
- pattern: "TO, TV, S(TS, TU)"
name: "tagged with scaler-unit"
- pattern: "TO, TV"
name: "flat OBIS + value pairs (no scaler)"
- pattern: "L, TSTR"
name: "last element as string"
- pattern: "TOW, TV, TSU"
name: "Landis+Gyr swapped OBIS"
TokenMeaningHex example
Ffirst element guardposition check only
Llast element guardposition check only
Cclass ID, 2-byte uint16 without tag00 03
TCtagged class ID12 00 03
OOBIS code, 6-byte octet string without tag01 00 01 08 00 FF
TOtagged OBIS code09 06 01 00 01 08 00 FF
TOWtagged OBIS with swapped tag bytes06 09 01 00 1F 07 00 FF
Aattribute index, 1-byte uint8 without tag02
TAtagged attribute11 02 or 0F 02
V / TVgeneric value06 00 00 07 A4
TSTRtagged string-like value09 08 38 34 38 39 35 31 32 36
TDTMtagged 12-byte date-time value19 ... or 09 0C ...
TStagged scaler0F FF
TUtagged unit enum16 23
TSUtagged scaler-unit pair02 02 0F FF 16 23
S(x, y, ...)inline sub-structure02 03
DNdescend into nested structurecontrol token
UPreturn from nested structurecontrol token

IMPORTANT

Always check if your meter reading already works natively with the default settings before adding any custom_patterns. The component’s built-in parser handles many standard meters automatically.

Natively Supported (No Custom Configuration Required)

Section titled “Natively Supported (No Custom Configuration Required)”

The vast majority of standard-compliant smart meters are supported right out of the box. If your meter follows the official DLMS specifications, you generally only need to provide the UART pins and your desired OBIS codes.

We have explicitly tested and confirmed native support for standard meters including (but not limited to):

Sagemcom XT211, Energomera, and Kaifa MA304H3E.

Some manufacturers implement the DLMS standard using non-standard object structuring or framing. Below are the tested configuration parameters required for these specific meters:

Salzburg Netz

dlms_meter:
# ...
custom_patterns:
- pattern: "TO, TDTM"
- pattern: "S(TO, TV)"

Iskra 550

dlms_meter:
# ...
custom_patterns:
- pattern: "S(TO, TV)"

Norway HAN (Aidon 1-phase and 3-phase)

dlms_meter:
# ...
custom_patterns:
- pattern: "F, S(TO, TDTM)"
name: "DateTime"
- pattern: "S(TO, TV, TSU)"
name: "Obis-Value-Scaler-Unit"
- pattern: "S(TO, TV)"

Landis+Gyr ZMF100 : This specific meter sends invalid Frame Check Sequences (FCS) and requires skipping the CRC check.

dlms_meter:
# ...
skip_crc: true
custom_patterns:
- pattern: "S(TO, TDTM)"
- pattern: "S(TO, TV)"
- pattern: "TOW, TV, TSU"

Landis+Gyr E450 : This meter uses encryption and requires a decryption key from your provider.

dlms_meter:
# ...
decryption_key: "YOUR_32_CHAR_HEX_KEY"
custom_patterns:
- pattern: "F, TDTM"
name: "DateTime"
- pattern: "TO, TV"
name: "Obis-Value Pair"

Kamstrup Omnipower : This meter uses encryption. Some regional variants also mandate an Authentication Key.

dlms_meter:
# ...
decryption_key: "YOUR_32_CHAR_HEX_KEY"
auth_key: "YOUR_32_CHAR_AUTH_KEY" # Add if required by your provider
custom_patterns:
- pattern: "F, TSTR"
name: "Obis List Ver"
- pattern: "TO, TV"
name: "Code-Value Pair"

Netz NOE P1 (M-Bus) : Requires encryption. The MeterID is untagged and requires a fallback default OBIS mapping.

dlms_meter:
# ...
decryption_key: "YOUR_32_CHAR_HEX_KEY"
custom_patterns:
- pattern: "L, TSTR"
name: "MeterID"
default_obis: "0.0.96.1.0.255"
- pattern: "S(TO, TV, TSU)"
name: "Obis-Value-Scaler-Unit"

(Additional instructions and specific custom_patterns for meters from manufacturers can be added here as users report the specific setups required for their unique smart meter firmware.)