Gestion de lave-vaisselle dans Home assistant

J’en ai déjà parlé sur d’autres topic mais j’ai améliorer mon système et rajouter fonctions/options donc je me suis dit que ça serait bien d’avoir un tuto avec tout ça , …

Ce que je fait:

  • Pouvoir programmer mon lave-vaisselle en heure-creuse
  • Notification quand cycle fini avec un résume d’information sur le cycle
  • Enregistrement du cycle dans un csv pour un usage ultérieur (statistique)
  • Gestion du nombre de pastille de lavage restante
  • Affichage des statistique d’utilisation

J’ai un lave-vaisselle « connecter » et je mesure sa consommation électrique
Donc si il n’est pas connecter chez vous, impossible de programmer via HA son démarrage et si vous n’avez pas sa mesure de consommation électrique adieu les notifications et gestion des pastilles restantes (mais vous pouvez, peut-être, avoir ça avec l’application du constructeur mais pour moi, toute ma domotique doit être dans HA, … )

Dashboard

pour moi, si on a pas besoin souvent, ça sert a rien d’exposer par défaut tous les paramètres, je préfère donc quelques chose d’épurer pour la page par défaut, pour moi c’est juste un bouton :

Capture d’écran du 2024-01-10 17-40-25

Capture d’écran du 2024-01-10 17-43-09

qui affiche

  • l’heure de démarrage prévu et couleur vert
  • ou éteint
  • ou l’heure de fin prévu et couleur rouge

un click programme le démarre en Heure Creuse, that it !

code
type: custom:button-card
show_name: false
show_icon: true
name: Lave Vaisselle
tap_action:
  action: call-service
  service: input_boolean.turn_on
  target:
    entity_id: input_boolean.lave_vaisselle_auto_start_protection
hold_action:
  action: navigate
  navigation_path: /lovelace-report/lave-vaisselle
double_tap_action:
  action: call-service
  service: input_boolean.turn_off
  target:
    entity_id: input_boolean.lave_vaisselle_auto_start_protection
entity: input_boolean.lave_vaisselle_auto_start_protection
variables:
  programme: >
    [[[ if (states['switch.lave_vaisselle_program_auto2'].state == "on" ) return
    "Auto2";

    if (states['switch.lave_vaisselle_program_eco50'].state == "on" ) return
    "Eco 50°";

    if (states['switch.lave_vaisselle_program_intensiv70'].state == "on" )
    return "70°";

    if (states['switch.lave_vaisselle_program_kurz60'].state == "on" ) return
    "Auto 60";

    if (states['switch.lave_vaisselle_program_machinecare'].state == "on" )
    return "machine care";

    if (states['switch.lave_vaisselle_program_nightwash'].state == "on" ) return
    "Night Wash";

    if (states['switch.lave_vaisselle_program_prerinse'].state == "on" ) return
    "Pre Rinse";

    return "underfined";

    ]]]
icon: |
  [[[
    if ( states['sensor.lave_vaisselle_operation_state'].state == "Run" ) return "mdi:dishwasher-alert";
    else if (states['input_boolean.lave_vaisselle_auto_start_protection'].state == "on") return "mdi:dishwasher";
    else if (states['sensor.lave_vaisselle_operation_state'].state == "DelayedStart") return "mdi:dishwasher-alert";
    return "mdi:dishwasher-off" ;
  ]]]
label: |
  [[[
    if ( states['sensor.lave_vaisselle_operation_state'].state == "Run" ) return states['sensor.lave_vaisselle_remaining_program_time'].state.substr(11,5) + " : " + variables.programme ;
    else if (states['input_boolean.lave_vaisselle_auto_start_protection'].state == "on")
      return states['input_datetime.lave_vaisselle_auto_start'].state.substr(0,5) ;
    else if (states['sensor.lave_vaisselle_operation_state'].state == "DelayedStart")
      if ( states['sensor.lave_vaisselle_remaining_program_time'].state == "unavailable" ) return "Programmer";
      else
        return states['sensor.lave_vaisselle_remaining_program_time'].state.substr(11,5) ;
    else
      return "Eteint" ;
  ]]]
show_label: true
styles:
  label:
    - font-size: 90%
  name:
    - font-size: 120%
  card:
    - height: 105px
  icon:
    - color: |
        [[[
          if ( states['sensor.lave_vaisselle_operation_state'].state == "Run" ) return "red";
          else if (states['input_boolean.lave_vaisselle_auto_start_protection'].state == "on") return "green";
          else if (states['sensor.lave_vaisselle_operation_state'].state == "DelayedStart") return "green";
          return "gray" ;
        ]]]

Et si besoin, on peut accéder a l’ensemble des paramètres via un long click sur le bouton :

