Severe Weather Alerts from the US National Weather Service

Probably…I don’t think it should hurt to leave it there and HACS should just overwrite the files but I’ve had some strange stuff go on with the atomic calendar card so just to be safe I would go ahead and delete the existing one first.

My migration to HACS was successful. I deleted the existing nws_alerts folder from custom components, rebooted HA, installed nws alerts using HACS, and rebooted HA. I left the sensor entries in my config file and everything worked after the final reboot. @finity, thanks again for your work on this.

2 Likes

I’ve set up similar to you where it only alerts overnight if there is a warning, but today I ran into an issue. In this case, the first alert in the chain (the 0 indexed one) was a watch and the [1] indexed alert was a warning. Is there any way to alert if any of the entries in the array are a warning and then announce specific to that one short of creating multiple automations?

EDIT: I just saw this gist you had posted - https://gist.github.com/finity69x2/7b50d2ba8b9d504a144b8ba66e3f2b18 - that might point me in the right direction. It’s difficult to test this when there’s not an active warning going on in the area!

If you don’t get it worked out from info at the gist then post your automation and I’ll see if I can help.

@finity, thank you for your hard work on this. I set it up today and made a pretend event. The wife was excited when she heard it over all the echo’s.

2 Likes

Has anyone managed to get this working with a Google Home device yet? I’ve been trying for days to get the alerts to work on my Google Home Mini to no avail T_T

Post your automation so we can help.

I’m assuming your comment was directed at me. Here’s what I currently have in place (based on the nws_alerts_custom_package.yaml):

  alias: NWS Announce Weather Alert
  description: ''
  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: tts.google_translate_say
      data_template:
        target: 
          - media_player.mini_speaker
        data:
        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 %}

You action is wrong try this:

  alias: NWS Announce Weather Alert
  description: ''
  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: tts.google_translate_say
      entity_id: media_player.mini_speaker
      data_template:
        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 %}

Manually executing the automation with the else message just set to “test” doesn’t end up sending any message to my speaker. Not sure what the best way to test this automation is. Anyway, I saw this in the error log:

NWS Announce Weather Alert: Error executing script. Unexpected error for call_service at pos 1: Error rendering data template: UndefinedError: ‘None’ has no attribute ‘split’

Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 228, in async_render
return compiled.render(kwargs).strip()
File “/usr/local/lib/python3.7/site-packages/jinja2/environment.py”, line 1090, in render
self.environment.handle_exception()
File “/usr/local/lib/python3.7/site-packages/jinja2/environment.py”, line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File “/usr/local/lib/python3.7/site-packages/jinja2/_compat.py”, line 28, in reraise
raise value.with_traceback(tb)
File “”, line 1, in top-level template code
File “/usr/local/lib/python3.7/site-packages/jinja2/sandbox.py”, line 460, in call
if not __self.is_safe_callable(__obj):
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 1032, in is_safe_callable
return isinstance(obj, AllStates) or super().is_safe_callable(obj)
File “/usr/local/lib/python3.7/site-packages/jinja2/sandbox.py”, line 360, in is_safe_callable
getattr(obj, “unsafe_callable”, False) or getattr(obj, “alters_data”, False)
jinja2.exceptions.UndefinedError: ‘None’ has no attribute ‘split’
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/service.py”, line 132, in async_prepare_call_from_config
template.render_complex(config[CONF_SERVICE_DATA_TEMPLATE], variables)
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 72, in render_complex
return {key: render_complex(item, variables) for key, item in value.items()}
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 72, in
return {key: render_complex(item, variables) for key, item in value.items()}
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 74, in render_complex
return value.async_render(variables)
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 230, in async_render
raise TemplateError(err)
homeassistant.exceptions.TemplateError: UndefinedError: ‘None’ has no attribute ‘split’
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/script.py”, line 153, in _async_step
self, f"async{cv.determine_script_action(self._action)}_step"
File “/usr/src/homeassistant/homeassistant/helpers/script.py”, line 656, in _async_call_service_step
*self._prep_call_service_step(), blocking=True, context=self._context
File “/usr/src/homeassistant/homeassistant/helpers/script.py”, line 252, in _prep_call_service_step
return async_prepare_call_from_config(self._hass, self._action, self._variables)
File “/usr/src/homeassistant/homeassistant/helpers/service.py”, line 135, in async_prepare_call_from_config
raise HomeAssistantError(f"Error rendering data template: {ex}") from ex
homeassistant.exceptions.HomeAssistantError: Error rendering data template: UndefinedError: ‘None’ has no attribute ‘split’

Correct since you don’t have an alert to parse it’s going to fail.

For 95% of the year we have no weather alerts.
Then from June to August we have severe monsoon alerts.

I do have the code working because I have tested it on areas that have weather alerts,
I would like to have a card based on this code that was posted to at least say there are currently no alerts so that I know the code is working.

