Tag: home assistant

  • Monitoring Predbat Plan Generation Times in Home Assistant

    Predbat from springfall2008 is a fantastic custom integration for Home Assistant that intelligently manages solar battery charging and discharging based on predicted solar generation and energy tariffs. It’s especially helpful for optimising when to charge from the grid or discharge to avoid peak tariffs, and it’s saved me a decent amount on my energy bill.

    chart showing predbat on times

    But like any planning tool, Predbat needs time to generate its plan. Most of the time it does this quickly – but occasionally it can take a little longer. I wanted a way to visualise and track how long Predbat was taking to generate its plan each time it ran.

    Why track Predbat’s ON time?

    The provided switch.predbat_active entity goes into the on state when Predbat is generating a new plan. Once complete, it switches back to off. By measuring how long it remains ON, I can catch cases where Predbat is taking longer than expected.

    If it ever takes more than 5 minutes, I want to know – either through a notification or visually via my dashboard.

    Step 1: Creating the Sensor

    I used a trigger-based template sensor that calculates the duration in minutes that the switch.predbat_active was ON.

    Here’s the YAML for the sensor:

    - trigger:
        - platform: state
          entity_id: switch.predbat_active
          from: 'on'
          to: 'off'
      sensor:
        - name: Predbat Last ON Duration
          unique_id: predbat_last_on_duration
          state: >
            {{ (as_timestamp(now()) - as_timestamp(trigger.from_state.last_changed)) / 60 }}
          unit_of_measurement: "minutes"
          icon: mdi:timer

    This sensor will only update when the switch turns OFF. It records how many minutes it was ON – which is effectively how long Predbat took to generate its plan.

    Step 2: Visualising ON Durations in ApexCharts

    To make this information more useful, I plotted it using the excellent ApexCharts card for Home Assistant.

    Here’s the chart YAML I used:

    type: custom:apexcharts-card
    graph_span: 24h
    header:
      show: true
      title: Predbat ON Durations
      show_states: true
      colorize_states: true
    series:
      - entity: sensor.predbat_last_on_duration
        type: column
    apex_config:
      yaxis:
        min: 0
        max: 6
      annotations:
        yaxis:
          - "y": 5
            borderColor: "#FF0000"
            strokeDashArray: 1

    This renders a neat column chart of how long each plan generation took. The red annotation line at 5 minutes gives a clear visual cue if something is taking too long.

    Notifications and Automations

    Now that we have this entity, its a simple job to create a notification if the ON time is longer than my desired 5 minutes. Just use the new entity to trigger a notification to home assistant or your mobile device.

  • Accessing UK Rainfall Data in Home Assistant with the Environment Agency’s Beta API

    If you’re looking to add real-time UK rainfall data to your Home Assistant setup, the Environment Agency (EA) offers a beta API that exposes official rain gauge readings from across England. This post explains how to access that data, find your nearest measurement station, and integrate it into Home Assistant using a REST sensor.

    dashboard image from home assistant showing a rain sensor

    What Is the EA Rainfall API?

    The EA’s Flood Monitoring API includes rainfall measurements from hundreds of monitoring stations across the UK. You can query specific stations to retrieve rainfall data from the past 24 hours.

    Note:
    This API is officially in beta, which means it’s not guaranteed to be available 24/7. The service occasionally times out or becomes unresponsive, so any sensors you create may intermittently return "unknown" or fail to update.


    Step 1: Find Your Nearest Rainfall Station

    To begin, you’ll need the station ID of the rainfall monitor closest to your location.

    1. Visit the EA’s monitoring station search page:
      https://check-for-flooding.service.gov.uk/river-and-sea-levels

    2. Use the search bar for your location / home / postcode.

    3. In the results page, choose the Rainfall tab.

    4. Click on a nearby station marker to bring up its detail page. It will look like this:
      https://check-for-flooding.service.gov.uk/rainfall-station/E1234
      The ID at the end (E1234 in this example) is what you’ll use in your sensor configuration.

    5. You can also test live readings using this format:
      https://environment.data.gov.uk/flood-monitoring/id/stations/E1234/readings?parameter=rainfall&today


    Step 2: Add the REST Sensor in Home Assistant

    Once you’ve chosen a suitable station ID, add the following to your Home Assistant configuration.yaml under sensor: (or a new YAML file if using rest: integration directly):

    - platform: rest
      name: Rainfall Today (EA)
      unique_id: rainfall_today_ea
      resource: https://environment.data.gov.uk/flood-monitoring/id/stations/YOUR_STATION_ID/readings?parameter=rainfall&today
      method: GET
      value_template: >
        {% set readings = value_json["items"] | default([]) %}
        {% if readings %}
          {% set total = readings
              | map(attribute='value')
              | map('float')
              | sum %}
          {{ '%.2f' | format(total) }}
        {% else %}
          0.00
        {% endif %}
      unit_of_measurement: mm
      device_class: precipitation
      state_class: total
      scan_interval: 900

    Important: Replace YOUR_STATION_ID with your chosen ID (e.g., E1234).

    Important: Restart Home Assistant to enable the new sensor.


    Step 3: Display on a Dashboard

    Now that the sensor is added, you can display the total rainfall for today using any standard card in Lovelace, using the entity sensor.rainfall_today_ea. You could also combine it with daily or weekly trend charts for deeper insight.


    Troubleshooting Tips

    • If the sensor value shows as "unknown" or doesn’t update, it’s likely due to temporary API downtime.
    • Double-check that the station you’ve chosen reports rainfall and not only water level or flow.
    • You can test the API manually in your browser to confirm it’s returning valid JSON.

    Using the EA’s beta rainfall API is a great way to get highly localised, official rainfall data into your smart home dashboard. While it’s not perfect due to its beta status, it adds valuable environmental awareness to any Home Assistant setup.

    If you’ve found a reliable station near you, this integration can help you:

    • Track rainfall for automation purposes
    • Cross-check rainfall against your garden’s needs
    • Build weather prediction models using historical patterns

    I am also using it to compare to the rainfall totals I get through my Weatherflow Tempest device. It uses haptics to measure rainfall which is not as exact as I hoped. Comparing its results with the official "close by" EA measurement station helped me understand how accurate it really was… in short – its close enough!

  • Building a Hourly Rain Forecast Chart in Home Assistant

    I’ve been playing around with ways to better visualise upcoming rainfall. The main weather integrations in Home Assistant often focus on current conditions or broad daily forecasts, but I wanted something more granular.

    Chart showing hourly rainfall

    Specifically, I wanted to see hourly rainfall predictions for the next 24 hours in a compact, clean, and useful format. Ideal for deciding if I need to bring the washing in or delay watering the garden. Here’s how I set it up.

    Step 1: Create the Input Text Helper (YAML)

    First, we need a place to store the hourly rainfall values. I created a simple input_text helper in configuration.yaml. This holds a JSON string that we can read later in the chart.

    Here’s the code to add:

    input_text:
      hourly_forecast_json:
        name: Hourly Forecast JSON
        initial: ""
        max: 255

    Note: The default limit is 255 characters, which fits roughly 24 hourly values. If you want to expand this for a longer range, you can increase the max value — for example, set max: 1024 for future-proofing.

    Once added, restart Home Assistant to activate the helper.

    Step 2: Pull the Hourly Forecast Data

    Next, I created an automation that fetches the next 24 hours of hourly weather data from my forecast provider. It extracts just the precipitation values and stores them as a JSON array in the helper.

    This runs every 5 minutes to keep the data fresh:

    alias: Update Hourly Forecast
    description: ""
    trigger:
      - platform: time_pattern
        minutes: "/5"
    action:
      - service: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id: weather.my_forecast_provider
        response_variable: forecast_data
    
      - service: input_text.set_value
        data:
          entity_id: input_text.hourly_forecast_json
          value: >
            {{
              forecast_data['weather.my_forecast_provider'].forecast[:24]
              | map(attribute='precipitation')
              | list
              | to_json
            }}
    mode: single

    This gives you a neat string like [0.0, 0.2, 0.4, 0.0, ...] representing each hour’s predicted rainfall in millimetres.

    Step 3: Display the Chart with ApexCharts

    I wanted the final chart to be small, clean, and focused. Using apexcharts-card, I built a column chart that only shows hours where rain is expected — zeroes are filtered out to reduce clutter.

    Here’s the YAML for the card:

    - type: custom:apexcharts-card
      header:
        title: 24h Precipitation Forecast
        show: true
      graph_span: 24h
      span:
        start: hour
      yaxis:
        - min: 0
          decimals: 2
      series:
        - entity: sun.sun  # dummy entity to enable chart
          name: Rain (mm)
          type: column
          color: rgb(76, 166, 238)
          data_generator: |
            try {
              const raw = hass.states['input_text.hourly_forecast_json']?.state;
              if (!raw || !raw.startsWith("[")) return [];
              const data = JSON.parse(raw);
              if (!Array.isArray(data)) return [];
              const now = new Date();
              now.setMinutes(0, 0, 0);  // align to hour start
              return data.reduce((acc, val, i) => {
                if (val !== 0) {
                  const time = new Date(now.getTime() + i * 3600 * 1000).getTime();
                  acc.push([time, val]);
                }
                return acc;
              }, []);
            } catch (e) {
              console.error("ApexCharts data_generator error:", e);
              return [];
            }
      apex_config:
        chart:
          height: 200px
        tooltip:
          enabled: false
        plotOptions:
          bar:
            columnWidth: 14
            borderRadius: 1
        stroke:
          width: 1
          colors:
            - "#FFFFFF"
        dataLabels:
          offsetY: -10
          style:
            fontSize: 9
        xaxis:
          labels:
            hideOverlappingLabels: false
            rotate: 90
            show: true
            style:
              fontSize: 9
            format: HH
        yaxis:
          show: false
        legend:
          show: false

    This chart gives a very quick heads-up on upcoming rain intensity. Because it only shows hours with rain (zero values are filtered out), it’s minimal and takes up little space. It works well on both mobile and wall-mounted dashboards.

    More importantly, it pulls real hourly forecast data rather than estimates or summaries. You get the precise precipitation expected in millimetres for each hour. Handy if you’re deciding whether to pause a garden irrigation schedule or go out for a walk.

  • A Small but Mighty Wind Card in Home Assistant

    As part of refining my Home Assistant dashboards, I wanted a lightweight, dynamic card to show current wind conditions from my Weatherflow Tempest.

    Screenshot 2025-09-01 at 12.36.38

    There are plenty of ways to visualise weather data, but most are either too large, too basic, or just not very readable. I wanted something compact, clean, and glanceable. A quick read, no fluff, and no wasted screen space.

    This is where the Mushroom Template Card really shines. It’s incredibly flexible, looks modern, and lets you pack a surprising amount of intelligence into a small card.

    What I Wanted

    The goal was simple:

    • Show the wind speed in mph.
    • Display a directional icon based on wind direction.
    • Change the icon colour if wind speed is high.
    • Keep it compact, no charts, no clutter.

    All powered by the Tempest sensors I already had in place.

    The YAML

    Here’s the full YAML I ended up with:

    type: custom:mushroom-template-card
    entity: sensor.tempest_wind_speed
    primary: Wind
    secondary: "{{ states('sensor.tempest_wind_speed') | float | round(2) }} mph"

    The secondary line uses Jinja2 to pull the wind speed and round it to two decimal places. I like that this keeps it readable without unnecessary decimals.

    Directional Icon Logic

    The icon is where it gets a bit more clever. If the wind sensor is reporting a valid direction and the wind isn’t zero, we map it to a directional arrow.

    icon: >-
      {% set raw_dir = states('sensor.tempest_wind_direction') %}
      {% set raw_speed = states('sensor.tempest_wind_speed') %}
      {% if raw_dir in ['unknown', 'unavailable', 'none', ''] or raw_speed | float == 0 %}
        mdi:compass
      {% else %}
        {% set d_from = ((raw_dir | float) % 360 + 360) % 360 %}
        {% set d_to = (d_from + 180) % 360 %}
        {% set idx = (((d_to + 22.5) % 360) // 45) | int %}
        {% set icons = [
          'mdi:arrow-up-circle-outline',
          'mdi:arrow-top-right-thin-circle-outline',
          'mdi:arrow-right-circle-outline',
          'mdi:arrow-bottom-right-thin-circle-outline',
          'mdi:arrow-down-circle-outline',
          'mdi:arrow-bottom-left-thin-circle-outline',
          'mdi:arrow-left-circle-outline',
          'mdi:arrow-top-left-thin-circle-outline'
        ] %}
        {{ icons[idx] }}
      {% endif %}

    Let me break that down:

    • If the direction or speed is unknown or zero, we show a generic compass icon.
    • Otherwise, we:
      • Calculate the direction the wind is going to (not coming from).
      • Convert it into an index between 0–7.
      • Map that to one of eight arrow icons using Material Design Icons (MDI).

    This gives a visual indication of direction without needing to read degrees.

    Icon Colour Based on Wind Speed

    Just for a bit of extra UX, I wanted the icon to go red if the wind is high (10+ mph). Otherwise, it uses the theme’s default colour.

    icon_color: >-
      {% set raw_speed = states('sensor.tempest_wind_speed') | float %}
      {% if raw_speed >= 10 %}
        red
      {% else %}
        "var(text-primary-color)"
      {% endif %}

    This makes it easy to spot when it’s particularly gusty outside without taking up extra space or alerting.

    Final Touch

    Finally, I added a tap action to bring up the more-info panel when you tap the card.

    tap_action:
      action: more-info

    That way, if I want to see the raw data or history graph, it’s just a tap away.

    Result

    What I ended up with is a sleek little wind tile that blends into my dashboard, gives me useful info at a glance, and doesn’t crowd the interface.

    It’s one of those tiny details that makes the whole dashboard feel more alive.

    shows a dashboard of weather widgets, wind, rain, temperature

    Entire YAML

    type: custom:mushroom-template-card
    entity: sensor.tempest_wind_speed
    primary: Wind
    secondary: "{{ states('sensor.tempest_wind_speed') | float | round(2) }} mph"
    icon: >-
      {% set raw_dir = states('sensor.tempest_wind_direction') %}
      {% set raw_speed = states('sensor.tempest_wind_speed') %}
      {% if raw_dir in ['unknown', 'unavailable', 'none', ''] or raw_speed | float == 0 %}
        mdi:compass
      {% else %}
        {% set d_from = ((raw_dir | float) % 360 + 360) % 360 %}
        {% set d_to = (d_from + 180) % 360 %}
        {% set idx = (((d_to + 22.5) % 360) // 45) | int %}
        {% set icons = [
          'mdi:arrow-up-circle-outline',
          'mdi:arrow-top-right-thin-circle-outline',
          'mdi:arrow-right-circle-outline',
          'mdi:arrow-bottom-right-thin-circle-outline',
          'mdi:arrow-down-circle-outline',
          'mdi:arrow-bottom-left-thin-circle-outline',
          'mdi:arrow-left-circle-outline',
          'mdi:arrow-top-left-thin-circle-outline'
        ] %}
        {{ icons[idx] }}
      {% endif %}
    icon_color: >-
      {% set raw_speed = states('sensor.tempest_wind_speed') | float %}
      {% if raw_speed >= 10 %}
        red
      {% else %}
        "var(text-primary-color)"
      {% endif %}
    tap_action:
      action: more-info