Severe Weather Alerts from the US National Weather Service

there is an open issue on the github repo that has suggested alternative automations. I’ve been working on tweaking those a bit and I’m pretty sure I’m pretty much there.

I’ll be adding those to my repo shortly but here are the ones I’m using now for testing based on those:

automation:

  - alias: NWS Test - Mobile App Notifications
    id: nws_test_mobile_app_notifications
    description: ""
    trigger:
      - platform: state
        entity_id: sensor.nws_alerts_test
    condition:
      - condition: numeric_state
        entity_id: sensor.nws_alerts_test
        above: 0
    action:
      - repeat:
          sequence:
            - service: script.turn_on
              continue_on_error: true
              entity_id: script.notification_pushover_message
              data:
                variables:
                  target: my_phone
                  message: "NWS Test: {{ repeat.item.Event }}"
                  sound: echo
            - delay:
                seconds: 5
          for_each: "{{ trigger.to_state.attributes.Alerts | reject('in', trigger.from_state.attributes.Alerts) | sort(attribute='ID') | list() }}"
    mode: queued
    initial_state: "on"
    max: 10         


#################################################################


  - alias: NWS Test - Persistent Notifications
    id: nws_test_persistent_notifications
    description: ""
    trigger:
      - platform: state
        entity_id: sensor.nws_alerts_test
    condition: 
      - condition: numeric_state
        entity_id: sensor.nws_alerts_test
        above: 0
    action:
      - repeat:
          sequence:
            - service: script.nws_alerts_persistent_notification
              data:
                notification_id: "NWS_{{ repeat.item.ID }}"
                title: "NWS Test: {{ repeat.item.Event }}"
                message: "{{ repeat.item.Description }}"
            - delay:
                seconds: 5
          for_each: "{{ trigger.to_state.attributes.Alerts | reject('in', trigger.from_state.attributes.Alerts) | sort(attribute='ID') | list() }}"
    mode: queued
    initial_state: "on"
    max: 10
    
    
######################################################
    
    
  - alias: NWS Test - TTS Announcements
    id: nws_test_tts_announcements
    description: ""
    trigger:
      - platform: state
        entity_id: sensor.nws_alerts_test
    condition:
      - condition: numeric_state
        entity_id: sensor.nws_alerts_test
        above: 0
    action:
      - repeat:
          sequence:
            - variables:
                alert: "{{ repeat.item }}"
            - if:
                - condition: template
                  value_template: "{{ ('Tornado Warning' in alert.Event) and (alert.Type == 'Alert') }}"
              then:
                - service: script.turn_on
                  entity_id: script.nws_alerts_test_announce
                  data:
                    variables:
                      message: This is only a test. The National Weather Service Has issued a tornado warning for our area! this is only a test. 
                - delay:
                    minutes: 1
          for_each: "{{ trigger.to_state.attributes.Alerts | reject('in', trigger.from_state.attributes.Alerts) | list() | sort(attribute='ID') }}"
      - repeat:
          sequence:
            - variables:
                alert: "{{ repeat.item }}"
            - if:
                - condition: template
                  value_template: "{{ ('Severe Thunderstorm Warning' in alert.Event) and (alert.Type == 'Alert') }}"
              then:
                - service: script.turn_on
                  entity_id: script.nws_alerts_test_announce
                  data:
                    variables:
                      message: This is only a test. The National Weather Service Has issued a severe thunderstorm warning for our area! this is only a test.
                - delay:
                    minutes: 1
          for_each: "{{ trigger.to_state.attributes.Alerts | reject('in', trigger.from_state.attributes.Alerts) | list() | sort(attribute='ID') }}"
    mode: queued
    initial_state: "on"
    max: 10

Of course you’ll need to modify for your needs.

And in my production setup I use two different scripts for the announcements. one for tornados that announces everywhere and one for everything else that doesn’t announce in the bedrooms.

I may still tweak a bit but likely not much.

2 Likes

Wonderful, thank you guys! I will take a closer look as this stuff you sent :slight_smile:

1 Like

