PZEM-6L24 on esphome

Anybody used PZEM-6L24 on esphome?

Thanks & Regards,

Aslam

Apparently yes according to a search of these forums. Best of luck defining your problem, describing it, and solving it.

Hi @aslu

Very interesting! Can you tell us more? :+1:

We use 6 PZEM… :star2:

I would also like to use a native in yaml input like in the case of pzem-004t

Modbus?

i have the following config.
β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™β€˜β€™
uart:
id: mod_bus
tx_pin: GPIO17 # Adjust to your wiring
rx_pin: GPIO16
baud_rate: 9600
parity: NONE
stop_bits: 1

Modbus RTU

modbus:
id: modbus_hub
uart_id: mod_bus
send_wait_time: 200ms

MODBUS CONTROLLER COMPONENT (THIS WAS MISSING!)

modbus_controller:

  • id: pzem
    modbus_id: modbus_hub
    address: 0x01 # Default slave ID for PZEM
    update_interval: 10s

Sensors using modbus_controller

sensor:

Voltage Phase A

  • platform: modbus_controller
    modbus_controller_id: pzem
    name: β€œVoltage Phase A”
    register_type: holding
    address: 0x0000
    unit_of_measurement: β€œV”
    device_class: voltage
    state_class: measurement
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    • multiply: 0.1

Voltage Phase B

  • platform: modbus_controller
    modbus_controller_id: pzem
    name: β€œVoltage Phase B”
    register_type: holding
    address: 0x0001
    unit_of_measurement: β€œV”
    device_class: voltage
    state_class: measurement
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    • multiply: 0.1

Voltage Phase C

  • platform: modbus_controller
    modbus_controller_id: pzem
    name: β€œVoltage Phase C”
    register_type: holding
    address: 0x0002
    unit_of_measurement: β€œV”
    device_class: voltage
    state_class: measurement
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
    • multiply: 0.1

Current Phase A

  • platform: modbus_controller
    modbus_controller_id: pzem
    name: β€œCurrent Phase A”
    register_type: holding
    address: 0x0003
    unit_of_measurement: β€œA”
    device_class: current
    state_class: measurement
    value_type: U_WORD
    accuracy_decimals: 3
    filters:
    • multiply: 0.001

Current Phase B

  • platform: modbus_controller
    modbus_controller_id: pzem
    name: β€œCurrent Phase B”
    register_type: holding
    address: 0x0004
    unit_of_measurement: β€œA”
    device_class: current
    state_class: measurement
    value_type: U_WORD
    accuracy_decimals: 3
    filters:
    • multiply: 0.001

Current Phase C

  • platform: modbus_controller
    modbus_controller_id: pzem
    name: β€œCurrent Phase C”
    register_type: holding
    address: 0x0005
    unit_of_measurement: β€œA”
    device_class: current
    state_class: measurement
    value_type: U_WORD
    accuracy_decimals: 3
    filters:
    • multiply: 0.001

Total Active Power (32-bit)

  • platform: modbus_controller
    modbus_controller_id: pzem
    name: β€œTotal Active Power”
    register_type: holding
    address: 0x000C
    unit_of_measurement: β€œW”
    device_class: power
    state_class: measurement
    value_type: U_DWORD
    accuracy_decimals: 0

Total Energy (kWh)

  • platform: modbus_controller
    modbus_controller_id: pzem
    name: β€œTotal Energy”
    register_type: holding
    address: 0x0018
    unit_of_measurement: β€œkWh”
    device_class: energy
    state_class: total_increasing
    value_type: U_DWORD
    accuracy_decimals: 3
    filters:
    • multiply: 0.001

and error:

[23:49:50.249][C][mdns:179]: mDNS:
[23:49:50.249][C][mdns:179]: Hostname: pzem-6l24
[23:49:56.665][D][modbus_controller:039]: Modbus command to device=1 register=0x00 no response received - removed from send queue
β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€β€œβ€
Any idea how to fix this?

