Tune laundry drying cycle
This commit is contained in:
parent
588666a967
commit
e394d03175
4 changed files with 79 additions and 40 deletions
10
AGENTS.md
10
AGENTS.md
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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";
|
condition = "state";
|
||||||
entity_id = haLaundryDryingToggle;
|
entity_id = haLaundryDryingToggle;
|
||||||
state = "on";
|
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,15 +403,7 @@ in {
|
||||||
value_template =
|
value_template =
|
||||||
"{{ current_temp >= 28 }}";
|
"{{ current_temp >= 28 }}";
|
||||||
}];
|
}];
|
||||||
sequence = [
|
sequence = haHotRoomCoolPulse ++ [
|
||||||
{
|
|
||||||
choose = [{
|
|
||||||
conditions = [{
|
|
||||||
condition = "template";
|
|
||||||
value_template =
|
|
||||||
"{{ current_action == 'idle' }}";
|
|
||||||
}];
|
|
||||||
sequence = haCoolPulse ++ [
|
|
||||||
(haWaitForDryingToggleOff "00:20:00")
|
(haWaitForDryingToggleOff "00:20:00")
|
||||||
{
|
{
|
||||||
choose = [{
|
choose = [{
|
||||||
|
|
@ -378,26 +412,19 @@ in {
|
||||||
entity_id = haLaundryDryingToggle;
|
entity_id = haLaundryDryingToggle;
|
||||||
state = "on";
|
state = "on";
|
||||||
}];
|
}];
|
||||||
sequence = haDryCycle ++ [
|
sequence = haDryCycle
|
||||||
(haWaitForDryingToggleOff "00:40:00")
|
++ [ (haWaitForDryingToggleOff "00:35:00") ];
|
||||||
];
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}];
|
|
||||||
default = haDryCycle
|
|
||||||
++ [ (haWaitForDryingToggleOff "00:45:00") ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
conditions = [{
|
conditions = [{
|
||||||
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 ];
|
||||||
|
}];
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue