Severe Weather Alerts from the US National Weather Service

Is it now limited to a single zone or is that just your testing?

just for testing. you can put in more than one zone by separating them by a comma.

- platform: nws_alerts
  zone_id: 'INZ009, INC033'
1 Like

One more updateā€¦

I was concerned that the timing of the update of the current/previous states might not happen in a consistently reliable way so (with the help of this awesome forum) I modified the conditions as follows:

EDIT: see post 112 for updated code.

3 Likes

Is there a repository set up where we can all get the entire shot, from sensor to automations to scriptsā€¦ including an install readme? Iā€™m a little slow and having a few issues knitting this all together.

Just on here.

I have a github account but Iā€™ve never set up any repo on it. Maybe Iā€™ll try to figure out how to do it and put it up there.

What are you having trouble with?

Well okay thenā€¦ :slight_smile: hereā€™s what I got.
This is in my sensors.yaml file:

- platform: nws_alerts
  zone_id: 'TXZ193, TXC021'

This is the automation as filename nwswxalert.yaml in my automations folder within config (entity_id: group.house_talk is a group of all my echos and dots):

- alias: 'NWS Weather Alert Pop Up Control'
  trigger:
    platform: state
    entity_id: sensor.nws_alerts_2
  condition:
    - condition: template
      value_template: '{{states.sensor.nws_alerts_2.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_2.attributes.title.split(' - ')[5] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[5] }}"
        {% elif states.sensor.nws_alerts_2.attributes.title.split(' - ')[4] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[4] }}"
        {% elif states.sensor.nws_alerts_2.attributes.title.split(' - ')[3] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[3] }}"
        {% elif states.sensor.nws_alerts_2.attributes.title.split(' - ')[2] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[2] }}"
        {% elif states.sensor.nws_alerts_2.attributes.title.split(' - ')[1] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[1] }}"
        {% else %}
          "{{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[0] }}"
        {% endif %}
      message: >
        {% if states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[5] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[5] }}"
        {% elif states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[4] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[4] }}"
        {% elif states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[3] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[3] }}"
        {% elif states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[2] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[2] }}"
        {% elif states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[1] is defined %}
          "{{ states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[1] }}"
        {% else %}
          "{{ states.sensor.nws_alerts_2.attributes.display_desc.split('\n\n-\n\n')[0] }}"
        {% endif %}
    
- alias: NWS Notification Weather Alert
  trigger:
    platform: state
    entity_id: sensor.nws_alerts_2
  condition:
    - condition: template
      value_template: '{{states.sensor.nws_alerts_2.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_2.attributes.title.split(' - ')[5] is defined %}
            "NWS: {{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[5] }}"
          {% elif states.sensor.nws_alerts_2.attributes.title.split(' - ')[4] is defined %}
            "NWS: {{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[4] }}"
          {% elif states.sensor.nws_alerts_2.attributes.title.split(' - ')[3] is defined %}
            "NWS: {{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[3] }}"
          {% elif states.sensor.nws_alerts_2.attributes.title.split(' - ')[2] is defined %}
            "NWS: {{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[2] }}"
          {% elif states.sensor.nws_alerts_2.attributes.title.split(' - ')[1] is defined %}
            "NWS: {{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[1] }}"
          {% else %}
            "NWS: {{ states.sensor.nws_alerts_2.attributes.title.split(' - ')[0] }}"
          {% endif %}