1 Like

It’s quite problematic; I don’t think it’s possible without lambdas. I’ve reached this stage, but I don’t have the time or energy to refine it. The values are incorrect. A test rig needs to be built to verify this.

uart:
  tx_pin: GPIO3
  rx_pin: GPIO2
  baud_rate: 9600
  data_bits: 8
  parity: NONE
  stop_bits: 1

modbus:
  id: modbus1
  send_wait_time: 200ms

modbus_controller:
  - id: pzem
    address: 0x01
    modbus_id: modbus1
    update_interval: 10s

sensor:
  # Voltage A (register 0x0000) - 1LSB = 0.1V, low byte first - USE FC4 (input registers)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: voltage_A
    name: "Voltage_A"
    address: 0x0000
    register_type: read           # <-- FC4 (input registers)
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "V"
    accuracy_decimals: 1
    lambda: |-
      if (data.size() < 2) return NAN;
      uint16_t raw = (uint8_t)data[0] | ((uint8_t)data[1] << 8); // low byte first
      float volts = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Voltage_A raw=0x%04X (%u) -> %.1f V", raw, raw, volts);
      return volts;

  # Voltage B (register 0x0001)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: voltage_B
    name: "Voltage_B"
    address: 0x0001
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "V"
    accuracy_decimals: 1
    lambda: |-
      if (data.size() < 2) return NAN;
      uint16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float volts = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Voltage_B raw=0x%04X -> %.1f V", raw, volts);
      return volts;

  # Voltage C (register 0x0002)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: voltage_C
    name: "Voltage_C"
    address: 0x0002
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "V"
    accuracy_decimals: 1
    lambda: |-
      if (data.size() < 2) return NAN;
      uint16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float volts = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Voltage_C raw=0x%04X -> %.1f V", raw, volts);
      return volts;

  # Current A (register 0x0003) - 1LSB = 0.01A, low byte first
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: current_A
    name: "Current_A"
    address: 0x0003
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "A"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      uint16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float amps = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Current_A raw=0x%04X -> %.2f A", raw, amps);
      return amps;

  # Current B (register 0x0004)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: current_B
    name: "Current_B"
    address: 0x0004
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "A"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      uint16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float amps = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Current_B raw=0x%04X -> %.2f A", raw, amps);
      return amps;

  # Current C (register 0x0005)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: current_C
    name: "Current_C"
    address: 0x0005
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "A"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      uint16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float amps = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Current_C raw=0x%04X -> %.2f A", raw, amps);
      return amps;

  # Frequency_A (register 0x0006)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: voltage_frequency_A
    name: "Frequency_A"
    address: 0x0006
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "Hz"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float hertz = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Frequency_A raw=0x%04X -> %.2f Hz", raw, hertz);
      return hertz;

  # Frequency_B (register 0x0007)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: voltage_frequency_B
    name: "Frequency_B"
    address: 0x0007
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "Hz"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float hertz = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Frequency_A raw=0x%04X -> %.2f Hz", raw, hertz);
      return hertz;

  # Frequency_C (register 0x0008)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: voltage_frequency_C
    name: "Frequency_C"
    address: 0x0008
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "Hz"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float hertz = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Frequency_A raw=0x%04X -> %.2f Hz", raw, hertz);
      return hertz;

  # Phase_Voltage_B_Relative_to_A (register 0x0009)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: voltage_phase_B
    name: "Voltage_Phase_B"
    address: 0x0009
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "Β°"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float degree = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Phase_B raw=0x%04X -> %.2f Β°", raw, degree);
      return degree;

  # Phase_Voltage_C_Relative_to_A (register 0x000A)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: voltage_phase_C
    name: "Voltage_Phase_C"
    address: 0x000A
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "Β°"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float degree = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Phase_C raw=0x%04X -> %.2f Β°", raw, degree);
      return degree;

  # Phase_Current_A_Relative_to_A_Voltage (register 0x000B)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: current_phase_A
    name: "Current_Phase_A"
    address: 0x000B
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "Β°"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float degree = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Phase_Current_A raw=0x%04X -> %.2f Β°", raw, degree);
      return degree;

