Aperfeiçoando a Medição de Energia com PZEM no ESPHome

O objetivo deste tópico não é fazer um passo a passo para fazer a integração do PZEM com o ESPHome, mas sim passar informações importantes para quem vem encontrado problemas na integração do PZEM com ESPHome.
Sugiro verificarem outros tópicos para os primeiros passos.

Nas minhas experiências com a medição de energia com PZEM e ESPHome, a partir tutoriais e informações colhidas na internet, me deparei com três problemas importantes:

  1. Não conseguia fazer funcionar consistentemente três PZEM conectados a uma rede modbus (utilizando uma uart), necessário para medição trifásica.
  2. Ocorriam dados espúrios ocasionais durante a energização do PZEM, que apresentavam valores transitórios muito altos que atrapalhavam a totalização de energia a partir da potência.
  3. Quando o PZEM era desenergizado e o ESP8266 continuava ligado (por exemplo quando desligava uma fase) as medições ficavam congeladas no último valor, também atrapalhando a totalização de energia a partir da potência.

Com relação ao primeiro problema, eu vinha utilizando uma configuração com uma rede modbus associada a uma uart com três PZEM. Para isso eu havia trocado o endereço do segundo PZEM para 2 (address = 2) e do terceiro para 3. Configuração encontrada em vários tutoriais.
Desta forma eu só conseguia ler dados consistentes de dois PZEM. Acredito que devido ao tempo de resposta da rede.
Tentei alternativas de hardware encontradas na internet colocando diodos, mas sem sucesso.
Foi então que pensei em fazer três redes modbus, uma para cada PZEM e mantendo o endereço 1 para os três, já que teria um máster para cada PZEM.
Assim, configurei três componentes uart e três redes modbus, cada uma associada a uma uart e configurei três sensores da plataforma pzemac, cada um associado a uma modbus.
Com esta configuração a comunicação ficou consistente e sem falhas.
Eu utilizei 3,3 Vcc para alimentar a interface serial do PZEM e não tive problemas.
Para uma instalação definitiva recomendo alimentar com 5 Vcc e utilizar adaptadores de tensão 5 Vcc / 3.3 Vcc nas linhas RX e TX.

Com relação ao segundo e ao terceiro problema, eu não encontrei uma boa solução via parametrização, então parti para fazer uma alteração no código fonte do sensor pzemac no repositório do ESPHome.
Fiz um fork do repositório original e modifiquei o código no meu repositório.
Criei uma nova variável de configuração chamada update_filter, que define o número de updates válidos para começar a transmitir os dados vindos do modbus e também para começar a transmitir valores zerados quando começar a falhar a resposta do modbus. Desta forma resolvo os dois problemas.
Tive bons resultados com update_filter: 3 e com update_interval: 2s.
O default de update_filter é 0, com este valor o funcionamento fica como anteriormente. Desta forma, se não definir update_filter a integração do pzemac não se altera.
Eu fiz um Pull Request para que esta alteração seja avaliada e implementada no repositório oficial do ESPHome, mas por enquanto é possível utiliza-la via External Components direcionando para o meu repositório.
Se o Pull Request for aceito, bastará remover o external_components do arquivo de configuração.

O meu arquivo de configuração ficou assim:

esphome:
  name: pzem-1
  platform: ESP8266
  board: nodemcuv2

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

  # Habilita "AP (captive portal)" para o caso de falha de conexão no wifi
  ap:
    ssid: "Pzem 1 AP"
    password: !secret ap_password

captive_portal:

# Habilita "ATA"
ota:
  password: !secret ota_password

# Habilita "logging"
logger:

# Habilita Home Assistant API
api:

# Habilita servidor
web_server:
  port: 80

# Usa pzemac do meu repositório no GitHub
external_components:
  - source: github://leofig-rj/esphome@pzemac_update_lf
    components: [ pzemac ]
    refresh: 0s
    
# Sincroniza relógio com o servidor de tempo do Home Assistant
time:
  - platform: homeassistant

