This is part 3 of my homeassistant migration. I’ll cover some insights on the automations (especially blueprints) here.

Why use automations?

In the past years, I’ve come across a few things I like to be automated in my home. It started with a few sensors for temperature monitoring, added Tasmota devices, Shellys and ended with open/close sensors for the doors.
So how to cobble all of this together? Common usecases are e.g. notifications on low temperatures, trigger a switch or light if movement was detected.

HA vs. OH3 automations

My largest fears were how automations will work in comparison to openHAB.
The main difference between the two system lies in HA using YAML configurations with Jinja2 templating support that evaluate to code vs. actual code that’s being written in a Java-like DSL in OH.
In opposition to OH, HA has things like blueprints and scripts to add to your automations. Everything goes into automations.yaml as a big pile of config.

You can choose to just click together what you need as an automation via the provided UI and fit in pieces of YAML config as you go, if you need non-standart stuff or just want to use evaluations via templates.
I strongly suggest you read up on automation basics in the documentation.
In addition to the basics: As soon as you have recurring tasks, consider to use a blueprint. Before you start to write one yourself, check the forums for available solutions you may reuse or adapt to your usecase.

My Automations so far

I went through everything I did in OH3 and made a list of all automations from my previous setup.

Usecases

These are the current usescases I have:

  • Motion triggered lights at night in my staircase, several instances, timer of 90s after last motion was detected.
  • Start a timer when a socket switch was turned on (for heating devices e.g.) and turn off after timer is over.
  • Use remote controls like the IKEA tradfri 5-button or 2-button to not only control lights, but also Shelly or Tasmota devices or groups of lights
  • Detect opened doors and alert via push messages
  • Alert on doors being open for >2 minutes
  • Alert on low temperature indoors
  • Check the current presence state of inhabitants
  • Combinations of the above

I’ve collected all my current solutions in a github repository, so make sure to collect what you want to reuse or change there, code samples below might be outdated.

Motion triggered lights

I prefer the lights in my staircase to turn on and off automatically, especially when it’s after dawn or before sunrise and on motion.
The below code is not perfectly elegant, since you can’t configure the offset for sunrise/sundawn.
What’s happeing?

  • Configure a motion sensor as trigger device
  • Add as many lights or switch devices, groups etc. as you need
  • configure brightness and how long lights will be on

The time for the light being on depends on three factors: How long does the sensor stay in the activated state and after it does not detect any more movement, the timer.

{% verbatim %}

# motion_activated_device.yaml
 
blueprint:
  name: Motion activated device at night
  description: Turn on a device when motion is detected, turn off after delay. Works only from dusk till dawn + offset
  domain: automation
  input:
 
    motion_entity:
      name: Motion Sensor
      selector:
        entity:
          domain: binary_sensor
          device_class: motion
    
    light_target:
      name: Light
      default: {}
      selector:
        target:
          entity:
            domain: light
 
    switch_target:
      name: Switch
      default: {}
      selector:
        target: 
          entity:
            domain: switch
 
    light_brightness:
      name: Night brightness
      description: The brightness to use when turning the light on
      default: 20
      selector:
        number:
          min: 10
          max: 100
          step: 10
          mode: slider      
 
    no_motion_wait:
      name: Wait time
      description: Time to leave the light on after last motion is detected.
      default: 90
      selector:
        number:
          min: 0
          max: 300
          step: 5
          unit_of_measurement: seconds
 
# If motion is detected within the delay,
# we restart the script.
# this resolves the timer reset issue
mode: restart
max_exceeded: silent
 
variables:
  motion_entity: !input 'motion_entity'
  light_target: !input 'light_target'
  switch_target: !input 'switch_target'
  light_brightness: !input 'light_brightness'
  no_motion_wait: !input 'no_motion_wait'
 
trigger:
  platform: state
  entity_id: !input 'motion_entity'
  from: 'off'
  to: 'on'
 
action:
  - condition: or
    conditions:
      - condition: sun
        after: sunset
        after_offset: '-1:00:00'
      - condition: sun
        before: sunrise
        before_offset: '+1:00:00'
 
  - choose:
 
    - conditions: 
        condition: template
        value_template: '{{ light_target | length > 0 }}'
      sequence:
        - alias: 'Turn on light'
          service: light.turn_on
          data:
            brightness: '{{ light_brightness }}'
          target: !input 'light_target'
 
    - conditions: 
        condition: template
        value_template: '{{ switch_target | length > 0 }}'
      sequence:
        - alias: 'Turn on Switch'
          service: switch.turn_on
          target: !input 'switch_target'
 
 
  - alias: 'Wait until there is no motion from device'
    wait_for_trigger:
      platform: state
      entity_id: !input 'motion_entity'
      from: 'on'
      to: 'off'
 
  - alias: 'Wait the number of seconds that has been set'
    delay: !input 'no_motion_wait'
 
  - choose:
 
    - conditions: 
        condition: template
        value_template: '{{ light_target | length > 0 }}'
      sequence:
        - alias: 'Turn off Light'
          service: light.turn_off
          target: !input 'light_target'
 
    - conditions: 
        condition: template
        value_template: '{{ switch_target | length > 0 }}'
      sequence:
        - alias: 'Turn off Switch'
          service: switch.turn_off
          target: !input 'switch_target'

