MeteoAlarm info card

The MeteoAlarm integration provides weather alarms for many regions in Europe.
The integration provides a binary sensor with several attributes that give current information about many types of weather alarms for the specified region.

I created some extra template sensors and a frontend card that uses the MeteoAlarm integration to warn for any local weather alert in a specific region.
This setup is based on the standard Home Assistant possibilities with one exception: I am using the Card-mod plugin to set the background color of the Tile card depending on the alarm severity level.
The card combines a Tile card, a Conditional card, a Markdown card, an Entity filter card and an Entities card.

This is an example of an effective weather alarm:
HA_MeteoAlarm_current_EN_20240126-0900
It shows the current severity level (green, yellow, orange or red), the awareness type including specific icon, the description, the time and date from when until when the warning is valid and the time and day the warning is published.

When the alarm will be effective in the near future this is indicated as “Future alarm” with the details of the coming alarm:
HA_MeteoAlarm_future_EN_20240126-0734

When there is no current alarm (level Green) only the upper Tile card is shown in green like this:
HA_MeteoAlarm_no-alarm_EN_20240126-1112

It sometimes can take a while for the MeteoAlarm integration to revert to a safe state after the real alarm is already is expired. In those cases the alarm will be shown like this:
HA_MeteoAlarm_expired_EN_20240126-1100

From two days ago until two days after the current day the days are indicated with terms like “two days ago”, “yesterday”, tomorrow” etc., and for dates further away from the current day it is indicated with the real date.
It currently is set-up for the region Friesland in the Netherlands, in the English language.

This is the Yaml code:
Binary sensor:

binary_sensor:
  - platform: meteoalarm
    name: "MeteoAlarm Friesland"
    country: "netherlands"
    province: "Friesland"
    language: "en-GB"

Template sensors (modern format):

