From 2bd4dac0c5335a21ead25a59451d4c11ee0d6949 Mon Sep 17 00:00:00 2001 From: ltadeu6 Date: Sun, 17 May 2026 14:30:22 -0300 Subject: [PATCH] Add laundry drying HA script --- .../home-assistant/secar_roupas_script.yaml | 257 ++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 configs/home-assistant/secar_roupas_script.yaml diff --git a/configs/home-assistant/secar_roupas_script.yaml b/configs/home-assistant/secar_roupas_script.yaml new file mode 100644 index 0000000..a387019 --- /dev/null +++ b/configs/home-assistant/secar_roupas_script.yaml @@ -0,0 +1,257 @@ +# Script standalone para Home Assistant. +# Uso previsto: +# 1. Crie o helper `input_boolean.secar_roupas` pela UI do Home Assistant. +# 2. Cole o bloco abaixo em `scripts.yaml` ou importe pelo editor YAML de Scripts. +# 3. Se o seu ar nao aceitar `medium` em `fan_mode`, troque para `auto`. + +secar_roupas_com_ar_condicionado: + alias: Secar roupas com ar-condicionado + description: > + Usa Dry como modo dominante para secar roupas em uma sala fechada. + Recorre a Heat apenas se a sala esfriar demais e usa Cool em pulsos curtos + quando o Dry aparenta ficar idle em temperatura ainda aceitavel. + mode: restart + icon: mdi:hanger + sequence: + - variables: + toggle_entity: input_boolean.secar_roupas + climate_entity: climate.ar + min_heat_temp: 21 + heat_target_temp: 24 + cool_pulse_target_temp: 22 + warm_room_threshold: 22 + hot_room_threshold: 28 + dry_fan_mode: medium + heat_fan_mode: high + cool_fan_mode: medium + + - condition: state + entity_id: input_boolean.secar_roupas + state: "on" + + # Fase inicial: comeca sempre em Dry para puxar umidade das roupas. + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: dry + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ dry_fan_mode }}" + + - wait_template: "{{ is_state(toggle_entity, 'off') }}" + timeout: "00:30:00" + continue_on_timeout: true + + - repeat: + while: + - condition: state + entity_id: input_boolean.secar_roupas + state: "on" + sequence: + - variables: + current_temp: >- + {{ state_attr(climate_entity, 'current_temperature') | float(0) }} + current_action: >- + {{ state_attr(climate_entity, 'hvac_action') | default('', true) | string | lower }} + + - choose: + # Sala fria: usa Heat apenas para nao deixar o ambiente frio demais. + - conditions: + - condition: template + value_template: "{{ current_temp < min_heat_temp }}" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: heat + + - service: climate.set_temperature + target: + entity_id: "{{ climate_entity }}" + data: + temperature: "{{ heat_target_temp }}" + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ heat_fan_mode }}" + + - wait_template: "{{ is_state(toggle_entity, 'off') }}" + timeout: "00:20:00" + continue_on_timeout: true + + - choose: + - conditions: + - condition: state + entity_id: input_boolean.secar_roupas + state: "on" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: dry + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ dry_fan_mode }}" + + - wait_template: "{{ is_state(toggle_entity, 'off') }}" + timeout: "00:10:00" + continue_on_timeout: true + + # Sala muito quente: nunca aquece. Mantem Dry ou usa um Cool curto + # apenas se o atributo `hvac_action` existir e vier como `idle`. + - conditions: + - condition: template + value_template: "{{ current_temp >= hot_room_threshold }}" + sequence: + - choose: + - conditions: + - condition: template + value_template: "{{ current_action == 'idle' }}" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: cool + + - service: climate.set_temperature + target: + entity_id: "{{ climate_entity }}" + data: + temperature: "{{ cool_pulse_target_temp }}" + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ cool_fan_mode }}" + + - wait_template: "{{ is_state(toggle_entity, 'off') }}" + timeout: "00:20:00" + continue_on_timeout: true + + - conditions: [] + sequence: + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: dry + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ dry_fan_mode }}" + + - wait_template: "{{ is_state(toggle_entity, 'off') }}" + timeout: "00:45:00" + continue_on_timeout: true + + - choose: + - conditions: + - condition: state + entity_id: input_boolean.secar_roupas + state: "on" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: dry + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ dry_fan_mode }}" + + # Dry parece parado/idle e a sala ainda esta relativamente quente: + # aplica um pulso curto de Cool e volta para Dry. + # Se o seu climate nao expuser `hvac_action`, esta heuristica nao dispara. + - conditions: + - condition: template + value_template: >- + {{ + current_temp > warm_room_threshold + and current_temp < hot_room_threshold + and current_action == 'idle' + }} + sequence: + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: cool + + - service: climate.set_temperature + target: + entity_id: "{{ climate_entity }}" + data: + temperature: "{{ cool_pulse_target_temp }}" + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ cool_fan_mode }}" + + - wait_template: "{{ is_state(toggle_entity, 'off') }}" + timeout: "00:15:00" + continue_on_timeout: true + + - choose: + - conditions: + - condition: state + entity_id: input_boolean.secar_roupas + state: "on" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: dry + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ dry_fan_mode }}" + + - wait_template: "{{ is_state(toggle_entity, 'off') }}" + timeout: "00:40:00" + continue_on_timeout: true + + default: + # Faixa normal: prioriza Dry por blocos longos. + - service: climate.set_hvac_mode + target: + entity_id: "{{ climate_entity }}" + data: + hvac_mode: dry + + - service: climate.set_fan_mode + target: + entity_id: "{{ climate_entity }}" + data: + fan_mode: "{{ dry_fan_mode }}" + + - wait_template: "{{ is_state(toggle_entity, 'off') }}" + timeout: "00:45:00" + continue_on_timeout: true + + # Ao desativar o helper, desliga o ar para sair em estado seguro. + - service: climate.turn_off + target: + entity_id: "{{ climate_entity }}"