UK MET Office Severe Weather Warnings

Ok got it now. I don’t use GUI to edit those automation. In fact, just checked, because it is a separate file (not stored in automations.yaml) I can’t edit it at all in GUI. Maybe that’s the problem, maybe GUI doesn’t handle variables properly as it is design for quite simple automations and that’s why it keeps known properties at the top and moves unknown (from the GUI automation template perspective) at the bottom, not sure tbh.
Looking at the automations.yaml I am guessing that the only properties GUI can handle are id, alias, description, trigger, condition, action, mode (also use_blueprint) in this exact order so when the GUI is parsing your automation to save it in the automations.yaml file it reorder your properties to this exact order and leaves everything else at the bottom.

In theory you could add additional if before warning.link to check if warnign is null then do nothing, and if not, then use warning.link. Potential problem you may get is that the warning will never be set at the moment the action is running so you will never get this link working.

Anyone getting anything show up for storm cathleen?
Should be a yellow warning.
I have mine set to do SW (South West) & Somerset.

Sensor seems to be working so maybe a problem with the card?

type: custom:stack-in-card
cards:
  - type: markdown
    content: >
      {% if state_attr('sensor.weather_alerts','entries') != [] %}
        {% for item in state_attr('sensor.weather_alerts','entries') %}
          {% for type, icon in
            [
              ('extreme heat', 'weather-sunny-alert'),
              ('fog', 'weather-fog'),
              ('ice', 'car-traction-control'),
              ('lightning', 'weather-lightning'),
              ('rain', 'weather-pouring'),
              ('rain, wind', 'weather-pouring'),
              ('snow', 'weather-snowy-heavy'),
              ('snow, ice', 'weather-snowy-heavy'),
              ('thunderstorm', 'weather-lightning'),
              ('thunderstorms', 'weather-lightning-rainy'),
              ('wind', 'weather-windy')
            ]
            if type == item.summary | regex_findall_index('.*warning of (.*) affecting.*', ignorecase=True) and item.summary | regex_findall('Somerset', ignorecase=True) %}
            {% set color = item.summary.split(' ')[0] %}
            {% set summary = item.summary | regex_findall_index('(.*) affecting South West England: (.*) valid from (.*) to (.*)', ignorecase=True) %}
            {% set link = item.link %}
            {% set time_utc_from = summary[2][0:2] ~':'~ summary[2][2:4] %}
            {% set time_utc_to = summary[3][0:2] ~':'~ summary[3][2:4] %}
            {% set date_from = summary[2][5:8] +'-'+ summary[2][9:11] +'-'+ summary[2][12:] %}
            {% set date_to = summary[3][5:8] +'-'+ summary[3][9:11] +'-'+ summary[3][12:] %}
            {% set time_local_from = ((now().date() ~ ' ' ~ time_utc_from ~ "+00:00") | as_datetime | as_local).strftime('%H:%M') %}  
            {% set time_local_to = ((now().date() ~ ' ' ~ time_utc_to ~ "+00:00") | as_datetime | as_local).strftime('%H:%M') %}
      |  |  |

      | -: | -- |

      | <font color = {%- if 'Yellow' == color %}'gold' {%- elif 'Amber' ==
      color %}'darkorange' {%- else %}'firebrick' {%- endif %}> <ha-icon icon={{
      "'mdi:" + icon + "'" }}> </ha-icon></font> | <a href='{{ link }}'>**{{
      summary[0] }}** </a> |

      | from: | **{{ time_local_from }}**, {{ date_from }} |

      | to: | **{{ time_local_to }}**, {{ date_to }} |
          {% endfor %}
      <br>
        {% endfor %}
      {% else %} No warnings at present {% endif %}

It looks like Somerset isn’t included in the current warning for the SW region, and you are filtering on Somerset for your card by the looks of it? I’m in Devon, and the warning is showing up correctly for me


I’m in Dorset and it’s showing up correctly for me too:

Yeah it’s odd though. I check the forecast for Street, in Somerset & the wind goes over 40mph. A yellow warning is triggered by winds over 40mph. but maybe it has to last more than 2-3hours?

can you share your card code please?

I thought I would share my own automation. It’s has less code and sends a notification for each alert stored in your sensor.

alias: Weather Warnings
description: ""
triggers:
  - entity_id:
      - sensor.weather_alerts_highlands
    id: weather_notify_warnings
    trigger: state
conditions:
  - condition: template
    value_template: "{{ alerts is not none }}"
actions:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ alerts | length > 0 }}"
        sequence:
          - repeat:
              for_each: "{{ alerts }}"
              sequence:
                - choose:
                    - conditions:
                        - condition: template
                          value_template: |
                            {{ 'Highlands' in repeat.item.summary }}
                      sequence:
                        - data:
                            title: ⚠️ Met Office Weather Alert
                            message: >
                              {% set summary =
                              repeat.item.summary.split('affecting')[0].strip()
                              %}

                              {% set times = repeat.item.summary |
                              regex_findall('(valid from (.*) to (.*))',
                              ignorecase=True) %}

                              {{ summary | title }}

                              From: {{ times[0][1] if times and times[0] else
                              'Unknown' }}

                              To: {{ times[0][2] if times and times[0] else
                              'Unknown' }}
                          action: notify.notify
variables:
  alerts: "{{ state_attr('sensor.weather_alerts', 'entries') }}"
mode: single

Anyone know why the sensor would show that I have 3 alerts for my area but only 2 are showing in the attributes? Is it because the event start time has already passed?


Apologies, i’ve only just seen your question. Sure, here’s the code I am using for my weather card and weather alerts combined:

- type: custom:stack-in-card
                cards:
                  - type: vertical-stack
                    cards:
                      - type: custom:platinum-weather-card
                        weather_entity: weather.home
                        forecast_type: daily
                        tap_action: !include popup/weather.yaml
                        card_config_version: 8
                        daily_forecast_days: 4
                        entity_apparent_temp: weather.home
                        entity_forecast_icon: weather.home
                        entity_forecast_icon_1: weather.home
                        entity_forecast_max: weather.home
                        entity_forecast_max_1: weather.home
                        entity_forecast_min: weather.home
                        entity_forecast_min_1: weather.home
                        entity_humidity: weather.home
                        entity_pop_1: weather.home
                        entity_pos: weather.home
                        entity_pressure: weather.home
                        entity_temperature: weather.home
                        entity_todays_uv_forecast: weather.home
                        entity_uv_alert_summary: weather.home
                        entity_wind_bearing: weather.home
                        entity_wind_speed: weather.home
                        extended_use_attr: false
                        option_locale: London
                        option_show_overview_decimals: true
                        option_time_format: 24hour
                        overview_layout: complete
                        section_order:
                          - overview
                          - extended
                          - slots
                          - daily_forecast
                        show_section_extended: false
                        show_section_slots: false
                        slot_l1: forecast_max
                        slot_l2: forecast_min
                        slot_l3: wind
                        slot_l4: pressure
                        slot_l5: sun_next
                        slot_r1: popforecast
                        slot_r2: humidity
                        slot_r3: uv_summary
                        slot_r4: fire_danger
                        slot_r5: sun_following
                        slot_r6: remove
                        slot_r7: remove
                        slot_r8: remove
                        card_mod:
                          style: |
                            .current-temp {
                              font-size: 0.8em;
                            }
                            .big-icon {
                              width: 120px;
                              height: 100px;
                              margin-top: -10px;
                            }
                            .overview-top {
                              margin-bottom: -35px;
                            }

                      - type: conditional
                        conditions:
                          - entity: sensor.weather_alerts_devon
                            state_not: "0"
                        card:
                          type: markdown
                          card_mod:
                            style:
                              .: |
                                ha-card {
                                  --mdc-icon-size: 40px;
                                }
                              ha-markdown:
                                $: |
                                  td {
                                    vertical-align: top;
                                  }
                          content: |
                            {% if state_attr('sensor.weather_alerts','entries') %}
                              {% for item in state_attr('sensor.weather_alerts','entries') %}
                                {% for type, icon in [('rain', 'weather-pouring'), ('thunderstorms', 'weather-lightning-rainy'),
                                                      ('wind', 'weather-windy'), ('snow', 'weather-snowy-heavy'), 
                                                      ('snow, ice', 'weather-snowy-heavy'),
                                                      ('lightning', 'weather-lightning'), ('ice', 'car-traction-control'),
                                                      ('fog', 'weather-fog'), ('extreme heat', 'weather-sunny-alert'), ('thunderstorm', 'weather-lightning')] if type == item.summary | regex_findall_index('.*warning of (.*) affecting.*', ignorecase=True) %}
                                  {% set color = item.summary.split(' ')[0] %}
                                  {% set summary = item.summary | regex_findall_index('(.*) affecting South West England: (.*) valid from (.*) to (.*)', ignorecase=True) %}
                                  {% set time_from = as_timestamp(strptime(summary[2], "%H%M %a %d %b")) | timestamp_custom("%H:%M") %}
                                  {% set time_to = as_timestamp(strptime(summary[3], "%H%M %a %d %b")) | timestamp_custom("%H:%M") %}
                                  {% set date_from = summary[2][5:8] +'-'+ summary[2][9:11] +'-'+ summary[2][12:] %}
                                  {% set date_to = summary[3][5:8] +'-'+ summary[3][9:11] +'-'+ summary[3][12:] %}
                            | | | |
                            | --- | --- | --- |
                            | <font color="{%- if 'Yellow' == color %}gold{%- elif 'Amber' == color %}darkorange{%- else %}firebrick{%- endif %}"><ha-icon icon={{ "'mdi:" + icon + "'" }}></ha-icon></font> | | <font color="{%- if 'Yellow' == color %}gold{%- elif 'Amber' == color %}darkorange{%- else %}firebrick{%- endif %}">{{ item.summary.split(':')[0] | title }}</font><br />{{ date_from }} {{ time_from }} ➜ {{ date_to }} {{ time_to }} |
                                {% endfor %}
                              {% endfor %}
                            {% endif %}

(pasting the code has knocked the alignment/indentation out)

1 Like

I’m not sure what has changed in a recent HA update, but I am only getting one alert showing on my dashboard now, yet my code hasn’t changed. There are currently 2 alerts for my region, so my sensor has a state of 2, with two seperate entries attributes, one for each alert, but only one of them appears. Could it be because they both mention a wind alert - one shows Wind and rain, and the other just shows wind. My card only displays the one with Wind. Here are the current 2 entries attributes of my sensor:

entries: 
- title: Yellow warning of rain, wind affecting South West England
  title_detail:
    type: text/plain
    language: null
    base: https://www.metoffice.gov.uk/public/data/PWSCache/WarningsRSS/Region/sw
    value: Yellow warning of rain, wind affecting South West England
  links:
    - rel: alternate
      type: text/html
      href: >-
        https://www.metoffice.gov.uk/weather/warnings-and-advice/uk-warnings#?date=2024-12-06&id=afa8586f-e81b-4263-af49-f20b58480cc1&referrer=rss
    - length: '17222'
      type: image/png
      href: >-
        https://data.consumer-digital.api.metoffice.gov.uk/v1/warnings/rss/image/yellow-rain-wind.png
      rel: enclosure
  link: >-
    https://www.metoffice.gov.uk/weather/warnings-and-advice/uk-warnings#?date=2024-12-06&id=afa8586f-e81b-4263-af49-f20b58480cc1&referrer=rss
  summary: >-
    Yellow warning of rain, wind affecting South West England: Bath and North
    East Somerset, Bournemouth Christchurch and Poole, Bristol, Cornwall, Devon,
    Dorset, Gloucestershire, North Somerset, Plymouth, Somerset, South
    Gloucestershire, Swindon, Torbay, Wiltshire valid from 1500 Fri 06 Dec to
    0600 Sun 08 Dec
  summary_detail:
    type: text/html
    language: null
    base: https://www.metoffice.gov.uk/public/data/PWSCache/WarningsRSS/Region/sw
    value: >-
      Yellow warning of rain, wind affecting South West England: Bath and North
      East Somerset, Bournemouth Christchurch and Poole, Bristol, Cornwall,
      Devon, Dorset, Gloucestershire, North Somerset, Plymouth, Somerset, South
      Gloucestershire, Swindon, Torbay, Wiltshire valid from 1500 Fri 06 Dec to
      0600 Sun 08 Dec
  id: >-
    https://www.metoffice.gov.uk/weather/warnings-and-advice/uk-warnings#?date=2024-12-06&id=afa8586f-e81b-4263-af49-f20b58480cc1&referrer=rss&region=South
    West England
  guidislink: false