# Cria três UARTs, uma para cada MODBUS
uart:
  - id: uart1
    tx_pin: D2
    rx_pin: D1
    baud_rate: 9600
    stop_bits: 1

  - id: uart2
    tx_pin: D4
    rx_pin: D3
    baud_rate: 9600
    stop_bits: 1

  - id: uart3
    tx_pin: D6
    rx_pin: D7
    baud_rate: 9600
    stop_bits: 1

# Cria três redes MODBUS, uma para cada PZEM, usando as UARTs acima.
modbus:
  - id: modbus1
    uart_id: uart1

  - id: modbus2
    uart_id: uart2

  - id: modbus3
    uart_id: uart3

# Cria três sensores PZEM, cada um associado a uma rede MODBUS acima.
sensor:
  # Fase A
  - platform: pzemac
    modbus_id: modbus1
    current:
      name: "PZEM Fase A Corrente"
    voltage:
      name: "PZEM Fase A Tensão"
    energy:
      name: "PZEM Fase A Energia"
      unit_of_measurement: kWh
      accuracy_decimals: 3
      filters:
          - multiply: 0.001
    power:
      name: "PZEM Fase A Potência"
      id: faseAPotencia
    frequency:
      name: "PZEM Fase A Frequência"
    power_factor:
      name: "PZEM Fase A Fator de Potência"
    update_interval: 2s    
    address: 1
    update_filter: 3
    
  # Fase B
  - platform: pzemac
    modbus_id: modbus2
    current:
      name: "PZEM Fase B Corrente"
    voltage:
      name: "PZEM Fase B Tensão"
    energy:
      name: "PZEM Fase B Energia"
      unit_of_measurement: kWh
      accuracy_decimals: 3
      filters:
          - multiply: 0.001
    power:
      name: "PZEM Fase B Potência"
      id: faseBPotencia
    frequency:
      name: "PZEM Fase B Frequência"
    power_factor:
      name: "PZEM Fase B Fator de Potência"
    update_interval: 2s    
    address: 1
    update_filter: 3
    
  # Fase C
  - platform: pzemac
    modbus_id: modbus3
    current:
      name: "PZEM Fase C Corrente"
    voltage:
      name: "PZEM Fase C Tensão"
    energy:
      name: "PZEM Fase C Energia"
      unit_of_measurement: kWh
      accuracy_decimals: 3
      filters:
          - multiply: 0.001
    power:
      name: "PZEM Fase C Potência"
      id: faseCPotencia
    frequency:
      name: "PZEM Fase C Frequência"
    power_factor:
      name: "PZEM Fase C Fator de Potência"
    update_interval: 2s    
    address: 1
    update_filter: 3

  # Total Potência - Calcula a Potência Total das três fases
  - platform: template
    name: "PZEM Total Potência"
    id: totalPotencia
    lambda: return id(faseAPotencia).state + id(faseBPotencia).state + id(faseCPotencia).state;
    accuracy_decimals: 1
    unit_of_measurement: W
    icon: "mdi:flash"
    update_interval: 2s

  # Total Energia Diária - totaliza a Energia Diária total das três fases
  - platform: total_daily_energy
    name: "PZEM Total Energia Diária"
    power_id: totalPotencia
    filters:
      - multiply: 0.001
    accuracy_decimals: 3
    unit_of_measurement: kWh

  # Tensão do ESP8266
  - platform: adc
    pin: VCC
    name: "PZEM ESP Tensão"

# Informa a versão do ESPHome
text_sensor:
  - platform: version
    name: "PZEM ESPHome Versão"
    hide_timestamp: True

# Para resetar o ESP8266
switch:
  - platform: restart
    name: "PZEM ESP Reset"

Espero que essas informações ajudem a obter uma medição de energia mais confiável com PZEM e ESPHome, o resultado que encontrei foi bom.

Aproveito para informar que produzo interruptores WiFi modulares que tem integração nativa com o Home Assistant, o nome é WiLight, caso tenham interesse, verifiquem a integração em WiLight - Home Assistant.

2 Likes