- alias: NWS Announce Weather Alert
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.nws_alerts_2
  condition:
    condition: and
    conditions:
      - condition: template
        value_template: "{{states.sensor.nws_alerts_2.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_2.attributes.title) or ('Tornado' in states.sensor.nws_alerts_2.attributes.title)) and 'Warning' in states.sensor.nws_alerts_2.attributes.title }}"
  action:
    - service: media_player.alexa_tts
      data_template:
        entity_id: 
          - group.house_talk
        message: >
          {% if states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[5] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[5] }}.
          {% elif states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[4] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[4] }}
          {% elif states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[3] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[3] }}
          {% elif states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[2] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[2] }}
          {% elif states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[1] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[1] }}
          {% else %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[0] }}
          {% endif %}
    - delay: '00:00:15'
    - service: media_player.alexa_tts
      data_template:
        entity_id: 
          - group.house_talk
        message: >
          {% if states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[5] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[5] }}.
          {% elif states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[4] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[4] }}
          {% elif states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[3] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[3] }}
          {% elif states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[2] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[2] }}
          {% elif states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[1] is defined %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[1] }}
          {% else %}
            Attention!,,,Attention!,,,The National Weather Service Has issued a {{ states.sensor.nws_alerts_2.attributes.spoken_desc.split('\n\n-\n\n')[0] }}
          {% endif %}

This is in my scripts.yaml file:

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_2.state != 'None' %}
          persistent_notification.create
        {% endif %}
      data_template:
        notification_id: "nwswxalert"
        message: "{{ message }}"
        title: "{{ title }}"

Nothing seems to be working except me seeing this in my attributes listing:

Your automations are looking for an entity id sensor.nws_alerts_2. In the screen shot your sensor entity id is sensor.nws_alerts. Try removing the ā€œ_2ā€ from your automations and scripts.

Okay, (multi sic coming) dunn after doin face palmā€¦ waiting for the next alert to see what happens (trust me, here in Texas today we will be getting them).

Wow, sorry about that. That was my bad.

I posted the config using my test sensor that I was using (sensor.nws_alerts_2)

I corrected the code by removing the ā€œ_testā€ from all the automations and scripts but I forgot to correct the sensor by removing the ā€œ_2ā€ from the end.

Iā€™ll go thru and correct all of my previous code examples.

Again, my apologies.

Never apologize to someone who is stealing your code. :slight_smile:

2 Likes

Better yet, I think Iā€™ll just post up the latest good working code here:

Disclaimer:

I still havenā€™t 100% fully tested this in the real world. Luckily we havenā€™t had any tornado warnings but Iā€™m pretty confident it will work as advertised.

EDIT: see post below for updated code

Iā€™ve created a couple of public gists to hold the implementation instructions and code snippets for both the original REST integration and the updated one using the custom sensor.

The original code (using the REST sensor) can be found here:

nws_wx_alert_rest.txt

The most recent code (using the custom sensor) can be found here:

nws_wx_alert_custom.txt

I canā€™t seem to be able to edit my original posts to insert that info there so itā€™s getting a little messy. Hopefully this clears things up a little.

3 Likes

I am curious how to do this with google home minis? I see that someone has a script for volume control for them but cant figure out how to add the media player part. I have a topic about the minis not being seen as a media player that someone has helped with by suggesting I set to IP address. is this how people have had to do this as well?
Thanks,

I donā€™t use Google Home devices so I donā€™t know how to do what youā€™re asking.

Hopefully someone who does will help you out or maybe start another thread asking about the google home media player generically that you can then modify to use for this.

got it. Thank you for your help. Your project works awesomely btw!

1 Like

I need to make note of a required change to the code for the announcement portion.

@Dixey noticed a bug that prevented the echoā€™s from making the announcement for the non-MasterBedRoom automation. This bug only affects the code using the custom_component. If you use the REST sensor code that should still work OK as is.

Apparently putting the outside quotes around the actual message inside the template prevents the echo from reading the message correctly so the end result isā€¦nothing. No errors in the log or anything. I threw those in to the code at the last minute before posting (or testing :roll_eyes:) just to make everything ā€œconsistentā€.

Iā€™m not sure why that would be an issue, tho. :thinking:

Anway, itā€™s an easy fix.

just replace the two ā€œmessage:ā€ sections of the non-MBR announcement with the following:

{% 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 %}

Iā€™ve also updated the public gist using the custom_component linked to above to reflect the required changes.

Thanks again to Dixey for pointing out the bug. Itā€™s good to get it fixed before the storm season kicks in full force.

@eracknaphobia

