Skip to content

Instantly share code, notes, and snippets.

@finity69x2
Last active July 25, 2022 20:23
Show Gist options
  • Save finity69x2/7b50d2ba8b9d504a144b8ba66e3f2b18 to your computer and use it in GitHub Desktop.
Save finity69x2/7b50d2ba8b9d504a144b8ba66e3f2b18 to your computer and use it in GitHub Desktop.
Home Assistant Configuration for Adding Weather Alerts from the US NWS using a Custom Sensor
This will allow several functions including a persistent pop-up notification on your HA front end, a notification to whichever notify service you use (I’m using Pushbullet in this example), and, if you use another custom component (https://community.home-assistant.io/t/echo-devices-alexa-as-media-player-testers-needed/58639), it will also trigger an announcement to all of your Echo devices.
This integration uses a custom sensor.
you can find the code and the instructions for use at the following location:
https://github.com/eracknaphobia/nws_custom_component
NOTE: you will need to change the name of the file dep[ending on the version of ha you are installing it in. The instructions in that repo makes a note of that.
I made some minor modifications to the code there:
I modified the update interval to 1 minute. (EDIT: I just noticed the latest version already has this set to a one minute update interval so disregard this if you have the latest version)
I also wanted to be able to split out the title, display_desc, and spoken_desc for the times that there are multiple alerts so that I will only get updates on the changes between them, not the entire message every time there is an update.
Here are the lines in the nws_alerts.py file to accomplish that (changes in bold):
Line 29:
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1)
Line 157:
display_desc += '\n\n-\n\n'
Line 168:
spoken_desc += '\n\n-\n\n'
Line 170:
spoken_desc += '\n\n-\n\n'
And I only want to get a notification if an alert is added (count increases) but not if one is removed.
You next need to find either your NWS Zone ID or County ID. It is better to use both ID's here.
You can find your Zone or County ID by going to https://alerts.weather.gov/, scroll down to your state and click on the “zone list” and/or "county list" then look for the entry for your county.
Once you have your desired ID you create a sensor, replacing my id (INZ009, INC033) with yours. The ID is case sensitive!
Then when you have your ID's, enter them into the configuration below
If you use the optional "name:" configuration entry then you will need to adjust your sensor entity_id in the automations and scripts to reflect the new sensor information.
Here are all the sections required in the configuration.yaml or, alternatively, if you use packages in Home Assistant you can copy the entire block of code below into a package ("packages:" goes under the "homeassistant:" section in configuration.yaml):
#################################################################################
#
# This is the package for NWS ALERTS USING THE CUSTOM COMPONENT
#
#################################################################################
######################## SENSOR ###############################################
sensor:
- platform: nws_alerts
zone_id: 'INZ009, INC033'
- platform: feedparser
name: NWS Alert RSS Feed
feed_url: 'https://alerts.weather.gov/cap/wwaatmget.php?x=INZ009&y=0'
date_format: '%a, %b %d %I:%M %p'
inclusions:
- title
- summary
- cap_expires
- platform: template
sensors:
nws_alerts_are_active:
friendly_name: NWS Alerts Are Active
entity_id: sensor.nws_alerts
value_template: >
{% if states.sensor.nws_alerts.state | int > 0 %}
on
{% else %}
off
{% endif %}
######################## AUTOMATION ###########################################
automation:
- alias: 'NWS Weather Alert Pop Up Control'
initial_state: 'on'
trigger:
- platform: state
entity_id: sensor.nws_alerts
- platform: homeassistant
event: start
condition:
- condition: template
value_template: '{{states.sensor.nws_alerts.state | int > 0}}'
- condition: template
value_template: '{{ trigger.to_state.state|float > trigger.from_state.state|float }}'
action:
service: script.nws_popup_on_wx_alert
data_template:
title: >
{% if states.sensor.nws_alerts.attributes.title.split(' - ')[5] is defined %}
"{{ states.sensor.nws_alerts.attributes.title.split(' - ')[5] }}"
{% elif states.sensor.nws_alerts.attributes.title.split(' - ')[4] is defined %}
"{{ states.sensor.nws_alerts.attributes.title.split(' - ')[4] }}"
{% elif states.sensor.nws_alerts.attributes.title.split(' - ')[3] is defined %}
"{{ states.sensor.nws_alerts.attributes.title.split(' - ')[3] }}"
{% elif states.sensor.nws_alerts.attributes.title.split(' - ')[2] is defined %}
"{{ states.sensor.nws_alerts.attributes.title.split(' - ')[2] }}"
{% elif states.sensor.nws_alerts.attributes.title.split(' - ')[1] is defined %}
"{{ states.sensor.nws_alerts.attributes.title.split(' - ')[1] }}"
{% else %}
"{{ states.sensor.nws_alerts.attributes.title.split(' - ')[0] }}"
{% endif %}
message: >
{% if states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[5] is defined %}
"{{ states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[5] }}"
{% elif states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[4] is defined %}
"{{ states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[4] }}"
{% elif states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[3] is defined %}
"{{ states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[3] }}"
{% elif states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[2] is defined %}
"{{ states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[2] }}"
{% elif states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[1] is defined %}
"{{ states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[1] }}"
{% else %}
"{{ states.sensor.nws_alerts.attributes.display_desc.split('\n\n-\n\n')[0] }}"
{% endif %}
- alias: NWS Notification Weather Alert
initial_state: 'on'
trigger:
platform: state
entity_id: sensor.nws_alerts
condition:
- condition: template
value_template: '{{states.sensor.nws_alerts.state | int > 0}}'
- condition: template
value_template: '{{ trigger.to_state.state|float > trigger.from_state.state|float }}'
action:
- service: notify.pushbullet_notify
data_template:
message: >
{% if states.sensor.nws_alerts.attributes.title.split(' - ')[5] is defined %}
"NWS: {{ states.sensor.nws_alerts.attributes.title.split(' - ')[5] }}"
{% elif states.sensor.nws_alerts.attributes.title.split(' - ')[4] is defined %}
"NWS: {{ states.sensor.nws_alerts.attributes.title.split(' - ')[4] }}"
{% elif states.sensor.nws_alerts.attributes.title.split(' - ')[3] is defined %}
"NWS: {{ states.sensor.nws_alerts.attributes.title.split(' - ')[3] }}"
{% elif states.sensor.nws_alerts.attributes.title.split(' - ')[2] is defined %}
"NWS: {{ states.sensor.nws_alerts.attributes.title.split(' - ')[2] }}"
{% elif states.sensor.nws_alerts.attributes.title.split(' - ')[1] is defined %}
"NWS: {{ states.sensor.nws_alerts.attributes.title.split(' - ')[1] }}"
{% else %}
"NWS: {{ states.sensor.nws_alerts.attributes.title.split(' - ')[0] }}"
{% endif %}
- alias: NWS Announce Weather Alert
initial_state: 'on'
trigger:
- platform: state
entity_id: sensor.nws_alerts
condition:
condition: and
conditions:
- condition: template
value_template: "{{states.sensor.nws_alerts.state | int > 0}}"
- condition: template
value_template: '{{ trigger.to_state.state|float > trigger.from_state.state|float }}'
- condition: template
value_template: "{{ (('Severe' in states.sensor.nws_alerts.attributes.title) or ('Tornado' in states.sensor.nws_alerts.attributes.title)) and 'Warning' in states.sensor.nws_alerts.attributes.title }}"
action:
- service: media_player.volume_set
data:
entity_id:
- media_player.computer_room_dot
- media_player.kitchen_dot
- media_player.livingroom_dot
- media_player.master_bedroom_dot
volume_level: 0.9
- service: notify.alexa_media
data_template:
target:
- media_player.computer_room_dot
- media_player.kitchen_dot
- media_player.livingroom_dot
- media_player.garage_dot
- media_player.big_room_dot
data:
type: announce
message: >
{% if states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[5] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[5] }}
{% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[4] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[4] }}
{% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[3] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[3] }}
{% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[2] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[2] }}
{% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[1] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[1] }}
{% else %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[0] }}
{% endif %}
- delay: '00:00:15'
- service: notify.alexa_media
data_template:
target:
- media_player.computer_room_dot
- media_player.kitchen_dot
- media_player.livingroom_dot
- media_player.garage_dot
- media_player.big_room_dot
data:
type: announce
message: >
{% if states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[5] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[5] }}
{% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[4] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[4] }}
{% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[3] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[3] }}
{% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[2] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[2] }}
{% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[1] is defined %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[1] }}
{% else %}
Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[0] }}
{% endif %}
- alias: NWS Announce Weather Alert for MBR
initial_state: 'on'
trigger:
- platform: state
entity_id: sensor.nws_alerts
condition:
condition: and
conditions:
- condition: template
value_template: "{{states.sensor.nws_alerts.state | int > 0}}"
- condition: template
value_template: "{{ 'Tornado' in states.sensor.nws_alerts.attributes.title and 'Warning' in states.sensor.nws_alerts.attributes.title }}"
action:
- service: media_player.volume_set
data:
entity_id:
- media_player.computer_room_dot
- media_player.kitchen_dot
- media_player.livingroom_dot
- media_player.master_bedroom_dot
volume_level: 0.9
- service: notify.alexa_media
data:
target: media_player.master_bedroom_dot
data:
type: announce
message: "Attention!,,,Attention!,,,The National Weather Service Has issued a Tornado Warning for our area."
- delay: '00:00:15'
- service: notify.alexa_media
data:
target: media_player.master_bedroom_dot
data:
type: announce
message: "Attention!,,,Attention!,,,The National Weather Service Has issued a Tornado Warning for our area."
################################# SCRIPT ###################################
script:
nws_popup_on_wx_alert:
alias: NWS Weather Alert Pop Up
sequence:
## Dismiss any current alert so the UI isn't filled
## up with these if there are more then one.
## Only show the latest alert
- service: persistent_notification.dismiss
data:
notification_id: "nwswxalert"
## Create a new persistant notification in the UI for a new alert
- service_template: >
{% if states.sensor.nws_alerts.state != '0' %}
persistent_notification.create
{% endif %}
data_template:
notification_id: "nwswxalert"
message: "{{ message }}"
title: '{{ title }}'
##################################################################################
I created two announcements so that a minor event won't wake you up in the middle of the night.
You’ll notice I repeat the announcement twice in case the first announcement doesn’t wake you up.
And I haven’t worked out the volume setting part yet. If anyone has any working solutions feel free to let me know.
The script above generates a persistent notification pop-up.
3/15/2019 - updated to use the updated code for the alexa media player TTS custom component.
@finity69x2
Copy link
Author

@SP410

Hey, I'm really sorry I didn't see you message before now. I'm not sure why I never got any notification that I had a comment here. Maybe it would be best to hit me up at the HA forum for any other questions since I'm confident that I'll definitely see the messages there.

Anyway,

The input boolean was only for some testing I was doing in my lovelace config to actually create a real persistent notification.

In lovelace the "persistent" notifications are really a misnomer since they get removed as soon as you restart Home Assistant.

So I was playing around with the custom "home-feed-card" to see if I could get the notification to stay after restarts but that card eventually became problematic itself so I don't use it anymore.

Bottom line - you can remove it from the config above. And I'll do the same.

Thank you for pointing it out. And thank you for your interest in this project. I'm glad it's helping people.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment