ESPHome powered P1 meter

For a long time I was avoiding ESPHome on my esp-based P1 readers. Not that it’s bad, au contraire, I love it. It was my lack of knowledge in getting it to work. I tried it, didn’t work, so I “left it on the shelf”.

Until now …

Esp-link was for me the best way. It’s exactly the same thing as an USB cable, only via tcp. Personally I keep using tcp, as I use dsmr-reader as main logging tool. For many I’ve noticed that Home Assistant is enough (and that’s fine). For those I wanted a better/easier way to connect the reader to Home Assistant.

Luckily an important person within the Home Assistant team pointed to nldroid on GitHub who had it working the way I wanted it the first time. He has made a custom component CustomP1UartComponent. He explained it perfectly and without issues it worked straight away πŸ˜ƒ

You need the library dsmr_p1_sensor.h and the configuration (all documented on his GitHub).

The config yaml:

esphome:
  name: esp_dsmr
  platform: ESP8266
  board: d1_mini
  includes:
    - dsmr_p1_uart.h
  libraries:
    - "Dsmr"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "esp_dsmr_uart Fallback Hotspot"
    password: ""

captive_portal:

# Enable logging
logger:
  level: DEBUG
  esp8266_store_log_strings_in_flash: False

# Enable Home Assistant API
api:
  password: ""

ota:
  password: ""
  
uart:
  - rx_pin: D2
    baud_rate: 115200
    id: uart_bus  

sensor:
  - platform: custom
    lambda: |-
      auto dsmr_p1_sensor = new CustomP1UartComponent(id(uart_bus));
      App.register_component(dsmr_p1_sensor);
      return {dsmr_p1_sensor->s_energy_delivered_tariff1, dsmr_p1_sensor->s_energy_delivered_tariff2, dsmr_p1_sensor->s_energy_returned_tariff1, dsmr_p1_sensor->s_energy_returned_tariff2, dsmr_p1_sensor->s_power_delivered, dsmr_p1_sensor->s_power_returned, dsmr_p1_sensor->s_voltage_l1, dsmr_p1_sensor->s_voltage_l2, dsmr_p1_sensor->s_voltage_l3, dsmr_p1_sensor->s_current_l1, dsmr_p1_sensor->s_current_l2, dsmr_p1_sensor->s_current_l3, dsmr_p1_sensor->s_power_delivered_l1, dsmr_p1_sensor->s_power_delivered_l2, dsmr_p1_sensor->s_power_delivered_l3, dsmr_p1_sensor->s_power_returned_l1, dsmr_p1_sensor->s_power_returned_l2, dsmr_p1_sensor->s_power_returned_l3, dsmr_p1_sensor->s_gas_device_type, dsmr_p1_sensor->s_gas_valve_position, dsmr_p1_sensor->s_gas_delivered};
    sensors:
    - name: "Consumption Low Tarif Sensor"
      unit_of_measurement: kWh
      accuracy_decimals: 3
    - name: "Consumption High Tarif Sensor"
      unit_of_measurement: kWh
      accuracy_decimals: 3  
    - name: "Return Low Tarif Sensor"
      unit_of_measurement: kWh
      accuracy_decimals: 3
    - name: "Return High Tarif Sensor"
      unit_of_measurement: kWh
      accuracy_decimals: 3  
    - name: "Actual Consumption Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Actual Delivery Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Instant Voltage L1 Sensor"
      unit_of_measurement: V
      accuracy_decimals: 3      
    - name: "Instant Voltage L2 Sensor"
      unit_of_measurement: V
      accuracy_decimals: 3      
    - name: "Instant Voltage L3 Sensor"
      unit_of_measurement: V
      accuracy_decimals: 3      
    - name: "Instant Current L1 Sensor"
      unit_of_measurement: A
      accuracy_decimals: 3      
    - name: "Instant Current L2 Sensor"
      unit_of_measurement: A
      accuracy_decimals: 3      
    - name: "Instant Current L3 Sensor"
      unit_of_measurement: A
      accuracy_decimals: 3      
    - name: "Power Delivered L1 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Delivered L2 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Delivered L3 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Returned L1 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Returned L2 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Returned L3 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Gas device type Sensor"
    - name: "Gas valve position Sensor"  
    - name: "Gas Meter M3 Sensor"
      unit_of_measurement: m3
      accuracy_decimals: 3 

Adding TCP server functionality

Ok, it is working perfectly, still I wanted the option to connect via TCP/Telnet. Luckily I had a component seen on GitHub from Oxan van Leeuwen. He made a custom component stream_server.cpp and stream_server.h.

The needed config is shown below:

esphome:
  # ...
  includes:
    - stream_server.h
    - stream_server.cpp

uart:
  id: uart_bus
  #  ...
  
custom_component:
  - lambda: |-
      auto stream_server = new StreamServerComponent(id(uart_bus));
      return {stream_server};

So, can those two be combined?

