More Home Assistant Automations
Following on from my pizza oven alarm post, I thought it was worth writing up some of the other home automations I have been running. Some of these have been in place for years, others are more recent additions. A few rely on MacroDroid — an Android automation app — working in tandem with Home Assistant via webhooks.
Arriving Home After Dark
When I arrive home after dark, the front door lights turn on at full brightness for ten minutes, then automatically switch off again.
Home Assistant does have its own presence detection, but I found it was too slow — often I would already be in the house by the time it registered that I had arrived. Using MacroDroid on the phone gives a much faster response, because it can combine two triggers: entering a GPS geofence around the house, or connecting to the home Wi-Fi network. Either one will fire the macro. The combination means it typically triggers before I have even reached the driveway.
Before doing anything, the macro checks two conditions. First, it must be after sunset — no point turning on lights in daylight. Second, a stopwatch that resets each time the macro fires must have been running for at least eight minutes. That second check prevents repeated triggering if the phone briefly drops off the Wi-Fi and reconnects, or drifts in and out of the geofence boundary.
If both conditions are satisfied, the macro makes an HTTP PUT request to a Home Assistant webhook. On the HA side, this triggers an automation that turns on the front door lights at full brightness and starts a ten-minute timer. When the timer finishes, a second automation turns the lights back off.
There is also a “leaving home” automation that turns off the lights when both adults have left the home zone, so there is no risk of them being left on all day.
The MacroDroid-to-HA webhook pattern is something I use in a few places. It lets me use the phone’s location and connectivity awareness — things MacroDroid handles very well — whilst leaving the actual smart home control to Home Assistant.
MacroDroid macro: The triggers are “Enter geofence: Home” and “Wi-Fi SSID in range: [your home SSIDs]”. The constraints are “After sunset” and “Stopwatch ‘Got home’ > 8 minutes”. The actions reset the stopwatch then make an HTTP PUT to the HA webhook URL.
Home Assistant automations:
# Turn on front door lights when arriving home after dark
- alias: Arrived Home After Dark
triggers:
- trigger: webhook
webhook_id: "arrived-home-after-dark"
allowed_methods: [PUT]
actions:
- action: light.turn_on
target:
area_id: front_door
data:
brightness_pct: 100
- action: timer.start
target:
entity_id: timer.arrived_home
data:
duration: "00:10:00"
# Turn lights off when the timer finishes
- alias: Arrived Home Complete
triggers:
- trigger: event
event_type: timer.finished
event_data:
entity_id: timer.arrived_home
actions:
- action: light.turn_off
target:
area_id: front_door
# Turn off front door lights when everyone has left the house
- alias: Leaving Home
triggers:
- trigger: zone
entity_id: person.adult_1
zone: zone.home
event: leave
- trigger: zone
entity_id: person.adult_2
zone: zone.home
event: leave
conditions:
- condition: not
conditions:
- condition: zone
entity_id: person.adult_1
zone: zone.home
- condition: not
conditions:
- condition: zone
entity_id: person.adult_2
zone: zone.home
actions:
- action: light.turn_off
target:
area_id: front_door
Children’s Bedroom Lights
Both children have loft beds with bright LED strips underneath. The LEDs are wired via smart switches that Home Assistant can control, but the only physical remote in each room is for the main ceiling light.
Rather than fitting extra remotes or switches, I set up automations that follow the main light’s brightness. When the main light is turned up above a high brightness threshold, the under-bed LEDs switch on. When the main light drops below a lower threshold — or is turned off entirely — they switch off. The gap between the two thresholds acts as a deadband, preventing the LEDs from flickering while someone is slowly adjusting the brightness.
The end result is that one remote effectively controls both the overhead light and the under-bed task lighting, without the children needing to think about it at all.
# Example for one child's room — repeat with different entities for the other
- alias: Set Child Bedroom Under-Bed Light
triggers:
- trigger: state
entity_id: light.bedroom_main_light
attribute: brightness
- trigger: state
entity_id: light.bedroom_main_light
actions:
- choose:
- conditions:
- condition: numeric_state
entity_id: light.bedroom_main_light
attribute: brightness
above: 190
sequence:
- action: light.turn_on
target:
entity_id: light.bedroom_under_bed
- conditions:
- condition: or
conditions:
- condition: numeric_state
entity_id: light.bedroom_main_light
attribute: brightness
below: 100
- condition: state
entity_id: light.bedroom_main_light
state:
- "off"
- unavailable
- unknown
sequence:
- action: light.turn_off
target:
entity_id: light.bedroom_under_bed
Note that HA represents brightness on a scale of 0–255, so above: 190 corresponds to roughly 75% brightness and below: 100 to roughly 40%.
The TV
Sharing Links from the Phone
One of my favourite automations is being able to share a link from my phone directly to the living room TV.
Home Assistant’s companion app registers itself as a share target on Android. When you share a URL to it, HA fires a mobile_app.share event containing the URL. An automation picks this up and checks whether the URL is a YouTube link using a regular expression. If it is, it extracts the video ID and launches the YouTube app on the TV at that specific video, rather than opening a browser. If the URL is not a YouTube link, it opens the TV’s built-in browser at that address instead.
The TV has a kids lock enabled, which requires a PIN before content will play. A parallel sequence handles this automatically: two seconds after launching the app (to give it time to open and show the PIN prompt), it sends the PIN digits as individual button presses to the TV, followed by Enter.
The whole thing means I can be reading something on my phone, tap Share, select Home Assistant, and it is playing on the TV within a few seconds.
- alias: Share to TV
triggers:
- trigger: event
event_type: mobile_app.share
actions:
- if:
- condition: template
value_template: >
{{ trigger.event.data.url | regex_match(
'^(?:https?:\/\/)?(?:www\.|m\.)?(?:youtube\.com\/(?:watch\?v=|shorts\/)|youtu\.be\/)([0-9A-Za-z_-]{11}).*'
) }}
then:
- variables:
vID: >
{{ trigger.event.data.url | regex_replace(
'^(?:https?:\/\/)?(?:www\.|m\.)?(?:youtube\.com\/(?:watch\?v=|shorts\/)|youtu\.be\/)([0-9A-Za-z_-]{11}).*$',
'v=\1'
) }}
- parallel:
- action: webostv.command
data:
entity_id: media_player.living_room_tv
command: system.launcher/launch
payload:
id: youtube.leanback.v4
contentId: "{{ vID }}"
- sequence:
- delay: "00:00:02"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: "1" # Replace these four digits with your PIN
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: "2"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: "3"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: "4"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: ENTER
else:
- parallel:
- action: webostv.command
data:
entity_id: media_player.living_room_tv
command: system.launcher/open
payload:
target: "{{ trigger.event.data.url }}"
- sequence:
- delay: "00:00:02"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: "1"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: "2"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: "3"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: "4"
- action: webostv.button
data:
entity_id: media_player.living_room_tv
button: ENTER
Notification When the TV Is Turned On
This one started as a parenting tool. When the TV is turned on, Home Assistant sends a notification to any adult who is currently at home, telling them what time it came on and offering a “Turn Off” button. The check for whether each adult is home is there to avoid spamming someone who is out at work with notifications they cannot act on. Tapping the button fires a separate automation that turns the TV off via the media player integration.
The idea was to make it obvious to the children that we would always know if they had turned the TV on without permission. These days they are well aware the notification exists, which is arguably just as effective as it ever was.
- alias: TV Is On
triggers:
- trigger: device
device_id: your_tv_device_id
domain: media_player
type: turned_on
actions:
- if:
- condition: zone
entity_id: person.adult_1
zone: zone.home
then:
- action: notify.mobile_app_adult_1_phone
data:
title: TV is on
message: "Someone turned on the TV at {{ now().strftime('%H:%M') }}"
data:
notification_icon: mdi:television
actions:
- action: TURN_OFF_TV
title: Turn Off
- if:
- condition: zone
entity_id: person.adult_2
zone: zone.home
then:
- action: notify.mobile_app_adult_2_phone
data:
title: TV is on
message: "Someone turned on the TV at {{ now().strftime('%H:%M') }}"
data:
notification_icon: mdi:television
actions:
- action: TURN_OFF_TV
title: Turn Off
- alias: Turn Off TV via Notification
triggers:
- trigger: event
event_type: mobile_app_notification_action
event_data:
action: TURN_OFF_TV
actions:
- action: media_player.turn_off
target:
entity_id: media_player.living_room_tv
Bluetooth Headphone Battery in Home Assistant
Home Assistant does a good job of tracking battery levels for devices — mobile phones, sensors, remote controls — but Bluetooth audio devices are a notable gap. There is no standard way for the Home Assistant mobile companion app to poll the battery level of a connected headset.
The solution uses MacroDroid on the phone. Android broadcasts a system intent (android.bluetooth.device.action.BATTERY_LEVEL_CHANGED) whenever a connected Bluetooth device reports a change in its battery level. MacroDroid can listen for system intents and extract values from the broadcast extras — in this case, the BATTERY_LEVEL extra is stored in a local variable.
The macro then POSTs that value as JSON to a Home Assistant webhook, but only when the value is not -1. Android uses -1 to indicate that the battery level is unknown or unavailable, so that constraint prevents spurious updates reaching HA.
On the Home Assistant side, the webhook automation reads the battery_level field from the JSON payload and writes it into an input_number helper. From there it appears on the dashboard alongside every other battery sensor.
MacroDroid macro: Trigger is “Intent received: android.bluetooth.device.action.BATTERY_LEVEL_CHANGED”, with the android.bluetooth.device.extra.BATTERY_LEVEL extra mapped to a local variable (e.g. bt_batt). The single action is an HTTP POST to the HA webhook with body {"battery_level": {lv=bt_batt}}, with a constraint that bt_batt != -1.
Home Assistant — helper and automation:
First, create an input_number helper for the battery level (this can also be done via the UI under Settings → Helpers):
input_number:
headphone_battery:
name: Headphone Battery
min: 0
max: 100
step: 1
unit_of_measurement: "%"
icon: mdi:headphones
Then the automation to receive updates from the webhook:
- alias: Update Headphone Battery
triggers:
- trigger: webhook
webhook_id: "headphone-battery-update"
allowed_methods: [POST]
actions:
- action: input_number.set_value
target:
entity_id: input_number.headphone_battery
data:
value: "{{ trigger.json.battery_level }}"
I have many other simple automations for example turning lights on and off at set times, but the ones listed here are the more interesting ones I thought it would be worth sharing. I hope this can be of help or inspiration to someone else.