Mijn standaard ESPHome configuratie(s)

Met het plan om een aantal van mijn ESPHome configuraties binnenkort op deze site te publiceren, leek het mij handig om eerst eens wat van mijn standaard configuraties door te nemen. Waarom configureer ik bepaalde zaken standaard zoals ik doe. En wat doen bepaalde onderdelen precies?

De basis configuratie

Omdat ik niet bij elke nieuwe configuratie in ESPhome het wiel opnieuw wil uitvinden, en omdat ik een aantal sensoren standaard tot mijn beschikking wil hebben, begin ik standaard met de volgende configuratie.

Hou hierbij in de gaten dat ESPhome zelf de eerste zaken al aanmaakt, grofweg vanaf esphome: tot en met captive_portal:, waarbij ik wel een aantal zaken aanvul of specifieker maak. Denk aan de naamgeving onder esphome en logger configuratie. Een specifiek eigen stukje dat ik toevoeg is de preferences sectie. In de gevallen waarin dit nodig is, laat ik zaken naar het flash geheugen schrijven. Hierbij treedt een minimaal stukje slijtage op bij iedere schrijfactie. Om deze slijtage te beperken, configureer ik dat slechts eens in de 600s = 10 minuten er een schrijf actie gebeurt.

Voor het inzicht krijgen in de wifi-verbinding heb ik een aantal standaard sensoren die ik gebruik. Hierdoor heb ik zicht op bijvoorbeeld de signaalsterkte, maar ook het IP adres dat is toegekend vanuit het netwerk (DHCP). En omdat ik gebruik maak van meerdere wifi-punten in huis (Mesh), heb ik ook standaard een sensor met het MAC-adres van het wifi-punt waarmee verbonden is.

Tot slot heb ik een aantal standaard schakelaars die ik gebruik. Ééntje om het device een normale restart te geven. Ééntje voor een restart in safe mode, deze kan handig zijn voor als een firmware update structureel niet wil uploaden. Mijn ervaring is dat na een restart in safe mode die standaard geen probleem meer is. Let wel op, een update van de firmware is ook het enige wat dan werkt, al het andere aan sensoren, schakelaars, etc. is uitgeschakeld. Tot slot maak ik een schakelaar aan voor een factory reset, maar houdt deze standaard verborgen. Dit omdat het gebruik nogal impacting is (bijvoorbeeld energietellers gaan terug naar 0).

esphome:
  name: "id-naam"
  friendly_name: "Leesbare naam"
  comment: "Aanvullende info, bijvoorbeeld type stekker"

esp8266:
  board: board-type
  restore_from_flash: true

# Write to flash for setting restore after restart or power cycle
preferences:
  flash_write_interval: 600s                                              # Only per 600s = 10 minutes to reduce flash degradation

# Enable logging
logger:
  baud_rate: 0
  logs:
    component: ERROR                                                      # Avoiding non stop messages in logging. Logging levels: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE

# Enable Home Assistant API
api:
  encryption:
    key: "auto generated key code"

ota:
  - platform: esphome
    password: "auto generated password"

# Configure wifi
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  min_auth_mode: wpa2
  fast_connect: true

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "auto generated ssid"
    password: "auto generated password"

captive_portal:

text_sensor:
  # Wifi text sensors
  - platform: wifi_info
    ip_address:
      id: wifi_ip
      name: "Wifi IP"
      icon: mdi:ip-network-outline
    mac_address:
      id: wifi_mac
      name: "Wifi mac"
      icon: mdi:network-outline
    ssid:
      id: wifi_ssid
      name: "Wifi SSID"
      icon: mdi:access-point-network
    bssid:
      id: wifi_connected
      name: "Wifi AP mac"
      icon: mdi:access-point-network

sensor:
  # Wifi signal strength in db
  - platform: wifi_signal
    id: wifi_signal_db
    name: "Wifi signal"
    icon: mdi:wifi
    update_interval: 300s

  # Wifi signal strength in %
  - platform: copy
    source_id: wifi_signal_db
    name: "Wifi signal strength"
    icon: mdi:wifi-strength-2
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"

  # System uptime sensor
  - platform: uptime
    id: system_uptime
    name: "System uptime"
    icon: mdi:timer-outline
    update_interval: 300s

  binary_sensor:
  # System connection to Home Assistant sensor
  - platform: status
    name: "System status"
    icon: mdi:check-network-outline

switch:
  # Switch to enable restart from Home Assistant
  - platform: restart
    name: "System restart"
    icon: mdi:restart

  # Switch to enable restart in Safe Mode from Home Assistant
  - platform: safe_mode
    name: "System restart in safe mode"
    icon: mdi:lifebuoy

  # Switch to enable restart in Safe Mode from Home Assistant
  - platform: factory_reset
    name: "Factory reset"
    icon: mdi:factory
    disabled_by_default: true

# Time based on SNTP-servers
time:
  - platform: sntp
    id: sntp_time
    update_interval: 6h

web_server:
  port: 80

Met deze basis configuratie begint dus standaard bijna ieder ESPHome project bij mij.

