Tune laundry drying cycle

This commit is contained in:
ltadeu6 2026-05-17 14:54:42 -03:00
parent 588666a967
commit e394d03175
4 changed files with 79 additions and 40 deletions

View file

@ -614,16 +614,18 @@ Estado atual:
- O script `script.secar_roupas_com_ar_condicionado` usa `climate.ar`. - O script `script.secar_roupas_com_ar_condicionado` usa `climate.ar`.
- As dashboards `ui-lovelace.yaml` e `ui-overview.yaml` exibem um botao para alternar `input_boolean.secar_roupas`. - 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 temperatura vem de `state_attr('climate.ar', 'current_temperature')`; nao ha sensor de umidade dedicado.
- O modo dominante e `dry`. - A estrategia alterna aquecimento moderado para evaporar agua das roupas e `cool`/`dry` para condensar e drenar a umidade.
- `heat` so e usado abaixo de 21 C, com setpoint 24 C. - No inicio, se a sala estiver abaixo de 24 C, o script usa `heat` com setpoint 25 C por ate 15 minutos.
- `cool` so entra em pulsos curtos se o `dry` estiver idle e a temperatura permitir. - Durante o loop, abaixo de 21 C o script usa `heat` com setpoint 24 C por ate 20 minutos para recuperar temperatura.
- 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`.
- Fan mode e definido apenas se o valor existir em `state_attr('climate.ar', 'fan_modes')`; tenta `medium`/`high` e cai para `auto`. - Fan mode e definido apenas se o valor existir em `state_attr('climate.ar', 'fan_modes')`; tenta `medium`/`high` e cai para `auto`.
Cuidados: Cuidados:
- Se trocar a entidade do ar, atualize `haAirConditioner` no `let` de `hosts/Nixos/configuration.nix`. - Se trocar a entidade do ar, atualize `haAirConditioner` no `let` de `hosts/Nixos/configuration.nix`.
- Se trocar o helper, atualize `haLaundryDryingToggle` no mesmo `let`. - Se trocar o helper, atualize `haLaundryDryingToggle` no mesmo `let`.
- Se a integracao do ar nao expuser `hvac_action = idle`, o fallback com `cool` nao dispara; o script continua funcionando em `dry`/`heat`.
- Nao mova essa logica para arquivos em `/var/lib/hass` ou pela UI sem refletir a mudanca no repo. - Nao mova essa logica para arquivos em `/var/lib/hass` ou pela UI sem refletir a mudanca no repo.
### Home Assistant / dashboard do Codex ### Home Assistant / dashboard do Codex

View file

@ -40,7 +40,7 @@ views:
]]] ]]]
mode: > mode: >
[[[ [[[
return entity.state === 'on' ? 'Dry dominante, heat so se esfriar' : 'Ar desligado ao parar'; return entity.state === 'on' ? 'Heat evapora, Cool/Dry drena' : 'Ar desligado ao parar';
]]] ]]]
styles: styles:
card: card:

View file

@ -40,7 +40,7 @@ views:
]]] ]]]
mode: > mode: >
[[[ [[[
return entity.state === 'on' ? 'Dry dominante, heat so se esfriar' : 'Ar desligado ao parar'; return entity.state === 'on' ? 'Heat evapora, Cool/Dry drena' : 'Ar desligado ao parar';
]]] ]]]
styles: styles:
card: card:

View file

@ -22,6 +22,10 @@ let
haSetFanMode = fan_mode: haSetFanMode = fan_mode:
haClimateAction "climate.set_fan_mode" { inherit fan_mode; }; haClimateAction "climate.set_fan_mode" { inherit fan_mode; };
haTurnOffClimate = haClimateAction "climate.turn_off" { }; haTurnOffClimate = haClimateAction "climate.turn_off" { };
haTurnOffDryingToggle = {
action = "input_boolean.turn_off";
target.entity_id = haLaundryDryingToggle;
};
haWaitForDryingToggleOff = timeout: { haWaitForDryingToggleOff = timeout: {
wait_template = "{{ is_state('${haLaundryDryingToggle}', 'off') }}"; wait_template = "{{ is_state('${haLaundryDryingToggle}', 'off') }}";
inherit timeout; inherit timeout;
@ -51,7 +55,12 @@ let
(haSetHvacMode "dry") (haSetHvacMode "dry")
(haSetFanModeIfAvailable "medium" "auto") (haSetFanModeIfAvailable "medium" "auto")
]; ];
haHeatCycle = [ haHeatEvaporationCycle = [
(haSetHvacMode "heat")
(haSetTemperature 25)
(haSetFanModeIfAvailable "high" "auto")
];
haHeatRecoveryCycle = [
(haSetHvacMode "heat") (haSetHvacMode "heat")
(haSetTemperature 24) (haSetTemperature 24)
(haSetFanModeIfAvailable "high" "auto") (haSetFanModeIfAvailable "high" "auto")
@ -61,6 +70,11 @@ let
(haSetTemperature 22) (haSetTemperature 22)
(haSetFanModeIfAvailable "medium" "auto") (haSetFanModeIfAvailable "medium" "auto")
]; ];
haHotRoomCoolPulse = [
(haSetHvacMode "cool")
(haSetTemperature 23)
(haSetFanModeIfAvailable "medium" "auto")
];
zenExtension = shortId: guid: { zenExtension = shortId: guid: {
name = guid; name = guid;
value = { value = {
@ -305,7 +319,7 @@ in {
secar_roupas_com_ar_condicionado = { secar_roupas_com_ar_condicionado = {
alias = "Secar roupas com ar-condicionado"; alias = "Secar roupas com ar-condicionado";
description = description =
"Seca roupas em uma sala fechada usando Dry como modo dominante, Heat apenas contra frio excessivo e Cool em pulsos curtos quando o Dry fica idle."; "Seca roupas em sala fechada alternando aquecimento moderado para evaporar agua e Cool/Dry para condensar e drenar umidade.";
mode = "restart"; mode = "restart";
icon = "mdi:hanger"; icon = "mdi:hanger";
sequence = [ sequence = [
@ -314,22 +328,50 @@ in {
entity_id = haLaundryDryingToggle; entity_id = haLaundryDryingToggle;
state = "on"; state = "on";
} }
{
variables = {
started_at = "{{ as_timestamp(now()) }}";
max_runtime_seconds = 21600;
current_temp =
"{{ state_attr('${haAirConditioner}', 'current_temperature') | float(24) }}";
};
}
{
choose = [{
conditions = [{
condition = "template";
value_template = "{{ current_temp < 24 }}";
}];
sequence = haHeatEvaporationCycle
++ [ (haWaitForDryingToggleOff "00:15:00") ];
}];
}
{
condition = "state";
entity_id = haLaundryDryingToggle;
state = "on";
}
] ++ haDryCycle ++ [ ] ++ haDryCycle ++ [
(haWaitForDryingToggleOff "00:30:00") (haWaitForDryingToggleOff "00:30:00")
{ {
repeat = { repeat = {
while = [{ while = [
condition = "state"; {
entity_id = haLaundryDryingToggle; condition = "state";
state = "on"; entity_id = haLaundryDryingToggle;
}]; state = "on";
}
{
condition = "template";
value_template =
"{{ (as_timestamp(now()) - (started_at | float(0))) < (max_runtime_seconds | float(0)) }}";
}
];
sequence = [ sequence = [
{ {
variables = { variables = {
current_temp = current_temp =
"{{ state_attr('${haAirConditioner}', 'current_temperature') | float(24) }}"; "{{ state_attr('${haAirConditioner}', 'current_temperature') | float(24) }}";
current_action =
"{{ state_attr('${haAirConditioner}', 'hvac_action') | default('', true) | string | lower }}";
}; };
} }
{ {
@ -340,7 +382,7 @@ in {
value_template = value_template =
"{{ current_temp < 21 }}"; "{{ current_temp < 21 }}";
}]; }];
sequence = haHeatCycle ++ [ sequence = haHeatRecoveryCycle ++ [
(haWaitForDryingToggleOff "00:20:00") (haWaitForDryingToggleOff "00:20:00")
{ {
choose = [{ choose = [{
@ -350,7 +392,7 @@ in {
state = "on"; state = "on";
}]; }];
sequence = haDryCycle sequence = haDryCycle
++ [ (haWaitForDryingToggleOff "00:10:00") ]; ++ [ (haWaitForDryingToggleOff "00:35:00") ];
}]; }];
} }
]; ];
@ -361,32 +403,18 @@ in {
value_template = value_template =
"{{ current_temp >= 28 }}"; "{{ current_temp >= 28 }}";
}]; }];
sequence = [ sequence = haHotRoomCoolPulse ++ [
(haWaitForDryingToggleOff "00:20:00")
{ {
choose = [{ choose = [{
conditions = [{ conditions = [{
condition = "template"; condition = "state";
value_template = entity_id = haLaundryDryingToggle;
"{{ current_action == 'idle' }}"; state = "on";
}]; }];
sequence = haCoolPulse ++ [ sequence = haDryCycle
(haWaitForDryingToggleOff "00:20:00") ++ [ (haWaitForDryingToggleOff "00:35:00") ];
{
choose = [{
conditions = [{
condition = "state";
entity_id = haLaundryDryingToggle;
state = "on";
}];
sequence = haDryCycle ++ [
(haWaitForDryingToggleOff "00:40:00")
];
}];
}
];
}]; }];
default = haDryCycle
++ [ (haWaitForDryingToggleOff "00:45:00") ];
} }
]; ];
} }
@ -395,9 +423,8 @@ in {
condition = "template"; condition = "template";
value_template = '' value_template = ''
{{ {{
current_temp > 22 current_temp >= 23
and current_temp < 28 and current_temp < 28
and current_action == 'idle'
}} }}
''; '';
}]; }];
@ -424,6 +451,16 @@ in {
}; };
} }
haTurnOffClimate haTurnOffClimate
{
choose = [{
conditions = [{
condition = "state";
entity_id = haLaundryDryingToggle;
state = "on";
}];
sequence = [ haTurnOffDryingToggle ];
}];
}
]; ];
}; };
}; };