#
# Weather Alert
#
          - type: "markdown"
            title: Weather Alert
            style: |
              ha-card {
              border-radius: 15px;
              background: rgba(255,255,240,0.9);
              background: #fff5bc;
              } 
            content: >-
              {% if states.sensor.nws_alert_event.attributes.features[0] is defined %}
                Headline   
        
                {{states.sensor.nws_alert_event.attributes.features[0].properties.headline }}

                Details
        
                {{states.sensor.nws_alert_event.attributes.features[0].properties.description }}

                Instructions

                {{states.sensor.nws_alert_event.attributes.features[0].properties.instruction }}
              {% else %}
                none
              {% endif %}

Screenshot from 2020-06-20 15-42-55

Though the card says Weather Alert, I would like it to say underneath something like “there are currently no alerts”

Any help greatly appreciated.
carltonb

What code are you using to get the alerts? the rest sensor or the custom integration?

Where is the “sensor.nws_alert_event” defined?

Based on the code you’ve posted it should say “none” if there’s no alerts.

That’s why I was asking where the sensor was defined.

If the sensor doesn’t exist it might give an error in the template and then nothing will be rendered for the markdown.

1 Like

It’s working now after a system reboot.
You know you try all the usual things to make it work (validate yaml, hard reset, delete cache) then after a reboot all is well.
Go figure.
Thanks for the suggestions.
carltonb

I could not find anything that worked with this setup.

In using the alexa integration how can one get a beep/siren (or some obnoxious noise) before the announcement.

I am usually listening to music when working at home, the kids have the TV on and the wife is banging pots and pans.
Thanks
carltonb

We had a cascade of alerts today from the NWS and it revealed a problem in my NWS Alert automations. I mostly copied the original automations from @finity’s repo and tweaked them to avoid issues during startup when the sensor isn’t ready. I’m still puzzling through fixes, but I’ll post some observations here to see if anyone else has solved this one.

Let’s start with the data from the sensor.nws_alerts:

attribution: Data provided by Weather.gov
title: Flash Flood Warning - Severe Thunderstorm Warning - Air Quality Alert
event_id: >-
  https://api.weather.gov/alerts/NWS-IDP-PROD-4311964-3618307---https://api.weather.gov/alerts/NWS-IDP-PROD-4311855-3618254---https://api.weather.gov/alerts/NWS-IDP-PROD-4311389
display_desc: |-
  Flash Flood Warning
  The National Weather Service in Upton NY has issued a

  * Flash Flood Warning for...
  Hudson County in northeastern New Jersey...
  Eastern Passaic County in northeastern New Jersey...
  Southeastern Bergen County in northeastern New Jersey...
  Northeastern Essex County in northeastern New Jersey...
  Queens County in southeastern New York...
  Bronx County in southeastern New York...
  Kings County in southeastern New York...
  New York (Manhattan) County in southeastern New York...

  * Until 700 PM EDT.

  * At 402 PM EDT, Doppler radar indicated thunderstorms producing
  heavy rain across the warned area. Up to one inch of rain has
  already fallen. Flash flooding is ongoing or expected to begin
  shortly.

  HAZARD...Flash flooding caused by thunderstorms.

  SOURCE...Radar indicated.

  IMPACT...Flooding of small creeks and streams, urban areas,
  highways, streets and underpasses as well as other
  drainage and low lying areas.

  * Some locations that will experience flooding include...
  New York, Jersey City, Paterson, Passaic, Hoboken, Bloomfield,
  Hackensack, Paramus, Ridgewood, Lyndhurst, Rutherford, Secaucus,
  Ridgefield, Rfk Bridge and Midtown Manhattan.
  Turn around, don't drown when encountering flooded roads. Most flood
  deaths occur in vehicles.

  Excessive runoff from heavy rainfall will cause flooding of urban
  areas, highways, streets and underpasses as well as other drainage
  areas and low lying spots.

  -

  Severe Thunderstorm Warning
  The National Weather Service in Upton NY has issued a

  * Severe Thunderstorm Warning for...
  Hudson County in northeastern New Jersey...
  Southeastern Bergen County in northeastern New Jersey...
  Queens County in southeastern New York...
  Bronx County in southeastern New York...
  New York (Manhattan) County in southeastern New York...

  * Until 415 PM EDT.

  * At 331 PM EDT, a severe thunderstorm was located over Hackensack,
  moving southeast at 10 mph.

  HAZARD...60 mph wind gusts and quarter size hail.

  SOURCE...Radar indicated.

  IMPACT...Minor hail damage to vehicles is possible. Expect wind
  damage to trees and power lines.

  * This severe thunderstorm will be near...
  Hackensack and Bergenfield around 335 PM EDT.
  Teterboro around 345 PM EDT.
  Englewood around 350 PM EDT.
  Ridgefield and Fort Lee around 405 PM EDT.
  New York and Mott Haven around 415 PM EDT.
  For your protection move to an interior room on the lowest floor of a
  building.

  Torrential rainfall is occurring with this storm, and may lead to
  flash flooding. Do not drive your vehicle through flooded roadways.

  -

  AIR QUALITY ALERT IN EFFECT FROM 11 AM THIS MORNING TO 11 PM EDT THIS EVENING
  The New York State Department of Environmental Conservation has
  issued an air quality health advisory for the following counties...

  Suffolk...Nassau...Richmond...Kings...Queens...New York...Bronx...Wes
  chester...Rockland.

  from 11 AM this morning to 11 PM EDT this evening.

  Air quality levels in outdoor air are predicted to be greater than
  an Air Quality Index value of 100 for the pollutant of Ground Level
  Ozone . The Air Quality Index...or AQI...was created as an easy way
  to correlate levels of different pollutants to one scale. The higher
  the AQI value...the greater the health concern.

  When pollution levels are elevated...the New York State Department
  of Health recommends that individuals consider limiting strenuous
  outdoor physical activity to reduce the risk of adverse health
  effects. People who may be especially sensitive to the effects of
  elevated levels of pollutants include the very young...and those
  with preexisting respiratory problems such as asthma or heart
  disease. Those with symptoms should consider consulting their
  personal physician.

  For additional information, please visit the New York State Department
  of Environmental Conservation website at, https://on.ny.gov/nyaqi,
  or call the Air Quality Hotline at 800-535-1345.
  None
spoken_desc: |-
  Flash Flood Warning

  -

  Severe Thunderstorm Warning

  -

  AIR QUALITY ALERT IN EFFECT FROM 11 AM THIS MORNING TO 11 PM EDT THIS EVENING
friendly_name: NWS Alerts
icon: 'mdi:alert'

That means there are three alerts in the sensor: Flash Flood Warning, Severe Thunderstorm Warning, and Air Quality Alert. They were issued in this order: Air Quality Alert, then Severe Thunderstorm Warning, then Flash Flood Warning.

I use data from the sensor.nws_alerts to trigger four automations:

  1. Announce All Echos for Severe Warning or Tornado Warning
  2. Announce on Bedroom Echo for Tornado Warning
  3. Send Notify Alert for All NWS Alerts
  4. Create HA Notification for All NWS Alerts

Each of these automations use some variation of the split() function in Jinja2 templates to identify the text of the message for the relevant alert. In other words, there is data in an attribute in the sensor that I split based on a delimiter, then use the relevant text in the array for messages. The existing automations use the data from the highest increment as the message text. For example:

...
        message: >
          {% if state_attr('sensor.nws_alerts','title').split(' - ')[5] is defined %}
            NWS: {{ state_attr('sensor.nws_alerts','title').split(' - ')[5] }}
          {% elif state_attr('sensor.nws_alerts','title').split(' - ')[4] is defined %}
            NWS: {{ state_attr('sensor.nws_alerts','title').split(' - ')[4] }}
          {% elif state_attr('sensor.nws_alerts','title').split(' - ')[3] is defined %}
            NWS: {{ state_attr('sensor.nws_alerts','title').split(' - ')[3] }}
          {% elif state_attr('sensor.nws_alerts','title').split(' - ')[2] is defined %}
            NWS: {{ state_attr('sensor.nws_alerts','title').split(' - ')[2] }}
          {% elif state_attr('sensor.nws_alerts','title').split(' - ')[1] is defined %}
            NWS: {{ state_attr('sensor.nws_alerts','title').split(' - ')[1] }}
          {% else %}
            NWS: {{ state_attr('sensor.nws_alerts','title').split(' - ')[0] }}
          {% endif %}

The issue is that the alerts are added to the sensor data by adding them to the 0 position in the array, not in +1 position. So each time a new alert is issued, I received the same message that described the oldest alert, the Air Quality Alert, because the array position for the air quality alert kept increasing as new alerts were added.

The easiest fix is to eliminate the if statements and use solely the array in the 0 position, like this:

...
          message: '{{ NWS: {{ state_attr('sensor.nws_alerts','title').split(' - ')[0]  }}'

But if I want the Echo devices to announce only if the alert is a severe warning or tornado warning, then I’ll need to add a condition that looks for that text in the 0 position in the array.

Before I attempt to tweak my NWS Alert automations, has anyone else been down this road and addressed the issue?

I use this to broadcast alerts over my google home devices:

 - alias: NWS Announce Weather Alert
   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:
     - delay: 00:00:02
     - service: script.house_annoucement  
       data_template:
         this_message: >
           {% if states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[5] is defined %}
             "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 %}
             "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 %}
             "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 %}
             "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 %}
             "The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[1] }}"
           {% else %}
             "The National Weather Service Has issued a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[0] }}"
           {% endif %}
         volume: 0.9

If you have multiple active alerts, it looks like you’ll run into the same issue I did. Have you run into a situation with multiple active alerts? If so, did you continue to get the oldest one repeated each time a new alert was issued?