Bij een schakelaar

Bij devices met een schakelaar (bijvoorbeeld slimme stekkers of stekkerdozen) heb ik een aantal zaken die ik standaard configureer. Zo vind ik het prettig om de schakelaar niet alleen te kunnen gebruiken om het aangesloten apparaat aan en uit te kunnen zetten (de standaard functie). Ik breid de schakelaar standaard uit met een dubbel-klIk en een driedubbel-klik functie.

Als voorbeeld; op mijn bureau heb ik een slimme stekkerdoos voor het aan- en uitschakelen van de apparatuur op en rond mijn bureau (één keer klikken). Tegelijkertijd kan ik de slimme verlichting boven het bureau bedienen door een automatisering in Home Assistant die reageert op de dubbel-klik-sensor.

De kop van de configuratie onder esphome heeft hiervoor de uitbreiding nodig met een on_boot deel. De powerbutton configuratie (die verscheelt per device) wordt uitgebreid met een on_multi_click configuratie. En er worden 3 sensoren aangemaakt om de single, double en triple kliks in Home Assistant beschikbaar te maken.

esphome:
  name: "id-naam"
  friendly_name: "Leesbare naam"
  comment: "Aanvullende info, bijvoorbeeld type stekker"
  on_boot:
    - priority: 600
      then:
        # Ensure all click sensors are initially off
        - lambda: id(single_click).publish_state(false);
        - lambda: id(double_click).publish_state(false);
        - lambda: id(triple_click).publish_state(false);

binary_sensor:
- platform: gpio
    id: power_button
    name: "Power button"
    pin:
      number: 3
      mode: INPUT_PULLUP
      inverted: true
    internal: true
    on_multi_click:
      # Single click on the button switches off all relays and usb ports, and triggers single click sensor
      - timing:
          - ON for at most 1s
          - OFF for at least 0.5s
        then:
          - logger.log: "Single-Clicked"
          - if:
              condition:
                and:
                  - light.is_off: the_status_led
                  - switch.is_on: all_grouped
              then:
                - light.turn_on: the_status_led
              else:
                - switch.toggle: all_grouped          
          - lambda: id(single_click).publish_state(true);
          - delay: 2s
          - lambda: id(single_click).publish_state(false);

  - platform: template
    id: single_click
    name: "1. Single click"
    icon: mdi:gesture-double-tap

  - platform: template
    id: double_click
    name: "2. Double click"
    icon: mdi:gesture-double-tap

  - platform: template
    id: triple_click
    name: "3. Triple click"
    icon: mdi:gesture-double-tap

Op de meeste apparaten is in de buurt van de schakelaar ook een status led aanwezig. Hiervoor hanteer ik standaard onderstaande configuratie.

# Status led under the power button
light:
  - platform: status_led
    name: "Status LED"
    id: the_status_led
    icon: mdi:led-outline
    pin:
      inverted: true
      number: GPIO13
    restore_mode: RESTORE_DEFAULT_ON

Met een energiemonitor

Bij heel veel slimme stekkers en stekkerdozen zit tegenwoordig ook een energiemonitor. Hiermee is het gebruik van de apparaten die je hebt aangesloten op de slimmer stekker of stekkerdoos bij te houden. Ook deze configureer ik op een standaard wijze in al mijn ESPHome-apparaten.

De basis configuratie is afhankelijk van het type energie-sensor dat aanwezig is. Dat vraagt vaak de nodige specifieke parameters onder platform:. Daarna configureer ik standaard los, zo compact mogelijk, en alleen als interne sensor (dus niet beschikbaar in Home Assistant) de current (stroom / amperage), voltage (spanning / voltage), power (wattage) en energy (kWh). Onder stroom gelijk een overstroombeveiliging; mocht het stroomverbruik boven de 16A komen, dan wordt er uitgeschakeld.

sensor:
  - platform: power_sensor_type

    current:
      id: current
      internal: true
      on_value_range:
        - above: 16             # Overload protection for above 16A
          then:
            - switch.turn_off: relay

    voltage:
      id: voltage
      internal: true

    power:
      id: power
      internal: true

    energy:
      id: energy
      internal: true

