/esphome-p1reader

ESPHome custom component for reading P1 data from electricity meters.

Primary LanguageC++MIT LicenseMIT

esphome-p1reader

ESPHome custom component for reading P1 data from electricity meters. Designed for Swedish meters that implement the specification defined in the Swedish Energy Industry Recommendation For Customer Interfaces version 1.3 and above.

ESPHome version

The current version in main is tested with ESPHome version 2023.8.1. Make sure your ESPHome version is up to date if you experience compile problems.

Verified meter hardware / supplier

Note: There's a bug in older E360 firmware, causing it to stop sending out data after a while. Check this comment for more info: #4 (comment)

Warning: Do not confuse KAIFA MA304H4E with MA304H4D as the latter uses M-Bus instead of P1. Apart from being incompatible protocols, M-Bus pin 1 exerts 27V instead of 5V and will fry your P1 equipment.

Hardware

I have used an ESP-12 based NodeMCU for my circuit, another alternative is the cheaper Wemos D1 mini but most ESP-based controllers would probably work. The P1 port on the meter provides 5V up to 250mA which makes it possible to power the circuit directly from the P1 port.

Parts

  • 1 NodeMCU, Wemos D1 mini or equivalent ESP-12 / ESP-32 microcontroller
  • 1 BC547 / 2N3904 NPN transistor
  • 1 4.7kOhm Resistor
  • 1 10kOhm Resistor
  • 1 RJ12 6P6C port
  • 1 RJ12 to RJ12 cable (6 wires)

Wiring

The circuit is very simple, basically the 5V TX output on the P1 connector is converted to 3.3V and inverted by the transistor and connected to the UART0 RX pin on the microcontroller. The RTS (request to send) pin is pulled high so that data is sent continuously and GND and 5V are taken from the P1 connector to drive the microcontroller.

Wiring NodeMCU ESP-12

Wiring Diagram

Wiring Wemos D1 mini

image

Wiring barebone ESP-12 with added voltage regulators and capacitors.

