UK Flood Alerts - a simple sensor and dashboard panel

Bunch of storms recently and flooding has been quite bad - so here is a little sensor to grab the UK Flood Alerts issued by the Environment Agency and display them in a Markdown card on the dashboard. It only displays if there are any flood alerts active in your region. Pretty simple stuff should take 5 mins to add it to any dashboard - no need to register for any data or any API’s - just cut and paste the code here and it should all just work.

STEP 1
First create a RESTful config to grab the information. There are two sensors, one to grab the flood alerts, one to construct a URL link based on your long/lat to a (stupidly clever) web page that shows all the river levels and flooding very neatly.

Add this to configuration.yaml in whatever way works for you:

rest: !include restful.yaml

Then create restful.yaml and add this and it will automatically pickup your location from your home zone:

- resource_template: |-
    https://environment.data.gov.uk/flood-monitoring/id/floods/?lat={{ state_attr('zone.home', 'latitude')|round(6) }}&long={{ state_attr('zone.home', 'longitude')|round(6) }}&dist=10&min-severity=3
  scan_interval: 3600
  method: GET
  sensor:
    - name: UK Flood Alerts
      unique_id: ea_flood_alerts
      icon: mdi:home-flood
      value_template: "{{ value_json['items']|length }}"
      json_attributes: 
        - items
    - name: UK Flood Map
      unique_id: ea_flood_map
      icon: mdi:home-flood
      value_template: |-
        https://check-for-flooding.service.gov.uk/?v=map-live&lyr=mv,ts,tw,ta,ri&ext={{ 
          (state_attr('zone.home', 'longitude') - 0.17117)|round(6) }},{{
          (state_attr('zone.home', 'latitude') - 0.09235)|round(6) }},{{
          (state_attr('zone.home', 'longitude') + 0.17117)|round(6) }},{{
          (state_attr('zone.home', 'latitude') + 0.09235)|round(6) }}

The dist=10 parameter is the radius you want to use to look for flood alerts (it’s in km from your location) - 10 seems about right - but you may want to make it larger or smaller.

Save it all out and reload your yaml config and you should have a sensor.uk_flood_alerts with a state that is the count of the number of active alerts and an attribute block full of the alerts (if there are any!), and another sensor sensor.uk_flood_map that has a state containing a URL.

For those that are interested the very odd bit of maths around the long/lat in the URL sensor are just the right bit of maths to make the map open at a useful zoom level centered on your long/lat.

If you don’t want the map - loose the last map sensor in the code above (from the line - name: UK Flood Map and below).

STEP 2
Next, add a markdown card to your dashboard to display it, here is the one I use, it makes the title a clickable link to open up the Environment Agency’s detail page for more information, colours the different types of alert title (redder is more serious) and adds the map link at the bottom - if you don’t want the map link just remove that last bit of markdown text after the </table>.

type: markdown
content: >
  {%- if states('sensor.uk_flood_alerts')|int(0) > 0 -%}<table width="100%">{%-
  for i in state_attr('sensor.uk_flood_alerts', 'items') -%}<tr><td>{%- if not
  loop.first -%}<br>{%- endif -%}{%- if i.severityLevel == 1 -%}<font
  color="firebrick" size="6"><b>Severe Flood Warning</b></font>{%- elif
  i.severityLevel == 2 -%}<font color="darkorange" size="6"><b>Flood
  Warning</b></font>{%- else -%}<font color="yellow" size="6"><b>Flood
  Alert</b></font>{%- endif -%}&nbsp;&nbsp;<font size="1">Updated: {{
  i.timeRaised | as_timestamp | timestamp_custom('%a %d %b %-I:%M %p')
  }}</font></td></tr><tr><td><a
  href="https://check-for-flooding.service.gov.uk/target-area/{{i.floodAreaID}}"
  target="_blank"><b>{{ i.description }}</b></a></td></tr><tr><td><font
  size="1"><i>{{ i.floodArea.riverOrSea }}</i></font></td></tr><tr><td>{{
  i.message }}</td></tr>{% endfor %}</table><br><ha-icon
  icon="mdi:information"></ha-icon>&nbsp;<a href="{{
  states('sensor.uk_flood_map') }}" target="_blank">Environment Agency Flood
  Map</a>{%- else -%}No active alerts.{%- endif -%}