I donā€™t know if you ever check your issues on your github but I created one a few days ago.

if you could look into that it would be greatly appreciated.

Here is the text from there:

I was just moving some stuff around to put all my alert stuff into a package and realized that my two alert sensors got their entity-idā€™s swapped around (sensor.nws_alerts became sensor.nws_alerts_2 and vice versa)

I think it was because I moved one sensor from the ā€œsensors.yamlā€ into the package but left the other in the ā€œsensors.yamlā€ file. So I think it loaded the sensor.yaml file first and then by default it made that one sensor.nws_alerts when it used to be sensor.nws_alerts_2.

I was able to fix it by moving both sensors into the package in the correct order again.

Is there any way that you can make an option to give them a unique name and make the entity_id from the unique name?

Thanks again for making this. Itā€™s still working greatā€¦except for this one little snafu.

I was just digging thru the code for the custom component from @eracknaphobia related to the post just above this to see if I could figure out how to add a name to the sensor and I realized that the functionality is already in there.

Here is the full configuration example:

- platform: nws_alerts (required)
  name: My NWS Sensor (optional)
  zone_id: 'ALC023' (required)

This will create a sensor called ā€œsensor.my_nws_sensorā€ in your states page that you can use in your automations and scripts. Without adding the ā€œname:ā€ option then the second sensor would have had ā€œ_2ā€ appended to the sensor name to denote the second sensor.

If you only use one sensor then you can disregard this. But if you want to use a different sensor for different locations then this is a good way of splitting them out to make the sensor descriptions more manageable or for any testing necessary which is what I would use it for.

I have needed to add another function to this project due to the recent switch to Lovelace as the default UI and the disappointing way that Lovelace handles the misleadingly named ā€œpersistentā€ notifications.

It used to be that the pop up would occur on every page in the UI and remain until you clicked on the ā€œDismissā€ button.

Now, in Lovelace, the persistent notifications donā€™t populate in the main window but iunstead just put a little orange indicator dot on top of the ā€œbellā€ icon in the top right corner. And I also realized that Persistent notifications donā€™t really persist thru HA restarts.

So in order to get some of the original functionality back Iā€™ve made some changes to the code in the gist that I will summarize here:

  1. I added an input boolean to control the actions of a Lovelace Conditional card. (gist line 49)

  2. I added a new template sensor to also control the actions of a Lovelace Conditional card. (gist line 60)

  3. I made changes to the pop up control script to set the correct input boolean state. (gist line 282)

  4. I added an automation to dismiss the persistent notification based on the state of the input boolean (gist line 250)

5 Lastly, I added a trigger to the pop control automation to re-trigger the persistent notification at HA restart. (gist line 79)

here is the link to the gist again:

NWS Alerts Using Custom Component

Then to get this to all work correctly in love lace you need to add the attributes state custom card to your lovelace UI:

Then add the following to every view that you want to have the pop up show up on:

  - type: conditional
    conditions:
      - entity: sensor.nws_alerts_are_active
        state: 'on'
      - entity: input_boolean.bool_9
        state: 'on'
    card:
      type: entities
      entities:
        - input_boolean.bool_9
        - type: custom:entity-attributes-card
          entity: sensor.nws_alers
          filter:
            include:
              - sensor.nws_alerts.display_desc

I donā€™t think it will cycle thru the different pop ups based on the number of active alerts but I think it will show every alert display description in the pop up card.

And then in the card that is displayed all you need to do to dismiss the window is turn off the switch (input boolean) in that same card.

I havenā€™t done much real world testing on this since I havenā€™t had more than one alert at a time so if anything changes Iā€™ll post it back here again.

And just as another FYI, I finally figured out how to use packages and the gist is now written to be used as a package in HA. Just copy the indicated section of code into the file name of your choosing and store it in your /packages folder and everything should work.

I hopeā€¦at least it does for me. :wink:

Iā€™m thinking about using your lib in a generic cap-component for hass. Just googled and found this here!

1 Like