EasyHAN com ESPHome

Boas!

Recentemente adquiri uma EasyHan ao @nikito7 e apesar de funcionar perfeitamente “out of the box” com Tasmota decidi “complicar” e flashar com ESPHome :smiley:

Com ESPHome é, na minha opinião, mais simples de manter e a integração com HA é nativa, sem recurso a MQTT.

Para o fazerem podem usar o yaml disponivel aqui (monofasico).

Caso não saibam como migrar de Tasmota para ESPHome, as instruções estão disponiveis aqui.

Apesar do yaml do @nikito7 funcionar perfeitamente, decidi “simplificar” por retirar o que não precisava (Exportação, Relogio, LP etc) e aumentar o refresh rate ao máximo (neste momento 5s).

Adicionei também uma entidade para o Tempo de Disparo que no meu caso é muito importante. Claro que já o podiam criar como template no HA mas assim é muito mais facil.

Segue o meu yaml atual (WIP)

substitutions:
  dev: EB1
  name: easyhan
  friendly_name: EasyHAN

# interval:
#   - interval: 9s
#     then:
#       - lambda: |-
#           if (id(edpbox_polling).state) {
#               id(edpbox).update();
#           }

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  platform: ESP8266
  board: esp07s # 4MB

  # on_boot:
  #   priority: -500
  #   then:
  #     - delay: 30s
  #     - switch.turn_on: edpbox_polling

wifi:
  output_power: 15db
  #domain: .lan
  use_address: 192.168.1.122
  # fix ota dns error
  reboot_timeout: 10min
  domain: .lan

  ssid: !secret wifi_ssid
  password: !secret wifi_password

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

captive_portal:

web_server:
  local: true

logger:
  level: verbose
#  baud_rate: 0

api:
  reboot_timeout: 45min
  encryption:
    key: "xxx"

ota:
  password: "xxx"

time:
  - platform: homeassistant
    id: esptime

button:
  - platform: restart
    name: "${dev} ESP Restart"
    device_class: restart
    entity_category: diagnostic

# switch:
#   - platform: template
#     name: "${dev} ESP Polling"
#     id: "edpbox_polling"
#     optimistic: yes
#     device_class: switch
#     entity_category: diagnostic

uart:

# esp32 19/18
# esp8266 3/1
# tfreire 14/5

  id: modbus_serial
  rx_pin: 3
  tx_pin: 1
  baud_rate: 9600
  stop_bits: 1
  #stop_bits: 2 # ziv

modbus:
  #flow_control_pin: 5
  id: modbus1
  uart_id: modbus_serial
  send_wait_time: 350ms

modbus_controller:
  - id: edpbox
    update_interval: 5s
    address: 0x1
    command_throttle: 150ms
    setup_priority: -10
    offline_skip_updates: 20

sensor:

  # - platform: adc
  #   # internal VCC esp8266 only
  #   # pin: VCC
  #   pin: A0
  #   filters:
  #     - multiply: 6.3
  #   name: "${dev} Adc Addon"
  #   accuracy_decimals: 3
  #   device_class: voltage
  #   state_class: measurement
  #   update_interval: 11s
  #   entity_category: diagnostic

  - platform: template
    name: "${dev} ESP Free Heap"
    lambda: |-
      int heap = ESP.getFreeHeap();
      return heap / 1024.0;
    unit_of_measurement: "kB"
    icon: mdi:chip
    entity_category: diagnostic

  - platform: wifi_signal
    name: "${dev} ESP Signal"
    unit_of_measurement: "dB"
    entity_category: diagnostic
    device_class: signal_strength

  - platform: uptime
    name: "${dev} ESP Uptime"
    filters:
      - lambda: return x/3600;
    unit_of_measurement: "h"
    accuracy_decimals: 1
    device_class: duration
    entity_category: diagnostic
### ### ###

