War Safety¶
In 2022, Russia launched a full-scale invasion of Ukraine, waging a genocidal war against my country. Ukraine is being hit by all types of weapons (except nuclear) daily. Home Assistant helps me stay safe and notifies me about incoming threats.
We hear the siren a few times a day. Life would completely stop if we went to the shelter every time the siren goes off. So, people adapt.
In Ukraine, we tend to differentiate the levels of danger. When the siren goes off, practically everyone starts checking their phones: "What is going on?"
We have various applications and Telegram channels for monitoring the type of danger, missile paths, and understanding whether we are in direct danger or can continue with our lives for another minute.
This is what war in the 21st century looks like: you can practically monitor a missile or a drone that is trying to kill you right from your phone. This is like a Black Mirror episode in real life. 😅
There are different kinds of air alarms with varying levels of danger:
- MiG-31K take off – This can happen multiple times during the day. The MiG-31K can carry a very dangerous Kh-47M2 Kinzhal hypersonic missile. Although it happens rarely, you can't predict when the missile is attached and when it is not, so most people tolerate this level of danger.
- Suicide drones attack – Usually carried out by Iranian Shahed 136 drones. Most of them get shot down, but they are still dangerous and scary. We call them "mopeds" or "lawn-mowers" because of the sound of their engine.
- Ballistic missile attack – This can happen multiple times a day. Ballistic missiles, like the 9K720 Iskander, are extremely fast (2 km/s). You have only up to 10 minutes to hide somewhere. Usually, the fastest way is to hide behind two walls (corridor or a bathroom).
- Cruise missile attack – Cruise missiles, like the Kalibr, are relatively slow and fly like a plane. Nevertheless, they can fly a long distance and easily reach any point in the country.
Of course, the most dangerous type of attack is a combined one. This means all of the above are raining down on Ukrainian cities simultaneously. These usually happen overnight at 4:00 in the morning. The drones and cruise missiles are used to exhaust air defenses, followed by ballistic and/or hypersonic strikes.
Monitoring Air Alerts¶
Home Assistant has a built-in Ukraine Alarm integration. It monitors the nation-wide system of air alarms and toggles safety sensors in HA.
When there is any type of danger, I send a critical notification and announce the message on my smart speakers.
Of course, the air siren goes off on the streets, roaring across the city, so everyone hears the danger is approaching. But I made an automation to send a critical notification and speak at home speakers, so I certainly wake up to check what is going on.
id: air_siren_kyiv
alias: 'Alert: Air Siren in Kyiv'
description:
Air Alert announcement when we are in Kyiv. Sends critical notifications
and announces on speakers.
trigger:
- platform: state
entity_id: binary_sensor.alerts_kyiv_air
to: 'on'
from: 'off'
variables:
title: Air Alert goes off!
- platform: state
entity_id: binary_sensor.alerts_kyiv_air
to: 'off'
from: 'on'
variables:
title: It is safe now!
condition:
- alias: Someone is in Kyiv
condition: state
entity_id: sensor.family_in_kyiv
state: 'on'
action:
- service: script.announcement
data:
title: '{{ title }}'
force_speak: true # Speaks even in DND mode
notify_data:
group: air-alerts
push:
sound:
name: default
critical: 1
volume: 0.75
Scraping Monitoring Channels¶
I already mentioned we have various Telegram channels for monitoring the situation during an attack. Those channels provide live updates on dangers, flight paths, and the type of attack.
So often I found myself constantly checking my phone to understand whether I am in direct danger or can sleep for a few hours. I know it sounds crazy, and normal people would go straight to the nearby shelter, but this is life in Ukraine. You don't have to follow my reckless example. If you are in Ukraine, GO TO THE SHELTER!
I decided to automate it. Instead of reading these channels myself, I delegate this task to HA.
I use the HA Multiscrape custom integration for that. You may ask, "why do you need a custom component when HA has a built-in scraping component?" Yes, it does, but I need multiple sensors from a single scrape, and I need to work with lists of data. The built-in component has some limitations with that.
Monitoring Imminent Danger¶
Cruise missiles are usually carried and launched by Tu-95 bombers.
They fly to the missile launch sites for about 3 hours, launch their missiles, then it takes about 1-2 hours for missiles to fly to Kyiv. So there's some time to prepare a hideout (in my case, it's the bathroom), gather documents, and sleep for a few hours before the "show" begins.
Usually, it happens in the evening and means tonight will be a massive missile attack.
I have a sensor that checks the Telegram channels, scrapes the list of messages every 5 seconds, and checks if the latest message contains a specific set of words, like "take off" and "plane" and "tu-95". It also stores the latest message as an attribute.
multiscrape:
- name: War Monitor
resource: https://t.me/s/war_monitor
scan_interval: 5
list_separator: '|||'
binary_sensor:
- unique_id: imminent_attack_in_war_monitor
name: Imminent Attack in War Monitor
icon: mdi:airplane-clock
device_class: safety
select_list: '.js-message_text'
value_template: >-
{% set message = value.split("|||") | last | lower %}
{{ "зліт" in message and "бортів" in message and "ту-95" in message }}
attributes:
- name: latest_message
select_list: '.js-message_text'
value_template: "{{ value.split('|||') | last }}"
So when the sensor turns on, it means the bombers are airborne and it's time to get ready. A notification is sent:
alias: 'Alert: Imminent Attack by Strategic Bombers'
description:
Send a notification when Tu-95 strategic bombers take off from Russian
airfields. This means an attack by cruise missiles is imminent. Prepare a hideout.
trigger:
- platform: state
entity_id:
- binary_sensor.imminent_attack_in_war_monitor
- binary_sensor.imminent_attack_in_operinform
from: 'off'
to: 'on'
action:
- service: script.announcement
data:
service: notify.all
speak: false
notify: true
title: 'Bombers take off 🛫'
messages:
- '{{ trigger.to_state.attributes.latest_message }}'
Direct Danger Alert¶
This is the most interesting sensor, which notifies me right when there's a direct threat to my location.
When an attack happens at night, you need to decide:
- Are you going to the shelter to get a sleepless night somewhere in a basement or in the subway?
- Or are you going to stay in bed as long as possible to get some sleep, because you need to go to work tomorrow?
Every normal person would go to the shelter. But when you live in these conditions for some time, you try to calculate the risk:
- You need to get proper sleep to be able to work.
- The air defenses are titans; they do their job excellently. Flying threats are getting shot down regularly.
- In Kyiv, the risk of a direct hit or hit by debris is relatively tolerable: I guess like being hit by a car (this estimate is completely unscientific!).
- If you are unlucky to catch a direct hit – you are dead anyway. There's very little chance to survive that.
- If the missile/drone gets shot down nearby, the shockwave will blow your windows.
So what do you do? It's up to you, but most of the time, I decide to sleep in bed. When things get hot, I hide in a bathroom so that when something blows up nearby, I will be behind two walls from glass shards and shockwaves.
I have a sensor that watches for specific keywords like "Kyiv" or a neighborhood name, for "warning" or "be in a safe place" or "fast target".
multiscrape:
- name: War Monitor
resource: https://t.me/s/war_monitor
scan_interval: 5
list_separator: '|||'
binary_sensor:
- unique_id: danger_in_war_monitor
name: Danger in War Monitor
icon: mdi:rocket-launch
device_class: safety
select_list: '.js-message_text'
value_template: >-
{% set message = value.split("|||") | last | lower %}
{% set in_kyiv = "київ" in message or "святошин" in message %}
{% set danger_now = "уважно" in message
or "швидкісна ціль" in message
or "подалі від зовнішніх стін" in message
or "безпечних місцях" in message
%}
{{ danger_now and in_kyiv }}
attributes:
- name: latest_message
select_list: '.js-message_text'
value_template: "{{ value.split('|||') | last }}"
When this sensor turns on, it means there's a direct danger to me and I should hide immediately. I send a critical notification, speak a danger message on speakers, so I can quickly wake up and go to the hideout.
alias: 'Alert: Danger in Kyiv'
description: Danger of missile/drone strike in Kyiv RIGHT NOW. Critical alert to
hide immediately.
trigger:
- platform: state
entity_id:
- binary_sensor.danger_in_war_monitor
- binary_sensor.danger_in_operinform
from: 'off'
to: 'on'
action:
- alias: Send a critical notification
service: script.announcement
data:
service: notify.all
speak: false
notify: true
title: Direct Danger ⚠️
messages:
- '{{ trigger.to_state.attributes.latest_message }}'
notify_data:
group: air-alerts
push:
sound:
name: default
critical: 1
volume: 1
- variables:
messages:
- Увага! Пряма загроза удару!
- Увага загроза удару по Києву!
- Увага! Негайно перейдіть до сховку!
- Увага! Негайно сховайтесь!
- Увага! Пряма загроза!
- Увага! Негайно сховайтесь!
- Увага! Атака на Київ!
- service: media_player.volume_set
entity_id:
data:
volume_level: 0.6
target:
device_id: media_player.bedroom_homepod
- alias: Speak in Bedroom
service: script.announcement
data:
speak: true
speaker: media_player.bedroom_homepod
notify: false
force_speak: true
messages: '{{ messages }}'
- delay:
hours: 2