template:
  - sensor:
      # Meteoalarm Friesland
    - name: MeteoAlarm Friesland - Event
      unique_id: maf_event
      state: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'event') }}"
      icon: mdi:shield-sun-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'event') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Type
      unique_id: maf_type
      state: >
        {% set mat = state_attr('binary_sensor.meteoalarm_friesland', 'awareness_type').split("; ")[0] %}
        {% if mat == "1" %}
          Wind
        {% elif mat == "2" %}
          Snow - Ice
        {% elif mat == "3" %}
          Thunderstorms
        {% elif mat == "4" %}
          Fog
        {% elif mat == "5" %}
          Extreme high temperature
        {% elif mat == "6" %}
          Extreme low temperature
        {% elif mat == "7" %}
          Coastal event
        {% elif mat == "8" %}
          Forestfire
        {% elif mat == "9" %}
          Avalanges
        {% elif mat == "10" %}
          Rain
        {% elif mat == "12" %}
          Flood
        {% elif mat == "13" %}
          Rain - Flood
        {% else %}
          Unknown
        {% endif %}
      icon: mdi:shield-sun-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'awareness_type') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Level
      unique_id: maf_level
      state: >
        {% set mal = state_attr('binary_sensor.meteoalarm_friesland', 'awareness_level').split("; ")[0] %}
        {% if mal == "1" %}
          Green
        {% elif mal == "2" %}
          Yellow
        {% elif mal == "3" %}
          Orange
        {% elif mal == "4" %}
          Red
        {% else %}
          Unknown
        {% endif %}
      icon: mdi:shield-sun-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'awareness_level') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Effective
      unique_id: maf_effective
      state: "{{ as_timestamp(state_attr('binary_sensor.meteoalarm_friesland', 'effective')) | timestamp_custom('%d %b %H:%M') }}"
      icon: mdi:clipboard-text-clock-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'effective') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Effective Day
      unique_id: maf_effectiveday
      state: >
        {% set ts_effective = as_timestamp(state_attr('binary_sensor.meteoalarm_friesland', 'effective')) %}
        {% set tstring = ts_effective | timestamp_custom('%Y-%m-%d %H:%M:%S') %}
        {% set effectivetime = ts_effective | timestamp_custom( 'at %H:%M') %}
        {% set tz = now().timestamp() | timestamp_custom('%z') %}
        {% set date = strptime(tstring+tz, '%Y-%m-%d %H:%M:%S%z') %}
        {% set cdate = now().replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) %}
        {% set change = (date - cdate).days %}
        {% if change == -2 %}
          two days ago {{ effectivetime }}
        {% elif change == -1 %}
          yesterday {{ effectivetime }}
        {% elif change == 0 %}
          today {{ effectivetime }}
        {% elif change == 1 %}
          tomorrow {{ effectivetime }}
        {% elif change == 2 %}
          in two days {{ effectivetime }}
        {% else %}
          {% set days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] %}
          {% set months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] %}
          {{ days[date.weekday()] }} {{ date.day }} {{ months[date.month-1] }} {{ effectivetime }}
        {% endif %}
      icon: mdi:clipboard-text-clock-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'effective') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Onset
      unique_id: maf_onset
      state: "{{ as_timestamp(state_attr('binary_sensor.meteoalarm_friesland', 'onset')) | timestamp_custom('%d %b %H:%M') }}"
      icon: mdi:clipboard-text-clock-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'onset') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Onset Day
      unique_id: maf_onsetday
      state: >
        {% set ts_onset = as_timestamp(state_attr('binary_sensor.meteoalarm_friesland', 'onset')) %}
        {% set tstring = ts_onset | timestamp_custom('%Y-%m-%d %H:%M:%S') %}
        {% set onsettime = ts_onset | timestamp_custom( 'at %H:%M') %}
        {% set tz = now().timestamp() | timestamp_custom('%z') %}
        {% set date = strptime(tstring+tz, '%Y-%m-%d %H:%M:%S%z') %}
        {% set cdate = now().replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) %}
        {% set change = (date - cdate).days %}
        {% if change == -2 %}
          two days ago {{ onsettime }}
        {% elif change == -1 %}
          yesterday {{ onsettime }}
        {% elif change == 0 %}
          today {{ onsettime }}
        {% elif change == 1 %}
          tomorrow {{ onsettime }}
        {% elif change == 2 %}
          in two days {{ onsettime }}
        {% else %}
          {% set days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] %}
          {% set months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] %}
          {{ days[date.weekday()] }} {{ date.day }} {{ months[date.month-1] }} {{ onsettime }}
        {% endif %}
      icon: mdi:clipboard-text-clock-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'onset') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Expires
      unique_id: maf_expires
      state: "{{ as_timestamp(state_attr('binary_sensor.meteoalarm_friesland', 'expires')) | timestamp_custom('%d %b %H:%M') }}"
      icon: mdi:clipboard-text-clock-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'expires') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Expires Day
      unique_id: maf_expiresday
      state: >
        {% set ts_expires = as_timestamp(state_attr('binary_sensor.meteoalarm_friesland', 'expires')) %}
        {% set tstring = ts_expires | timestamp_custom('%Y-%m-%d %H:%M:%S') %}
        {% set expirestime = ts_expires | timestamp_custom( 'at %H:%M') %}
        {% set tz = now().timestamp() | timestamp_custom('%z') %}
        {% set date = strptime(tstring+tz, '%Y-%m-%d %H:%M:%S%z') %}
        {% set cdate = now().replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) %}
        {% set change = (date - cdate).days %}
        {% if change == -2 %}
          two days ago {{ expirestime }}
        {% elif change == -1 %}
          yesterday {{ expirestime }}
        {% elif change == 0 %}
          today {{ expirestime }}
        {% elif change == 1 %}
          tomorrow {{ expirestime }}
        {% elif change == 2 %}
          in two days {{ expirestime }}
        {% else %}
          {% set days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] %}
          {% set months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] %}
          {{ days[date.weekday()] }} {{ date.day }} {{ months[date.month-1] }} {{ expirestime }}
        {% endif %}
      icon: mdi:clipboard-text-clock-outline
      availability: "{{ state_attr('binary_sensor.meteoalarm_friesland', 'expires') not in ['unknown', 'unavailable'] }}"
    - name: MeteoAlarm Friesland - Current
      unique_id: maf_current
      state: >
        {% set bma = states( 'binary_sensor.meteoalarm_friesland' ) %}
        {% if bma == 'off' %}
          No alarm
        {% else %}
          {% set ts_onset = as_timestamp(state_attr('binary_sensor.meteoalarm_friesland', 'onset')) %}
          {% set ts_expires = as_timestamp(state_attr('binary_sensor.meteoalarm_friesland', 'expires')) %}
          {% set tz = now().timestamp() %}
          {% if tz < ts_onset %}
            Future: {{ states( 'sensor.meteoalarm_friesland_level' ) }} alarm for {{ states( 'sensor.meteoalarm_friesland_type' ) }}
          {% elif tz > ts_onset and tz < ts_expires %}
            {{ states( 'sensor.meteoalarm_friesland_level' ) }} alarm: {{ states( 'sensor.meteoalarm_friesland_type' ) }}
          {% else %}
            Expired {{ states( 'sensor.meteoalarm_friesland_level' ) }} alarm for {{ states( 'sensor.meteoalarm_friesland_type' ) }}
          {% endif %}
        {% endif %}
      icon: >
        {% set bma = states( 'binary_sensor.meteoalarm_friesland' ) %}
        {% if bma == 'off' %}
          mdi:shield-sun-outline
        {% else %}
          {% set mat = state_attr('binary_sensor.meteoalarm_friesland', 'awareness_type').split("; ")[0] %}
          {% if mat == "1" %}
            mdi:weather-windy
          {% elif mat == "2" %}
            mdi:weather-snowy-heavy
          {% elif mat == "3" %}
            mdi:weather-lightning
          {% elif mat == "4" %}
            mdi:weather-fog
          {% elif mat == "5" %}
            mdi:sun-thermometer-outline
          {% elif mat == "6" %}
            mdi:snowflake-thermometer
          {% elif mat == "7" %}
            mdi:shore
          {% elif mat == "8" %}
            mdi:pine-tree-fire
          {% elif mat == "9" %}
            mdi:landslide
          {% elif mat == "10" %}
            mdi:weather-pouring
          {% elif mat == "12" %}
            mdi:home-flood
          {% elif mat == "13" %}
            mdi:waves-arrow-up
          {% else %}
            mdi:shield-sun-outline
          {% endif %}
        {% endif %}
      availability: "{{ states('binary_sensor.meteoalarm_friesland') not in ['unknown', 'unavailable'] }}"