# Phase_Current_B_Relative_to_A_Voltage (register 0x000C)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: current_phase_B
    name: "Current_Phase_B"
    address: 0x000C
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "Β°"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float degree = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Phase_Current_B raw=0x%04X -> %.2f Β°", raw, degree);
      return degree;

# Phase_Current_C_Relative_to_A_Voltage (register 0x000D)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: current_phase_C
    name: "Current_Phase_C"
    address: 0x000D
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    unit_of_measurement: "Β°"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int16_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
      float degree = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Phase_Current_C raw=0x%04X -> %.2f Β°", raw, degree);
      return degree;

# Active_Power_A (register 0x000E)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: active_power_A
    name: "Active_Power_A"
    address: 0x000E
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "W"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Active_Power_A raw=0x%04X -> %.2f W", raw, power);
      return power;

# Active_Power_B (register 0x0010)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: active_power_B
    name: "Active_Power_B"
    address: 0x0010
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "W"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Active_Power_B raw=0x%04X -> %.2f W", raw, power);
      return power;

# Active_Power_C (register 0x0012)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: active_power_C
    name: "Active_Power_C"
    address: 0x0012
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "W"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Active_Power_C raw=0x%04X -> %.2f W", raw, power);
      return power;

# Reactive_Power_A (register 0x0014)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: reactive_power_A
    name: "Reactive_Power_A"
    address: 0x0014
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "Var"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Reactive_Power_A raw=0x%04X -> %.2f Var", raw, power);
      return power;

# Reactive_Power_B (register 0x0016)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: reactive_power_B
    name: "Reactive_Power_B"
    address: 0x0016
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "Var"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Reactive_Power_B raw=0x%04X -> %.2f Var", raw, power);
      return power;

# Reactive_Power_C (register 0x0018)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: reactive_power_C
    name: "Reactive_Power_C"
    address: 0x0018
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "Var"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Reactive_Power_C raw=0x%04X -> %.2f Var", raw, power);
      return power;

# Apparent_Power_A (register 0x001A)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: apparent_power_A
    name: "Apparent_Power_A"
    address: 0x001A
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "VA"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Apparent_Power_A raw=0x%04X -> %.2f VA", raw, power);
      return power;

# Apparent_Power_B (register 0x001C)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: apparent_power_B
    name: "Apparent_Power_B"
    address: 0x001C
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "VA"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Apparent_Power_B raw=0x%04X -> %.2f VA", raw, power);
      return power;

# Apparent_Power_C (register 0x001E)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: apparent_power_C
    name: "Apparent_Power_C"
    address: 0x001E
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "VA"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Apparent_Power_C raw=0x%04X -> %.2f VA", raw, power);
      return power;

# Combined_Active_power (register 0x0020)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: combined_active_power
    name: "Combined_Active_Power"
    address: 0x0020
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "W"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Combined_Active_Power raw=0x%04X -> %.2f W", raw, power);
      return power;

# Combined_Reactive_power (register 0x0022)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: combined_reactive_power
    name: "Combined_Reactive_Power"
    address: 0x0022
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "Var"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Combined_Reactive_Power raw=0x%04X -> %.2f Var", raw, power);
      return power;

# Combined_Apparent_power (register 0x0024)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: combined_apparent_power
    name: "Combined_Apparent_Power"
    address: 0x0024
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "VA"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float power = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Combined_Apparent_Power raw=0x%04X -> %.2f VA", raw, power);
      return power;

# Power_Factor_A (register 0x0026)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: power_factor_A
    name: "Power_Factor_A"
    address: 0x0026
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      uint8_t raw = (uint8_t)data[0];
      float powerfactor = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Power_Factor_A raw=0x%04X -> %.2f", raw, powerfactor);
      return powerfactor;

