Severe Weather Alerts from the US National Weather Service

@NYC

I haven’t had any multiple alerts in a while. Maybe the NWS changed how they added active alerts. I’m pretty sure that when I created this it all worked ok.

I’ll look into it a bit further and see if I can figure out how to send out a new announcement/message when the issued order is reversed (newest first [index 0] instead of last [index +1])

1 Like

Last time I had sever weather, yes all the alerts were played, which is fine by me.

I dug into the NWS API documentation to see if I could help. Although I wasn’t able to find documentation, I confirmed with NWS that the order is newest to oldest based on sent time. FWIW, here are my updates to the 4 automations:

Severe or Tornado Warning:

...
- id: '[uniqueID]'
  alias: 'NWS Weather Alert - Announce'
  description: Announce on Severe Warning or Tornado Warning
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.nws_alerts
  condition:
    condition: and
    conditions:
      - condition: template
        value_template: "{{ states('sensor.nws_alerts') | int > 0 }}"
      - condition: template
        value_template: "{{ trigger.to_state.state|float > trigger.from_state.state|float }}"
      - condition: template
        value_template: "{{ ((('Severe' in(state_attr('sensor.nws_alerts','title').split(' - ')[0])) or ('Tornado' in(state_attr('sensor.nws_alerts','title').split(' - ')[0]))) and ('Tornado' in(state_attr('sensor.nws_alerts','title').split(' - ')[0]))) }}"
      # Alert only if someone is home
      - condition: state
        entity_id: group.people
        state: 'on'
  action:
    - service: media_player.volume_set
      data:
        entity_id: media_player.[EchoName]
        volume_level: 0.5
    - delay: '00:00:05'
    - service: notify.alexa_media
      data_template:
        target: media_player.[EchoName]
        data:
          type: announce
        message: >
          Attention!,,,Attention!,,,The National Weather Service Has issued a {{ state_attr('sensor.nws_alerts','spoken_desc').split('\n\n-\n\n')[0] }}
    - delay: '00:00:15'
    - service: notify.alexa_media
      data_template:
        target: media_player.[EchoName]
        data:
          type: announce
        message: >
          Attention!,,,Attention!,,,The National Weather Service Has issued a {{ state_attr('sensor.nws_alerts','spoken_desc').split('\n\n-\n\n')[0] }}

Wake Up on Tornado Warning

...
- id: '[UniqueID]'
  alias: 'NWS Weather Alert - Bedroom Announce'
  description: Announce on Bedroom Echo if Tornado Warning Issued 
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.nws_alerts
  condition:
    condition: and
    conditions:
      - condition: template
        value_template: "{{ states('sensor.nws_alerts') | int > 0 }}"
      - condition: template
        value_template: "{{ (('Tornado' in(state_attr('sensor.nws_alerts','title').split(' - ')[0])) and ('Warning' in(state_attr('sensor.nws_alerts','title').split(' - ')[0]))) }}"
      # Alert only if someone is home
      - condition: state
        entity_id: group.people
        state: 'on'
  action:
    - service: media_player.volume_set
      data:
        entity_id:
           - media_player.[EchoName]
        volume_level: 0.5
    - service: notify.alexa_media
      data:
        target: media_player.[EchoName]
        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.[EchoName]
        data:
          type: announce
        message: "Attention!,,,Attention!,,,The National Weather Service Has issued a Tornado Warning for our area."

Send Notification on all NWS Alerts

...
- id: '[UniqueID]'
  alias: 'NWS Weather Alert - Notify'
  description: Send Notifications on All NWS Alerts
  initial_state: 'on'
  trigger:
    platform: state
    entity_id: sensor.nws_alerts
  condition:
    - condition: template
      value_template: "{{ states('sensor.nws_alerts') | int > 0 }}"
    - condition: template
      value_template: "{{ trigger.to_state.state|float > trigger.from_state.state|float }}"
  action:
    - service: notify.[Target]
      data_template:
        message: >
          NWS: {{ state_attr('sensor.nws_alerts','title').split(' - ')[0] }}

Pop up Notification in Home Assistant

...
- id: '[UniqueID]'
  alias: 'NWS Weather Alert Pop Up Control'
  description: Create Pop Up in HA for All NWS Alerts
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.nws_alerts
    - platform: homeassistant
      event: start
  condition:
    - condition: template
      value_template: "{{ states('sensor.nws_alerts') | 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: >
        {{ state_attr('sensor.nws_alerts','title').split(' - ')[0] }}
      message: >
        "{{ state_attr('sensor.nws_alerts','display_desc').split('\n\n-\n\n')[0] }}"

The script remains unchanged:

...
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 }}'

3 Likes

Thanks for looking into it.