Card:

type: vertical-stack
cards:
  - type: tile
    entity: sensor.meteoalarm_friesland_current
    show_entity_picture: false
    vertical: false
    hide_state: false
    name: MeteoAlarm Friesland
    card_mod:
      style: |
        ha-card {
          background-color:
            {%- set bma = states( 'binary_sensor.meteoalarm_friesland' ) %}
            {%- if bma == 'off' %}#90ee90
            {%- else %}
              {%- set mal = states( 'sensor.meteoalarm_friesland_level' ) %}
              {%- set mac = states( 'sensor.meteoalarm_friesland_current' ) %}
              {%- if mal == 'Green' %}#90ee90
              {%- elif 'Future' in mac %}#90ee90
              {%- elif mal == 'Yellow' %}#ffff00
              {%- elif mal == 'Orange' %}#ffa500
              {%- elif mal == 'Red' %}#ff3300
              {%- else %}#ffaec9
              {%- endif %}
            {%- endif %}
        }
  - type: conditional
    conditions:
      - condition: state
        entity: binary_sensor.meteoalarm_friesland
        state: 'on'
    card:
      type: markdown
      content: >
        **{{ state_attr('binary_sensor.meteoalarm_friesland', 'description') |
        trim }}** {% if 'Future' in states(
        'sensor.meteoalarm_friesland_current' ) %}
          **Starts {{states( 'sensor.meteoalarm_friesland_onset_day' ) }}** {% else %}
          **Ends {{states( 'sensor.meteoalarm_friesland_expires_day' ) }}**
        {% endif %}
  - type: entity-filter
    show_empty: false
    entities:
      - entity: sensor.meteoalarm_friesland_onset_day
        name: 'Start:'
      - entity: sensor.meteoalarm_friesland_expires_day
        name: 'End:'
      - entity: sensor.meteoalarm_friesland_effective_day
        name: 'Published:'
    state_filter:
      - operator: '!='
        value: unknown
    card:
      type: entities