### Voltage & Current ###

  - platform: modbus_controller
    name: "${dev} Voltage L1"
    address: 0x006C
    unit_of_measurement: "V"
    register_type: read
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
      - multiply: 0.1
    device_class: voltage

  - platform: modbus_controller
    name: "${dev} Current L1"
    address: 0x006D
    unit_of_measurement: "A"
    register_type: read
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
      - multiply: 0.1
    device_class: current

### Active Power & Power Factor ###

  - platform: modbus_controller
    name: "${dev} Active Power Import"
    id: power_import
    address: 0x0079
    register_type: read
    value_type: U_DWORD
    register_count: 1
    response_size: 4
    accuracy_decimals: 0
    device_class: power
    unit_of_measurement: "W"
    on_value:
      then:
        component.update: icp_fire_time

  # - platform: modbus_controller
  #   name: "${dev} Active Power Export"
  #   address: 0x007A
  #   register_type: read
  #   value_type: U_DWORD
  #   register_count: 1
  #   response_size: 4
  #   accuracy_decimals: 0
  #   device_class: power
  #   unit_of_measurement: "W"

  - platform: modbus_controller
    name: "${dev} Power Factor"
    id: power_factor
    address: 0x007B
    unit_of_measurement: ""
    register_type: read
    value_type: U_WORD
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    device_class: power_factor
    on_value:
      then:
        component.update: icp_fire_time

### Frequency ###

  # - platform: modbus_controller
  #   name: "${dev} Frequency"
  #   address: 0x007F
  #   unit_of_measurement: "Hz"
  #   register_type: read
  #   value_type: U_WORD
  #   accuracy_decimals: 1
  #   filters:
  #     - multiply: 0.1
  #   icon: "mdi:pulse"

### Total Energy Tariffs ###

  - platform: modbus_controller
    name: "${dev} T1 Vazio"
    address: 0x0026
    register_type: read
    value_type: U_DWORD
    register_count: 1
    response_size: 4
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    unit_of_measurement: "kWh"
    state_class: total_increasing
    device_class: energy
    skip_updates: 2

  - platform: modbus_controller 
    name: "${dev} T2 Ponta"
    address: 0x0027
    register_type: read
    value_type: U_DWORD
    register_count: 1
    response_size: 4
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    unit_of_measurement: "kWh"
    state_class: total_increasing
    device_class: energy

  - platform: modbus_controller
    name: "${dev} T3 Cheias"
    address: 0x0028
    register_type: read
    value_type: U_DWORD
    register_count: 1
    response_size: 4
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    unit_of_measurement: "kWh"
    state_class: total_increasing
    device_class: energy

### Total Energy ###

  - platform: modbus_controller
    name: "${dev} Import"
    address: 0x0016
    register_type: read
    value_type: U_DWORD
    register_count: 1
    response_size: 4
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    unit_of_measurement: "kWh"
    state_class: total_increasing
    device_class: energy

  # - platform: modbus_controller
  #   name: "${dev} Export"
  #   address: 0x0017
  #   register_type: read
  #   value_type: U_DWORD
  #   register_count: 1
  #   response_size: 4
  #   accuracy_decimals: 3
  #   filters:
  #     - multiply: 0.001
  #   unit_of_measurement: "kWh"
  #   state_class: total_increasing
  #   device_class: energy

### Contract ###

  - platform: modbus_controller
    name: "${dev} Contract T1"
    id: contract_t1
    address: 0x000C
    force_new_range: true
    register_type: read
    value_type: U_DWORD
    register_count: 1
    response_size: 4
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    unit_of_measurement: "kVA"
    state_class: measurement

