PZEM_017 using Modbus and USR_DR302

Hi there.
I have a PZEM_017 and using the USR_DR302 I was able to connect from my Windows 10 computer using the oficial software and USR-VCOM.
Now, of course I’m asking here because I need to connect this unit to my Home Assistant.

I’m already using the EPEver Solar Controller with rtuovertcp with another USR_DR302, so I have this configuration:

modbus:
  - name: hub1
    type: rtuovertcp
    host: 172.16.10.98
    port: 8088
    timeout: 2
  - name: hub2
    type: rtuovertcp
    host: 172.16.10.99
    port: 8088
    timeout: 2
  - name: hub3
    type: rtuovertcp
    host: 172.16.10.100
    port: 8088
    timeout: 2

It works fine for my EPEver. This is my modbus.yaml file:

- platform: modbus
  scan_interval: 30
  registers:
    #Solar Registers
    - name: EPEver_Solar_Voltage #3100
      hub: hub1
      unit_of_measurement: V
      slave: 1
      register: 12544
      register_type: input
      scale: 0.01
    - name: EPEver_Solar_Current #3101
      hub: hub1
      unit_of_measurement: A
      slave: 1
      register: 12545
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Solar_Power_Instant #3102
      hub: hub1
      unit_of_measurement: W
      slave: 1
      register: 12546
      register_type: input
      scale: 0.01
      precision: 2
      reverse_order: true
    - name: EPEver_Solar_Status #3201
      hub: hub1
      slave: 1
      register: 12801
      register_type: input
      #Discovered status: 11 == 'Cut Out'
    - name: EPEver_Device_Temperature #3111
      hub: hub1
      unit_of_measurement: °C
      slave: 1
      register: 12561
      register_type: input
      scale: 0.01
      precision: 2
##########################Modbus Config Test for pzem-017##########################
- platform: modbus
  scan_interval: 30
  registers:
    - name: PZEM_Voltage
      unit_of_measurement: V
      slave: 1
      register: 0
      register_type: input
      scale: 0.01
    - name: PZEM_Current
      unit_of_measurement: A
      slave: 1
      register: 1
      register_type: input
      scale: 0.01
      precision: 2
    - name: PZEM_Power_Instant
      unit_of_measurement: W
      slave: 1
      register: 2
      register_type: input
      scale: 0.1
      precision: 1
    - name: PZEM_Energy
      unit_of_measurement: Wh
      slave: 1
      register: 4
      register_type: input
    - name: PZEM_High_Voltage_Alarm_Status
      slave: 1
      register: 6
      register_type: input
    - name: PZEM_Low_Voltage_Alarm_Status
      slave: 1
      register: 7
      register_type: input

Using the EPEver config as example I tried to setup a modbus config for the PZEM-017, and as you can see, I don’t really know anything about modbus nor serial communication, so I’m on a try-and-error manner here, but after spending many hours of my weekend without luck, I stopped and decided to ask for help.

Using a software called Modbus Poll I was able to find that this address works for getting the values of Voltage, Current, Power, Energy, High-Voltage and Low-Voltage from the PZEM-017 with Slave ID: 1.

ModBus_poll

As you can see on the screenshot, I was able to get raw data from the unit, but I’m unable to transform that into something home-assistant will understand.

RTU Request on Modbus Poll

01 04 00 07 00 08 40 0D 

Can anybody help me get this config right? I don’t really know anything about coils or registers. If someone helps me with this, probably many people will benefit from using this configuration. I searched all over the internet and was unable to find how to do this.

This is the error I’m getting on home-assistant logs:

2021-04-19 00:24:26 WARNING (MainThread) [homeassistant.components.modbus.sensor] Sensor configuration is deprecated, will be removed in a future release
2021-04-19 00:24:26 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up modbus platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 205, in _async_setup_platform
    await asyncio.shield(task)
  File "/usr/src/homeassistant/homeassistant/components/modbus/sensor.py", line 178, in async_setup_platform
    hub: ModbusHub = hass.data[MODBUS_DOMAIN][discovery_info[CONF_NAME]]