If you want to set it up for your own local region you have to modify these entries in the Yaml code:

binary_sensor: name, country, province, language (ensure to use the correct country and province (region) names, see MeteoAlarm integration)

template_sensors: names, unique_ids, name of the binary_sensor and the template sensors

card: the names of the binary_sensor and the template sensors

If you want to have more regions shown in the frontend you can duplicate these sensors and card. Just ensure to create unique ids and names.

If you want to translate the used terms to another language you have to modify these entries in the Yaml code:

binary_sensor: language

template sensors: the terms for the weather types (Wind, Snow – Ice etc.), the terms for the levels (Green, Yellow etc.) , the term “at” for the time indications (3x), the terms for the days (two days ago, yesterday etc. 3x) the names of the weekdays and months (3x), the terms “No alarm”, Future:”, “Expired”, “alarm for”.

card: Green, Future, Yellow, Orange, Red, Starts, Ends, Start, End, Published

Enjoy!

If anyone has some tips for improvements of this set-up then please let me know.

5 Likes

@thusassistint

Hi, thank you very much for sharing your code. I works perfectly. I just implemented it for Lower Austria.
And as a beginner I really appreciate your detailed description.
Simply perfect.

Thanks

Perhaps an idea … it’s difficult to read the white text on the green background on my mobile. What about implementing an easy way to change the color of the text? Or could you please share a link of an easy how to change text and background color in a card?

Thanks and br,

check the card-mod thread, first post, link at the bottom and select the card you need to change.

its a generic thing you want to do, nothing special related to MeteoAlarm, so a good thing to check out

btw, if you’d want to translate the time and dates to your local language, I suggest you install custom_template Easy_time (find in on HACS) , set your default language in it and use things like:

      {% from 'easy_time.jinja' import weekday, month %}
      {% set meteo = 'binary_sensor.meteoalarm_brabant' %}

      {% set van = state_attr(meteo,'effective')|as_datetime|as_local %}
      {% set tot = state_attr(meteo,'expires')|as_datetime|as_local %}
      {% set gepubliceerd = state_attr(meteo,'onset')|as_datetime|as_local %}

      <b>Geldig:</b>

      <i>van: </i>{{weekday(van)}} {{van.day}} {{month(van)}} {{van.strftime('%H:%M')}}
      <i>tot: </i> {{weekday(tot)}} {{tot.day}} {{month(tot)}} {{tot.strftime('%H:%M')}}

      <b>Gepubliceerd:</b> {{weekday(gepubliceerd) ~' '~gepubliceerd.day~' '~month(gepubliceerd)~' om '~gepubliceerd.strftime('%H:%M') }}

Aware I use Onset in a wrong way, but that is besides the templating suggestion :wink:

1 Like

Hi Marius,
Thanks for your immediate response. Highly appreciate the hint. As you said it’s a good starting point for a beginner.
Anyhow it’s challenging for a beginner because you have millions of puzzles and it’s almost impossible to get it to an picture.
Perhaps you can help me with another issue. Having MeteoAlarm working the next step is getting notified if there is an alarm.
My knowledge ends with I get an notification if there is any alarm. It would be great to get which alarm it is at what severity level.

Thanks

added all your code but a get the error " ‘None’ has no attribute ‘split’". any ideas why?