Autolämmitys, joka lämmittää auton juuri lähtöaikaan
Home Assistant -blueprint käynnistää auton lohkolämmittimen lähtöajan ja ulkolämpötilan mukaan ja sammuttaa sen, kun olet lähtenyt.
- Julkaistu
- Taso
- Keskitaso
- Laitteet
- Matter-ulkopistorasia, ulkolämpötila-anturi
Suomen talvessa auto on töpselissä joka yö. Tavallinen ajastin lämmittää yhtä kauan, oli ulkona −2 °C tai −25 °C, joten auto on joko kylmä tai lämmitin käy turhaan. Tämä toteutus aloittaa lämmityksen sopivan ajan ennen lähtöä, valitsee lämmitysajan ulkolämpötilan mukaan ja sammuttaa lämmittimen, kun olet lähtenyt.
Jokaiselle autolle asetetaan kaksi asiaa: lähtöaika ja se, onko ajastettu lämmitys päällä. Kaikki muu hoituu itsestään.
Mitä se tekee
- Aloittaa ajoissa. Lämmitys alkaa lämmitysajan verran ennen lähtöä. Kun ulkona on +5 °C tai lämpimämpää, lämmitysaika on nolla eikä mitään käynnisty.
- Sammuu lähdön jälkeen. Lämmitin sammuu 15 minuuttia lähtöajan jälkeen.
- Hoitaa käsin käynnistyksen. Kun kytket lämmittimen itse päälle, se sammuu lämmitysajan ja 15 minuutin jälkeen. Unohtunut lämmitin ei siis jää päälle koko päiväksi.
- Reagoi muutoksiisi. Jos siirrät lähtöaikaa niin, että lämmityksen pitäisi jo olla käynnissä, se käynnistyy heti.
- Ei sahaa sään mukana. Jos ulkona kylmenee ja lämmitysikkunan pitäisi jo olla alkanut, lämmitys käynnistyy heti. Kun lämmitys on kerran alkanut, lämpötilan nousu ei enää katkaise sitä.
- Kestää uudelleenkäynnistyksen. Jos Home Assistant käynnistyy uudelleen kesken lämmitysikkunan, lämmitys jatkuu. Viiden minuutin välein ajettava tarkistus sammuttaa lämmittimen, joka on jäänyt päälle uudelleenkäynnistyksen jälkeen.
- Lämmitysajat säädetään dashboardilta. Jokaisella lämpötila-alueella on oma minuuttimääränsä, eikä YAMLia tarvitse muokata.
- Ei koske lämmittimeen, kun ajastus on pois. Silloin rasia on tavallinen älypistorasia.
Mitä tarvitset
- Älypistorasian, joka kestää lämmittimen kuorman ja sopii ulkokäyttöön. Itse käytän Matter-ulkopistorasioita, mutta mikä tahansa Home Assistantissa
switch-entiteettinä näkyvä rasia käy. - Ulkolämpötila-anturin Home Assistantissa.
Vaihe 1: apuentiteetit ja lämmitysaika
Alla oleva paketti luo lähtöajan, ajastuksen kytkimen, neljä lämmitysaikaa (yksi kullekin lämpötila-alueelle) ja kaksi template-sensoria: montako minuuttia lämmitetään juuri nyt ja milloin lämmitys alkaa. Tallenna se nimellä config/packages/car_block_heater.yaml ja vaihda sensor.outdoor_temperature omaan anturiisi.
Näytä paketti
# Car block heater: helpers and heating time.# Save as config/packages/car_block_heater.yaml (packages must be enabled in configuration.yaml).# Replace sensor.outdoor_temperature with your own outdoor temperature sensor.# For a second car, copy the block and change "car" to e.g. "car_2".
input_datetime: car_departure_time: name: Car departure time has_date: false has_time: true icon: mdi:clock-outline
input_boolean: car_heating_schedule: name: Car scheduled heating icon: mdi:calendar-clock
# Heating time for each temperature band. Adjust these from the dashboard;# Home Assistant remembers the values across restarts.input_number: car_heating_minus_20: name: Car heating time at −20 °C or colder min: 0 max: 180 step: 5 mode: box unit_of_measurement: min car_heating_minus_10: name: Car heating time at −10 to −20 °C min: 0 max: 180 step: 5 mode: box unit_of_measurement: min car_heating_minus_5: name: Car heating time at −5 to −10 °C min: 0 max: 180 step: 5 mode: box unit_of_measurement: min car_heating_below_5: name: Car heating time below +5 °C min: 0 max: 180 step: 5 mode: box unit_of_measurement: min
template: - sensor: # Minutes of heating at the current outdoor temperature, from the times above - name: Car heating time unique_id: car_heating_time unit_of_measurement: min icon: mdi:timer-outline state: > {% set t = states('sensor.outdoor_temperature') | float(99) %} {% if t <= -20 %}{{ states('input_number.car_heating_minus_20') | int(0) }} {% elif t <= -10 %}{{ states('input_number.car_heating_minus_10') | int(0) }} {% elif t <= -5 %}{{ states('input_number.car_heating_minus_5') | int(0) }} {% elif t < 5 %}{{ states('input_number.car_heating_below_5') | int(0) }} {% else %}0 {% endif %}
# When heating starts, for the dashboard - name: Car heating starts unique_id: car_heating_starts icon: mdi:clock-start state: > {% set h = state_attr('input_datetime.car_departure_time', 'hour') | int(0) %} {% set m = state_attr('input_datetime.car_departure_time', 'minute') | int(0) %} {% set dep = h * 60 + m %} {% set dur = states('sensor.car_heating_time') | int(0) %} {% if dur == 0 %}none{% else %} {% set start = (dep - dur) % 1440 %} {{ '%02d:%02d' | format(start // 60, start % 60) }} {% endif %}Mistä lämmitysajat säädetään: vaiheen 4 dashboardilta, Lämmitysajat-kortista. Ne löytyvät myös kohdasta Asetukset → Laitteet ja palvelut → Entiteetit hakemalla sanalla “heating time”. Uudet apuentiteetit alkavat arvosta 0 minuuttia, eli lämmitystä ei tule, joten syötä omat aikasi kerran käyttöönoton jälkeen.
Yhden auton arvot ovat minulla nämä:
| Ulkolämpötila | Lämmitysaika |
|---|---|
| −20 °C tai kylmempää | 60 min |
| −10 °C … −20 °C | 50 min |
| −5 °C … −10 °C | 30 min |
| alle +5 °C | 20 min |
| +5 °C tai lämpimämpää | ei lämmitystä |
Toinen auto saa 90, 60, 45 ja 30 minuuttia. Kahta autoa varten kopioi paketin lohkot ja vaihda car esimerkiksi muotoon car_2.
Paketit otetaan käyttöön kerran configuration.yaml-tiedostossa:
homeassistant: packages: !include_dir_named packagesLataa sen jälkeen uudelleen kohdasta Kehitystyökalut → YAML: template-entiteetit, input boolean-, input datetime- ja input number -apuentiteetit. Uudelleenkäynnistystä ei tarvita.
Vaihe 2: blueprint
Blueprint hoitaa ajastuksen. Tallenna se nimellä config/blueprints/automation/automate_the_north/car_block_heater.yaml ja lataa automaatiot uudelleen kohdasta Kehitystyökalut → YAML. Blueprintin tekstit ovat englanniksi, koska Home Assistant ei tue blueprintien kääntämistä.
Näytä blueprint
blueprint: name: Car block heater by departure time author: Automate the North description: > Switches a car engine block heater on so the car is warm at your departure time, and off again shortly after you leave.
**How it works**
- Heating starts *heating time* minutes before the departure time. The heating time comes from a sensor you choose (minutes), so you decide how long to heat at each outdoor temperature. A heating time of 0 means no heating that day.
- The heater switches off a few minutes after departure.
- If you switch the heater on by hand, it switches itself off after the heating time plus the after-departure buffer, so a forgotten heater never runs all day.
- If you change the departure time so heating should already be running, it starts immediately.
- When the schedule toggle is off, this automation never touches the heater. domain: automation input: heater: name: Heater switch description: The smart plug or relay that powers the block heater. selector: entity: filter: - domain: switch departure_time: name: Departure time description: An input_datetime helper with time only. selector: entity: filter: - domain: input_datetime schedule_enabled: name: Scheduled heating toggle description: An input_boolean that turns scheduled heating on or off. selector: entity: filter: - domain: input_boolean heating_time: name: Heating time sensor description: A sensor whose state is the heating time in minutes, usually a template based on the outdoor temperature. selector: entity: filter: - domain: sensor after_departure: name: Keep heating after departure description: Minutes the heater stays on after the departure time. Also the run time of a manual start on a warm day. default: 15 selector: number: min: 0 max: 60 unit_of_measurement: min
mode: queuedmax: 10
trigger_variables: heater: !input heater departure: !input departure_time heating_time: !input heating_time buffer: !input after_departure
triggers: # Departure minus heating time - trigger: template id: start value_template: > {% set dep = (state_attr(departure, 'hour') | int(0)) * 60 + (state_attr(departure, 'minute') | int(0)) %} {% set dur = states(heating_time) | int(0) %} {{ dur > 0 and (now().hour * 60 + now().minute) == (dep - dur) % 1440 }} # Departure plus buffer - trigger: template id: end value_template: > {% set dep = (state_attr(departure, 'hour') | int(0)) * 60 + (state_attr(departure, 'minute') | int(0)) %} {{ (now().hour * 60 + now().minute) == (dep + buffer | int(0)) % 1440 }} # Any run (manual or scheduled) ends after heating time + buffer at the latest - trigger: state id: timeout entity_id: !input heater to: 'on' for: minutes: '{{ [states(heating_time) | int(0), 0] | max + buffer | int(0) }}' # Settings changed: start right away if we're already inside the heating window - trigger: state id: settings entity_id: - !input departure_time - !input schedule_enabled # Heating time grew so that the window now includes the current minute - trigger: state id: heating_time entity_id: !input heating_time # After a restart: resume a heating window that started while HA was down - trigger: homeassistant id: ha_start event: start # Safety net for runs whose timer was lost in a restart - trigger: time_pattern id: watchdog minutes: /5
conditions: - condition: state entity_id: !input schedule_enabled state: 'on'
variables: now_min: '{{ now().hour * 60 + now().minute }}' dep_min: "{{ (state_attr(departure, 'hour') | int(0)) * 60 + (state_attr(departure, 'minute') | int(0)) }}" end_min: '{{ (dep_min + buffer | int(0)) % 1440 }}' # Is now_min inside [departure - heating time, departure + buffer)? Wraps past midnight. in_window: >- {%- set dur = states(heating_time) | int(0) -%} {%- set start = (dep_min - dur) % 1440 -%} {{ dur > 0 and ((start <= end_min and start <= now_min and now_min < end_min) or (start > end_min and (now_min >= start or now_min < end_min))) }} # Same test with the heating time before this change (only for heating_time triggers) was_in_window: >- {%- set dur = trigger.from_state.state | int(0) if trigger.id == 'heating_time' else 0 -%} {%- set start = (dep_min - dur) % 1440 -%} {{ dur > 0 and ((start <= end_min and start <= now_min and now_min < end_min) or (start > end_min and (now_min >= start or now_min < end_min))) }}
actions: - choose: - conditions: - condition: trigger id: start - condition: template value_template: "{{ is_state(heater, 'off') }}" sequence: - action: switch.turn_on target: entity_id: !input heater
- conditions: - condition: trigger id: [settings, heating_time, ha_start] - condition: template value_template: "{{ in_window | bool and not was_in_window | bool and is_state(heater, 'off') }}" sequence: - action: switch.turn_on target: entity_id: !input heater
- conditions: - condition: trigger id: [end, timeout] - condition: template value_template: "{{ is_state(heater, 'on') }}" sequence: - action: switch.turn_off target: entity_id: !input heater
# Heater left on outside the heating window for longer than a run may last - conditions: - condition: trigger id: [watchdog, ha_start] - condition: template value_template: >- {%- set on_min = (now() - states[heater].last_changed).total_seconds() / 60 -%} {%- set limit = [states(heating_time) | int(0), 0] | max + buffer | int(0) -%} {{ is_state(heater, 'on') and not in_window | bool and on_min >= limit }} sequence: - action: switch.turn_off target: entity_id: !input heaterVaihe 3: yksi automaatio per auto
Avaa Asetukset → Automaatiot ja tilanteet → Blueprintit, valitse Car block heater by departure time ja täytä:
- Heater switch: älypistorasiasi
- Departure time:
input_datetime.car_departure_time - Scheduled heating toggle:
input_boolean.car_heating_schedule - Heating time sensor:
sensor.car_heating_time
Tallenna. Toiselle autolle luodaan oma automaatio samasta blueprintista sen auton entiteeteillä.
Vaihe 4: dashboard
Osio käyttää vain Home Assistantin omia kortteja. Ylin rivi kertoo selkokielellä, mitä seuraavaksi tapahtuu, esimerkiksi “Lämmitys alkaa klo 06:55”. Alimmasta Lämmitysajat-kortista säädetään minuutit kullekin lämpötila-alueelle. Lisää Sections-näkymään osio, avaa Muokkaa YAML:na ja liitä:
Näytä dashboardin YAML
# Yhden auton dashboard-osio. Sections-näkymässä: lisää osio → ⋮ → Muokkaa YAML:na ja liitä tämä.type: 'grid'cards: - type: 'heading' heading: 'Auto' heading_style: 'title' icon: 'mdi:car' badges: - type: 'entity' entity: 'sensor.outdoor_temperature' name: 'Ulkona' show_name: false show_icon: true icon: 'mdi:thermometer' show_state: true - type: 'markdown' text_only: true content: |- {%- set t = states('sensor.outdoor_temperature') | float(none) -%} {%- set tt = (t | round(1) | string) | replace('.', ',') if t is not none else '–' -%} {%- set dur = states('sensor.car_heating_time') | int(0) -%} {%- set dep = states('input_datetime.car_departure_time')[:5] -%} {%- if is_state('switch.car_block_heater','on') and is_state('input_boolean.car_heating_schedule','off') -%} ## Lämmitin päällä Ajastus on pois, joten lämmitin on päällä, kunnes sammutat sen. {%- elif is_state('switch.car_block_heater','on') -%} ## Lämmitys päällä Valmis lähtöön klo {{ dep }}. {%- elif is_state('input_boolean.car_heating_schedule','off') -%} ## Ajastus pois Lämmitin on päällä vain, kun kytket sen itse. {%- elif dur == 0 -%} ## Lämmitystä ei tarvita Ulkona on {{ tt }} °C. Auto on valmis klo {{ dep }} sellaisenaan. {%- else -%} ## Lämmitys alkaa klo {{ states('sensor.car_heating_starts') }} {{ dur }} minuuttia, kun ulkona on {{ tt }} °C. Lämmin klo {{ dep }}. {%- endif -%} grid_options: columns: 'full' - type: 'tile' entity: 'switch.car_block_heater' name: 'Lämmitin' icon: 'mdi:car-seat-heater' vertical: false grid_options: columns: 6 tap_action: action: 'toggle' icon_tap_action: action: 'toggle' hide_state: true - type: 'tile' entity: 'input_boolean.car_heating_schedule' name: 'Ajastettu lämmitys' icon: 'mdi:calendar-clock' vertical: false grid_options: columns: 6 tap_action: action: 'toggle' icon_tap_action: action: 'toggle' - type: 'tile' entity: 'input_datetime.car_departure_time' name: 'Lähtöaika' icon: 'mdi:clock-outline' vertical: false grid_options: columns: 6 - type: 'tile' entity: 'sensor.car_heating_time' name: 'Lämmitysaika' icon: 'mdi:timer-outline' vertical: false grid_options: columns: 6 - type: 'entities' title: 'Lämmitysajat' state_color: false grid_options: columns: 'full' entities: - entity: 'input_number.car_heating_minus_20' name: '−20 °C tai kylmempää' icon: 'mdi:thermometer' - entity: 'input_number.car_heating_minus_10' name: '−10 … −20 °C' icon: 'mdi:thermometer' - entity: 'input_number.car_heating_minus_5' name: '−5 … −10 °C' icon: 'mdi:thermometer' - entity: 'input_number.car_heating_below_5' name: 'alle +5 °C' icon: 'mdi:thermometer'Lämmitin-kortin tila on piilotettu tarkoituksella. Kuvakkeen väri ja tilarivi kertovat jo, onko lämmitin päällä. Lisäksi Home Assistantin suomennoksessa pistorasian tila näkyy englanniksi (“On”/“Off”).
Hyvä tietää
- Miksi lämmitysaika on sensori. Blueprint tarvitsee vain minuuttimäärän. Lämpötilataulukon voi korvata millä tahansa: tuulen viilentävällä vaikutuksella, eri taulukolla viikonlopuille tai kiinteällä arvolla.
- Käsin käynnistetty lämmitys päättyy viimeistään 15 minuuttia lähtöajan jälkeen, kun ajastus on päällä. Jos kytket lämmittimen 10 minuuttia ennen lähtöä, se sammuu 15 minuuttia lähdön jälkeen eikä vasta täyden lämmitysjakson päästä.