But yeah, I was thinking about it and concluded that the only way to do it would just be to look for index[0] since that would always be the latest one sent and since they would have all cycled thru index[0] at some point you end up seeing all of them. Which is what you ended up doing so good job on that.

And it has the benefit of reducing the complexity of the templates too.

I’ll test it as much as I can but the issue is we don’t typically get multiple alerts on a regular basis (which is good! :smile:). I think it should work tho.

Thanks again!

EDIT:

I have to say I’m really impressed by the responsiveness of the NWS code guys on the github issues. I’ve contacted them recently myself and got a reply within a short time.

Unfortunately, during this time of year, we regularly have multiple active alerts. All worked well today when we had two or three alerts going.

Thanks for all your work on this. NYC lost its NOAA weather radio a few years ago and only recently got it back. I was using this as a replacement until NOAA finally restored the tower. With restoration of the tower, we’ll continue to use this as our backup.

Thanks for the useful integration option! I’ve never liked any of the apps for Android to inform me of severe weather events, so I always wanted to set something like this up myself. I’ve taken your utility and incorporated it into node red, which I don’t see having been done just yet in this thread. Feel free to build upon/change my flow as needed.

The flow has a switch to enable only certain weather alerts from sending out, in addition to preventing duplicate alerts from being sent. Since all testing for this really needs to be done during an actual weather alert, I haven’t been able to fully test everything (I don’t know the exact verbiage to expect for instance, though I figure it’s pretty self explanatory).

I also included a cast node for Google Home devices, but since I don’t have an Alexa device I don’t know how to set it up for those.