Yes it can πŸ₯³

I ran in to some “issues”. Like WiFi settings. I wanted it to be plug & play, so no WiFi config and starting with Hotspot. Connect to the Hotspot, and there join it to your own wireless network. The ssid couldn’t be empty, so for formality I entered there “dummy_ssid”. A non existing network. Therefor it wil start automatically the hotspot after several tries (which will fail as the network doesn’t exist).

Update 15 December 2020:

It seems that if you’re not using ssid, but network (with no network defined) that it goes straight into hotspot (jay, success!). Yet now it is not showing the list of scanned networks, only the option to fill in the ssid and password/secret.

The code as it is now:

esphome:
  name: de_slimme_meter
  platform: ESP8266
  board: d1_mini
  includes:
    - dsmr_p1_uart.h
    - stream_server.h
    - stream_server.cpp
  libraries:
    - "Dsmr"

wifi:
  networks:

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "De Slimme Meter"
    password: ""

captive_portal:

web_server:
  port: 80
  
# Enable logging
logger:
  level: DEBUG
  esp8266_store_log_strings_in_flash: False

# Enable Home Assistant API
api:
  password: ""

ota:
  password: ""

uart:
  - rx_pin: D7
    baud_rate: 115200
    id: uart_p1
  - tx_pin: D0
    rx_pin: D1
    baud_rate: 115200

custom_component:
  - lambda: |-
      auto stream_server = new StreamServerComponent(id(uart_p1));
      return {stream_server};

sensor:
  - platform: custom
    lambda: |-
      auto dsmr_p1_sensor = new CustomP1UartComponent(id(uart_p1));
      App.register_component(dsmr_p1_sensor);
      return {dsmr_p1_sensor->s_energy_delivered_tariff1, dsmr_p1_sensor->s_energy_delivered_tariff2, dsmr_p1_sensor->s_energy_returned_tariff1, dsmr_p1_sensor->s_energy_returned_tariff2, dsmr_p1_sensor->s_power_delivered, dsmr_p1_sensor->s_power_returned, dsmr_p1_sensor->s_voltage_l1, dsmr_p1_sensor->s_voltage_l2, dsmr_p1_sensor->s_voltage_l3, dsmr_p1_sensor->s_current_l1, dsmr_p1_sensor->s_current_l2, dsmr_p1_sensor->s_current_l3, dsmr_p1_sensor->s_power_delivered_l1, dsmr_p1_sensor->s_power_delivered_l2, dsmr_p1_sensor->s_power_delivered_l3, dsmr_p1_sensor->s_power_returned_l1, dsmr_p1_sensor->s_power_returned_l2, dsmr_p1_sensor->s_power_returned_l3, dsmr_p1_sensor->s_gas_device_type, dsmr_p1_sensor->s_gas_valve_position, dsmr_p1_sensor->s_gas_delivered};
    sensors:
    - name: "Consumption Low Tarif Sensor"
      unit_of_measurement: kWh
      accuracy_decimals: 3
    - name: "Consumption High Tarif Sensor"
      unit_of_measurement: kWh
      accuracy_decimals: 3  
    - name: "Return Low Tarif Sensor"
      unit_of_measurement: kWh
      accuracy_decimals: 3
    - name: "Return High Tarif Sensor"
      unit_of_measurement: kWh
      accuracy_decimals: 3  
    - name: "Actual Consumption Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Actual Delivery Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Instant Voltage L1 Sensor"
      unit_of_measurement: V
      accuracy_decimals: 3      
    - name: "Instant Voltage L2 Sensor"
      unit_of_measurement: V
      accuracy_decimals: 3      
    - name: "Instant Voltage L3 Sensor"
      unit_of_measurement: V
      accuracy_decimals: 3      
    - name: "Instant Current L1 Sensor"
      unit_of_measurement: A
      accuracy_decimals: 3      
    - name: "Instant Current L2 Sensor"
      unit_of_measurement: A
      accuracy_decimals: 3      
    - name: "Instant Current L3 Sensor"
      unit_of_measurement: A
      accuracy_decimals: 3      
    - name: "Power Delivered L1 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Delivered L2 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Delivered L3 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Returned L1 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Returned L2 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Power Returned L3 Sensor"
      unit_of_measurement: W
      accuracy_decimals: 3      
      filters:
        - multiply: 1000
    - name: "Gas device type Sensor"
    - name: "Gas valve position Sensor"  
    - name: "Gas Meter M3 Sensor"
      unit_of_measurement: m3
      accuracy_decimals: 3

Room for improvement?

Yes there is. At time of writing, the hotspot will start after one minute when it is not connecting to a wireless network. I wish this to be straight away. No minute delay. This I will look into and try to get it done βœ…

Well as of the update of 15 December, it goes straight into hotspot mode, yet without the list of scanned devices. I’ve seen that list and I want that list, so still room for improvement.

Leave a Reply

Your email address will not be published. Required fields are marked *