{% endverbatim %} Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

Turn-off timer

I’m using a few devices for heating e.g. water (boiler).

{% verbatim %}

# timed_device.yaml
 
blueprint:
  name: Switch Timer
  description: Start a Timer on turning on a device.
  domain: automation
  input:
 
    switch_trigger:
      name: Trigger device
      description: Device that will trigger the timer
      selector:
        entity:
          domain: switch
 
    wait_for_it:
      name: Wait time
      description: Time to wait until device is turned off.
      default: 10
      selector:
        number:
          min: 1
          max: 60
          unit_of_measurement: minutes
 
variables:
  switch_trigger: !input 'switch_trigger'
  wait_for_it: !input 'wait_for_it'
 
mode: restart
max_exceeded: silent
 
trigger:
  platform: state
  entity_id: !input 'switch_trigger'
  from: 'off'
  to: 'on'
 
action:
 
  - alias: 'Wait the number of minutes that has been set'
    delay: "{{ wait_for_it | multiply(60) | int }}"
 
  - alias: 'Turn off switch'
    service: switch.turn_off
    entity_id: !input 'switch_trigger'

{% endverbatim %} Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

Door open/close notify

I want to know when my doors are opened… And also if/when they are closed. The difficulty here, is to provide a name and the state for a message in a notifier service. With this blueprint you only have to c&p the template snippet into the message field.
I would have preferred a pre-filled variable and evaluated/translated state. But this only works for values that come with the inputs themselfs. The trigger is evaluated on state change and is therefore dynamic :-(

{% verbatim %}

# open_close_notifier.yaml
 
blueprint:
  name: Open/Close notifier
  description: Notify if a door was opened or closed
  domain: automation
  input:
    
    trigger_device:
      name: Door
      description: The triggering binary sensor
      selector:
        entity:
          domain: binary_sensor
          device_class: opening
 
    actions:
      name: Actions
      description: >
        Run notifications or similar actions.
        Use something like 
        {{ trigger.to_state.attributes.friendly_name }} was {% if trigger.to_state.state == "off" %}closed{% elif trigger.to_state.state == "on" %}opened{% endif %}
      selector:
        action: {}
 
mode: single
 
variables:
  trigger_device: !input 'trigger_device'
 
trigger:
  platform: state
  entity_id: !input 'trigger_device'
 
action:
  - choose: []
    default: !input 'actions'

{% endverbatim %} Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

Temperature alert

I stole this nifty piece of code from this template and re-arranged it to fit my usecase.
There are 9 temp sensors in my home and I want to monitor all of them, exept e.g. the outdoor ones, because they are allowed to have temperatures below 10°C.
This blueprint checks the states of the sensors every 15 minutes, whis is the trigger, naturally. It’s running through all sensors with temperature and evaluates vs. the temperature threshold.
If the threshold is met, it sends a notification.
And you can set which sensors to ignore.

{% verbatim %}

# temperature_alert.yaml
 
blueprint:
  name: Low temperature alert for all temperature sensors
  description: Regularly test all sensors with 'temperature' device-class for crossing
    a certain temperature threshold and if so execute an action.
  domain: automation
  input:
 
    threshold:
      name: Temperature threshold
      description: Temperature 
      default: 10
      selector:
        number:
          min: 0.0
          max: 30.0
          unit_of_measurement: '°C'
          mode: slider
          step: 5.0
 
    exclude:
      name: Excluded Sensors
      description: Battery sensors (e.g. smartphone) to exclude from detection. Only entities are supported, devices must be expanded!
      default: {entity_id: []}
      selector:
        target:
          entity:
            device_class: temperature
 
    actions:
      name: Actions
      description: Notifications or similar to be run. {{ sensors }} is replaced with
        the names of sensors being below temperature threshold.
      selector:
        action: {}
 
variables:
  threshold: !input 'threshold'
  exclude: !input 'exclude'
  sensors: >-
    {% set result = namespace(sensors=[]) %}
    {% for state in states.sensor | selectattr('attributes.device_class', '==', 'temperature') %}
      {% if 0 <= state.state | int(-1) < threshold | int and not state.entity_id in exclude.entity_id %}
        {% set result.sensors = result.sensors + [state.name ~ ' (' ~ state.state ~ ' °C)'] %}
      {% endif %}
    {% endfor %}
    {% for state in states.binary_sensor | selectattr('attributes.device_class', '==', 'temperature') | selectattr('state', '==', 'on') %}
      {% if not state.entity_id in exclude.entity_id %}
        {% set result.sensors = result.sensors + [state.name] %}
      {% endif %}
    {% endfor %}
    {{ result.sensors|join(', ') }}
 
trigger:
    - platform: time_pattern
      # You can also match on interval. This will match every 5 minutes
      minutes: "/15"
 
condition:
  - condition: template
    value_template: '{{ sensors != '''' }}'
 
action:
  - choose: []
    default: !input 'actions'
 
mode: single

{% endverbatim %} Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

part 1 | part 2 | part 3

programminghomeassistantautomation