From 8e03bf57ee5576b02ab97a382a5c1aa957cefc36 Mon Sep 17 00:00:00 2001 From: ltadeu6 Date: Sun, 17 May 2026 15:28:39 -0300 Subject: [PATCH] Refine laundry heat stabilization --- AGENTS.md | 4 ++-- hosts/Nixos/configuration.nix | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 96c0af3..88aa085 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -615,8 +615,8 @@ Estado atual: - As dashboards `ui-lovelace.yaml` e `ui-overview.yaml` exibem um botao para alternar `input_boolean.secar_roupas`. - A temperatura vem de `state_attr('climate.ar', 'current_temperature')`; nao ha sensor de umidade dedicado. - A estrategia alterna aquecimento moderado para evaporar agua das roupas e `cool`/`dry` para condensar e drenar a umidade. -- No inicio, se a sala estiver abaixo de 24 C, o script usa `heat` com setpoint 25 C por ate 15 minutos. -- Durante o loop, abaixo de 21 C o script usa `heat` com setpoint 24 C por ate 20 minutos para recuperar temperatura. +- No inicio, se a sala estiver abaixo de 24 C, o script usa `heat` com setpoint 25 C ate chegar em 25 C, segura ate 5 minutos se ainda estiver abaixo de 27 C, e tem timeout maximo de 15 minutos. +- Durante o loop, abaixo de 21 C o script usa `heat` com setpoint 24 C ate chegar em 24 C, segura ate 5 minutos se ainda estiver abaixo de 26 C, e tem timeout maximo de 20 minutos. - Entre 23 C e 28 C, o script usa pulsos planejados de `cool` com setpoint 22 C por ate 15 minutos, depois volta para `dry` por ate 40 minutos. - Acima de 28 C, o script nunca aquece; usa `cool` com setpoint 23 C por ate 20 minutos e depois `dry`. - O tempo maximo de execucao e 6 horas; ao expirar, o script desliga `climate.ar` e desliga `input_boolean.secar_roupas`. diff --git a/hosts/Nixos/configuration.nix b/hosts/Nixos/configuration.nix index 6d38178..008e698 100644 --- a/hosts/Nixos/configuration.nix +++ b/hosts/Nixos/configuration.nix @@ -41,6 +41,22 @@ let inherit timeout; continue_on_timeout = true; }; + haWaitForTemperatureOrToggleOff = temperature: timeout: { + wait_template = + "{{ is_state('${haLaundryDryingToggle}', 'off') or (state_attr('${haAirConditioner}', 'current_temperature') | float(0)) >= ${toString temperature} }}"; + inherit timeout; + continue_on_timeout = true; + }; + haHoldHeatIfStillUseful = cutoffTemperature: holdTimeout: { + choose = [{ + conditions = [{ + condition = "template"; + value_template = + "{{ is_state('${haLaundryDryingToggle}', 'on') and (state_attr('${haAirConditioner}', 'current_temperature') | float(0)) < ${toString cutoffTemperature} }}"; + }]; + sequence = [ (haWaitForDryingToggleOff holdTimeout) ]; + }]; + }; haSetFanModeIfAvailable = preferred: fallback: { choose = [ { @@ -71,12 +87,16 @@ let haWaitForClimateReady (haSetTemperature 25) (haSetFanModeIfAvailable "5" "4") + (haWaitForTemperatureOrToggleOff 25 "00:15:00") + (haHoldHeatIfStillUseful 27 "00:05:00") ]; haHeatRecoveryCycle = [ (haSetHvacMode "heat") haWaitForClimateReady (haSetTemperature 24) (haSetFanModeIfAvailable "5" "4") + (haWaitForTemperatureOrToggleOff 24 "00:20:00") + (haHoldHeatIfStillUseful 26 "00:05:00") ]; haCoolPulse = [ (haSetHvacMode "cool") @@ -357,8 +377,7 @@ in { condition = "template"; value_template = "{{ current_temp < 24 }}"; }]; - sequence = haHeatEvaporationCycle - ++ [ (haWaitForDryingToggleOff "00:15:00") ]; + sequence = haHeatEvaporationCycle; }]; } { @@ -398,7 +417,6 @@ in { "{{ current_temp < 21 }}"; }]; sequence = haHeatRecoveryCycle ++ [ - (haWaitForDryingToggleOff "00:20:00") { choose = [{ conditions = [{