The schematics show a 2SC1815 NPN transistor being used (because that's what I had laying around), will work just fine with either one of the transistors listed under the parts section. Wiring Diagram

PCB and enclosures

Naesstrom

Naesstrom has made a nice PCB layout for the P1 reader using a Wemos D1 mini as the controller along with a 3D printable enclosure.

Check out the PCB here: https://oshwlab.com/Naesstrom/esphome-p1reader and the enclosure here: https://www.thingiverse.com/thing:4961372.

EHjortberg

EHjortberg has made an equally nice PCB layout based on an ESP07 module along with a 3D printable enclosure. Check it out here: https://github.com/ehjortberg/kicad-p1-port-thingie.

Alternate hardware

Since most of the actual specification is, for all practical purposes, identical across Europe/EU (with the exception of Norway) we can use many kinds of different hardware that supports ESPHome and can interface with the P1 port. Both other custom made solutions and some commercial options. The key to using them is to combine them with the code here that handles the Swedish selection of data values sent from the smart meter. The DSMR module in ESPHome follows the Dutch specification for values to be used.

(Finland and Denmark seems to have the exact same configuration as Sweden)

Running on ESP32

The ESP32 requires an external power supply since it cannot be powered by the low amperage available from the P1-port itself. Using the hardware UART on GPIO3 is required.

Use a pull-up resistor (1k) from RXD to 3V3.

uart:
    id: uart_bus
    rx_pin:
      number: GPIO3
      inverted: true
    baud_rate: 115200

image

Image credit: https://github.com/Josverl/micropython-p1meter

Running on SmartyReader P1

Weigu has designed SmartyReader P1 that also can be running with this code and configuration with a few small adaptions.

This hardware runs on ESP8266 Wemos D1 mini pro but with less components.

Basic steps to run this code on SmartyReader P1:

  1. Set the board to Wemos D1 mini pro
board: d1_mini_pro
  1. Adjust the UART section to invert the RX pin (removed TX pin config since it is not used).
uart:
    id: uart_bus
    rx_pin:
      number: 3
      inverted: true
    baud_rate: 115200

Note that the inverted flag is only supported in ESPHome beta as of now. Monitor this PR to follow if it is released to general version. inverted flag feature has been added in ESPHome 2021.12.0 released on 11th December 2021.

Running on Slimmelezer(+)

Marcel Zuidwijk has designed Slimmelezer+ that also can be used with this code and combined with the standard configuration for the Slimmelezer+. (Also the non + version works fine, the software is compatible).

It is designed as a custom board with a P1 interface that is software equivalent with the Wemos D1 Mini.

Basic steps to run this code on the Slimmelezer+:

  1. Set the board to Wemos D1 mini
board: d1_mini
  1. Adjust the UART section to set the rx_pin used by the Slimmelezer
uart:
    id: uart_bus
    baud_rate: 115200
    rx_pin: D7
    rx_buffer_size: 3072    

Sample configuration, uses !secret for all site specific configuration, see below.

Installation

Clone the repository and create a companion secrets.yaml file with the following fields:

Create a companion secrets.yaml file with the following fields:

wifi_ssid: <your wifi SSID>
wifi_password: <your wifi password>
fallback_password: <fallback AP password>
encryption_key: the encryption key shared with HA
ota_password: <The OTA password>

Check the Native API Component chapter of the ESPHome documentation for more info on the encryption key, this page also let you easily generate an encryption key.

Make sure to place the secrets.yaml file in the root path of the cloned project. The fallback_password and ota_password fields can be set to any password before doing the initial upload of the firmware.

If your electricity supplier is using an Aidon 6442SE or Aidon 653X meter, they might still be using the HDLC protocol rather than the ASCII format for the meter data on the P1 port. Use the Sample configuration for HDLC to handle this setup. It configures a different input parser to handle the HDLC protocol.

Prepare the microcontroller with ESPHome before you connect it to the circuit:

  • Install the esphome command line tool
  • Plug in the microcontroller to your USB port and run esphome run p1reader.yaml to flash the firmware
  • Remove the USB connection and connect the microcontroller to the rest of the circuit and plug it into the P1 port.
  • If everything works, your Home Assistant will now auto detect your new ESPHome integration.

You can check the logs by issuing esphome p1reader.yaml logs (or use the super awesome ESPHome dashboard available as a Hass.io add-on or standalone). The logs should output data similar to this every 10 seconds when using DEBUG loglevel:

[18:40:01][D][data:264]: /ELL5\253833635_A
[18:40:01][D][data:264]:
[18:40:01][D][data:264]: 0-0:1.0.0(210217184019W)
[18:40:01][D][data:264]: 1-0:1.8.0(00006678.394*kWh)
[18:40:01][D][data:264]: 1-0:2.8.0(00000000.000*kWh)
[18:40:01][D][data:264]: 1-0:3.8.0(00000021.988*kvarh)
[18:40:01][D][data:264]: 1-0:4.8.0(00001020.971*kvarh)
[18:40:01][D][data:264]: 1-0:1.7.0(0001.727*kW)
[18:40:01][D][data:264]: 1-0:2.7.0(0000.000*kW)
[18:40:01][D][data:264]: 1-0:3.7.0(0000.000*kvar)
[18:40:01][D][data:264]: 1-0:4.7.0(0000.309*kvar)
[18:40:01][D][data:264]: 1-0:21.7.0(0001.023*kW)
[18:40:01][D][data:264]: 1-0:41.7.0(0000.350*kW)
[18:40:01][D][data:264]: 1-0:61.7.0(0000.353*kW)
[18:40:01][D][data:264]: 1-0:22.7.0(0000.000*kW)
[18:40:01][D][data:264]: 1-0:42.7.0(0000.000*kW)
[18:40:01][D][data:264]: 1-0:62.7.0(0000.000*kW)
[18:40:01][D][data:264]: 1-0:23.7.0(0000.000*kvar)
[18:40:01][D][data:264]: 1-0:43.7.0(0000.000*kvar)
[18:40:01][D][data:264]: 1-0:63.7.0(0000.000*kvar)
[18:40:01][D][data:264]: 1-0:24.7.0(0000.009*kvar)
[18:40:01][D][data:264]: 1-0:44.7.0(0000.161*kvar)
[18:40:01][D][data:264]: 1-0:64.7.0(0000.138*kvar)
[18:40:01][D][data:264]: 1-0:32.7.0(240.3*V)
[18:40:01][D][data:264]: 1-0:52.7.0(240.1*V)
[18:40:01][D][data:264]: 1-0:72.7.0(241.3*V)
[18:40:01][D][data:264]: 1-0:31.7.0(004.2*A)
[18:40:01][D][data:264]: 1-0:51.7.0(001.6*A)
[18:40:01][D][data:264]: 1-0:71.7.0(001.7*A)
[18:40:01][D][data:264]: !7945
[18:40:01][I][crc:275]: Telegram read. CRC: 7945 = 7945. PASS = YES

Note that the default is the INFO loglevel since logging affects performance.

The last row contains the CRC check. If you constantly get invalid CRC there might be something wrong with the serial communication.

Technical documentation

Specification overview: https://www.tekniskaverken.se/siteassets/tekniska-verken/elnat/elmatare-och-elanvandning/aidon-rj12-han-interface-v17a.pdf