KeyError: 'modbus_hub'

Here’s the PDF for the PZEM-017 where I found the addresses for voltage, current, power, energy, low-voltage and high-voltage alarms:
https://www.solar-thailand.com/pdf/PZEM-003-Manual.pdf

Thank you!
And if I need to buy a coffee for someone, I’ll be glad to do it, just ask!

1 Like

I found out that my modbus.yaml file was missing the hub: hub3 line on each of my register definitions, so I went and added it, the error on the log went away, but the sensors on developer tools for PZEM are showing empty values.

Here’s my new modbus.yaml file:

- platform: modbus
  scan_interval: 30
  registers:
    #Solar Registers
    - name: EPEver_Solar_Voltage #3100
      hub: hub1
      unit_of_measurement: V
      slave: 1
      register: 12544
      register_type: input
      scale: 0.01
    - name: EPEver_Solar_Current #3101
      hub: hub1
      unit_of_measurement: A
      slave: 1
      register: 12545
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Solar_Power_Instant #3102
      hub: hub1
      unit_of_measurement: W
      slave: 1
      register: 12546
      register_type: input
      scale: 0.01
      precision: 2
      reverse_order: true
    - name: EPEver_Solar_Status #3201
      hub: hub1
      slave: 1
      register: 12801
      register_type: input
      #Discovered status: 11 == 'Cut Out'
    - name: EPEver_Device_Temperature #3111
      hub: hub1
      unit_of_measurement: °C
      slave: 1
      register: 12561
      register_type: input
      scale: 0.01
      precision: 2
    #    - name: EPEver_OverTemp_Inside_Device #2000  # Not available with 3210AN
    #      hub: hub1
    #      slave: 1
    #      register: 8192
    #      register_type: input
    #      scale: 1
    #      precision: 0
    #    - name: EPEver_RealTimeClock #9013   # Not available with 3210AN
    #      hub: hub1
    #      slave: 1
    #      register: 36883
    #      register_type: input
    #    - name: EPEver_Day/Night #200C  # Not available with 3210AN
    #      hub: hub1
    #      slave: 1
    #      register: 8204
    #      register_type: input
    #      scale: 1
    #      precision: 0
    - name: EPEver_Solar_to_Batt_Power_Instant #3106
      hub: hub1
      unit_of_measurement: W
      slave: 1
      register: 12550
      register_type: input
      scale: 0.01
      precision: 2
    #Battery Registers
    - name: EPEver_Battery_Voltage #331A
      hub: hub1
      unit_of_measurement: V
      slave: 1
      register: 13082
      register_type: input
      scale: 0.01
      precision: 2
    - name: "Experimental Battery Charging Amps 4"
      hub: hub1
      unit_of_measurement: A
      slave: 1
      register: 13083
      register_type: input
      scale: 0.01
      precision: 2
      count: 1
      reverse_order: true
    - name: EPEver_Battery_Charging_Current #3105
      hub: hub1
      unit_of_measurement: A
      slave: 1
      register: 12549
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Battery_Temperature #3110
      hub: hub1
      unit_of_measurement: °C
      slave: 1
      register: 12560
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Battery_SOC #311A
      hub: hub1
      unit_of_measurement: "%"
      slave: 1
      register: 12570
      register_type: input
      precision: 2
    - name: EPEver_Battery_Status #3200
      hub: hub1
      slave: 1
      register: 12800
      register_type: input
    - name: EPEver_Max_Battery_Voltage_Today #3302
      hub: hub1
      unit_of_measurement: V
      slave: 1
      register: 13058
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Min_Battery_Voltage_Today #3303
      hub: hub1
      unit_of_measurement: V
      slave: 1
      register: 13059
      register_type: input
      scale: 0.01
      precision: 2
    #Load Registers #Disabled, very imprecise, not useful.
    - name: EPEver_Load_Power #310E
      hub: hub1
      unit_of_measurement: W
      slave: 1
      register: 12558
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Load_Current #310D
      hub: hub1
      unit_of_measurement: A
      slave: 1
      register: 12557
      register_type: input
      scale: 0.01
      precision: 2
    # Generation Reports Registers
    - name: EPEver_Generated_Today #330C
      hub: hub1
      unit_of_measurement: "kWh"
      slave: 1
      register: 13068
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Generated_Month #330E
      hub: hub1
      unit_of_measurement: "kWh"
      slave: 1
      register: 13070
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Generated_Year #3310
      hub: hub1
      unit_of_measurement: "kWh"
      slave: 1
      register: 13072
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Generated_LifeTime #3312
      hub: hub1
      unit_of_measurement: "kWh"
      slave: 1
      register: 13074
      register_type: input
    # Consumtion Reports Registers
    - name: EPEver_Consumed_Energy_Today #3304
      hub: hub1
      unit_of_measurement: "kWh"
      slave: 1
      register: 13060
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Consumed_Energy_Month #3306
      hub: hub1
      unit_of_measurement: "kWh"
      slave: 1
      register: 13062
      register_type: input
      scale: 0.01
      precision: 2
    - name: EPEver_Consumed_Energy_Year #3308
      hub: hub1
      unit_of_measurement: "kWh"
      slave: 1
      register: 13064
      register_type: input
      scale: 0.01
      precision: 2
