No más ropa olvidada: CONVERTÍ MI LAVARROPAS EN INTELIGENTE con Home Assistant!

Casa inteligente Video
No más ropa olvidada: CONVERTÍ MI LAVARROPAS EN INTELIGENTE con Home Assistant!

Tenés un lavarropas común y corriente y te pasa como a mi que lavas y te olvidas sacar la ropa? Seguime que te muestro como!

Entendiendo el comportamiento del lavarropas

Para comprender como es el funcionamiento, me puse a ver el consumo del lavarropa en sus distintos estados (standby, lavado programado, lavando y apagado). Para poder generar dichos estados en Home Assistant, tuve que utilizar un template sensor que, dependiendo el consumo que realiza el lavarropas, identifica los estados. Además, tuve que utilizar un input datetime para guardar la hora de encendido del lavarropas, que sirve para poder diferenciar Standby de Lavado programado. Este input datetime se actualiza mediante esta automatización.

  • Standby: este estado es cuando encendemos el lavarropas y consume menos de 8w durante un periodo menor a 10 minutos, ya que el modelo de mi lavarropas cuando pasan 10 minutos se apaga automáticamente.
  • Lavado programado: cuando el consumo está por debajo de los 8w y ya pasaron 10 minutos de encendido, se considera que está en este estadío esperando a arrancar a lavar.
  • Lavando: acá tuve que hacer algo particular, si bien cuando lava consume más de estos 8w, por momentos el consumo baja este umbral y hacía que cambie de estado a programado mientras lavaba. Para solucionar esto, la condición verifica si el estado anterior es Lavando, si esto es así, continúa con dicho estado. La lógica siempre es que de Lavando pasa a apagado, es raro que cancele un lavado.
  • Apagado: tan simple como que el consumo es 0w.

De paso, guardé algunos atributos para poder hacer troubleshooting más fácilmente y los íconos del template sensor van cambiando dependiendo del estado.

Código - template sensor