# Power_Factor_B (register 0x0026)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: power_factor_B
    name: "Power_Factor_B"
    address: 0x0026
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      uint8_t raw = (uint8_t)data[1];
      float powerfactor = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Power_Factor_B raw=0x%04X -> %.2f", raw, powerfactor);
      return powerfactor;

# Power_Factor_C (register 0x0027)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: power_factor_C
    name: "Power_Factor_C"
    address: 0x0027
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      uint8_t raw = (uint8_t)data[0];
      float powerfactor = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Power_Factor_C raw=0x%04X -> %.2f", raw, powerfactor);
      return powerfactor;

# Power_Factor_Combined (register 0x0027)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: power_factor_combined
    name: "Power_Factor_Combined"
    address: 0x0027
    register_type: read
    value_type: RAW
    register_count: 1
    force_new_range: true
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      uint8_t raw = (uint8_t)data[1];
      float powerfactor = (float)raw * 0.01f;
      ESP_LOGI("pzem_dbg","Power_Factor_Combined raw=0x%04X -> %.2f", raw, powerfactor);
      return powerfactor;

# Active_Energy_A (register 0x0028)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: active_energy_A
    name: "Active_Energy_A"
    address: 0x0028
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Active_Energy_A raw=0x%04X -> %.2f kWh", raw, energy);
      return energy;

# Active_Energy_B (register 0x002A)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: active_energy_B
    name: "Active_Energy_B"
    address: 0x002A
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Active_Energy_B raw=0x%04X -> %.2f kWh", raw, energy);
      return energy;

# Active_Energy_C (register 0x002C)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: active_energy_C
    name: "Active_Energy_C"
    address: 0x002C
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Active_Energy_C raw=0x%04X -> %.2f kWh", raw, energy);
      return energy;

# Reactive_Energy_A (register 0x002E)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: Reactive_energy_A
    name: "Reactive_Energy_A"
    address: 0x002E
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kVarh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Reactive_Energy_A raw=0x%04X -> %.2f kVarh", raw, energy);
      return energy;

# Reactive_Energy_B (register 0x0030)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: Reactive_energy_B
    name: "Reactive_Energy_B"
    address: 0x0030
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kVarh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Reactive_Energy_B raw=0x%04X -> %.2f kVarh", raw, energy);
      return energy;

# Reactive_Energy_C (register 0x0032)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: Reactive_energy_C
    name: "Reactive_Energy_C"
    address: 0x0032
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kVarh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Reactive_Energy_C raw=0x%04X -> %.2f kVarh", raw, energy);
      return energy;

# Apparent_Energy_A (register 0x0034)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: apparent_energy_A
    name: "Apparent_Energy_A"
    address: 0x0034
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kVAh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Apparent_Energy_A raw=0x%04X -> %.2f kVAh", raw, energy);
      return energy;

# Apparent_Energy_B (register 0x0036)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: apparent_energy_B
    name: "Apparent_Energy_B"
    address: 0x0036
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kVAh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Apparent_Energy_B raw=0x%04X -> %.2f kVAh", raw, energy);
      return energy;

# Apparent_Energy_C (register 0x0038)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: apparent_energy_C
    name: "Apparent_Energy_C"
    address: 0x0038
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kVAh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Apparent_Energy_C raw=0x%04X -> %.2f kVAh", raw, energy);
      return energy;

# Combined_Active_Energy (register 0x003A)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: combined_active_energy
    name: "Combined_Active_Energy"
    address: 0x003A
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "KWh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Combined_Active_Energy raw=0x%04X -> %.2f kWh", raw, energy);
      return energy;

# Combined_Reactive_Energy_A (register 0x003C)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: combined_reactive_energy
    name: "Combined_Reactive_Energy"
    address: 0x003C
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kVarh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Combined_Reactive_Energy raw=0x%04X -> %.2f kVarh", raw, energy);
      return energy;