cette partie est moins travailler graphiquement car moins utiliser , …

Elle permet de :

  • lancer manuellement le lave-vaisselle
  • changer l’heure de démarrage des cycles en heure creuse
  • changer le nombre de pastille restante
code
  • l’heure
type: custom:time-picker-card
entity: input_datetime.lave_vaisselle_auto_start
hour_mode: 24
hour_step: 1
minute_step: 15
layout:
  hour_mode: double
  align_controls: center
  name: header
  thin: false
hide:
  seconds: true
name: Démarrage Lave Vaisselle
link_values: true
tap_action:
  action: call-service
  service: input_boolean.toggle
  target:
    entity_id: input_boolean.lave_vaisselle_auto_start_protection
double_tap_action:
  action: call-service
  service: input_boolean.toggle
  target:
    entity_id: input_boolean.lave_vaisselle_auto_start_protection
style: |
  .time-picker-content{
    {% set planned = states('input_boolean.lave_vaisselle_auto_start_protection') %}
    {% if planned == "on" %}
      background-color: green;
    {% endif %}  
  }
  • pastille restante
type: entities
entities:
  - entity: input_number.lv_pastille
    secondary_info: last-changed
    name: Pastille Restante

Automatisation

Prérequis

  • Le lave-vaisselle est sur une prise connecté qui mesure la consommation électrique ou via une pince ampérométriques
  • et/ou le lave-vaisselle est connecté à HA

Variable qu’il faut crée

  • input_number.lv_pastille
    variable de suivi du nombre de pastille de lavage restant
  • input_boolean.lave_vaisselle_cycle
    variable de protection pour la detection si on encore dans un cycle du lave-vaisselle ou pas
  • input_datetime.lave_vaisselle_auto_start
    variable de temps pour programme le lave-vaisselle en heure creuse
  • input_boolean.lave_vaisselle_auto_start_protection
    variable pour activer ou pas le demarrage du LV en heure creuse
  • sensor.lave_vaisselle_power_cycle
    utility_meter permettant de savoir la conso du cycle en électricité
  • sensor.lave_vaisselle_eau_power_cycle
    utility_meter permettant de savoir la conso du cycle en eau
  • notify.lave_vaisselle

Tous peuvent être crée en interface graphique sauf les utilty meter & le notify :

utility_meter:
  lave_vaisselle_eau_power_cycle:
    unique_id: lave_vaisselle_eau_power_cycle
    source: sensor.eau_froide_eau_froide_du_jour
    cycle: monthly
  lave_vaisselle_power_cycle:
    unique_id: lave_vaisselle_power_cycle
    source: sensor.emporiavue2_circuit_13_daily_energy
    cycle: monthly
...
...
notify:
  - name: lave_vaisselle
    platform: file
    filename: /data/git/cycle/lave_vaisselle.csv

Info

Fonction des automatisations :

  • Notification programme fini avec plein d’info
  • Enregistrement des infos du cycle dans un fichier csv
  • décompte du nombre de pastille restante
  • Notification si porte ouverte & LV programmer pour ce soir/nuit

J’ai 5 automatisations

Lave-Vaisselle : Start

automatisation
alias: "Lave-Vaisselle : Start"
description: Lave vaisselle Start
trigger:
  - type: power
    platform: device
    device_id: ...
    entity_id: sensor....._power
    domain: sensor
    above: 5
    for:
      hours: 0
      minutes: 1
      seconds: 0
condition:
  - condition: state
    entity_id: input_boolean.lave_vaisselle_cycle
    state: "off"
action:
  - service: utility_meter.calibrate
    data:
      value: "0"
    target:
      entity_id: sensor.lave_vaisselle_power_cycle
  - service: utility_meter.calibrate
    data:
      value: "0"
    target:
      entity_id: sensor.lave_vaisselle_eau_power_cycle
  - service: input_boolean.turn_on
    data: {}
    target:
      entity_id: input_boolean.lave_vaisselle_cycle
mode: single

Lave-Vaisselle : Fin

automatisation
alias: "Lave-Vaisselle : Fin"
description: Lave vaisselle Fin
trigger:
  - type: power
    platform: device
    device_id: ...
    entity_id: sensor....._power
    domain: sensor
    below: 2.5
    for:
      hours: 0
      minutes: 1
      seconds: 0
condition:
  - condition: state
    entity_id: input_boolean.lave_vaisselle_cycle
    state: "on"
action: null
mode: restart

Lave-Vaisselle : Fin , Notification

  • bien sur le code est a adapater
    • si vous avez pas de compteur d’eau ou …
    • d’enregistre le mode « eco/intensif/normal » dans le csv via des conditions de temps et de consommation electrique, il faudra adapter les valeurs ou sabrer cette partie de code si ça vous interresse pas.