- title: Yellow warning of wind affecting South West England
  title_detail:
    type: text/plain
    language: null
    base: https://www.metoffice.gov.uk/public/data/PWSCache/WarningsRSS/Region/sw
    value: Yellow warning of wind affecting South West England
  links:
    - rel: alternate
      type: text/html
      href: >-
        https://www.metoffice.gov.uk/weather/warnings-and-advice/uk-warnings#?date=2024-12-05&id=cf60b074-d757-48b9-ba9e-9fec1097fdf9&referrer=rss
    - length: '15776'
      type: image/png
      href: >-
        https://data.consumer-digital.api.metoffice.gov.uk/v1/warnings/rss/image/yellow-wind.png
      rel: enclosure
  link: >-
    https://www.metoffice.gov.uk/weather/warnings-and-advice/uk-warnings#?date=2024-12-05&id=cf60b074-d757-48b9-ba9e-9fec1097fdf9&referrer=rss
  summary: >-
    Yellow warning of wind affecting South West England: Bath and North East
    Somerset, Bristol, Cornwall, Devon, Gloucestershire, North Somerset,
    Somerset, South Gloucestershire, Swindon, Wiltshire valid from 1500 Thu 05
    Dec to 0300 Fri 06 Dec
  summary_detail:
    type: text/html
    language: null
    base: https://www.metoffice.gov.uk/public/data/PWSCache/WarningsRSS/Region/sw
    value: >-
      Yellow warning of wind affecting South West England: Bath and North East
      Somerset, Bristol, Cornwall, Devon, Gloucestershire, North Somerset,
      Somerset, South Gloucestershire, Swindon, Wiltshire valid from 1500 Thu 05
      Dec to 0300 Fri 06 Dec
  id: >-
    https://www.metoffice.gov.uk/weather/warnings-and-advice/uk-warnings#?date=2024-12-05&id=cf60b074-d757-48b9-ba9e-9fec1097fdf9&referrer=rss&region=South
    West England
  guidislink: false

icon: mdi:rss
friendly_name: Weather Alerts

I’ve always had multiple alerts show in the past, even if they both contain one of the same type of weather - anyone else seen a change in what displays?

During summer time if the utc start time is 23:00 so the local start time correctly shows 00:00 but the date from still shows the previous day, is there any way to correct this?

I’m seeing it as well (for the first time). Will take a look later.


Edit: It’s a little more complicated as I first thought because the date that the Met Office provides is not formatted for easy manipulation. I’ll need a few days to think the though.


EdIt 2:

OK, here is a slightly dodgy quick workaround which will still be wrong if the warning is in a different month/year (but will fix the current problem). I will continue to work on a proper fix over the next few days

Change these 2 lines:

{%- set date_from = (now().year ~'-' ~ now().month ~'-' ~ summary[2][9:11] ~ ' ' ~ time_utc_from ~ "+00:00")  | as_datetime | as_local |as_timestamp | timestamp_custom('%a-%d-%b') %}
{%- set date_to =   (now().year ~'-' ~ now().month ~'-' ~ summary[3][9:11] ~ ' ' ~ time_utc_to ~ "+00:00")    | as_datetime | as_local |as_timestamp | timestamp_custom('%a-%d-%b') %}

Edit 3:
OK here is the month fix (and I think there is no year problem). Paste the following over the 2 set date_from & set date_to lines

                {% set month =
                  {
                  'Jan':'01',
                  'Feb':'02',
                  'Mar':'03',
                  'Apr':'04',
                  'May':'05',
                  'Jun':'06',
                  'Jul':'07',
                  'Aug':'08',
                  'Sep':'09',
                  'Oct':'10',
                  'Nov':'11',
                  'Dec':'12'
                  } %}
                {%- set date_from = (now().year ~'-' ~ month[summary[2][12:]] ~'-' ~ summary[2][9:11] ~ ' ' ~ time_utc_from ~ "+00:00")  | as_datetime | as_local |as_timestamp | timestamp_custom('%a-%d-%b') %}
                {%- set date_to =   (now().year ~'-' ~ month[summary[3][12:]] ~'-' ~ summary[3][9:11] ~ ' ' ~ time_utc_to ~ "+00:00")    | as_datetime | as_local |as_timestamp | timestamp_custom('%a-%d-%b') %}

1 Like

Thank you for this

This is great thanks! Finally had time to put a bit more effort into it and I now use an automation to parse the events into a calendar so I can make use of the calendar cards.

Ok, I’m going to be first to say…
…nice.

What weather provider are you using for all those ‘entities’, I’d like to include some in my dashboard?

Also, I already parse the weather warnings for notifications, and for my morning announcement where I add human readable valid from and to dates and times. But my conditional card like you seem have doesn’t included the ‘fancy’ icons. Rather than trawl through the mdi icons and reinventing the wheel are you inclined to share your config?

It's long (and it was written a long time ago before I knew better so it's pretty clunky) but in the interest of sharing here's how I do it.
#================
#=== Input Texts
#================
input_text:
  weather_warning1:
    min: 0
    max: 255

  weather_warning2:
    min: 0
    max: 255

  weather_warning3:
    min: 0
    max: 255

  weather_warning4:
    min: 0
    max: 255

  weather_warning5:
    min: 0
    max: 255


#============
#=== Sensors
#============
sensor:
  #================================================================================
  #=== RSS Feed for Met Office Severe weather warnings (London and the South East)
  #=== Note that these warnings do not all necessarily affect 'Greater London'
  #================================================================================
  - platform: feedparser
    name: Met Office RSS FeedParser South East Weather Warnings
    feed_url: 'http://metoffice.gov.uk/public/data/PWSCache/WarningsRSS/Region/se'
    date_format: '%a, %b %d %I:%M %p'


