Using Slimmelezer+ to read data from energy meter Aidon 6534 with communication module 6442SE (swedish branschrekommendation)

Recently setup reading data from the energy meter Aidon 6534 with communication module 6442SE and thought I’d do a write up on the process as it was a bit tricky to solve for this specific meter, that follows the swedish standard HDLC-based “Branschrekommendation 1.2”

I bought the hardware Slimmelezer+

But this does not initially support the format of the data from the Aidon meter. So after looking far and wide on the internet I found a forum where a guy, smarter than me, had solved specifically this problem with the same hardware.

Post:

So, he used a edited version of Forsbergs code:

(I would attach the edited files but cant see that possibility in forum post, sent them to Forsberg and hopefully he might add the to git)

The steps needed to get this to work is listed below:

Using ESPHome integration do the following:

  • Click “+ NEW DEVICE”

  • Give name: p1reader

  • Click “SKIP THIS STEP”

  • Choose ESP8266

  • Click “SKIP”

  • Click “EDIT” -button on your newly created device.

  • Copy and paste the content of edited p1reader.yaml. Wirte over the old content.

  • Click “SAVE”

  • Click “SECRETS” in upper right corner and copy paste content

# ESPHome secrets
wifi_ssid: your_WIFI_SSID
wifi_password: your_WIFI_LÖSEN
fallback_password: choose_FALLBACK_LÖSEN
hass_api_password: choose_API_LÖSEN
ota_password: choose_Over_The_Air_LÖSEN
  • Add your WIFI info and choose passwords for the rest freely.
  • Click “SAVE”
  • Copy edited p1reader.h to ESPHome -catalog on your Home Assistant machine. path: /config/esphome/
  • Connect SlimmeLezer:n to computer with USB-C -cabel. (the computer running the ESPHome browser-window)
  • Click 3 dots on device p1resder and choose “INSTALL”
  • Choose “Plug into this computer”
  • Choose the serieport installed when connecting the SlimmeLezer
    (I actually downloaded the project and used the web-interface to install=

once finished connect Slimmelezer to energy meter and check that it is ONLINE in ESPHome.

  • Go to Home Assistant/Devices & Services och click “+ ADD INTEGRATION” in lower right corner.
  • Search for ESPHome (if it is not automatically detected already)
  • Fill in p1reader.local under HOST. Port should be default, 6053.
  • Fill in API-password you wrote in secrets.

Data should now come in to HA, atleast it did for me.

Hope someone is helped by this, I know I would have been.

1 Like

I have same issue with my ISKRA AM550 meter that uses DLMS/COSEM protocol over DSMR P1 port.
Could you please copy the content of your edited files p1reader.h and p1reader.yaml here?

Otherwise, you could also share them through Google drive or Dropbox…

Thank you

p1reader.h

//-------------------------------------------------------------------------------------
// ESPHome P1 Electricity Meter custom sensor
// Copyright 2020 Pär Svanström
// 
// History
//  0.1.0 2020-11-05:   Initial release
//
// MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
// IN THE SOFTWARE.
//-------------------------------------------------------------------------------------

#include "esphome.h"

#define BUF_SIZE 60

class ParsedMessage {
  public:
    double cumulativeActiveImport;
    double cumulativeActiveExport;

    double cumulativeReactiveImport;
    double cumulativeReactiveExport;

    double momentaryActiveImport;
    double momentaryActiveExport;

    double momentaryReactiveImport;
    double momentaryReactiveExport;

    double momentaryActiveImportL1;
    double momentaryActiveExportL1;

    double momentaryActiveImportL2;
    double momentaryActiveExportL2;

    double momentaryActiveImportL3;
    double momentaryActiveExportL3;

    double momentaryReactiveImportL1;
    double momentaryReactiveExportL1;

    double momentaryReactiveImportL2;
    double momentaryReactiveExportL2;

    double momentaryReactiveImportL3;
    double momentaryReactiveExportL3;

    double voltageL1;
    double voltageL2;
    double voltageL3;

    double currentL1;
    double currentL2;
    double currentL3;
};

class P1Reader : public Component, public UARTDevice {
  char buffer[BUF_SIZE];

  const int8_t OUTSIDE_FRAME = 0;
  const int8_t FOUND_FRAME = 1;


  int8_t parseHDLCState = OUTSIDE_FRAME;

  public:
    Sensor *cumulativeActiveImport = new Sensor();
    Sensor *cumulativeActiveExport = new Sensor();

    Sensor *cumulativeReactiveImport = new Sensor();
    Sensor *cumulativeReactiveExport = new Sensor();

    Sensor *momentaryActiveImport = new Sensor();
    Sensor *momentaryActiveExport = new Sensor();

    Sensor *momentaryReactiveImport = new Sensor();
    Sensor *momentaryReactiveExport = new Sensor();

    Sensor *momentaryActiveImportL1 = new Sensor();
    Sensor *momentaryActiveExportL1 = new Sensor();

    Sensor *momentaryActiveImportL2 = new Sensor();
    Sensor *momentaryActiveExportL2 = new Sensor();

    Sensor *momentaryActiveImportL3 = new Sensor();
    Sensor *momentaryActiveExportL3 = new Sensor();

    Sensor *momentaryReactiveImportL1 = new Sensor();
    Sensor *momentaryReactiveExportL1 = new Sensor();

    Sensor *momentaryReactiveImportL2 = new Sensor();
    Sensor *momentaryReactiveExportL2 = new Sensor();

    Sensor *momentaryReactiveImportL3 = new Sensor();
    Sensor *momentaryReactiveExportL3 = new Sensor();

    Sensor *voltageL1 = new Sensor();
    Sensor *voltageL2 = new Sensor();
    Sensor *voltageL3 = new Sensor();

    Sensor *currentL1 = new Sensor();
    Sensor *currentL2 = new Sensor();
    Sensor *currentL3 = new Sensor();

    P1Reader(UARTComponent *parent) : UARTDevice(parent) {}


    void setup() override {
    }

    void loop() override {
      readHDLCMessage();
    }


  private:
    void parseRow(ParsedMessage* parsed, char* obisCode, double value) {
      //ESP_LOGD("parseRow", "OBIS %s value %f", obisCode, value);
      if (strncmp(obisCode, "1.8.0", 5) == 0) {
        parsed->cumulativeActiveImport = value;
      }
      else if (strncmp(obisCode, "2.8.0", 5) == 0) {
        parsed->cumulativeActiveExport = value;
      }
      else if (strncmp(obisCode, "3.8.0", 5) == 0) {
        parsed->cumulativeReactiveImport = value;
      }
      else if (strncmp(obisCode, "4.8.0", 5) == 0) {
        parsed->cumulativeReactiveExport = value;
      }
      else if (strncmp(obisCode, "1.7.0", 5) == 0) {
        parsed->momentaryActiveImport = value;
      }
      else if (strncmp(obisCode, "2.7.0", 5) == 0) {
        parsed->momentaryActiveExport = value;
      }
      else if (strncmp(obisCode, "3.7.0", 5) == 0) {
        parsed->momentaryReactiveImport = value;
      }
      else if (strncmp(obisCode, "4.7.0", 5) == 0) {
        parsed->momentaryReactiveExport = value;
      }
      else if (strncmp(obisCode, "21.7.0", 6) == 0) {
        parsed->momentaryActiveImportL1 = value;
      }
      else if (strncmp(obisCode, "22.7.0", 6) == 0) {
        parsed->momentaryActiveExportL1 = value;
      }
      else if (strncmp(obisCode, "41.7.0", 6) == 0) {
        parsed->momentaryActiveImportL2 = value;
      }
      else if (strncmp(obisCode, "42.7.0", 6) == 0) {
        parsed->momentaryActiveExportL2 = value;
      }
      else if (strncmp(obisCode, "61.7.0", 6) == 0) {
        parsed->momentaryActiveImportL3 = value;
      }
      else if (strncmp(obisCode, "62.7.0", 6) == 0) {
        parsed->momentaryActiveExportL3 = value;
      }
      else if (strncmp(obisCode, "23.7.0", 6) == 0) {
        parsed->momentaryReactiveImportL1 = value;
      }
      else if (strncmp(obisCode, "24.7.0", 6) == 0) {
        parsed->momentaryReactiveExportL1 = value;
      }
      else if (strncmp(obisCode, "43.7.0", 6) == 0) {
        parsed->momentaryReactiveImportL2 = value;
      }
      else if (strncmp(obisCode, "44.7.0", 6) == 0) {
        parsed->momentaryReactiveExportL2 = value;
      }
      else if (strncmp(obisCode, "63.7.0", 6) == 0) {
        parsed->momentaryReactiveImportL3 = value;
      }
      else if (strncmp(obisCode, "64.7.0", 6) == 0) {
        parsed->momentaryReactiveExportL3 = value;
      }
      else if (strncmp(obisCode, "32.7.0", 6) == 0) {
        parsed->voltageL1 = value;
      }
      else if (strncmp(obisCode, "52.7.0", 6) == 0) {
        parsed->voltageL2 = value;
      }
      else if (strncmp(obisCode, "72.7.0", 6) == 0) {
        parsed->voltageL3 = value;
      }
      else if (strncmp(obisCode, "31.7.0", 6) == 0) {
        parsed->currentL1 = value;
      }
      else if (strncmp(obisCode, "51.7.0", 6) == 0) {
        parsed->currentL2 = value;
      }
      else if (strncmp(obisCode, "71.7.0", 6) == 0) {
        parsed->currentL3 = value;
      }
    }


    void publishSensors(ParsedMessage* parsed) {
      cumulativeActiveImport->publish_state(parsed->cumulativeActiveImport);
      cumulativeActiveExport->publish_state(parsed->cumulativeActiveExport);

      cumulativeReactiveImport->publish_state(parsed->cumulativeReactiveImport);
      cumulativeReactiveExport->publish_state(parsed->cumulativeReactiveExport);

      momentaryActiveImport->publish_state(parsed->momentaryActiveImport);
      momentaryActiveExport->publish_state(parsed->momentaryActiveExport);

      momentaryReactiveImport->publish_state(parsed->momentaryReactiveImport);
      momentaryReactiveExport->publish_state(parsed->momentaryReactiveExport);

      momentaryActiveImportL1->publish_state(parsed->momentaryActiveImportL1);
      momentaryActiveExportL1->publish_state(parsed->momentaryActiveExportL1);

      momentaryActiveImportL2->publish_state(parsed->momentaryActiveImportL2);
      momentaryActiveExportL2->publish_state(parsed->momentaryActiveExportL2);

      momentaryActiveImportL3->publish_state(parsed->momentaryActiveImportL3);
      momentaryActiveExportL3->publish_state(parsed->momentaryActiveExportL3);

      momentaryReactiveImportL1->publish_state(parsed->momentaryReactiveImportL1);
      momentaryReactiveExportL1->publish_state(parsed->momentaryReactiveExportL1);

      momentaryReactiveImportL2->publish_state(parsed->momentaryReactiveImportL2);
      momentaryReactiveExportL2->publish_state(parsed->momentaryReactiveExportL2);

      momentaryReactiveImportL3->publish_state(parsed->momentaryReactiveImportL3);
      momentaryReactiveExportL3->publish_state(parsed->momentaryReactiveExportL3);

      voltageL1->publish_state(parsed->voltageL1);
      voltageL2->publish_state(parsed->voltageL2);
      voltageL3->publish_state(parsed->voltageL3);

      currentL1->publish_state(parsed->currentL1);
      currentL2->publish_state(parsed->currentL2);
      currentL3->publish_state(parsed->currentL3);
    }


    bool readHDLCStruct(ParsedMessage* parsed) {
      if (Serial.readBytes(buffer, 3) != 3)
        return false;

      if (buffer[0] != 0x02) {
        return false;
      }

      char obis[7];

      uint8_t struct_len = buffer[1];
      //ESP_LOGD("hdlc", "Struct length is %d", struct_len);

      uint8_t tag = buffer[2];

      if (tag != 0x09) {
        ESP_LOGE("hdcl", "Unexpected tag %X in struct, bailing out", tag);
        return false;
      }
      
      uint8_t str_length = read();
      if (Serial.readBytes(buffer, str_length) != str_length) {
        ESP_LOGE("hdlc", "Unable to read %d bytes of OBIS code", str_length);
        return false;
      }
      buffer[str_length] = 0; // Null-terminate
      sprintf(obis, "%d.%d.%d", buffer[2], buffer[3], buffer[4]);

      tag = read();

      bool is_signed = false;
      uint32_t uvalue = 0;
      int32_t value = 0;
      if (tag == 0x09) {
        str_length = read();
        if (Serial.readBytes(buffer, str_length) != str_length) {
          ESP_LOGE("hdlc", "Unable to read %d bytes of string", str_length);
          return false;
        }

        buffer[str_length] = 0;
        //ESP_LOGD("hdlc", "Read string length %d", str_length);
      }
      else if(tag == 0x06) {
        Serial.readBytes(buffer, 4);
        uvalue = buffer[3] | buffer[2] << 8 | buffer[1] << 16 | buffer[0] << 24;
        //ESP_LOGD("hdlc", "Value of uvalue is %u", uvalue);
      }
      else if (tag == 0x10) {
        Serial.readBytes(buffer, 2); 
        is_signed = true;
        value = buffer[1] | buffer[0] << 8;
        //ESP_LOGD("hdlc", "(Signed) Value of value is %d", value);
      }
      else if (tag == 0x12) {
        Serial.readBytes(buffer, 2); 
        uvalue = buffer[1] | buffer[0] << 8;
        //ESP_LOGD("hdlc", "(Unsigned) Value of uvalue is %u", uvalue);
      }
      else {
        ESP_LOGE("hdlc", "unknown tag %X", tag);
      }

      int8_t scaler;
      uint8_t unit;
      if (struct_len == 3) {
        Serial.readBytes(buffer, 6);
        scaler = buffer[3];
        unit = buffer[5];
        //ESP_LOGD("hdlc", "Scaler %u", scaler);
        //ESP_LOGD("hdlc", "Unit %d", buffer[5]);

        if (!is_signed) {
          value = uvalue;
        }
        double scaled_value = pow(10, scaler) * value;

        // Report Wh and varh as kWh and kvarh.
        if (unit == 30 || unit == 32) {
          scaled_value = scaled_value / 1000;
        }
        parseRow(parsed, obis, scaled_value);
      }
      return true;
    }


    /* Reads messages formatted according to "Branschrekommendation v1.2", which
       at the time of writing (20210207) is used by Tekniska Verken's Aidon 6442SE
       meters. This is a binary format, with a HDLC Frame. 

       This code is in no way a generic HDLC Frame parser, but it does the job
       of decoding this particular data stream.
    */
    void readHDLCMessage() {
      if (available()) {
        uint8_t data = 0;
        uint16_t crc = 0x0000;
        ParsedMessage parsed = ParsedMessage();

        while (parseHDLCState == OUTSIDE_FRAME) {
          data = read();
          if (data == 0x7e) {
            // ESP_LOGD("hdlc", "Found start of frame");
            parseHDLCState = FOUND_FRAME;
            break;

            int8_t next = peek();

            // ESP_LOGD("hdlc", "Next is %d", next);

            if (next == 0x7e) {
              read(); // We were actually at the end flag, consume the start flag of the next frame.
            }
            else if (next == -1) {
              ESP_LOGE("hdlc", "No char available after flag, out of sync. Returning");
              parseHDLCState = OUTSIDE_FRAME;
              return;
            }
          }
        }

        if (parseHDLCState == FOUND_FRAME) {
          // Read various static HDLC Frame information we don't care about
          int len = Serial.readBytes(buffer, 12);
          if (len != 12) {
            ESP_LOGE("hdlc", "Expected 12 bytes, got %d bytes - out of sync. Returning", len);
            parseHDLCState = OUTSIDE_FRAME;
            return;
          }
          // ESP_LOGD("hdlc", "Got %d HDLC bytes, now reading 4 Invoke ID And Priority bytes", len);          
          len = Serial.readBytes(buffer, 4);
          if (!len == 4 || buffer[0] != 0x40 || buffer[1] != 0x00 || buffer[2] != 0x00 || buffer[3] != 0x00) {
            ESP_LOGE("hdlc", "Expected 0x40 0x00 0x00 0x00, got %X %X %X %X - out of sync, returning.", buffer[0], buffer[1], buffer[2], buffer[3]);
            parseHDLCState = OUTSIDE_FRAME;
            return;
          }
        }

        data = read(); // Expect length of time field, usually 0
        //ESP_LOGD("hdlc", "Length of datetime field is %d", data);
        Serial.readBytes(buffer, data);

        data = read();      
        //ESP_LOGD("hdlc", "Expect 0x01 (array tag), got %02X", data);
        if (data != 0x01) {
          parseHDLCState = OUTSIDE_FRAME;
          return;
        }

        uint8_t array_length = read();
        //ESP_LOGD("hdlc", "Array length is %d", array_length);

        for (int i=0;i<array_length;i++) {
          if (!readHDLCStruct(&parsed)) {
            parseHDLCState = OUTSIDE_FRAME;
            return;
          }
        }

        publishSensors(&parsed);


        while (true) {
          data = read();
          //ESP_LOGD("hdlc", "Read char %02X", data);
          if (data == 0x7e) {
            //ESP_LOGD("hdlc", "Found end of frame");
            parseHDLCState = OUTSIDE_FRAME;
            return;
          }
        }
      }
    }
};

p1reader.yaml

---
substitutions:
  device_name: p1reader
  device_description: "DIY P1 module to read your smart meter"
     
esphome:
  name: ${device_name}
  comment: "${device_description}"
  platform: ESP8266
#  esp8266_restore_from_flash: true
  board: d1_mini
  name_add_mac_suffix: false
  project:
    name: "elt_hack.p1reader"
    version: "0.1"
  includes:
    - p1reader.h

wifi:
  networks:
    - ssid: !secret wifi_ssid
      password: !secret wifi_password
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${device_name}
    ap_timeout: 15s
    password: !secret fallback_password
 
captive_portal:
 
# Enable logging
logger:
#  level: DEBUG
  level: INFO
  baud_rate: 0 # disable logging over uart
#  baud_rate: 9600
 
# Enable Home Assistant API
api:
  password: !secret hass_api_password
 
ota:
  password: !secret ota_password

#web_server:
#  port: 80
 
uart:
  id: uart_bus
  tx_pin: D8
  rx_pin: D7
  baud_rate: 115200
  rx_buffer_size: 256
  data_bits: 8
  parity: NONE
  stop_bits: 1

sensor:
- platform: custom
  lambda: |-
    auto meter_sensor = new P1Reader(id(uart_bus));
    App.register_component(meter_sensor);
    return {
      meter_sensor->cumulativeActiveImport,
      meter_sensor->cumulativeActiveExport,
      meter_sensor->cumulativeReactiveImport,
      meter_sensor->cumulativeReactiveExport,
      meter_sensor->momentaryActiveImport,
      meter_sensor->momentaryActiveExport,
      meter_sensor->momentaryReactiveImport,
      meter_sensor->momentaryReactiveExport,
      meter_sensor->momentaryActiveImportL1,
      meter_sensor->momentaryActiveExportL1,
      meter_sensor->momentaryActiveImportL2,
      meter_sensor->momentaryActiveExportL2,
      meter_sensor->momentaryActiveImportL3,
      meter_sensor->momentaryActiveExportL3,
      meter_sensor->momentaryReactiveImportL1,
      meter_sensor->momentaryReactiveExportL1,
      meter_sensor->momentaryReactiveImportL2,
      meter_sensor->momentaryReactiveExportL2,
      meter_sensor->momentaryReactiveImportL3,
      meter_sensor->momentaryReactiveExportL3,
      meter_sensor->voltageL1,
      meter_sensor->voltageL2,
      meter_sensor->voltageL3,
      meter_sensor->currentL1,
      meter_sensor->currentL2,
      meter_sensor->currentL3
    };

  sensors:
  - name: "Cumulative Active Import"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    state_class: "total_increasing"
    device_class: "energy"

  - name: "Cumulative Active Export"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    state_class: "total_increasing"
    device_class: "energy"

  - name: "Cumulative Reactive Import"
    unit_of_measurement: kvarh
    accuracy_decimals: 3
    state_class: "total_increasing"

  - name: "Cumulative Reactive Export"
    unit_of_measurement: kvarh
    accuracy_decimals: 3
    state_class: "total_increasing"

  - name: "Momentary Active Import"
    unit_of_measurement: W
    accuracy_decimals: 2
    state_class: "measurement"
    device_class: "power"

  - name: "Momentary Active Export"
    unit_of_measurement: W
    accuracy_decimals: 2
    state_class: "measurement"
    device_class: "power"

  - name: "Momentary Reactive Import"
    unit_of_measurement: var
    accuracy_decimals: 2
    state_class: "measurement"

  - name: "Momentary Reactive Export"
    unit_of_measurement: var
    accuracy_decimals: 2
    state_class: "measurement"

  - name: "Momentary Active Import Phase 1"
    unit_of_measurement: W
    accuracy_decimals: 2
    state_class: "measurement"
    device_class: "power"

  - name: "Momentary Active Export Phase 1"
    unit_of_measurement: W
    accuracy_decimals: 2
    state_class: "measurement"
    device_class: "power"

  - name: "Momentary Active Import Phase 2"
    unit_of_measurement: W
    accuracy_decimals: 2
    state_class: "measurement"
    device_class: "power"

  - name: "Momentary Active Export Phase 2"
    unit_of_measurement: W
    accuracy_decimals: 2
    state_class: "measurement"
    device_class: "power"

  - name: "Momentary Active Import Phase 3"
    unit_of_measurement: W
    accuracy_decimals: 2
    state_class: "measurement"
    device_class: "power"

  - name: "Momentary Active Export Phase 3"
    unit_of_measurement: W
    accuracy_decimals: 2
    state_class: "measurement"
    device_class: "power"

  - name: "Momentary Reactive Import Phase 1"
    unit_of_measurement: var
    accuracy_decimals: 2
    state_class: "measurement"

  - name: "Momentary Reactive Export Phase 1"
    unit_of_measurement: var
    accuracy_decimals: 2
    state_class: "measurement"

  - name: "Momentary Reactive Import Phase 2"
    unit_of_measurement: var
    accuracy_decimals: 2
    state_class: "measurement"

  - name: "Momentary Reactive Export Phase 2"
    unit_of_measurement: var
    accuracy_decimals: 2
    state_class: "measurement"

  - name: "Momentary Reactive Import Phase 3"
    unit_of_measurement: var
    accuracy_decimals: 2
    state_class: "measurement"

  - name: "Momentary Reactive Export Phase 3"
    unit_of_measurement: var
    accuracy_decimals: 2
    state_class: "measurement"

  - name: "Voltage Phase 1"
    unit_of_measurement: V
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "voltage"

  - name: "Voltage Phase 2"
    unit_of_measurement: V
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "voltage"

  - name: "Voltage Phase 3"
    unit_of_measurement: V
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "voltage"

  - name: "Current Phase 1"
    unit_of_measurement: A
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "current"

  - name: "Current Phase 2"
    unit_of_measurement: A
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "current"

  - name: "Current Phase 3"
    unit_of_measurement: A
    accuracy_decimals: 1
    state_class: "measurement"
    device_class: "current"

Dear JTech,

I’m following your work and it is really much appreciated. Thank you for sharing.
My aim is to read the 6534. As you suggested, I bought the slimmelezer+.
And now I need your help :grin:
I succeeded to overwrite the provided fw immediately :clap:
Now I trying to implement your codes. The Apr 22 code doesn’t work. I found out that the syntax has been changed (?). The recent code passes the validation, but after the install the slimmelezer hangs :cry:
“error” message:


Can you please suggest ?
rgds

No, Beyond doing exactly the steps i wrote i cant help. I dont know anything else, sorry. I just got this served from someone, Im not familiar with this stuff myself.

Which version of ESPHome did you use / are you using?

Which ever was the current one, on the day of my post, when using it through HomeAssistant. It might be updated since. I’m now on v2022.8.1

I just keep on failing. I’m sure that I do something wrong.
Can’t run the jeelabs esp-link (have tried 2.2.3, 3.0.14, 3.2.47 from github) on the stick following Marcel’s guide neither the precompiled esp-link = fail
Have a spare d1-mini. flashed esp-link on the serial with FTDI chip = fail
Compiled your code on windows = fail
Compiled your code on an rpi running hassos = fail
Interestingly, the latest firmware is running smooth,
integrated in HA seamlessly. However, not powering on on P1.

If you have the time, would it be possible for you to compile it and send the bin file itself to me?
Thank you for your efforts.

Hi,

Have tried to compile with an old esphome version (2022.3) on windows, resulted in the same error like above.
Moreover, I tried to modify the original Forsberg code as it was suggested by skracke, and resulted in the same error.
I’m stuck.

I got this all working using a ESP8266 with a RJ12 cable. No transistors or alike, just cable.


uart:
  id: uart_bus
  rx_pin: 
    number: RX
    inverted: true
    mode:
      input: true
      pullup: true
  rx_buffer_size: 4096
  baud_rate: 115200

Thank you for sharing @ danielholm, I’ll give it a try.

meanwhile, with zero programming skills i managed to get rid of the warning messages.
Can someone please check and confirm that I didn’t mess up the code:

original line in p1reader.h
if (!len == 4 || buffer[0] != 0x40 || buffer[1] != 0x00 || buffer[2] != 0x00 || buffer[3] != 0x00)
edited
if (! ( len == 4 || buffer[0] != 0x40 || buffer[1] != 0x00 || buffer[2] != 0x00 || buffer[3] != 0x00) )

original
char obis[7];
edited
char obis[12];

Beside now I can compile without any warning message, it is still not working. As long as the slimmelezer is connected to a USB psu, it just works fine. As soon as I connect it to the meter, it does not go online. Looks like a power or wiring issue, but there’s 5V1 between leg 1 and 6 on the RJ12. Can someone pls suggest?

Hello, I’ve also been stuck on this @peter.sv .
I get to the part where it won’t connect, getting an error.

INFO Successfully compiled program.
INFO Connecting to <my.local.ip>
ERROR Connecting to <my.local.ip>:8266 failed: [Errno 113] No route to host

And it kinda looks like it has something to do with the port 8266. Because HA uses 8123 and ESPHome uses something that starts with 60**.

Any ideas?

I’ve been using the code that others suggested for Aidon.
Now I can’t connect to it wirelessly anymore and I have no way of changing the code back to the original either :frowning:

Same here.
Tried downloading the code and installing it manually.
Tried correcting code according to danielholm’s post
Tried correcting code according to peter.sv’s post

It just never comes up online again

I think mine is branschstandard 2.0 so it should be able to read i guess, but I really can not get it to work eiter.

Oh, strange. I just tried re-doing everything without any edit. Now the reader is online and I can see values when i check the different enteties. Gonna test it out and then see.

Just getting errors, or managing to set it up but all readings are unknown. If anyone finds a solution let us now :slight_smile:

Let us know your solution. This project is still hanging for me :frowning:

I’ve been hard at work trying to get this thing to work with my Aidon. I can’t get the reads to work, if someone has a solution for code that works with an Aidon that would be much appreciated. I’m stuck after days of working on this thing.

I did find these which might be of help to someone trying to make it work:

I happened to stumble upon this thread while trying to get my SlimmeLezer+ up and running today and after a bunch of Googleing I stumbled up this project

and this issue in particular which is from the creator of the SlimmeLezer

So for anyone that wants to avoid going down the same rabbit hole I went down for a couple of hours I recommend checking that project out first and seeing if that works for you

Best Christmas gift ever !!! :smiley:
By following Gronsak’s advice, I’m happy to report that my slimmelezer is reading values into HA.
Unit: Aidon 6442 S / Tekniska Verken
ESP home: 2022.12.3
Slimmelezer + v1.2 with ESP-12F

  1. download & install Firmware SlimmeLezer (ESPHome 2022.9.4) on Slimmelezer
  2. Adopt slimmelezer into ESP Home.
  3. Copy psvanstrom’s p1reader.h to /config/esphome
  4. edit slimmelezer in ESP Home: paste psvanstrom’s p1reader.yaml
  5. install & run
  6. edit esp-p1reader: in the uart section change
    from
    tx_pin: TX
    rx_pin: RX
    to
    rx_pin: D7

Hereby I’d like to express my gratitude to Marcel Zuidwijk, Pär Svanström and all those people above for your efforts to create such beautiful things.
Merry Christmas & a Happy New Year!