automatisation
alias: "Lave-Vaisselle : Fin , Notification"
description: >-
  a la fin du cycle notification de la durée et de la consommation du cycle de
  lave-vaisselle
trigger:
  - type: power
    platform: device
    device_id: 
    entity_id: sensor....._power
    domain: sensor
    below: 2.5
    for:
      hours: 0
      minutes: 20
      seconds: 0
condition:
  - condition: state
    entity_id: input_boolean.lave_vaisselle_cycle
    state: "on"
action:
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.lave_vaisselle_cycle
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.lave_vaisselle_auto_start_protection
  - service: notify.mobile_...
    data:
      title: Lave-Vaisselle Fini
      message: >
        {%- set time =
        ((state_attr('automation.lave_vaisselle_fin','last_triggered')) -
        (state_attr('automation.lave_vaisselle_start','last_triggered'))).seconds
        -%} {%- set minutes = ((time % 3600) / 60) | round | int -%} {%- set
        hours = ((time % 86400) / 3600) | int -%} Le cycle s'est déroulé de {{
        ((state_attr('automation.lave_vaisselle_start','last_triggered')) |
        as_local).strftime("%Hh%M") }} à {{
        ((state_attr('automation.lave_vaisselle_fin','last_triggered')) |
        as_local).strftime("%Hh%M") }}. Soit une durée de {{
        '{:01}h{:02}m'.format(hours, minutes) }}\n Le cycle a consommé {{
        states('sensor.lave_vaisselle_power_cycle') | round }}Wh\n Pour un coût
        de {{(states('sensor.lave_vaisselle_power_cycle') | float(default=0) *
        (states('sensor.edf_tempo_current_cost')|float(default=0)) /1000) |
        round(2) }}€ et {{ states('sensor.lave_vaisselle_eau_power_cycle') }}L
        d'eau.
  - service: notify.lave_vaisselle
    data:
      message: >
        {%- set time =
        ((state_attr('automation.lave_vaisselle_fin','last_triggered')) -
        (state_attr('automation.lave_vaisselle_start','last_triggered'))).seconds
        -%} {%- set minutes = ((time % 3600) / 60) | round | int -%} {%- set
        hours = ((time % 86400) / 3600) | int -%}{# si > 5h30 : Souci#}{%- if
        time > 19800 -%} {%- set mode = "unknown" -%}{# si > 4h30 & < 5h30 :
        Mode eco #} {%- elif time > 16200 %}{%- set mode = "eco" -%}{# si > 3h &
        > 1200Wh Mode  intensif #}{%- elif time > 10800 and 
        (states('sensor.lave_vaisselle_power_cycle')|float) > 1200 -%} {%- set
        mode = "intensif" -%}{# si > 1h30 & > 1000Wh Mode Auto #} {%- elif time
        > 5400 and (states('sensor.lave_vaisselle_power_cycle')|float)  > 1000
        -%}{%- set mode = "auto" -%}{%- else -%}{%- set mode = "unknown" -%} {%-
        endif -%} {{ now().strftime("%d/%m/%Y") }};{{
        ((state_attr('automation.lave_vaisselle_start','last_triggered')) |
        as_local).strftime("%Hh%M") }};{{
        (state_attr('automation.lave_vaisselle_fin','last_triggered')|
        as_local).strftime("%Hh%M") }};{{ '{:01}h{:02}m'.format(hours,minutes)
        }};{{  states('sensor.lave_vaisselle_power_cycle') | round }}Wh;{{
        (states('sensor.lave_vaisselle_power_cycle') | float(default=0) *
        (states('sensor.edf_tempo_current_cost')| float(default=0)) /1000) |
        round(2) }}€;{{ mode }}
  - service: input_number.decrement
    target:
      entity_id: input_number.lv_pastille
    data: {}

Suivant le fonctionnement électrique de votre Lave Vaisselle et la précision de l’heure de fin que vous voulez et si vous voulez (ou pas) être notifier au plus vite lors d’un cycle de fin : il est possible de fusionner les automatisations « Lave-Vaisselle : Fin » et « Lave-Vaisselle : Fin , Notification »

Lave-Vaisselle programmer mais la porte est ouverte

pas le plus utile mais permet d’éviter que le LV ne se lance pas la nuit a cause d’un oubli …

automatisation
alias: Lave-Vaisselle programmer mais la porte est ouverte
description: >-
  Alarme si la porte est ouverte et le LV est programmer pour fonctionner cette
  nuit ...
trigger:
  - platform: state
    entity_id:
      - input_boolean.lave_vaisselle_auto_start_protection
    to: "on"
  - platform: state
    entity_id:
      - sensor.lave_vaisselle_operation_state
    to: DelayedStart