##ICP Fire Timre

  - platform: template
    name: "${dev} ICP Fire Time"
    id: icp_fire_time
    icon: mdi:clock
    unit_of_measurement: "s"
    device_class: duration
    accuracy_decimals: 0
    #update_interval: 2s
    lambda: |-
          int watts = int(id(power_import).state);
          ESP_LOGD("main", "Watts: %d", watts);
          float pf = float(id(power_factor).state);
          ESP_LOGD("main", "pf: %f", pf);
          float potencia_inst = (watts/pf);
          ESP_LOGD("main", "potencia_inst: %f", potencia_inst);
          float potencia_max_kva = float(id(contract_t1).state)*1000;
          ESP_LOGD("main", "potencia_max_kva: %f", potencia_max_kva);
          int q_factor = 50;
          ESP_LOGD("main", "q_factor: %d", q_factor);
          float k_factor = (120.0/100.0);
          ESP_LOGD("main", "k_factor: %f", k_factor);
          int x = round(q_factor/((potencia_inst/potencia_max_kva)-k_factor));
          ESP_LOGD("main", "x: %d", x);
          if(x > 0 and x < 900) {
              return x;
          } else {
              return 0;
          }
### ### ###

text_sensor:
  # - platform: template
  #   name: "${dev} ESP Clock"
  #   id: esp_clock
  #   icon: mdi:clock
  #   entity_category: diagnostic

###

  # - platform: modbus_controller
  #   name: "${dev} Clock"
  #   register_type: read
  #   address: 0x0001
  #   register_count: 1
  #   response_size: 12
  #   raw_encode: HEXBYTES
  #   icon: mdi:clock
  #   lambda: |-
  #       uint8_t hh=0,mm=0,ss=0;
  #       hh = esphome::modbus_controller::byte_from_hex_str(x,5);
  #       mm = esphome::modbus_controller::byte_from_hex_str(x,6);
  #       ss = esphome::modbus_controller::byte_from_hex_str(x,7);
  #       char buffer[20];
  #       sprintf(buffer,"%02d:%02d:%02d",hh,mm,ss);
  #       return {buffer};
  #   on_value:
  #     - then:
  #       - lambda: |-
  #           char str[25];
  #           time_t currTime = id(esptime).now().timestamp;
  #           strftime(str, sizeof(str), "%H:%M:%S", localtime(&currTime));
  #           id(esp_clock).publish_state({str});

###

  - platform: modbus_controller
    name: "${dev} Tariff"
    register_type: read
    address: 0x000B
    register_count: 1
    response_size: 2
    raw_encode: COMMA
    icon: mdi:counter
    lambda: |-
        auto z = "Null";
        if (x == "1,0") z = "Vazio";
        else if (x == "2,0") z = "Ponta";
        else if (x == "3,0") z = "Cheias";
        return {z};

#######
# eof #
#######

Não sou de todo expert na materia mas creio que com modbus é impossivel ter dados em “real time” e vamos ter sempre de ter um polling rate definido?

2 Curtiram
logger:
  level: verbose
#  baud_rate: 0

Com modbus (pin 1 e 3) tens de ter o baud_rate 0 no logger

  - platform: template
    name: "${dev} ICP Fire Time"
    id: icp_fire_time
    icon: mdi:clock
    unit_of_measurement: "s"
    device_class: duration
    accuracy_decimals: 0

Alternativamente pode ser um template vazio.

E meter o lambda no on_value: dos watts

Alguma ideia de porque isto está com os logs como texto em vez de numerico (com o grafico temporal)?

image

Falta de unidades ou state_class.

    name: "${dev} Power Factor"
    address: 0x007B
    unit_of_measurement: ""
    register_type: read
    value_type: U_WORD
    accuracy_decimals: 3
    filters:
      - multiply: 0.001
    device_class: power_factor
    state_class: measurement

Se não funcionar mete % como unidade.

Por acaso tenho isso no EB3 :sweat_smile:🫣

Confirmo, tá resolvido

O meu até ver esta fixe e a entidade do ICP Trigger parece funcionar perfeitamente


Copyright © 2017-2021. Todos os direitos reservados
CPHA.pt - info@cpha.pt


FAQ | Termos de Serviço/Regras | Política de Privacidade