How to use PZEM004T Energy Monitor with esphome

@sendorm

Addresses of each pzem should be changed manually. Tasmota has a command to do so.

I can make the 3 phase work in Tasmota. (followed this https://zorruno.com/w/EnergyMonitoringPZEM004T) , but I can’t use them in EspHome afterwards…

Can you post your esphome code.

FWWI:

be aware there’s a difference between:
- platform: pzemac

- platform: pzemdc

This works for me:

uart:
  tx_pin: D1
  rx_pin: D2
  baud_rate: 9600
  # stop_bits: 2

sensor:
  - platform: pzemac
    update_interval: 1s
    current:
      name: "${esp_name} A"
      #filters:
      #- calibrate_linear:
      # Map from sensor -> measured value
      #    - 0.0 -> 0.0
      #    - 1.231 -> 2.695
      #    - 1.606 -> 3.651
      #    - 1.928 -> 4.920
    voltage:
      name: "${esp_name} V"
    power:
      name: "${esp_name} W"
      unit_of_measurement: W
      id: "${esp_name}_W"
      icon: mdi:flash-outline
      filters:
       - calibrate_linear:
       # Map from sensor -> measured value
          - 0.0 -> 0.0
          - 256.0 -> 248.0
          - 662.0 -> 642.0
          - 1050.0 -> 1030.0
       - lambda: if (x < 5.0) return 0.0; else return x;
    frequency:
      name: "${esp_name} Hz"
    power_factor:
      name: "${esp_name} Pf"
    energy:
      name: "${esp_name} kWh"
      filters:
        # Multiplication factor from Wh to kWh is 0.001
        - multiply: 0.001
      unit_of_measurement: kWh

My first 3 phase esp works with EspHome :metal:
This is my code

substitutions:
  devicename: smappee_fluvius
  ip: 192.168.xx.xx
  
  ssid: !secret ssid
  password: !secret password
  
esphome:
  name: ${devicename}
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: ${ssid}
  password: ${password}
  power_save_mode: none
  manual_ip:
    static_ip: ${ip}
    gateway: 192.168.79.1
    subnet: 255.255.255.0
    dns1: 8.8.8.8
    dns2: 8.8.4.4

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${devicename}
    password: ${password}
    manual_ip: 
      static_ip: 192.168.100.2
      gateway: 192.168.100.1
      subnet: 255.255.255.0
      dns1: 8.8.8.8
      dns2: 8.8.4.4

captive_portal:

web_server:
  port: 80

debug:

# Enable logging
logger:
  level: DEBUG
  baud_rate: 0

# Enable Home Assistant API
api:
  password: ${password}

ota:
  password: ${password}

uart:
  - id: ubus
    tx_pin: GPIO1
    rx_pin: GPIO3
    baud_rate: 9600
    stop_bits: 1

modbus:
  id: mbus
  uart_id: ubus
  
switch:
  - platform: restart
    name: Smappee fluvius herstarten  
    
sensor:
  - platform: wifi_signal
    name: "WiFi Smappee fluvius"
    update_interval: 60s
    
  - platform: pzemac
    address: 1
    modbus_id: mbus
    current:
      name: "L1 stroom"
    voltage:
      name: "L1 spanning"
    energy:
      name: "L1 verbruik"
    power:
      name: "L1 vermogen"
    frequency:
      name: "L1 frequentie"
    power_factor:
      name: "L1 cos phi"
    update_interval: 2s
  - platform: pzemac
    address: 2
    current:
      name: "L2 stroom"
    voltage:
      name: "L2 spanning"
    energy:
      name: "L2 verbruik"
    power:
      name: "L2 vermogen"
    frequency:
      name: "L2 frequentie"
    power_factor:
      name: "L2 cos phi"
    update_interval: 2s
  - platform: pzemac
    modbus_id: mbus
    address: 3
    current:
      name: "L3 stroom"
    voltage:
      name: "L3 spanning"
    energy:
      name: "L3 verbruik"
    power:
      name: "L3 vermogen"
    frequency:
      name: "L3 frequentie"
    power_factor:
      name: "L3 cos phi"
    update_interval: 2s

I’ve had to add this part

modbus:
  id: mbus
  uart_id: ubus
  
...
sensor:
  - platform: pzemac
    address: 1
    modbus_id: mbus
...

It should be a lot easier if we could set the address in EspHome instead of first flashing the esp with Tasmota -> set address -> reflash esp with EspHome -> :crossed_fingers: it works with EspHome

3 Likes

If you are using Pzem004-T v3, you should connect it to a Pc (using a serial to usb converter) and then use the Peacefair PC software to change pzem address. I used this way with pzem016. Pzem004-T v3 should work in the same way. Look here for pc software:

This software is windows only, I do not have acces anymore to a windows pc.
But I have managed to set the address by first flash an esp as Tasmota and then

Setting Module ID

As well as wiring for multidrop, the devices need to have an ID set (Sometimes referred to as IP address online, but it is a serial address). Tasmota now also allows you to set this easily with the ModuleAddress command- previously this was done with some serial commands (or with windows software linked below, but I tried this unsuccessfully).

To set the address, connect each module one at a time and on the Tasmota console, run eg

                  ModuleAddress 2

You'll get a response to say 'Done', but there is no reply to ensure it is carried out successfully. Obviously, set 1, 2 or 3 as needed but remember to disconnect the others when you set each one.

And then connect them to and esp with esphome flashed

Hey benek984, love what you have done wit the LCD Display, Is it a 2004 with I2C?

Also is it ESPHOME or Arduino Code?,
Could you share your config?

Kind Regards,

This project is not with Esphome but Zigbee. Can be realized in 1 phase version or in three-phase.

2 Likes

Hello,

My Pzem is directly plug into the gpio 14 and 15 of my raspberry (same as the video:link )
the code below don’t work i got the message:

Platform error sensor.pzemac - Integration 'pzemac' not found.
Component error: uart - Integration 'uart' not found.

Have somehone a idea how make this work?

Thanks

Has anybody take a step further and played with appliances classification? Now this is working fine here I was wondering how to automatically identify certain appliances or loads activation and individually monitor their consumption. I’m not the “AI guy” but pretty sure ML can do a good job for that. If anyone can point out a starting point, that would be great.

Hello,
I used your example. All three PZEM-004T(v3.0) changed to Address: 1, 2, 3. But only one checking, not three, Diodes used 1N5819:

Here is my code in esphome:

esphome:
  name: pzem_3phase
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: "******"
  password: "********"
  manual_ip:
    static_ip: 192.168.1.*
    gateway: 192.168.1.1
    subnet: 255.255.255.0

  ap:
    ssid: "Pzem 3Phase Fallback Hotspot"
    password: "euB80xyaDEPM"

captive_portal:

logger:
  #level: VERY_VERBOSE    #too much info for board
  level: DEBUG
  baud_rate: 0  #needs 0, because info & data goes thru one line.

api:
  password: "********"

ota:

web_server:
  port: 80

time:
  - platform: homeassistant
    id: homeassistant_time

uart:
  - id: ubus
    tx_pin: GPIO1  #to RX, doesn't working right now
    rx_pin: GPIO3  #to TX, doesn't working right now
    baud_rate: 9600
    stop_bits: 1

modbus:
  id: mbus
  uart_id: ubus

switch:
  - platform: restart
    name: needs restart 

text_sensor:
  - platform: version
    name: "ESPHome Version"
    hide_timestamp: True

sensor:
  - platform: wifi_signal
    name: "PZEM 3 phase WiFi Signal Sensor"
    update_interval: 60s
    
  - platform: pzemac
    modbus_id: mbus
    voltage:
      name: "PZEM-004T V3 L1 Voltage"
      unit_of_measurement: V
    current:
      name: "PZEM-004T V3 L1 Current"
      unit_of_measurement: A
    energy:
      name: "PZEM-004T V3 L1 Energy"
    power:
      name: "PZEM-004T V3 L1 Power"
      unit_of_measurement: W
    frequency:
      name: "PZEM-004T V3 L1 Frequency"
      unit_of_measurement: hz
    power_factor:
      name: "PZEM-004T V3 L1 Power Factor"
    update_interval: 2s
    address: 1
  - platform: pzemac
    modbus_id: mbus
    voltage:
      name: "PZEM-004T V3 L2 Voltage"
      unit_of_measurement: V
    current:
      name: "PZEM-004T V3 L2 Current"
      unit_of_measurement: A
    energy:
      name: "PZEM-004T V3 L2 Energy"
    power:
      name: "PZEM-004T V3 L2 Power"
      unit_of_measurement: W
    frequency:
      name: "PZEM-004T V3 L2 Frequency"
      unit_of_measurement: hz
    power_factor:
      name: "PZEM-004T V3 L2 Power Factor"
    update_interval: 2s
    address: 2
  - platform: pzemac
    modbus_id: mbus
    voltage:
      name: "PZEM-004T V3 L3 Voltage"
      unit_of_measurement: V
    current:
      name: "PZEM-004T V3 L3 Current"
      unit_of_measurement: A
    energy:
      name: "PZEM-004T V3 L3 Energy"
    power:
      name: "PZEM-004T V3 L3 Power"
      unit_of_measurement: W
    frequency:
      name: "PZEM-004T V3 L3 Frequency"
      unit_of_measurement: hz
    power_factor:
      name: "PZEM-004T V3 L3 Power Factor"
    update_interval: 2s
    address: 3

This is working schematic & code, if someone needs, take a look

I’m not at home now, I’ve use scheme 1 BUT I think you have to use the VU instead of the 3V

Schematic to use is the first, but there is an error in R1 10k placement there:
it must be placed between 3V3 and Node Mcu RX pin.
You placed R1 on D1 catode: this is wrong.
Schematic 2 is totally wrong instead. Is better if you throw it away

PS: you don’t need rs485 converter with pzem 004T.

1 Like

What’s the reporting response time on these with esphome?

Wondering if I could make a automatic sensor to turn on my dust collector. Table saw and other tools draw plent my of power and combined with a relay it could be an awesome solution if quick enough.

Hello,

Thank you, I found it issue. Needed logger to change it to 0:

logger:
  level: DEBUG
  baud_rate: 0

Hello,

one question appear, why these diodes needs, if all have different address?

Is there a way to reset the energy counter of the individual setups?
Also is there a way to find the address of the pzem connected to this?

Copied this code,
Got all three PZEMs (V3’s)addresses through Tasmota ModuleAddress and got “Done” answer from them.
Connected to NodeMCU
Diodes are 1N4148 that I had in hand (Maybe that’s my issue?)
10K resistor between 5v and RX
If I connect more than one PZEM I get
“[modbus:074]: Modbus CRC Check failed!”

Anyone had this issue?
I’ve been at it for days now

Hi, I have done in an other way, maybe this can help you.

First I have found the PZEM04 complete schematic below:

First before connected all RX/TX PZEM04, set the address individually.
I have done with the windows software, one connected at a time, and set a different address

I use one ESP8266, with 4 PZEM04, with following connections:
The GND of ESP8266 and 4 PZEM04 connected together.
The +5V pin of the 4 PZEM04 connected to the ESP8266 3V3.
The TX pin of ESP8266 is connected to the RX 4 PZEM04 together.
The RX pin of ESP8266 is connected to the TX 4 PZEM04 together.

  • this because the TX PZEM04 is Open Collector type
  • but to not overload the TX optocouplers, I remove the R4 and R9 on 3 PZEM04

That works fine for me.
Benefits:

  • The RX signal ESP8266 “voltage low” value is better with this solution. (may reduce CRC Check failed)
  • no need to add external components

Another recommendation:
As the CT is connected to the neutral by the PZEM04, it is better to install the CT on neutral wire.
This because the difference voltage from CT and neutral is near than 0V.
But when installing the CT on live wire, the difference voltage from CT and live is the AC grid voltage.
=> So the risk to make a short circuit live to neutral is bigger
The only protection to prevent it is the plastic insulation of the CT (which is probably not certified for this)

5 Likes

Hi @4xvince, when you say that you have removed the R4 and R9 on 3 PZEM04, you mean that you really removed the R4 and R9 so no connection anymore with TX in that line

option 1

or you have connected directly the 5V to TX with no R4 and R9?

option 2