##########################Modbus Config Test for pzem-017##########################
- platform: modbus
  scan_interval: 30
  registers:
    - name: PZEM_Voltage
      hub: hub3    
      unit_of_measurement: V
      slave: 1
      register: 0
      register_type: input
      scale: 0.01
    - name: PZEM_Current
      hub: hub3    
      unit_of_measurement: A
      slave: 1
      register: 1
      register_type: input
      scale: 0.01
      precision: 2
    - name: PZEM_Power_Instant
      hub: hub3    
      unit_of_measurement: W
      slave: 1
      register: 2
      register_type: input
      scale: 0.1
      precision: 1
    - name: PZEM_Energy
      hub: hub3    
      unit_of_measurement: Wh
      slave: 1
      register: 4
      register_type: input
    - name: PZEM_High_Voltage_Alarm_Status
      hub: hub3    
      slave: 1
      register: 6
      register_type: input
    - name: PZEM_Low_Voltage_Alarm_Status
      hub: hub3    
      slave: 1
      register: 7
      register_type: input

Seems like my mistake was I wasn’t setting the baud rate on the USR_DR302 to 9600, 8 Data Bits, 2 Stop Bits and no Parity. I was using it on default, 115200.
Here’s a picture of how it looks when it’s working with the PZEM_017:

Now I’m having a problem with the values, it’s giving me for Voltage 30,000 instead of the real 23.7v, but at least I have communication.

Finally, here’s the current code, in case someone else’s need to use it with a PZEM meter:

configuration.yaml

# modbus integration section on configuration.yaml
# TCP connection to PZEM-017
modbus:
  - name: PZEM_017
    type: rtuovertcp
    host: 172.16.10.98
    port: 8088
    timeout: 5

modbus.yaml

##########################Modbus Config Test for pzem-017##########################
- platform: modbus
  scan_interval: 10
  registers:
    - name: PZEM_Voltage
      hub: PZEM_017
      unit_of_measurement: V
      slave: 1
      register: 0
      register_type: input
      scale: 0.01
      precision: 2
    - name: PZEM_Current
      hub: PZEM_017
      unit_of_measurement: A
      slave: 1
      register: 1
      register_type: input
      scale: 0.01
      precision: 2
    - name: PZEM_Power_Instant
      hub: PZEM_017
      unit_of_measurement: W
      slave: 1
      register: 2
      register_type: input
      scale: 0.1
      precision: 1
    - name: PZEM_Energy
      hub: PZEM_017
      unit_of_measurement: Wh
      slave: 1
      register: 4
      register_type: input
#    - name: PZEM_High_Voltage_Alarm_Status
#      hub: PZEM_017
#      slave: 1
#      register: 6
#      register_type: input
#    - name: PZEM_Low_Voltage_Alarm_Status
#      hub: PZEM_017
#      slave: 1
#      register: 7
#      register_type: input
1 Like