Since this seems to be gathering several examples, here’s what I have, combining some of what is above. Vertical stack card, but only display if the title contains “Watch” or “Warning” (see Watch/Warning/Advisory Definitions for the possible alerts and definitions, and https://www.weather.gov/media/alert/CAP_v12_guide_05-16-2017.pdf for even more definitions)

title: Alerts
type: vertical-stack
cards:
  - type: conditional
    conditions:
      - entity: sensor.nws_alerts
        state_not: '0'
    card:
      type: markdown
      content: |
        {% set num_alerts = states('sensor.nws_alerts_2') | int  %}
        {% for alert_num in range(num_alerts) %}
        {% set alert = state_attr('sensor.nws_alerts_2', 'Alerts')[alert_num].Event %}
        {% if 'Warning' in alert or 'Watch' in alert %}
        ---
        ## {{ state_attr('sensor.nws_alerts_2', 'Alerts')[alert_num].Event }}
        {{ state_attr('sensor.nws_alerts_2', 'Alerts')[alert_num].Description }}
        {% endif %}
        {% endfor %}

You could also trigger the display of the alert on other things, like the Severity being “Extreme” or “Severe” for example. I’m still working on the logic for notifications.

the examples shown above work pretty well.

what do those lack that you’re looking for?

Perhaps a better phrasing would be “still working through the notifications, because I’m figuring out notifications in general, and what I even want”. The persistent notification example seems good, I’m just trying to wrap my head around it!

1 Like

I have a FR in an issue from @GreyBandit which is also related to a request from @Sekonicpr above about the “ends” vs “expires” data from the API.

The request is to add “ends”.

I can actually see why the “ends” might be better data to provide than the “expires” data. TBH, I’m not really sure why “expires” is there but I think someone asked for that data a long time back.

I don’t use “expires” in any way personally so I have no strong opinion either way.

I resist the urge to make anything break but I also resist the urge to just add every field from the API to the attributes since it makes the sensor harder to read for us mere humans.

So the question I’ll ask here is does anyone actually use the “expires” in automations or rely on that data that using “ends” wouldn’t actually be a better alternative?

I’m suggesting replacing “expires” with “ends” instead of having both.

Seeing as how elections are in the air in the US i’ll (hopefully) solve this question with a poll.

“ends” vs “expires”
  • Keep “expires” only
  • remove “expires” and add “ends” only
  • keep “expires” and still add “ends”
0 voters

the poll closes in 2 weeks so I’ll make the decision then.

but for full disclosure the option to have both will need to have a strong mandate to be implemented.

1 Like

So I’m a bit of a purist. The EAS message that comes through the SAME header format only has the fields for start time and duration. The duration is not a date/time it ends at, just how long after the message is issued that it will auto expire and no longer be active. You could use the issue date/time and add the duration to it to get expiration date/time, yes. And that information may be available over the API (which is different than the EAS message). So that said, personally I’d choose neither, but if I had to it would be just expires.

Here’s what an API response looks like:

Hello! I think we need both, or we need some logic … what I have found is that:

(1) When populated, “ends” is the best indicator of when the alert is no longer applicable. Looking at other web sites and how they present alerts for my area, this is always the value that is shown (when it is not null).

(2) However, “ends” is sometimes null. In those cases, the value for “expires” is the one that seems to communicate when the alert is no longer applicable.

I manually changed my local copy of your integration several months ago to add “ends”. I have also included this … which is admittedly a bit of a hack but has resulted in my alert end dates/times always matching what I see displayed elsewhere:

        if tmp_dict["Ends"] == None:
            tmp_dict["Ends"] = alert["properties"]["expires"]

Realizing this is a hack, I don’t expect you to implement the same. However, I would request both attributes be available so we can build the necessary logic into our dashboards. Thank you!

I’ve updated the example code in the “nws_alerts_package.yaml” at the repo using the above code. It’s way cleaner and doesn’t use any external dependencies.

thanks again to @T3chArmy for the suggestions. the ones I put in the repo are only minimally modified from their suggestions.

1 Like

I also just added the “Ends” attribute (keeping “Expires”) along with another requested “AreasAffected”.

the poll might not have had hardly any votes but the people spoke and I listened. No need to continue it.

:laughing:

2 Likes

Hi:
Thank for add end attribute. In the Headline attribute is there any way that when I use it for notifications it doesn’t show all caps?

Here is my test sensor converted to be capitalized lower case:

{{ state_attr('sensor.nws_alerts_test', 'Alerts')[0].Headline|title }}

the result was:

“HEAT ADVISORY REMAINS IN EFFECT UNTIL 8 PM PDT FRIDAY”

then after conversion:

“Heat Advisory Remains In Effect Until 8 Pm Pdt Friday”

you can make it all lower case by:

{{ state_attr('sensor.nws_alerts_test', 'Alerts')[0].Headline|lower }}

which results in:

“heat advisory remains in effect until 8 pm pdt friday”

or to capitalize the first letter of the sentence:

{{ state_attr('sensor.nws_alerts_test', 'Alerts')[0].Headline|capitalize }}

result:

“Heat advisory remains in effect until 8 pm pdt friday”

3 Likes

Thank finity now I have everything what I need!!!

1 Like

Pardon my ignorance, but the package file seems to be missing the Persistent Notifications script. Or am I looking in the wrong place? I keep getting an error that tells me that script.nws_alerts_persistent_notification is not a valid action.

1 Like

Are you using the newest version of the package contents or the previous version?

nevermind…

I found it. I forgot to add that script code.

it’s there now.

Thanks for letting me know.

1 Like

Hi. Is anyone sending these alerts via SMS/txt? I had it setup previously, but it is no longer working with the latest integration update. It would be great to sent the alerts in the same format as they appear in the alerts_tab.yaml file.(nws_alerts/lovelace/alerts_tab.yaml at 62343590e4db694db202980934ea839803830f95 · finity69x2/nws_alerts · GitHub)

This was my previously working automation. This would sent 1 notification for each new alert.

alias: SMS - Weather Alert - NWS Alert
description: ""
trigger:
  - platform: numeric_state
    entity_id: sensor.nws_alerts
    above: "0"
condition: []
action:
  - data:
      message: >-
        NWS Alert for XXXX

        {{state_attr('sensor.nws_alerts', 'title') }}

        Event Severity - {{state_attr('sensor.nws_alerts', 'event_severity') }}

        Event Status - {{state_attr('sensor.nws_alerts', 'event_status') }}

        Source - {{state_attr('sensor.nws_alerts', 'attribution') }}

        Description -  {{state_attr('sensor.nws_alerts', 'display_desc') }} 

        This alert was sent from the XXXX Home Assistant.  Save
        this number to your contacts for future reference.
    action: notify.sms_alerts_small_group
mode: single

I think you can use the same/similar code for the mobile app notification automation posted above or at the repo in the new version package.

this hasn’t been tested but might get you what you want. Except it won’t give you the attribution but since that is always a static value (it’s always “Data provided by Weather.gov”) so adding it as a template doesn’t really gain you anything. Just hard code it if you want it which is what I’ll do in the example:

automation:

  - alias: NWS - Mobile App Notifications
    id: nws_mobile_app_notifications
    trigger:
      - platform: state
        entity_id: sensor.nws_alerts
    condition:
      - condition: numeric_state
        entity_id: sensor.nws_alerts
        above: 0
    action:
      - repeat:
          sequence:
            - data:
                message: >-
                  NWS Alert for XXXX

                  {{ repeat.item.Event }}

                  Event Severity - {{ repeat.item.Severity }}

                  Event Status - {{ repeat.item.Status }}

                  Source - Data provided by Weather.gov

                  Description -  {{ repeat.item.Description }} 

                  This alert was sent from the XXXX Home Assistant.  Save this number to your contacts for future reference.
              action: notify.sms_alerts_small_group
            - delay:
                seconds: 5
          for_each: "{{ trigger.to_state.attributes.Alerts | reject('in', trigger.from_state.attributes.Alerts) | sort(attribute='ID') | list() }}"
    mode: queued
    initial_state: "on"
    max: 10         

Appreciate it. I’ll test it out. Thanks.

I am having trouble understanding how to just read certain alerts. I only want to know if my county is under a Tornado warning/watch and severe thunderstorm warning. Can i have a sensor only detect these 3 items and base notifications off that?