# Combined_Apparent_Energy (register 0x003E)
  - platform: modbus_controller
    modbus_controller_id: pzem
    id: Combined_Apparent_Energy
    name: "Combined_Apparent_Energy"
    address: 0x003E
    register_type: read
    value_type: RAW
    register_count: 2
    force_new_range: true
    unit_of_measurement: "kVAh"
    accuracy_decimals: 2
    lambda: |-
      if (data.size() < 2) return NAN;
      int32_t raw = (uint16_t)data[0] | ((uint16_t)data[1] << 8) | ((uint16_t)data[2] << 16) | ((uint16_t)data[3] << 24);
      float energy = (float)raw * 0.1f;
      ESP_LOGI("pzem_dbg","Combined_Apparent_Energy raw=0x%04X -> %.2f kVAh", raw, energy);
      return energy;
1 Like

I’m getting the following error. How to fix this?

[11:17:54][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=58 count=2
[11:17:54][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=60 count=2
[11:17:54][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=62 count=2
[11:17:54][D][modbus_controller:039]: Modbus command to device=1 register=0x22 no response received - removed from send queue
[11:17:55][D][modbus_controller:039]: Modbus command to device=1 register=0x24 no response received - removed from send queue
[11:17:57][D][modbus_controller:039]: Modbus command to device=1 register=0x26 no response received - removed from send queue
[11:17:58][D][modbus_controller:039]: Modbus command to device=1 register=0x27 no response received - removed from send queue
[11:17:59][D][modbus_controller:039]: Modbus command to device=1 register=0x28 no response received - removed from send queue
[11:18:00][D][modbus_controller:039]: Modbus command to device=1 register=0x2A no response received - removed from send queue
[11:18:01][D][modbus_controller:039]: Modbus command to device=1 register=0x2C no response received - removed from send queue
[11:18:02][D][modbus_controller:039]: Modbus command to device=1 register=0x2E no response received - removed from send queue
[11:18:03][D][modbus_controller:039]: Modbus command to device=1 register=0x30 no response received - removed from send queue
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=0 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=1 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=2 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=3 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=4 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=5 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=6 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=7 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=8 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=9 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=10 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=11 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=12 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=13 count=1
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=14 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=16 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=18 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=20 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=22 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=24 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=26 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=28 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=30 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=32 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=50 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=52 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=54 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=56 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=58 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=60 count=2
[11:18:04][W][modbus_controller:284]: Duplicate modbus command found: type=0x4 address=62 count=2
[11:18:04][D][modbus_controller:039]: Modbus command to device=1 register=0x32 no response received - removed from send queue
[11:18:05][D][modbus_controller:039]: Modbus command to device=1 register=0x34 no response received - removed from send queue
[11:18:06][D][modbus_controller:039]: Modbus command to device=1 register=0x36 no response received - removed from send queue

I created some helper scripts to use Lucas Hudsons PZEMPlus library with ESP Home. You can find it here: GitHub - p2baron/pzemplus-esphome: ESPHome external component for the PZEM-6L24 three-phase energy meter, using the PZEMPlus library.

1 Like

after trying your scripts i get error:

Compiling .pioenvs/pzem-6l24/src/esphome/components/restart/switch/restart_switch.cpp.o
In file included from src/esphome/components/pzem6l24_plus/pzem6l24_plus.cpp:1:
src/esphome/components/pzem6l24_plus/pzem6l24_plus.h:5:10: fatal error: HardwareSerial.h: No such file or directory

******************************************************************************
* Looking for HardwareSerial.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:HardwareSerial.h"
* Web  > https://registry.platformio.org/search?q=header:%1B%5Bm%1B%5BKHardwareSerial.h
*
******************************************************************************

    5 | #include <HardwareSerial.h>
      |          ^~~~~~~~~~~~~~~~~~
compilation terminated.
*** [.pioenvs/pzem-6l24/src/esphome/components/pzem6l24_plus/pzem6l24_plus.cpp.o] Error 1
========================= [FAILED] Took 168.17 seconds =========================

Any idea how to make it ok?

Modbus?

if you are so smart, please make it work.

This error occurs when the PZEM-6L24 is not supplied with mains voltage.

What board are you using? What happens if you include the hardwareserial library in esp yml?

esp32 c3 mini.
how to include the hardwareserial library in yaml?

I think your trying to compile the idf core and not the Arduino core.

Is this in your yaml?

esp32:
board: esp32-c3-devkitm-1 # replace with your board
framework:
type: arduino

Its my yaml:

esphome:
  name: pzem-6l24
  friendly_name: PZEM-6L24

  libraries:
    - PZEMPlus=https://github.com/lucashudson-eng/PZEMPlus.git

external_components:
  - source:
      type: local
      path: components


esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxx"

ota:
  - platform: esphome
    password: "xxxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  output_power: 8.5dB
  manual_ip:
    static_ip: xxxxxxxxxxx
    gateway: xxxxxxxxxxxxxxxxx
    subnet: 255.255.255.0
    dns1 : 8.8.8.8


  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Pzem-6L24 Fallback Hotspot"
    password: "xxxxxxxxxxxx"

captive_portal:


status_led:
  pin:
    number: GPIO8
    inverted: false

uart:
  tx_pin: 4
  rx_pin: 5
  rx_buffer_size: 512
  baud_rate: 9600
  # parity: NONE
  # data_bits: 8
  # s top_bits: 1
  id: uart_to_modbus

sensor:
  - platform: pzem6l24_plus
    id: pzem1
    address: 1
    rx_pin: 5
    tx_pin: 4
    de_re_pin: -1
    update_interval: 5s

    voltage_a:
      name: "Voltage Phase A"
    voltage_b:
      name: "Voltage Pahse B"
    voltage_c:
      name: "Voltage Pahce C"

    current_a:
      name: "Current A"
    current_b:
      name: "Current B"
    current_c:
      name: "Current C"      

    total_active_power:
      name: "Total Power"

    total_active_energy:
      name: "Total Energy"

And get this:

Compiling .pioenvs/pzem-6l24/lib9c0/PZEMPlus/PZEM003.cpp.o
In file included from .piolibdeps/pzem-6l24/PZEMPlus/src/PZEM003.h:11,
                 from .piolibdeps/pzem-6l24/PZEMPlus/src/PZEM003.cpp:8:
.piolibdeps/pzem-6l24/PZEMPlus/src/RS485.h:12:10: fatal error: SoftwareSerial.h: No such file or directory

************************************************************************
* Looking for SoftwareSerial.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:SoftwareSerial.h"
* Web  > https://registry.platformio.org/search?q=header:SoftwareSerial.h
*
************************************************************************

   12 | #include <SoftwareSerial.h>
      |          ^~~~~~~~~~~~~~~~~~
compilation terminated.
*** [.pioenvs/pzem-6l24/lib9c0/PZEMPlus/PZEM003.cpp.o] Error 1
========================= [FAILED] Took 41.95 seconds =========================
`

Was this yaml AI generated?

Is this question for me?
no, its from esphome new device and from GitHub - p2baron/pzemplus-esphome: ESPHome external component for the PZEM-6L24 three-phase energy meter, using the PZEMPlus library.

Um: GitHub - p2baron/pzemplus-esphome: ESPHome external component for the PZEM-6L24 three-phase energy meter, using the PZEMPlus library.

Known Limitations

Second point:
Not all function’s from Lucas his library are linked. ← this appears to be your problem. Raise a bug report in GitHub and get it fixed or examine the folder structure and copy the appropriate files yourself to there, and compile again. Look for other variants and forks of the code that may be more complete, or fork your own.

Welcome to the world of open source!