Op basis van bovenstaande sensoren, configureer ik vervolgens de volgende sensoren. Ik trek dit bewust apart in template_sensoren, omdat sommige energiesensoren meerdere keren per seconde metingen doen en doorgeven. Daarbij heb ik ervaren dat dit nogal een overload aan meetwaardes richting Home Assistant kan opleveren.

  - platform: template
    id: current_sensor
    name: "Current"
    icon: mdi:current-ac
    device_class: current
    state_class: measurement
    unit_of_measurement: A
    accuracy_decimals: 2
    update_interval: 30s
    lambda: |-
      return  id(current).state;

  # Voltage sensor
  - platform: template
    id: voltage_sensor
    name: "Voltage"
    icon: mdi:sine-wave
    device_class: voltage
    state_class: measurement
    unit_of_measurement: V
    accuracy_decimals: 2
    update_interval: 30s
    lambda: |-
      return  id(voltage).state;

  # Power sensor
  - platform: template
    id: power_sensor
    name: "Power"
    icon: mdi:lightning-bolt
    device_class: power
    state_class: measurement
    unit_of_measurement: W
    accuracy_decimals: 2
    update_interval: 30s
    # Average usage by plug itself is +/- 1.75W. So if lower then 2W (just to be sure) 0W is reported.
    lambda: |-
      if (id(power).state < 2) {
        return 0;
        } else {
          return  (id(power).state - 1.75);
        }
    # To report if e.g. a washing machine or dishwasher is running, the work in progress sensor is set to active with a load above 3W.
    on_value:
      then:
        - if:
            any:
              # If power sensor is not available (NAN) work in progress is set to off.
              - lambda: 'return isnan(id(power).raw_state);'
              # If power sensor is below 5W (+ 1.75 for plug itself) for more than 5 minutes, work is considered to be done, so work in progress set to off.
              - for:
                  time: 5min
                  condition:
                    lambda: 'return id(power).state < 6.75;'
            then:
              binary_sensor.template.publish:
                id: work_in_progress
                state: off
        - if:
            condition:
              # To prevent work in progress turns on at startup, uptime needs to be at least 5 minutes / 300 seconds.
              lambda: 'return id(power).state > 6.75 && id(system_uptime).state > 300;'
            then:
              binary_sensor.template.publish:
                id: work_in_progress
                state: on

  # Enery sensor
  - platform: template
    id: energy_sensor
    name: "Energy"
    icon: mdi:lightning-bolt-outline
    device_class: energy
    state_class: measurement
    unit_of_measurement: kWh
    accuracy_decimals: 2
    update_interval: 30s
    disabled_by_default: true
    lambda: |-
      return  id(energy).state;

  # Daily energy measurement, resets to zero at 00:00 every day.
  - platform: total_daily_energy
    id: tot_daily_energy
    name: "Total daily energy"
    icon: mdi:counter
    device_class: energy
    state_class: measurement
    unit_of_measurement: kWh
    accuracy_decimals: 2
    disabled_by_default: true
    power_id: power
    filters:
      - multiply: 0.001                                                   # Multiplication factor from W to kW is 0.001
    on_value:
      then:
        # Calculate the difference between last daily energy reading (from global float temp_energy) and current daily_energy.
        - lambda: |-
              float current_energy = id(tot_daily_energy).state;
              
              // At 00:00 total_daily_energy value is reset to 0.
              // If not just reset, add difference between last value (temp_enery) and current (current_energy).
              if (current_energy > id(temp_energy)) {
                id(total_energy) += current_energy - id(temp_energy);
              }
              // If just resetted, add only the current_energy (measured since 00:00), only done once per reset cyclus.
              else {
                id(total_energy) += current_energy;
              }
              id(temp_energy) = current_energy;
              id(total_energy_sensor).update();

  # Total energy measurement sensor (for publishing), value comes from global value.
  - platform: template
    id: total_energy_sensor
    name: "Total energy"
    icon: mdi:counter
    device_class: energy
    state_class: total_increasing
    unit_of_measurement: kWh
    accuracy_decimals: 2
    update_interval: 30s
    lambda: |-
      return id(total_energy);

  # Apparent power sensor, simple P = U * I calculation
  - platform: template
    id: apparent_power
    name: "Apparent power"
    icon: mdi:lightning-bolt-outline
    device_class: energy
    state_class: measurement
    unit_of_measurement: VA
    accuracy_decimals: 2
    update_interval: 30s
    disabled_by_default: true
    lambda: |-
      return id(voltage).state * id(current).state;

  # Power factor sensor, with P / U * I calculation
  - platform: template
    id: power_factor
    name: "Power factor"
    icon: mdi:lightning-bolt-outline
    device_class: energy
    state_class: measurement
    accuracy_decimals: 2
    update_interval: 30s
    disabled_by_default: true
    lambda: |-
      return id(power).state / (id(voltage).state * id(current).state);

Voor het berekenen en opslaan van de totale hoeveelheid energie die er is gebruik via deze stekker of stekkerdoos, wordt gebruik gemaakt van twee globals die ook weggeschreven worden in het flashgeheugen;

globals:
  # Shows the lifetime Energy kWh used by the device, may reset to zero upon firmware updates
  - id: total_energy
    type: float
    restore_value: true
    initial_value: '0.0'

  # Store last daily energy value calculated with
  - id: temp_energy
    type: float
    restore_value: true
    initial_value: '0.0'

In de temp_energy wordt alleen de laatste meetwaarde van de total_daily_energy sensor opgeslagen. Zodra hierop een nieuwe meetwaarde beschikbaar komt, wordt het verschil tussen deze waarde en de temp-waarde berekent. Het verschil tussen deze twee wordt vervolgens opgeteld bij total_energy. Daarmee wordt dat een non-stop doorlopende teller, totdat je eventueel een factory reset uitvoert.

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *

Deze site gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie gegevens worden verwerkt.