template:
  - sensor:
      - name: "Estado Lavarropas"
        unique_id: lavarropas_status
        state: >
          {# Variables #}
          {% set power = states('sensor.lavarropas_power') | float(0) %}
          {% set current_state = states('sensor.lavarropas_status') | default('Apagado') %}
          {% set standby_start =
              states('input_datetime.lavarropas_hora_de_encendido')
              | as_datetime
              | default(now())
              | as_local %}
          {% set minutes_in_standby = (now() - standby_start).total_seconds() / 60 %}

          {# Umbrales #}
          {% set standby_w = 8 %}        {# Consumo máximo para standby/programado #}
          {% set program_delay = 10 %}   {# Minutos para pasar a Lavado programado #}

          {# Logica del estado #}
          {% if power == 0 %}
            Apagado
          {% elif power > standby_w %}
            Lavando
          {% elif 0 < power <= standby_w %}
            {% if current_state == 'Lavando' %}
              Lavando
            {% elif minutes_in_standby < program_delay %}
              Standby
            {% else %}
              Lavado programado
            {% endif %}
          {% endif %}
        attributes:
          current_power: "{{ states('sensor.lavarropas_power') | float(0) }}"
          standby_start_time: "{{ states('input_datetime.lavarropas_hora_de_encendido') }}"
          minutes_in_standby: >
            {% if this.state == 'Apagado' %}
              0
            {% else %}
              {% set ss = states('input_datetime.lavarropas_hora_de_encendido')
                  | as_datetime
                  | default(now())
                  | as_local %}
              {{ (now() - ss).total_seconds() / 60 }}
            {% endif %}
        icon: >
          {% set s = this.state %}
          {% if s == 'Apagado' %}
            mdi:power-plug-off
          {% elif s == 'Standby' %}
            mdi:power-standby
          {% elif s == 'Lavado programado' %}
            mdi:washing-machine-alert
          {% elif s == 'Lavando' %}
            mdi:washing-machine
          {% else %}
            mdi:help-circle
          {% endif %}

Automatización - Guardar hora de encendido

alias: Lavarropas - Guardar hora de encendido
description: ""
triggers:
  - entity_id: sensor.lavarropas_status
    from: Apagado
    to:
      - Standby
      - Lavando
      - Lavado programado
    trigger: state
actions:
  - data:
      datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
    action: input_datetime.set_datetime
    target:
      entity_id: input_datetime.lavarropas_hora_de_encendido
mode: single

Automatizaciones

Acá tengo una lista variada de automatizaciones, algunas relacionadas al lavarropas y el aviso de cuando termina de lavar, y otras para lo que es la automatización de la luz del lavadero.

Aviso de colgar ropa

Para lo que es la notificación recurrente, utilicé un input_boolean que se llama colgar_ropa. Cuando el lavarropas pasa de Lavando a Apagado, cambia el valor a encendido.

Esto lo hago para mantener el estado de colgar_ropa hasta que realmente pase esa acción y desactivar las notificaciones recurrentes con el botón.

Setear colgar ropa despues del lavado

Esta automatización además de cambiar el estado a encendido, hace que el led del pulsador se encienda en color azul:

alias: Setear colgar ropa despues del lavado
description: ""
triggers:
  - trigger: state
    entity_id:
      - sensor.lavarropas_status
    from: Lavando
    to: Apagado
conditions: []
actions:
  - action: input_boolean.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: input_boolean.colgar_ropa
  - action: light.turn_on
    metadata: {}
    data:
      rgb_color:
        - 0
        - 0
        - 255
      brightness_pct: 30
    target:
      entity_id: light.lavadero_led_lavarropas
mode: single

Sonar cuando hay ropa para colgar y entro al lavadero

Esta es la automatización que hace que cada vez que entro al lavadero, suene la melodía de Volver al Futuro y titile el LED.

alias: Sonar cuando hay ropa para colgar y entro al lavadero
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.lavadero_ld2410_presence
    from: "off"
    to: "on"
conditions:
  - condition: state
    entity_id: input_boolean.colgar_ropa
    state: "on"
actions:
  - action: esphome.lavadero_play_song
    metadata: {}
    data: {}
mode: single

Notificacion terminó el lavarropas

Esta automatización es un poco más “compleja” por así decirlo, ya que depende si estoy en casa o no, que notificaciones envía.

Si estoy en casa, cada 10 minutos envía un mensaje a la app de Home Assistant en iOS y además Alexa me notifica lo mismo. Para enviar este tipo de notificaciones utilizo el custom component de Alexa Media Player.

Si no estoy en casa, me manda una notificación a la app de Home Assistant de iOS cada media hora.

alias: Notificacion termino el lavarropas
description: ""
triggers:
  - trigger: state
    entity_id:
      - input_boolean.colgar_ropa
    to: "on"
conditions: []
actions:
  - repeat:
      until:
        - condition: state
          entity_id: input_boolean.colgar_ropa
          state: "off"
      sequence:
        - if:
            - condition: state
              entity_id: person.ezequiel
              state: home
          then:
            - action: notify.mobile_app_itasskkk
              metadata: {}
              data:
                title: Lavarropas
                message: >-
                  Terminó el lavado, andá a colgarla antes que quede arrugada y
                  con olor!
            - action: notify.alexa_media_echo
              metadata: {}
              data:
                message: Pochito, terminó el lavarropas!
            - delay:
                hours: 0
                minutes: 10
                seconds: 0
                milliseconds: 0
          else:
            - repeat:
                until:
                  - condition: zone
                    entity_id: person.ezequiel
                    zone: zone.home
                sequence:
                  - action: notify.mobile_app_itasskkk
                    metadata: {}
                    data:
                      title: Lavarropas
                      message: >-
                        Terminó el lavado, andá a colgarla antes que quede
                        arrugada y con olor!
                  - delay:
                      hours: 0
                      minutes: 30
                      seconds: 0
                      milliseconds: 0
mode: single

Apagar el switch despues de lavar

alias: Apagar switch despues de lavar
description: ""
triggers:
  - trigger: state
    entity_id:
      - sensor.lavarropas_status
    to: Apagado
    for:
      hours: 0
      minutes: 10
      seconds: 0
conditions: []
actions:
  - action: switch.turn_off
    metadata: {}
    data: {}
    target:
      entity_id: switch.lavarropas
mode: single

Enciende la luz del lavadero cuando detecta presencia

Cuando es de noche y detecta que entro al lavadero, enciende la luz.

alias: Encende la luz del lavadero cuando detecte presencia
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.lavadero_ld2410_presence
    from: "off"
    to: "on"
conditions:
  - condition: sun
    before: sunrise
    after: sunset
    enabled: false
actions:
  - action: light.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: light.lavadero_lavadero
mode: single

Apaga la luz del lavadero cuando no hay nadie

No hay mucha más complejidad en esta automatización, espera 2 minutos luego de cambiar el estado de Detected a Clear para apagar la luz.

alias: Apaga la luz del lavadero cuando no hay nadie
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.lavadero_ld2410_presence
    from: "on"
    to: "off"
    for:
      hours: 0
      minutes: 2
      seconds: 0
conditions: []
actions:
  - action: light.turn_off
    metadata: {}
    data: {}
    target:
      entity_id: light.lavadero_lavadero
mode: single

Dispositivo con ESPHome

Para este proyecto, utilicé un ESP32-C6-Zero. Es un microcontrolador bastante potente, soporta WiFi 6, Bluetooth 5 y soporta el estándar IEEE 802.15.4 - Zigbee 3.0/Thread. Les comparto el link del fabricante para más info.

Si lo comparamos con el ESP32 más comun que conocemos es muchísimo más chico, casi del tamaño de una moneda:

Comparativa entre un NodeMCU ESP32-WROOM-32 y el Waveshare ESP32-C6-Zero

Componentes

En el microcontrolador utilicé:

  • Modulo doble de relays (para la luz del lavadero y del pasillo)
  • Botón pulsador rojo (puede ser cualquier boton)
  • LED RGB
  • Buzzer (usé uno típico de PC)
  • Resistencias 220 Ohms para el LED RGB (1 en cada paga de los colores)
  • Transistor 2N2222 (para potenciar el sonido del buzzer)
  • Resistencia de 1k Ohms (conectada a la pata base del transistor)
  • 2 switches típicos de electricidad para controlar los relays de las luces

El PCB que usé es una típica placa de desarrollo que se puede cortar a gusto.

Esquema de conexión

ESPHome 01

Como hacemos para que el buzzer reproducza melodías?

Para que el buzzer reproduzca melodías, debemos utilizar el formato RTTTL. Ring Tone Text Transfer Language es un formato desarrollado por Nokia y que podemos utilizar en nuestros microcontroladores. En internet hay varios sitios de donde podemos descargar estas cadenas de texto, les dejo los que anduve investigando:

Si quieren innovar y probar sus propios RTTTL, está este sitio.

También les dejo la configuración del ESP32 con ESPHome para que puedan crear su propio dispositivo:

ESPHome - yaml

esphome:
  name: lavadero
  friendly_name: lavadero

esp32:
  board: esp32-c6-devkitc-1
  framework:
    type: esp-idf

logger:

api:
  encryption:
    key: !secret lavadero_encryption
  services:
    - service: play_song
      then:
        - script.execute: play_song

ota:
  - platform: esphome
    password: !secret lavadero_ota_pwd

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

  ap:
    ssid: "Lavadero-dev Fallback Hotspot"
    password: "W37rGZVhYdF2"

captive_portal:

output:
  # Buzzer
  - platform: ledc
    pin: GPIO14
    id: buzzer_output
    frequency: 1000Hz
  
  # LED RGB
  - platform: ledc
    pin: GPIO22
    id: led_r
    inverted: true
  - platform: ledc
    pin: GPIO4
    id: led_g
    inverted: true
  - platform: ledc
    pin: GPIO5
    id: led_b
    inverted: true

  # Relays
  - platform: gpio
    pin: GPIO18
    id: relay_pasillo
    inverted: true

  - platform: gpio
    pin: GPIO19
    id: relay_lavadero
    inverted: true

rtttl:
  output: buzzer_output
  id: my_buzzer
  gain: 40%

# Script para reproducir la melodía y alternar colores
script:
  - id: play_song
    then:
      - rtttl.play: "BackToTheFuture:d=16,o=5,b=200:4g.,p,4c.,p,2f#.,p,g.,p,a.,p,8g,p,8e,p,8c,p,4f#,p,g.,p,a.,p,8g.,p,8d.,p,8g.,p,8d6.,p,4d6.,p,4c#6,p,b.,p,c#6.,p,2d6."
      - repeat:
          count: 7
          then:
            - light.turn_on:
                id: led_lavarropas
                red: 50%
                green: 0%
                blue: 0%
                transition_length: 0s
            - delay: 500ms
            - light.turn_on:
                id: led_lavarropas
                red: 0%
                green: 0%
                blue: 50%
                transition_length: 0s
            - delay: 500ms

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO0
      inverted: true
      mode:
        input: true
        pullup: true
    name: "Pulsador"
    internal: true
    on_click:
      - homeassistant.service:
          service: input_boolean.turn_off
          data:
            entity_id: input_boolean.colgar_ropa
      - light.turn_off:
          id: led_lavarropas


  # Interruptores
  - platform: gpio
    pin:
      number: GPIO20
      mode: INPUT_PULLUP
      # inverted: true
    name: "Switch Lavadero"
    internal: true
    on_press:
      - light.toggle: lavadero
    on_release:
      - light.toggle: lavadero

  - platform: gpio
    pin:
      number: GPIO21
      mode: INPUT_PULLUP
      # inverted: true
    name: "Switch Pasillo"
    internal: true
    on_press:
      - light.toggle: pasillo
    on_release:
      - light.toggle: pasillo
  
  # Sensor de presencia LD2410
  - platform: ld2410
    has_target:
      name: "LD2410 Presence"
      id: presence_sensor
    has_moving_target:
      name: "LD2410 Moving Target"
    has_still_target:
      name: "LD2410 Still Target"

uart:
  id: uart_ld2410
  tx_pin: GPIO1
  rx_pin: GPIO3
  baud_rate: 256000

ld2410:
  uart_id: uart_ld2410

sensor:
  - platform: ld2410
    moving_distance:
      name: "LD2410 Moving Distance"
    still_distance:
      name: "LD2410 Still Distance"
    moving_energy:
      name: "LD2410 Moving Energy"
    still_energy:
      name: "LD2410 Still Energy"
    detection_distance:
      name: "LD2410 Detection Distance"

light:
  - platform: rgb
    id: led_lavarropas
    name: "Led Lavarropas"
    red: led_r
    green: led_g
    blue: led_b

  - platform: binary
    name: "Lavadero"
    id: lavadero
    output: relay_lavadero

  - platform: binary
    name: "Pasillo"
    id: pasillo
    output: relay_pasillo

NOTA IMPORTANTE!

Para que el microcontrolador pueda ejecutar acciones dentro de Home Assistant, tenemos que ir al dispositivo dentro de HA y habilitarle que pueda realizar acciones, sinó la parte de presionar el botón y que cambie el estado de colgar_ropa no va a funcionar.

ESPHome 01

ESPHome 02

Caja

En breve voy a estar subiendo el diseño de la caja para que puedan descargarlo e imprimirlo.

Espero que les haya gustado este proyecto y les sea de utilidad. Si tienen alguna duda o sugerencia, los leo en los comentarios del video!

comments powered by Disqus