[{"id":"f2706b35.4906e","type":"ha-get-entities","z":"f1e1b905.e9a56","server":"497693ef.d5e6bc","name":"Retrieve Weather Alert","rules":[{"property":"entity_id","logic":"is","value":"sensor.nws_alerts","valueType":"str"},{"property":"state","logic":"is_not","value":"0","valueType":"str"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":230,"y":980,"wires":[["ff9a7aa4.34c04"]]},{"id":"da43a5e8.36b758","type":"api-call-service","z":"f1e1b905.e9a56","name":"Send Notification","server":"497693ef.d5e6bc","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_yourdevicehere","entityId":"","data":"{\"title\":\"Severe Weather Event\",\"message\":\"{{payload}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1590,"y":827,"wires":[[]]},{"id":"80424c86.40dbe8","type":"server-state-changed","z":"f1e1b905.e9a56","name":"Is there a severe weather event?","server":"497693ef.d5e6bc","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.nws_alerts","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"0","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"x":170,"y":908,"wires":[["f2706b35.4906e"],[]]},{"id":"b2a217d7.20bd7","type":"template","z":"f1e1b905.e9a56","name":"Format Weather Alert Description ","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"The National Weather Service has issued a ({{payload.0.attributes.title}}) for your area. {{payload.0.attributes.spoken_desc}}","output":"str","x":1000,"y":827,"wires":[["88a10452.43207"]]},{"id":"88a10452.43207","type":"rbe","z":"f1e1b905.e9a56","name":"Does value match previous value?","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":1320,"y":827,"wires":[["da43a5e8.36b758"]]},{"id":"e913d18a.d31ed8","type":"switch","z":"f1e1b905.e9a56","name":"Type of alert","property":"payload","propertyType":"msg","rules":[{"t":"neq","v":"","vt":"str"},{"t":"cont","v":"Watch","vt":"str"},{"t":"cont","v":"Warning","vt":"str"},{"t":"cont","v":"Tornado Warning","vt":"str"},{"t":"cont","v":"Advisory","vt":"str"}],"checkall":"true","repair":false,"outputs":5,"x":450,"y":927,"wires":[["c930075.26fa078","a237bab7.efb9f"],["c930075.26fa078"],["693351d.de90c3"],["bdc154a2.f604b"],[]],"outputLabels":["Export all alerts","Export only \"Watch\"","Export only \"Warning\"","Export only \"Tornado Warning\"","Export only \"Advisory\""]},{"id":"8839a3cb.b313f8","type":"template","z":"f1e1b905.e9a56","name":"Format Weather Alert Description ","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"The National Weather Service has issued a ({{payload.0.attributes.title}}) for your area. {{payload.0.attributes.spoken_desc}}","output":"str","x":1000,"y":947,"wires":[["dd62355b.93c268"]]},{"id":"dd62355b.93c268","type":"rbe","z":"f1e1b905.e9a56","name":"Does value match previous value?","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":1320,"y":947,"wires":[["9fa1242a.538a3","b3933094.a5fde8"]]},{"id":"3a54bcd4.937aa4","type":"template","z":"f1e1b905.e9a56","name":"Format Weather Alert Description ","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"The National Weather Service has issued a ({{payload.0.attributes.title}}) for your area. {{payload.0.attributes.spoken_desc}}","output":"str","x":1000,"y":1007,"wires":[["419ac4dc.743ed4"]]},{"id":"419ac4dc.743ed4","type":"rbe","z":"f1e1b905.e9a56","name":"Does value match previous value?","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":1320,"y":1007,"wires":[["790322e4.9f383c"]]},{"id":"9fa1242a.538a3","type":"cast-to-client","z":"f1e1b905.e9a56","name":"Cast alert to speaker","url":"","contentType":"","message":"","language":"en","ip":"Your IP Here","port":"","volume":"40","x":1609,"y":947,"wires":[[]]},{"id":"b3933094.a5fde8","type":"api-call-service","z":"f1e1b905.e9a56","name":"Send Notification","server":"497693ef.d5e6bc","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_yourdevicehere","entityId":"","data":"{\"title\":\"Severe Weather Event\",\"message\":\"{{payload}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1600,"y":995,"wires":[[]]},{"id":"790322e4.9f383c","type":"api-call-service","z":"f1e1b905.e9a56","name":"Send Notification","server":"497693ef.d5e6bc","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_yourdevicehere","entityId":"","data":"{\"title\":\"Severe Weather Event\",\"message\":\"{{payload}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1600,"y":1047,"wires":[[]]},{"id":"4375289e.b147b","type":"template","z":"f1e1b905.e9a56","name":"Format Full Alert","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"The National Weather Service has issued a ({{payload.0.attributes.title}}) for your area. {{payload.0.attributes.display_desc}}","output":"str","x":952,"y":887,"wires":[["6f1e33df.08619c"]]},{"id":"2533a297.75979e","type":"e-mail","z":"f1e1b905.e9a56","server":"smtp.gmail.com","port":"465","secure":true,"tls":true,"name":"Your Email Address Here","dname":"Send emails","x":1570,"y":887,"wires":[]},{"id":"6f1e33df.08619c","type":"rbe","z":"f1e1b905.e9a56","name":"Does value match previous value?","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":1320,"y":887,"wires":[["2533a297.75979e"]]},{"id":"ff9a7aa4.34c04","type":"template","z":"f1e1b905.e9a56","name":"Store type of alert","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{payload.0.attributes.title}}","output":"str","x":330,"y":1040,"wires":[["e913d18a.d31ed8"]]},{"id":"a237bab7.efb9f","type":"ha-get-entities","z":"f1e1b905.e9a56","server":"497693ef.d5e6bc","name":"Retrieve Weather Alert","rules":[{"property":"entity_id","logic":"is","value":"sensor.nws_alerts","valueType":"str"},{"property":"state","logic":"is_not","value":"0","valueType":"str"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":710,"y":827,"wires":[["b2a217d7.20bd7"]]},{"id":"c930075.26fa078","type":"ha-get-entities","z":"f1e1b905.e9a56","server":"497693ef.d5e6bc","name":"Retrieve Weather Alert","rules":[{"property":"entity_id","logic":"is","value":"sensor.nws_alerts","valueType":"str"},{"property":"state","logic":"is_not","value":"0","valueType":"str"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":710,"y":887,"wires":[["4375289e.b147b"]]},{"id":"693351d.de90c3","type":"ha-get-entities","z":"f1e1b905.e9a56","server":"497693ef.d5e6bc","name":"Retrieve Weather Alert","rules":[{"property":"entity_id","logic":"is","value":"sensor.nws_alerts","valueType":"str"},{"property":"state","logic":"is_not","value":"0","valueType":"str"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":710,"y":947,"wires":[["8839a3cb.b313f8"]]},{"id":"bdc154a2.f604b","type":"ha-get-entities","z":"f1e1b905.e9a56","server":"497693ef.d5e6bc","name":"Retrieve Weather Alert","rules":[{"property":"entity_id","logic":"is","value":"sensor.nws_alerts","valueType":"str"},{"property":"state","logic":"is_not","value":"0","valueType":"str"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":710,"y":1007,"wires":[["3a54bcd4.937aa4"]]},{"id":"d8441dfd.276d38","type":"cast-to-client","z":"f1e1b905.e9a56","name":"Cast alert to speaker","url":"","contentType":"","message":"","language":"en","ip":"Your IP Here","port":"","volume":"40","x":1610,"y":1096,"wires":[[]]},{"id":"497693ef.d5e6bc","type":"server","z":"","name":"Home Assistant"}]

EDIT 07/22/2020: Found an issue with the flow where the switch would only export the first value. Updated the flow, everything should work now.

1 Like

Thanks for adding to this functionality to the thread! :+1:

I have next to zero experience with node-red so I don’t know how much help I can be in testing it for you.

Are there any special nodes that need to be included in node-red for this to work or can someone just copy your flow over to node-red and get things to work (after updating entities to their own, I assume)?

Thanks! Completely up to you if you wanted to test, I meant my comment as more of a disclaimer. I will definitely be testing it until I’m officially satisfied. I’ve only had excessive heat advisories to work off of so far though… Never been more excited for a severe weather event to happen in my life!

To the best of my knowledge, there shouldn’t be anything extra needed for node red. The only possible exception is the rbe node, but I believe that one is included in the base version now. Everything else should be installed by default. Worst case when someone imports it will mention which nodes are missing, and they can go in and import the missing options from the manage palette option.

Today I had the problem that my NWS alert sensors goes multiple times from ‘no event’ to ‘heat advisory’:

Of course this triggered multiple announcements via my automation.

Not sure what has changed since the same event worked flawless one week earlier (only changed to the event once until expired) and I did not change anything on home assistant in the meantime. I’d be glad if anyone can point me into the direction where to look for this flaw as I am no expert with the scripts for the sensors.
Thanks!

Unfortunately the NWS web API isn’t the most reliable at times and goes to “unavailable”. At that point the sensor may reflect that unreliability. I had exactly the same issue as you did and got over 130 notifications about the heat advisory.

ex

Luckily (and TBH) I only use the announcements for severe weather (tornado or severe thunderstorm warnings) for that reason. It’s easier to ignore a bunch of pushbullet notifications than the Echo’s going off every couple of minutes for the exact same alerts.

I changed the custom component a while back to try to see if I could filter out duplicate notifications but I haven’t had a chance to dig in and try to work out a filter scheme yet but I really need to get that done.

I’ll let you know if I get anything worked out.

1 Like

As a matter of fact, even right now the NWS API site is showing as unavailable as I’m trying to do some tests.

It kind of sucks… :frowning_face:

Odd they even closed my ticket regarding the API being flaky. :frowning:

Of course. “There’s nothing to see here. Move along…” :neutral_face:

But seriously tho, I’m surprised with that since the couple of times I’ve interacted with the devs and from the experience of NYC above they seem to be pretty responsive.

Well it was the “ok api’s fixed” then the next day it was broken again.

Hey, they fixed it again! It’s back up.

Until tomorrow… or in an hour…or a minute. Whichever occurs first. :wink:

1 Like

Well, fingers crossed that it becomes stable again and stays that way. Thanks for your replies and all your efforts!

1 Like

It was stable for a few hours, but it’s starting to slip.

Screen Shot 2020-07-26 at 4.59.04 PM

I haven’t made much headway on the filter but in my testing I found (and fixed!! :smile:) a bug that had been confounding me for the last few hours.

eracknaphobia had originally set up the sensor to only display events that weren’t labeled the same.

So, for example, if you have several alerts that are all called “Special Weather Statement” then there would only be one alert displayed in the sensor and it would be the first one in the list.

I was using zone AKC290 (for somewhere in alaska) that was supposed to have 4 alerts going and for the reason above the sensor was only showing one alert active.

But it’s fixed now and it should be showing up in HACS as release 1.2 pretty soon.

Now that I’ve got that sorted out I can finally get back to the original problem. :disappointed_relieved:

1 Like

Congrats on the bug squashing. I was trying to think through the logic to smooth out the instability of the API. Could you use a combination of ID and messageType? I’m not familiar enough with what data you can store with these components. I have to cheat in my other automations and use input_datetime and other helpers.

I’m actually trying to use a custom variable component to save a history of all the event_id’s. Then I can use those attributes to do a compare to see if the new event_id is in the list.

But using the raw event_id list could (will…?) easily exceed the 255 character limit of the state. so I’m trying to work out some fancy templating to just use the last 7 digits of each of the entity_id’s in the list.

Or it might be easier if I try to do it in the component itself.

I haven’t fully decided yet.

edit:

I’ve decided to make the cut in the component itself.

So instead of the event_id being like:

"https://api.weather.gov/alerts/NWS-IDP-PROD-4351124---https://api.weather.gov/alerts/NWS-IDP-PROD-4351112---https://api.weather.gov/alerts/NWS-IDP-PROD-4349794---https://api.weather.gov/alerts/NWS-IDP-PROD-4349765"

it will just be:

4351124---4351112---4349794---4349765

then if i do that I can get rid of the extra dashes and make the list consistent with the other lists in the attributes:

4351124-4351112-4349794-4349765

Hopefully they always use the same format for the event_id’s.

Also I had a feature request to add some other data from the alerts (severity, certainty) so I’m also in the process of doing that too.

I don’t think it should break anything tho. Just be aware that you may need to change your templates for extracting data from the attributes depending on how you split it up. And that’s if you are even using the event_id’s at all.

2 Likes