Esphome code, dsmr not working, for unencrypted ascii uart-data using Slimmelezer+

I live in Finland, Tampere region and finally got HAN enabled meter from utility company. Bought Slimmelezer+ several years ago and was hoping to have easy integration to HA. Sadly, DSMR did not work and after few hours of debugging and scratching head, needed just to do all parsing bymyself with own code.

So, if you live in Finland in Tampere region (maybe someone elsewhere in the world can use same code too, let me know!) and you can read unencrypted uart-data, here’s one example of epshome code:


esphome:
  name: slimmelezer
  name_add_mac_suffix: false
  platform: ESP8266
  esp8266_restore_from_flash: true
  board: d1_mini
  project:
    name: nikop.slimmelezer
    version: "2024.11.0"

api:
  encryption:
    key: **your*encryption*key*here*

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: slimmelezer
  manual_ip:
    static_ip: 192.168.1.200
    gateway: 192.168.1.1
    subnet: 255.255.255.0

safe_mode:

captive_portal:

logger:
  baud_rate: 0

ota:
  platform: esphome

dashboard_import:
  package_import_url: github://zuidwijk/dsmr/slimmelezer.yaml@main
  import_full_config: true

web_server:
  port: 80

uart:
  - id: uart_bus
    baud_rate: 115200
    rx_pin: D7
    rx_buffer_size: 1700
    debug:
      direction: RX
      dummy_receiver: true
      after:
        delimiter: "\r\n"
      sequence:
        - lambda: |-
            std::string data(bytes.begin(), bytes.end());

            // Helper function to extract a numeric value safely
            auto extract_value = [&](const std::string& key, float& result) -> bool {
              size_t start = data.find(key + "(");
              if (start == std::string::npos) return false;
              size_t end = data.find(')', start);
              if (end == std::string::npos) return false;
              std::string value_str = data.substr(start + key.length() + 1, end - start - key.length() - 1);
              char* end_ptr;
              result = strtof(value_str.c_str(), &end_ptr);
              return end_ptr != value_str.c_str();  // Ensure valid conversion
            };

            // Helper function to extract a string value
            auto extract_string = [&](const std::string& key, std::string& result) -> bool {
              size_t start = data.find(key + "(");
              if (start == std::string::npos) return false;
              size_t end = data.find(')', start);
              if (end == std::string::npos) return false;
              result = data.substr(start + key.length() + 1, end - start - key.length() - 1);
              return true;
            };

            float value;
            std::string str_value;

            // OBIS codes and sensor publishing
            if (extract_string("0-0:1.0.0", str_value)) {  // Timestamp
              id(timestamp_sensor).publish_state(str_value.c_str());
            }

            if (extract_value("1-0:1.8.0", value)) {  // Active energy import
              id(active_energy_import_sensor).publish_state(value);
            }
            if (extract_value("1-0:2.8.0", value)) {  // Active energy export
              id(active_energy_export_sensor).publish_state(value);
            }
            // OBIS Code: 1-0:1.7.0 (Active power import)
            if (extract_value("1-0:1.7.0", value)) {
              id(active_power_import_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:2.7.0 (Active power export)
            if (extract_value("1-0:2.7.0", value)) {
              id(active_power_export_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:3.7.0 (Reactive power import)
            if (extract_value("1-0:3.7.0", value)) {
              id(reactive_power_import_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:4.7.0 (Reactive power export)
            if (extract_value("1-0:4.7.0", value)) {
              id(reactive_power_export_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:5.7.0 (Apparent power)
            if (extract_value("1-0:5.7.0", value)) {
              id(apparent_power_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:6.7.0 (Active energy)
            if (extract_value("1-0:6.7.0", value)) {
              id(active_energy_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:7.7.0 (Reactive energy)
            if (extract_value("1-0:7.7.0", value)) {
              id(reactive_energy_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:8.7.0 (Apparent energy)
            if (extract_value("1-0:8.7.0", value)) {
              id(apparent_energy_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:9.7.0 (Power factor)
            if (extract_value("1-0:9.7.0", value)) {
              id(power_factor_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:10.7.0 (Voltage L1)
            if (extract_value("1-0:10.7.0", value)) {
              id(voltage_L1_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:11.7.0 (Voltage L2)
            if (extract_value("1-0:11.7.0", value)) {
              id(voltage_L2_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:12.7.0 (Voltage L3)
            if (extract_value("1-0:12.7.0", value)) {
              id(voltage_L3_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:13.7.0 (Current L1)
            if (extract_value("1-0:13.7.0", value)) {
              id(current_L1_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:14.7.0 (Current L2)
            if (extract_value("1-0:14.7.0", value)) {
              id(current_L2_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:15.7.0 (Current L3)
            if (extract_value("1-0:15.7.0", value)) {
              id(current_L3_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:16.7.0 (Power demand)
            if (extract_value("1-0:16.7.0", value)) {
              id(power_demand_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:17.7.0 (Maximum power demand)
            if (extract_value("1-0:17.7.0", value)) {
              id(max_power_demand_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:18.7.0 (Energy import in last 15 minutes)
            if (extract_value("1-0:18.7.0", value)) {
              id(energy_import_15min_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:19.7.0 (Energy export in last 15 minutes)
            if (extract_value("1-0:19.7.0", value)) {
              id(energy_export_15min_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:20.7.0 (Energy import in last 60 minutes)
            if (extract_value("1-0:20.7.0", value)) {
              id(energy_import_60min_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:21.7.0 (Energy export in last 60 minutes)
            if (extract_value("1-0:21.7.0", value)) {
              id(energy_export_60min_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:22.7.0 (Total energy import)
            if (extract_value("1-0:22.7.0", value)) {
              id(total_energy_import_sensor).publish_state(value);
            }

            // OBIS Code: 1-0:23.7.0 (Total energy export)
            if (extract_value("1-0:23.7.0", value)) {
              id(total_energy_export_sensor).publish_state(value);
            }


sensor:
  - platform: template
    name: "Active Energy Import"
    id: active_energy_import_sensor
    unit_of_measurement: "kWh"
    state_class: total
    device_class: energy
    accuracy_decimals: 3

  - platform: template
    name: "Active Energy Export"
    id: active_energy_export_sensor
    unit_of_measurement: "kWh"
    state_class: total
    device_class: energy
    accuracy_decimals: 3

  - platform: template
    name: "Active Power Import"
    id: active_power_import_sensor
    unit_of_measurement: "W"
    accuracy_decimals: 2

  - platform: template
    name: "Active Power Export"
    id: active_power_export_sensor
    unit_of_measurement: "W"
    accuracy_decimals: 2

  - platform: template
    name: "Reactive Power Import"
    id: reactive_power_import_sensor
    unit_of_measurement: "var"
    accuracy_decimals: 2

  - platform: template
    name: "Reactive Power Export"
    id: reactive_power_export_sensor
    unit_of_measurement: "var"
    accuracy_decimals: 2

  - platform: template
    name: "Apparent Power"
    id: apparent_power_sensor
    unit_of_measurement: "VA"
    accuracy_decimals: 2

  - platform: template
    name: "Active Energy"
    id: active_energy_sensor
    unit_of_measurement: "kWh"
    accuracy_decimals: 3

  - platform: template
    name: "Reactive Energy"
    id: reactive_energy_sensor
    unit_of_measurement: "kvarh"
    accuracy_decimals: 3

  - platform: template
    name: "Apparent Energy"
    id: apparent_energy_sensor
    unit_of_measurement: "kVAh"
    accuracy_decimals: 3

  - platform: template
    name: "Power Factor"
    id: power_factor_sensor
    unit_of_measurement: ""
    accuracy_decimals: 2

  - platform: template
    name: "Voltage L1"
    id: voltage_L1_sensor
    unit_of_measurement: "V"
    accuracy_decimals: 2

  - platform: template
    name: "Voltage L2"
    id: voltage_L2_sensor
    unit_of_measurement: "V"
    accuracy_decimals: 2

  - platform: template
    name: "Voltage L3"
    id: voltage_L3_sensor
    unit_of_measurement: "V"
    accuracy_decimals: 2

  - platform: template
    name: "Current L1"
    id: current_L1_sensor
    unit_of_measurement: "A"
    accuracy_decimals: 2

  - platform: template
    name: "Current L2"
    id: current_L2_sensor
    unit_of_measurement: "A"
    accuracy_decimals: 2

  - platform: template
    name: "Current L3"
    id: current_L3_sensor
    unit_of_measurement: "A"
    accuracy_decimals: 2

  - platform: template
    name: "Power Demand"
    id: power_demand_sensor
    unit_of_measurement: "W"
    accuracy_decimals: 2

  - platform: template
    name: "Maximum Power Demand"
    id: max_power_demand_sensor
    unit_of_measurement: "W"
    accuracy_decimals: 2

  - platform: template
    name: "Energy Import in Last 15 Minutes"
    id: energy_import_15min_sensor
    unit_of_measurement: "Wh"
    accuracy_decimals: 2

  - platform: template
    name: "Energy Export in Last 15 Minutes"
    id: energy_export_15min_sensor
    unit_of_measurement: "Wh"
    accuracy_decimals: 2

  - platform: template
    name: "Energy Import in Last 60 Minutes"
    id: energy_import_60min_sensor
    unit_of_measurement: "Wh"
    accuracy_decimals: 2

  - platform: template
    name: "Energy Export in Last 60 Minutes"
    id: energy_export_60min_sensor
    unit_of_measurement: "Wh"
    accuracy_decimals: 2

  - platform: template
    name: "Total Energy Import"
    id: total_energy_import_sensor
    unit_of_measurement: "kWh"
    accuracy_decimals: 3

  - platform: template
    name: "Total Energy Export"
    id: total_energy_export_sensor
    unit_of_measurement: "kWh"
    accuracy_decimals: 3

text_sensor:
  - platform: template
    name: "Timestamp"
    id: timestamp_sensor  
  - platform: wifi_info
    ip_address:
      name: "SlimmeLezer IP Address"
    ssid:
      name: "SlimmeLezer Wi-Fi SSID"
    bssid:
      name: "SlimmeLezer Wi-Fi BSSID"
  - platform: version
    name: "ESPHome Version"
    hide_timestamp: true