condition:
  - condition: state
    entity_id: binary_sensor.lave_vaisselle_door
    state: "on"
action:
  - service: notify.mobile_...
    data:
      title: Fermer le Lave-Vaisselle
      message: >-
        Le lave-vaisselle est programmer pour démarrer à {{
        states('input_datetime.lave_vaisselle_auto_start')[0:5] }} mais la porte
        est ouverte ...
mode: single

Lava-Vaisselle Start HC

automatisation
alias: Lave-Vaisselle Start HC
description: Programmer le démarrage du Lave-Vaisselle en Heure Creuse
trigger:
  - platform: template
    value_template: >-
      {{ states('sensor.time') ==
      (states('input_datetime.lave_vaisselle_auto_start')[0:5]) }}
condition:
  - condition: state
    entity_id: input_boolean.lave_vaisselle_auto_start_protection
    state: "on"
action:
  - service: switch.turn_on
    data: {}
    target:
      entity_id: switch.lave_vaisselle_program_eco50
mode: single

Statistique d’utilisation

  • affichage des données
    après avoir réaliser toutes les étate ci-dessous, voici ce qu’il est possible de faire :

Capture d’écran du 2024-03-06 13-57-12

  • Code custom:apexcharts-card : a mettre dans le dashboard
type: custom:apexcharts-card
chart_type: pie
header:
  show: true
  title: ApexCharts-Card
  show_states: true
  colorize_states: true
series:
  - entity: sensor.statistique_lave_vaisselle
    name: Eco
    attribute: mode_eco
  - entity: sensor.statistique_lave_vaisselle
    name: unknown
    attribute: mode_unknown
  - entity: sensor.statistique_lave_vaisselle
    name: Auto
    attribute: mode_auto
  - entity: sensor.statistique_lave_vaisselle
    name: Express
    attribute: mode_express

Les statistiques d’utilisations étant dans un fichier csv en dehors d’home-assistant
voici comment j’ai fait pour les ré-injecter :

  • command_line.yaml :
    une fois par jour, je convertir le fichier csv en json dans un chemin disponible sur mon serveur web
- sensor:
    name: "Statistique du Lave Vaisselle"
    unique_id: stat_lv
    command: '/usr/local/bin/csvtk csv2json /data/git/cycle/lave_vaisselle.csv --delimiter ";" > /var/www/html/private_site/stat_lv.json'
    command_timeout: 10
    scan_interval: 86400
    value_template: >-
      {{now().strftime("%Y-%m-%d %Hh%M")}}

Conversion en sensor via multiscrape :

  • multiscrape.yaml
- name: Statistique Lave-Vaisselle
  resource: https://url_private_website/stat_lv.json
  button:
    - name: Statistique Force refresh Information
      unique_id: stat_lv_refresh
  scan_interval: 86400
  sensor:
    - name: Statistique Lave-Vaisselle
      value_template: >
        {{ value_json[0].prix }}
      attributes:
        - name: Nombre Cycle
          value_template: "{{ value_json | rejectattr('mode', 'match', 'ancien_lv') | list | count }}"
        - name: mode_eco
          value_template: "{{ value_json | selectattr('mode', 'match', 'eco') | list | count }}"
        - name: mode_unknown
          value_template: "{{ value_json | selectattr('mode', 'match', 'unknown') | list | count }}"
        - name: mode_auto
          value_template: "{{ value_json | selectattr('mode', 'match', 'auto') | list | count }}"
        - name: mode_express
          value_template: "{{ value_json | selectattr('mode', 'match', 'express') | list | count }}"
        - name: cycle
          value_template: >
            [
            {%- for i in range(0, value_json | list | count, 1) -%}
              {%- set cycle = {'datetime': value_json[i].timestamp, 'date': value_json[i].date, 'debut': value_json[i].debut, 'fin': value_json[i].fin, 'duree': value_json[i].duree, 'Wh': value_json[i].Wh, 'prix': value_json[i].prix, 'mode': value_json[i].mode }-%}
              {{ cycle }},
            {% endfor %}
            ]
4 « J'aime »

Ça fait des années que je peste contre les fabricants électroménager qui ne permettent pas le control des machines. Au moins un bornier contact sec, bluetooth, un emetteur IR.
J’espère qu’avec Matter, ça va changer.

J’ai rajouter la section « Statistique d’utilisation » :

Les statistiques d’utilisations étant dans un fichier csv en dehors d’home-assistant
il faut proceder a étape pour pouvoir avoir les données dans Home Assistant :

  • Conversion de csv en json
  • Copie du json sur un site web (privé de preference)
  • Parser ce json pour crée un sensor et des attributs « utile »
  • Affichage sous forme de camembert de ce sensor via apexcharts-card