visibility:
  - condition: numeric_state
    entity: sensor.uk_flood_alerts
    above: 0

Nice and simple, nice and quick. No Auth needed, no API keys - just super easy.

OPTIONAL TWEAKS
If you prefer you can plug in some other long/lat and get alerts for somewhere else :slight_smile: using this config for the RESTful sensors - just remember to put in your long/lat numbers where indicated - and do it to 6 decimal places.

- resource: https://environment.data.gov.uk/flood-monitoring/id/floods/?lat=YOUR_LAT&long=YOUR_LONG&dist=10&min-severity=3
  scan_interval: 3600
  method: GET
  sensor:
    - name: UK Flood Alerts
      unique_id: ea_flood_alerts
      value_template: "{{ value_json['items']|length }}"
      json_attributes:
        - items
    - name: UK Flood Map
      unique_id: ea_flood_map
      value_template: |-
        https://check-for-flooding.service.gov.uk/?v=map-live&lyr=mv,ts,tw,ta,ri&ext={{ 
          (YOUR_LONG - 0.17117)|round(6) }},{{
          (YOUR_LAT - 0.09235)|round(6) }},{{
          (YOUR_LONG + 0.17117)|round(6) }},{{
          (YOUR_LAT + 0.09235)|round(6) }}

Another version of the markdown card config - this one strips the long text after four sentences (which is where the main body of information is generally speaking) - just use this version instead of the one above:

type: markdown
content: >
  {%- if states('sensor.uk_flood_alerts')|int(0) > 0 -%}<table width="100%">{%-
  for i in state_attr('sensor.uk_flood_alerts', 'items') -%}<tr><td>{%- if not
  loop.first -%}<br>{%- endif -%}{%- if i.severityLevel == 1 -%}<font
  color="firebrick" size="6"><b>Severe Flood Warning</b></font>{%- elif
  i.severityLevel == 2 -%}<font color="darkorange" size="6"><b>Flood
  Warning</b></font>{%- else -%}<font color="yellow" size="6"><b>Flood
  Alert</b></font>{%- endif -%}&nbsp;&nbsp;<font size="1">Updated: {{
  i.timeRaised | as_timestamp | timestamp_custom('%a %d %b %-I:%M %p')
  }}</font></td></tr><tr><td><a
  href="https://check-for-flooding.service.gov.uk/target-area/{{i.floodAreaID}}"
  target="_blank"><b>{{ i.description }}</b></a></td></tr><tr><td><font
  size="1"><i>{{ i.floodArea.riverOrSea }}</i></font></td></tr><tr><td>{%- if
  i.message|length -%}{{ i.message.split('.')[:4] | join('.') | replace('\s+','
  ') | trim }}.{%- else -%}Updates will follow.{%- endif -%}</td></tr>{% endfor
  %}</table><br><ha-icon icon="mdi:information"></ha-icon>&nbsp;<a href="{{
  states('sensor.uk_flood_map') }}" target="_blank">Environment Agency Flood
  Map</a>{%- else -%}No active alerts.{%- endif -%}
visibility:
  - condition: numeric_state
    entity: sensor.uk_flood_alerts
    above: 0

And some screenshots so you can see what it looks like. The markdown contains all the font size information so feel free to tweak the various <font size="X"> and play around until it looks right on your dashboard.

4 Likes

Updated original post to add a nice link to the governments ‘check for flooding’ interactive map based on the long/lat you enter - updated the markdown to include it, and tweaked the instructions to make it obvious how to remove it if you want to.

Example of the web page link that gets generated (well designed and works well on mobiles):

And an example of the reduced text version of the markdown card:

1 Like

Brilliant - thanks for sharing.

Is there a typo here?

1 Like

There is - will fix :slight_smile: silly autocorrect working it’s magic on cut and paste clearly :slight_smile:

Update: Now fixed in the original post

1 Like