#=============
#=== Template
#=============
template:
  #=== Met Office London Weather Warnings
  - trigger:
      - platform: state
        entity_id: sensor.met_office_rss_feedparser_south_east_weather_warnings
        attribute: entries

      #=== If HA starts
      - platform: homeassistant
        event: start

      - platform: state
        entity_id: sensor.date

    sensor:
      name: Met Office London Weather Warnings
      unique_id: met_office_london_weather_warnings
      state: >
        {% set ns = namespace(warning_count = 0) %}
        {% for entries in state_attr('sensor.met_office_rss_feedparser_south_east_weather_warnings', 'entries') %}
          {% if 'Greater London' in state_attr('sensor.met_office_rss_feedparser_south_east_weather_warnings', 'entries')[loop.index - 1].summary %}
            {% set ns.warning_count = ns.warning_count + 1 %}
          {% endif %}
        {% endfor %}
        {{ ns.warning_count }}
      attributes:
        warnings: >
          {% set warning_count = states('sensor.met_office_london_weather_warnings') %}
          {% set ns = namespace(json = '[') %}

          {% for entries in state_attr('sensor.met_office_rss_feedparser_south_east_weather_warnings', 'entries') %}
            {% if 'Greater London' in state_attr('sensor.met_office_rss_feedparser_south_east_weather_warnings', 'entries')[loop.index - 1].summary %}
              {% set ns.json = ns.json + '{"warning": "' + state_attr('sensor.met_office_rss_feedparser_south_east_weather_warnings', 'entries')[loop.index - 1].title + '", "period": "' %}

              {% set summary = state_attr('sensor.met_office_rss_feedparser_south_east_weather_warnings', 'entries')[loop.index - 1].summary %}
              {% set valid_period = summary.split(' valid from ')[1] %}
              {% set valid_from = valid_period.split(' to ')[0] %}
              {% set valid_to = valid_period.split(' to ')[1] %}

              {% set days_map = { 'Sat': 'Saturday', 'Sun': 'Sunday', 'Mon': 'Monday', 'Tue': 'Tuesday',
                                  'Wed': 'Wednesday', 'Thu': 'Thursday', 'Fri': 'Friday'} %}

              {% set months_map = { 'Jan': 'January', 'Feb': 'February', 'Mar': 'March', 'Apr': 'April',
                                    'May': 'May', 'Jun': 'June', 'Jul': 'July', 'Aug': 'August',
                                    'Sep': 'September', 'Oct': 'October', 'Nov': 'November', 'Dec': 'December'} %}

              {#                                                  #}
              {#-- Macro to build the valid from and to phrases --#}
              {#   --------------------------------------------   #}
              {#                                                  #}

              {% macro valid_from_to(validity_time) %}

              {#                              #}
              {#-- Extract hour and minutes --#}
              {#                              #}
              {% set validity_hour = validity_time.split(' ')[0][0:2] | int %}
              {% set validity_minutes = validity_time.split(' ')[0][2:4] | int %}

              {#                           #}
              {#-- Get period of the day --#}
              {#                           #}
              {% if validity_hour == 12 %}
                {% set validity_day_period = '' %}
              {% elif validity_hour == 0 %}
                {% set validity_day_period = '' %}
              {% elif validity_hour < 12 %}
                {% set validity_day_period = "morning" %}
              {% elif validity_hour > 16 %}
                {% set validity_day_period = "evening" %}
              {% else %}
                {% set validity_day_period = "afternoon" %}
              {% endif %}

              {#                                                  #}
              {#-- Convert time to 12 hour format and get AM/PM --#}
              {#                                                  #}
              {% set am_pm = '' %}
              {% if validity_hour == 12 and validity_minutes == 0 %}
                {% set validity_hour = 'noon' %}
              {% elif validity_hour == 11 and (50 < validity_minutes <= 59) %}
                {% set validity_hour = 'noon' %}
              {% elif validity_hour == 0  and validity_minutes == 0 %}
                {% set validity_hour = 'the beginning of ' %}
              {% elif validity_hour == 23 and (50 < validity_minutes <= 59) %}
                {% set validity_hour = 'the end of ' %}
              {% elif validity_hour > 12 %}
                {% set am_pm = 'pm' %}
                {% set validity_hour = validity_hour - 12 %}
              {% else %}
                {% set am_pm = 'am' %}
              {% endif %}

              {#                     #}
              {#-- Extract minutes --#}              
              {#                     #}
              {% if (0 <= validity_minutes < 10) or (50 < validity_minutes <= 59) %}
                {% set validity_minutes = am_pm %}
              {% else %}
                {% if validity_minutes < 10 %}
                  {% set validity_minutes = '0' ~ validity_minutes %}
                {% endif %}
                {% set validity_minutes = ':' ~ validity_minutes ~ am_pm %}
              {% endif %}

              {#                                 #}
              {#-- Extract day, month and date --#}
              {#                                 #}
              {% set validity_day = days_map[validity_time.split(' ')[1][0:3]] %}
              {% set validity_month = months_map[validity_time.split(' ')[-1]] %}
              {% set validity_date = validity_time.split(' ')[-2] | int | string %}

              {#                                        #}
              {#-- Build the final phrase             --#}
              {#-- First we need to zero pad the date --#}
              {#                                        #}
              {% set zero_padded_date = '{:02}'.format(validity_time[5:].split(' ')[1] | int) %}
              {% set zero_padded_date = validity_time[5:].split(' ')[0] + ' ' + zero_padded_date + ' ' + validity_time[5:].split(' ')[2] %}
              {% if as_timestamp(now()) | timestamp_custom('%a %d %b') == zero_padded_date %}
                {% if validity_hour == 'noon' %}
                  {% set phrase = validity_hour  ~ ' today' %}
                {% elif validity_hour == 'the beginning of ' %}
                  {% set phrase = validity_hour  ~ ' tomorrow' %}
                {% else %}
                  {% set phrase = validity_hour ~ validity_minutes ~ ' this ' ~ validity_day_period %}
                {% endif %}
              {% elif now().day + 1 == validity_date | int %}
                {% set phrase = validity_hour ~ validity_minutes ~ ' tomorrow ' ~ validity_day_period %}
              {% elif now().day - 1 == validity_date | int %}
                {% set phrase = validity_hour ~ validity_minutes ~ ' yesterday ' ~ validity_day_period %}
              {% else %}
                {% if validity_hour == 'the beginning of ' or 
                      validity_hour == 'the end of ' %}
                  {% set phrase = validity_hour ~ validity_minutes ~ validity_day ~ ' the ' ~ validity_date | ordinal ~ ' of ' ~ validity_month %}
                {% else %}
                  {% set phrase = validity_hour ~ validity_minutes ~ ' on ' ~ validity_day ~ ' the ' ~ validity_date | ordinal ~ ' of ' ~ validity_month %}
                {% endif %}
              {% endif %}

              {{ phrase }}

              {% endmacro %}

              {#                  #}
              {#-- End of Macro --#}
              {#   ------------   #}
              {#                  #}

              {#                                           #}
              {#-- Get the valid to and valid from phrases #}
              {#                                           #}
              {% if valid_to[:2] == '00' %}
                {% if valid_to[2:4] == '00' %}
                  {% set to = 'the beginning of ' ~ days_map[valid_to[5:8]] %}
                {% else %}
                  {% set to = valid_to[2:4] ~ ' minutes past midnight on' ~ valid_to[4:] %}
                {% endif %}
              {% else %}
                {% set to = valid_from_to(valid_to) %}
              {% endif %}

              {% if valid_from[:2] == '00' %}
                {% if valid_from[2:4] == '00' %}
                  {% set from = 'the beginning of ' ~ days_map[valid_to[5:8]] %}
                {% else %}
                  {% set from = valid_from[2:4] ~ ' minutes past midnight on' ~ valid_from[4:] %}
                {% endif %}
              {% else %}
                {% set from = valid_from_to(valid_from) %}
              {% endif %}

              {% if 'the beginning of' in from and
                    'the end of' not in to %}
                {% if now().strftime('%A') in from %}
                  {% set from = 'the beginning of today' %}
                {% elif (as_timestamp(now()) + 86400) | timestamp_custom('%A') in from %}
                  {% set from = 'the beginning of tomorrow' %}
                {% else %}
                {% endif %}

              {% elif 'the beginning of' not in to and
                    'the end of' in to %}
                {% if now().strftime('%A') in from %}
                  {% set to = 'the end of today' %}
                {% elif (as_timestamp(now()) + 86400) | timestamp_custom('%A') in from %}
                  {% set to = 'the end of tomorrow' %}
                {% else %}
                {% endif %}

              {% elif 'the beginning of' in from and
                    'the end of' in to %}
                {% if now().strftime('%A') in from %}
                  {% set from = 'All day today' %}
                {% elif (as_timestamp(now()) + 86400) | timestamp_custom('%A') in from %}
                  {% set from = 'All day tomorrow' %}
                {% else %}
                  {% set from = from.replace('the beginning of', 'All day on') + '."' %}
                {% endif %}
              {% endif %}

              {% set ns.json = ns.json + 'Valid from ' + from | trim + ' until ' + to | trim + '."' %}

              {% set ns.json = ns.json + '}, ' %}

            {% endif %}
          {% endfor %}

          {% if ns.json == '[' %}
            {% set ns.json = ns.json + ']' %}
          {% else %}
            {% set ns.json = ns.json[0:-3] + '}]' %}
          {% endif %}

          {{ ns.json }}


#================
#=== Automations
#================
automation:
  #==============================
  #=== Populate Weather Warnings
  #==============================
  - alias: Weather Populate Weather Warnings
    id: weather_populate_weather_warnings
    trigger:

      - platform: state
        entity_id: sensor.met_office_london_weather_warnings

      #=== If HA starts
      - platform: homeassistant
        event: start

    action:
      #=== Empty weather warning input texts
      - service: input_text.set_value
        data:
          entity_id:
            - input_text.weather_warning1
            - input_text.weather_warning2
            - input_text.weather_warning3
            - input_text.weather_warning4
            - input_text.weather_warning5
          value: ""

      #=== Check there are any weather warnings for London
      - condition: numeric_state
        entity_id: sensor.met_office_london_weather_warnings
        above: 0

      #=== Populate the input text for each warning
      - repeat:
          count: >
            {{ states('sensor.met_office_london_weather_warnings') }}
          sequence:
            - service: input_text.set_value
              data:
                entity_id: input_text.weather_warning{{ repeat.index }}
                value: >
                  {% set warning = state_attr('sensor.met_office_london_weather_warnings', 'warnings')[repeat.index-1].warning %}
                  {% set warning = warning.replace('affecting London & South East England)', 'affecting London') + '. ' %}
                  {% set period = state_attr('sensor.met_office_london_weather_warnings', 'warnings')[repeat.index-1].period %}
                  {{ warning + period }}

Thanks!

I use Pirate weather and some templates for other stuff.

I’ll dig them out and post them up later on as they’re gathered from various places on the forum/internet and I can’t exactly remember where.

The calendar script has one little annoyance in that it doesn’t correctly deal with updated warnings as I’ve recently found when the met office changed some dates and/or times and I’m not sure how to work around that one at the moment. I could clear the calendar and re-add them but I originally wanted to keep a history or weather events.

The icons are just emjoi’s and I match those too the “ice”, “snow”, “rain” text in the warning and convert it there. It should be easy to adapt your current config though.

The Yaml as requested. Posted the last comment too soon sorry.

Same warning as you really :joy: clunky, with room for improvement. They all have been working fine for ages though.

🌨️ Whether warnings as calendars 🌨️ As I said before this could really do with having a way to update events, as currently if a weather warning changes then it will duplicate it. I'm not sure what timescale Met office posts the warnings in, maybe it's just a simple case as looking at future events and re-writing those.

Edit: TIL there is no delete calendar event… so scratch that for now

###############################################################
###### RSS Feedparser sensor for my region
###############################################################
sensor:
- platform: feedparser
  name: "Weather Alerts"
  feed_url: 'https://www.metoffice.gov.uk/public/data/PWSCache/WarningsRSS/Region/yh'
  date_format: '%a, %b %d %I:%M %p'
  inclusions:
    - summary
    - link

###############################################################
###### Template Sensor to check for my location
###############################################################
template:
- sensor:
    - name: "Weather Alerts Yorkshire & Humber"
      state: >
        {{ state_attr('sensor.weather_alerts','entries')
          | map(attribute='summary')
          | select('search', 'North Yorkshire') 
          | list
          | count
        }}

###############################################################
###### Automation to monitor the state of yorkshire and humber and create a calendar event
###############################################################
alias: Create Calendar Event - Weather Alerts
description: ""
triggers:
  - trigger: state
    entity_id:
      - sensor.weather_alerts_yorkshire_humber
    from: null
    to: null
conditions: []
actions:
  - variables:
      alerts: >-
        {% set year = now().year %} {% set ns = namespace(alerts=[]) %} {% if
        state_attr('sensor.weather_alerts','entries') != 0 %}
                    {% for item in state_attr('sensor.weather_alerts','entries') %}
                      {% for type, icon in [('rain', '🌧️'), ('thunderstorms', '⛈️'),
                                            ('wind', '🌪️'), ('snow', '❄️'), ('snow, ice', '❄️ 🧊'),
                                            ('lightning', '🌩️'), ('ice', '🧊'),
                                            ('fog', '🌫️'), ('extreme heat', '🥵'), ('thunderstorm', '⛈️')] if type == item.summary | regex_findall_index('.*warning of (.*) affecting.*', ignorecase=True) %}
                        {% set color = item.summary.split(' ')[0] %}
                        {% set summary = item.summary | regex_findall_index('(.*) affecting Yorkshire & Humber: (.*) valid from (.*) to (.*)', ignorecase=True) %}
                        {% set time_from = as_timestamp(strptime(summary[2], "%H%M %a %d %b")) | timestamp_custom('%m-%d %H:%M:%S') %}
                        {% set time_to = as_timestamp(strptime(summary[3], "%H%M %a %d %b")) | timestamp_custom('%m-%d %H:%M:%S') %}
                        {% set ns.alerts = ns.alerts + [{ "title": icon+" "+summary[0], "message": summary[1], "from": year~"-"~time_from, "to": year~"-"~time_to  }] %}
                      {% endfor %}
                    {% endfor %}
        {% endif %}

        {{ ns.alerts }}
  - repeat:
      for_each: "{{ alerts|list }}"
      sequence:
        - if:
            - condition: template
              value_template: "{{ \"North Yorkshire\" in repeat.item.message }}"
          then:
            - action: script.create_a_calendar_event
              metadata: {}
              data:
                all_day: false
                title: "{{ repeat.item.title }}"
                description: "{{ repeat.item.message }}"
                calendar: calendar.weather_alerts
                start_date: "{{ repeat.item.from }}"
                end_date: "{{ repeat.item.to }}"
mode: single
###############################################################
###### Script I created to make sure a calendar event isn't duplicated, used in automation above
###############################################################
sequence:
  - action: calendar.get_events
    metadata: {}
    data:
      duration:
        hours: 120
        minutes: 0
        seconds: 0
      start_date_time: "{{ (now() - timedelta(days=1) ).strftime('%Y-%m-%dT%H:%M:%S') }}"
    response_variable: events
    target:
      entity_id: calendar.weather_alerts
  - variables:
      does_event_exist: >-
        {% set event_list = events[calendar].events %} {% set ns =
        namespace(name=false, start=false, end=false) %} {% for event in
        event_list %}
          {% if(event.summary == title) %}
            {% set ns.name = true %}
          {% endif %}
          {% if(strptime(event.start[:18], '%Y-%m-%dT%H:%M:%S') == strptime(start_date, '%Y-%m-%d %H:%M:%S') ) %}
            {% set ns.start = true %}
          {% endif %}
          {% if(strptime(event.end[:18], '%Y-%m-%dT%H:%M:%S') == strptime(end_date, '%Y-%m-%d %H:%M:%S') ) %}
            {% set ns.end = true %}
          {% endif %}      
        {% endfor %}

        {{ ns.name and ns.start and ns.end }}
  - if:
      - condition: template
        value_template: "{{ not does_event_exist }}"
    then:
      - action: calendar.create_event
        metadata: {}
        data:
          summary: "{{ title }}"
          description: "{{ description }}"
          start_date_time: "{{ start_date }}"
          end_date_time: "{{ end_date }}"
        target:
          entity_id: "{{ calendar }}"
    alias: If event doesn't exist
fields:
  title:
    selector:
      text: null
    name: Title
    required: true
    description: "The title of the event "
  description:
    selector:
      text: null
    name: Description
    required: true
    description: "The description of the event. "
  calendar:
    selector:
      entity:
        filter:
          domain: calendar
    name: Calendar
    required: true
    description: "Which calendar to add the event too. "
  start_date:
    selector:
      datetime: {}
    name: Start Date
    required: false
    description: "The date and time the event begins. "
  end_date:
    selector:
      datetime: {}
    name: End Date
    required: false
    description: "The date and time the event ends. Must be after the start date. "
  all_day:
    selector:
      boolean: {}
    default: false
    name: All Day Event
    required: true
    description: "Whether the event is all day or not. Default: Off"
alias: Create a Calendar Event If One Doesn't Exist
description: Creates a calendar event

👚 Thin/Thick clothing dry time 👚 This was working "okay" in summer, in winter it's not worked as well not that I get chance to dry the clothes outside much at the minute.

The original script is from this thread: To Line Dry or Not

I use the illuminance integration as I don’t have an outdoor light sensor, so I calculate the sunshine_percent from that which is probably why it fails quite often. Either way it’s been an ok indication of whether I should put the clothes on the line. I also use my rain sensors below too to make a better decision.

I also haven’t gotten around to updating this to make it show hours, currently the calculation comes out in seconds.

###############################################################
###### To line dry or not template sensor. 
###############################################################
template:
  - trigger:
      - platform: time_pattern
        minutes: /6
      - platform: homeassistant
        event: start
    action:
      - service: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id: weather.###
        response_variable: hourly
    unique_id: weather_forcast
    sensor:
  ## Line Drying
  - trigger:
      - platform: time_pattern
        id: "update"
        minutes: "/6" # repeat every 15 minutes
    sensor:
      - name: Time to line dry a towel
        unique_id: time_to_line_dry_a_towel
        unit_of_measurement: "min"
        device_class: duration
        state_class: "measurement"
        state: >
          {% set clothing_value = 0.25 %}
          {% set illuminance = states('sensor.outdoor_illuminance')|int(0) %}
          {% set sunshine_percent = (illuminance / 150000) * 100 %}
          {% set current_temp = states('sensor.average_outdoor_temperature')|float(0) or states('sensor.###_temperature')|float(0) %}        
          {% set current_humidity = states('sensor.average_outdoor_humidity')|float(0) or states('sensor.###_humidity')|float(0) %}            
          {% set temp = current_temp|round(2) + 273.15 %}
          {% set wind = states('sensor.###_wind_speed')|float(0)|round(2) *  0.2777777778 %}
          {% set humidity = current_humidity|round(2) / 100 %}
          {% set pressure = states('sensor.###_pressure')|float(0) / 10 %}
          {% set rn = 9.4*(sunshine_percent / 100) %}

          {% set delta=((5336/temp)**(21.07-(5336/temp))) %}
          {% set lamda=2.501-0.002361*(temp-273) %}
          {% set y=(0.0016286*pressure)/lamda %}
          {% set ea=1**(21.07-(5336/temp)) %}
          {% set d=(1-humidity)*ea %}
          {% set e=(delta*rn+y*(6.43*(1+0.536*wind)*d))/(lamda*(delta+y)) %}
          {{ ((clothing_value/(e))*1440)|round(2) }}
      - name: Time to line dry a t-shirt
        unique_id: time_to_line_dry_a_t_shirt
        unit_of_measurement: "min"
        device_class: duration
        state_class: "measurement"
        state: >
          {% set clothing_value = 0.075 %}
          {% set illuminance = states('sensor.outdoor_illuminance')|int(0) %}
          {% set sunshine_percent = (illuminance / 150000) * 100 %}
          {% set current_temp = states('sensor.average_outdoor_temperature')|float(0) or states('sensor.###_temperature')|float(0) %}        
          {% set current_humidity = states('sensor.average_outdoor_humidity')|float(0) or states('sensor.###_humidity')|float(0) %}  
          {% set temp = current_temp|round(2) + 273.15 %}
          {% set wind = states('sensor.###_wind_speed')|float(0)|round(2) *  0.2777777778 %}
          {% set humidity = current_humidity|round(2) / 100 %}
          {% set pressure = states('sensor.###_pressure')|float(0) / 10 %}
          {% set rn = 9.4*(sunshine_percent / 100) %}

          {% set delta=((5336/temp)**(21.07-(5336/temp))) %}
          {% set lamda=2.501-0.002361*(temp-273) %}
          {% set y=(0.0016286*pressure)/lamda %}
          {% set ea=1**(21.07-(5336/temp)) %}
          {% set d=(1-humidity)*ea %}
          {% set e=(delta*rn+y*(6.43*(1+0.536*wind)*d))/(lamda*(delta+y)) %}
          {{ ((clothing_value/(e))*1440)|round(2) }}

🌧️ Rain and Temperature Average Forecasts 🌡️ These I quite like to give an average of the future conditions rather than having to look at the forecast. I use them on my home page to tell me weather rain is more than likely continuing or stopping in the next 6/12 hours and similar for temperature, I can check whether it's going to get warmer/cooler.
###############################################################
###### Rain and Temperature Sensor Average Forecasts
###############################################################
template:
  - trigger:
      - platform: time_pattern
        minutes: /6
      - platform: homeassistant
        event: start
    action:
      - service: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id: ###
        response_variable: hourly
    unique_id: weather_forcast
    sensor:
      - name: Next 6 Hours Chance of Rain
        unique_id: next_6_hours_rain
        unit_of_measurement: "%"
        state_class: "measurement"
        state: >-
          {% set forecast = hourly['###'].forecast %}
          {{ 
            ((
              forecast[5].precipitation_probability | float +
              forecast[4].precipitation_probability | float +
              forecast[3].precipitation_probability | float +
              forecast[2].precipitation_probability | float +
              forecast[1].precipitation_probability | float + 
              forecast[0].precipitation_probability | float) / 6
            )|round(2)
          }}
      - name: Next 12 Hours Chance of Rain
        unique_id: next_12_hours_rain
        unit_of_measurement: "%"
        state_class: "measurement"
        state: >-
          {% set forecast = hourly['###'].forecast %}
          {{ 
            ((           
              forecast[11].precipitation_probability | float +
              forecast[10].precipitation_probability | float +
              forecast[9].precipitation_probability | float +
              forecast[8].precipitation_probability | float +
              forecast[7].precipitation_probability | float + 
              forecast[6].precipitation_probability | float) / 6
            )|round(2)
          }}
      - name: Next 6 Hours Average Temperature Forecast
        unique_id: next_6_hours_temperature
        unit_of_measurement: "°C"
        state_class: "measurement"
        state: >-
          {% set forecast = hourly['###'].forecast %}
          {{ 
            ((
              forecast[5].temperature | float +
              forecast[4].temperature | float +
              forecast[3].temperature | float +
              forecast[2].temperature | float +
              forecast[1].temperature | float + 
              forecast[0].temperature | float) / 6
            )|round(2)
          }}
      - name: Next 12 Hours Average Temperature Forecast
        unique_id: next_12_hours_temperature
        unit_of_measurement: "°C"
        state_class: "measurement"
        state: >-
          {% set forecast = hourly['###'].forecast %}
          {{ 
            ((           
              forecast[11].temperature | float +
              forecast[10].temperature | float +
              forecast[9].temperature | float +
              forecast[8].temperature | float +
              forecast[7].temperature | float + 
              forecast[6].temperature | float) / 6
            )|round(2)
          }}

###############################################################
###### Mushroom Badge to display the temperatures from the template
###### Limits visibility to really cold, or overly hot. 
###############################################################

type: custom:mushroom-template-badge
content: |-
  {% set six = states(entity)|float(0) %}
  {% set twelve = states(entity.replace("6","12"))|float(0) %}


  {% if(six > 18) %}
    {{ six|int(0) }}°C {% if six > twelve %}- Cooling{% else %}- Warming{% endif %}
  {% elif(twelve > 18) %}
    {{ twelve|int(0) }}°C
  {% elif(six < 5) %}
    {{ twelve|int(0) }}°C
  {% elif(twelve < 5) %}
    {{ six|int(0) }}°C {% if six > twelve %}- Cooling{% else %}- Warming{% endif %}
  {% else %}
    Cold
  {% endif %}
icon: mdi:thermometer
color: |-
  {% set six = states(entity)|float(0) %}
  {% set twelve = states(entity.replace("6","12"))|float(0) %}

  {% if(six > 18) %}
    orange
  {% elif(twelve > 18) %}
    red 
  {% elif(six < 5) %}
    cyan 
  {% elif(twelve < 5) %}
    blue 
  {% else %}
    black
  {% endif %}
label: |-
  {% set six = states(entity)|float(0) %}
  {% set twelve = states(entity.replace("6","12"))|float(0) %}


  {% if(six > 18) %}
    6 Hour Temp
  {% elif(twelve > 18) %}
    12 Hour Temp
  {% elif(six < 5) %}
    6 Hour Temp
  {% elif(twelve < 5) %}
    12 Hour Temp
  {% else %}
    Cold
  {% endif %}
tap_action:
  action: navigate
  navigation_path: /lovelace/weather
entity: sensor.next_6_hours_average_temperature_forecast
visibility:
  - condition: or
    conditions:
      - condition: numeric_state
        entity: sensor.next_6_hours_average_temperature_forecast
        above: 18
      - condition: numeric_state
        entity: sensor.next_12_hours_average_temperature_forecast
        above: 18
      - condition: numeric_state
        entity: sensor.next_6_hours_average_temperature_forecast
        below: 5
      - condition: numeric_state
        entity: sensor.next_12_hours_average_temperature_forecast
        below: 5

###############################################################
###### Mushroom Card Template Badges to display the chance of Rain
###### Limits visibility to percentages I've settled at when Rain occured from what pirate weather said.
###############################################################
type: custom:mushroom-template-badge
content: |-
  {% set six = states(entity)|float(0) %}
  {% set twelve = states(entity.replace("6","12"))|float(0) %}


  {% if(six > 20) %}
    {{ six|int(0) }}% {% if six > twelve %}- Passing{% else %}- Continuing{% endif %}
  {% elif(twelve > 20) %}
    {{ twelve|int(0) }}%
  {% else %}
    No Rain
  {% endif %}
icon: mdi:weather-rainy
color: |-
  {% set six = states(entity)|float(0) %}
  {% set twelve = states(entity.replace("6","12"))|float(0) %}

  {% if(six > 20) %}
    cyan
  {% elif(twelve > 20) %}
    lightblue 
  {% else %}
    black
  {% endif %}
label: |-
  {% set six = states(entity)|float(0) %}
  {% set twelve = states(entity.replace("6","12"))|float(0) %}


  {% if(six > 20) %}
   Rain in 6 hours
  {% elif(twelve > 20) %}
    Rain in 12 hours
  {% else %}
    No Rain
  {% endif %}
tap_action:
  action: navigate
  navigation_path: /lovelace/rain
entity: sensor.next_6_hours_chance_of_rain
visibility:
  - condition: or
    conditions:
      - condition: numeric_state
        entity: sensor.next_6_hours_chance_of_rain
        above: 20
      - condition: numeric_state
        entity: sensor.next_12_hours_chance_of_rain
        above: 20


🕰️ Daylights Savings Sensor 🕰️ Original Thread: [Daylight Savings Time](https://community.home-assistant.io/t/daylight-savings-time-dst-template-and-automation/351889)
template:
  - trigger:
      - platform: time
        at: "00:00:00"
      - platform: homeassistant
        event: start
      - platform: event
        event_type: call_service
        event_data:
          domain: template
          service: reload
    sensor:
      - unique_id: dst_next
        name: "Daylight Savings Next"
        device_class: timestamp
        state: >
          {%- macro hms(t) %}
          {%- set dststr = t.dst() | string if t.dst() is not none else "00:00:00" %}
          {%- set h, m, s = dststr.split(':') | map('int') %}
          {{- h * 60 * 60 + m * 60 + s }}   
          {%- endmacro %}

          {%- macro is_dst(t) %}
          {{- hms(t) | int != 0 }}
          {%- endmacro %}

          {%- macro finddst(t, kwarg, rng) %}
          {%- set ns = namespace(previous=is_dst(t), found=none) %}
          {%- for i in range(rng) %}
            {%- set ts = t + timedelta(**{kwarg:i}) %}
            {%- if ns.previous != is_dst(ts) and ns.found is none %}
              {%- set ns.found = i %}
            {%- endif %}
          {%- endfor %}
          {{- ns.found }}
          {%- endmacro %}

          {%- set t = now().replace(hour=0, minute=0, second=0, microsecond=0) %}
          {%- set d = finddst(t, 'days', 366) | int - 1 %}
          {%- set h = finddst(t + timedelta(days=d), 'hours', 25) | int - 1 %}
          {%- set m = finddst(t + timedelta(days=d, hours=h), 'minutes', 61) | int %}
          {{ (t + timedelta(days=d, hours=h, minutes=m)) }}

      - unique_id: dst_phrase
        name: "Daylight Savings Phrase"
        state: >
          {%- macro hms(t) %}
          {%- set dststr = t.dst() | string if t.dst() is not none else "00:00:00" %}
          {%- set h, m, s = dststr.split(':') | map('int') %}
          {{- h * 60 * 60 + m * 60 + s }}   
          {%- endmacro %}

          {%- macro phrase(seconds, name, divisor, mod=None) %}
            {%- set value = ((seconds | abs // divisor) % (mod if mod else divisor)) | int %}
            {%- set end = 's' if value > 1 else '' %}
            {{- '{} {}{}'.format(value, name, end) if value > 0 else '' }}
          {%- endmacro %}

          {%- macro total(seconds) %}
          {%- set values = [ 
            phrase(seconds, 'hour', 60*60, 60*60*24),
            phrase(seconds, 'minute', 60, 60),
            ] | select('!=','') | list %}
          {{- values[:-1] | join(', ') ~ ' and ' ~ values[-1] if values | length > 1 else values | first | default}}
          {%- endmacro %}

          {%- macro finddelta(t, kwarg, rng) %}
          {%- set ns = namespace(previous=hms(t), found=none) %}
          {%- for i in range(rng) %}
            {%- set ts = t + timedelta(**{kwarg:i}) %}
            {%- if ns.previous != hms(ts) and ns.found is none %}
              {%- set before = hms(ts - timedelta(days=1)) | int %}
              {%- set after = hms(ts) | int %}
              {%- set ns.found =  after - before %}
            {%- endif %}
          {%- endfor %}
          {{ ns.found }}
          {%- endmacro %}

          {%- set t = now().replace(hour=0, minute=0, second=0, microsecond=0) %}
          {%- set delta = finddelta(t, 'days', 365) | int %}
          {% if delta > 0 %}
            lose {{ total(delta | abs) }}
          {% else %}
            gain {{ total(delta | abs) }}
          {% endif %}

  - sensor:
      - unique_id: dst_days
        name: "Daylight Savings Days Until"
        unit_of_measurement: days
        state: >
          {% set next = states('sensor.daylight_savings_next') | as_datetime %}
          {% set today = now().replace(hour=0, minute=0, second=0, microsecond=0) %}
          {{ (next - today).days if next is not none else 0 }}
        availability: >
          {{ states('sensor.daylight_savings_next') not in ['unknown', 'unavailable'] }}

Don’t think I’ve missed any. The lightning sensor is just blitzortung integration and the custom card “blitzortung-lightning-card”. The “Outside Rain %” is just something I’m messing around with currently. I’ve got 2 soil moisture sensors sat outside open to the air and when they get wet that percent rises. It was working ok until it decided to get frosty and dewy on a morning :joy:. If you need help with anything let me know. I’ll update if I change how I do the calendar as events, as I think I might clear any future events from the day the event changes and then re-create the new ones. Thinking that might solve the duplicate issue and allow me to keep a history.

2 Likes

Has anybody created a ‘fake’ weather alert as a template sensor, for testing purposes? Up until now, I’ve just been testing and making changes to my alerts on my dashboard while there is an active weather alert, however it would be much easier if a fake alert could be created and set to active, for testing purposes. I’m just unsure exactly how to construct it?

EDIT: I figured it out through some trial and error! In case anyone else wants to do this, here is what i used for my template sensor:

    - name: "Fake Weather Alerts"
      unique_id: fake_weather_alert
      icon: mdi:weather-lightning
      state: "1"
      attributes:
        entries: >
          {{ [
            {
              "title": "Yellow warning of rain affecting South West England",
              "link": "https://www.metoffice.gov.uk",
              "summary": "Yellow warning of rain affecting South West England: Devon, Somerset valid from 0200 Fri 16 Jan to 0600 Sat 17 Jan",
              "title_detail": {
                "type": "text/plain",
                "value": "Yellow warning of rain affecting South West England"
              },
              "links": [
                {
                  "rel": "alternate",
                  "type": "text/html",
                  "href": "https://www.metoffice.gov.uk"
                },
                {
                  "rel": "enclosure",
                  "type": "image/png",
                  "href": "https://data.consumer-digital.api.metoffice.gov.uk"
                }
              ],
              "guidislink": false
            }
          ] }}

Good enough for testing at least.

Wow this great.
One thing I am not sure about is the way you put the alerts in your dashboard.
Please can you show us. eg: which card?