Melbourne Pollen Forecast Scrape Sensor and Lovelace "Card"

thanks, this is super helpful!

I’m chipping away at it and making some progress. Don’t really know what I’m doing though.

I’ve been trying to hack something together this morning to use the asthma forecast.

The HTML nested within the JSON makes it hard to work with.

my solution at the moment is this:
I’m using a shell command to extract just the asthma forecast HTML from the API (this is div 5)
asthma_refresh: 'curl "https://api.pollenforecast.com.au/app/json/app_data.php?app=1&version=2" | jq .div5 >/config/www/asthma.html'

I’m running this as a service every 30 mins.

I’m then running multiscrape over the output:

  - resource: http://[IP address]/local/asthma.html
    scan_interval: 3600 #3600 sec = hr
    name: Asthma forecast
    sensor:
      - unique_id: asthma_forecast_scrape
        name: Asthma forecast 
        select: '#\\\"ta-forecast-table\\\" > tbody > tr:nth-child(1) > td.\\\"center\\\" > p'
        attributes:
          - name: Website Last Updated
            select: 'body > div > div > div:nth-child(8) > p'

This is not a neat way to do it, but it does give me a sensor in homeassistant.

Nice progress. Better than my attempts. Yeah I had the same struggles with the html nested in the json.

I managed to get the forecast html in as text using the rest sensor, then I was tinkering with some very gross parsing of the HTML as text, despite finding some hilarious warnings.

Edit: Added detail

Like If you have this:

rest:
  - authentication: basic
    scan_interval: 600
    resource: https://api.pollenforecast.com.au/app/json/app_data.php?app=1&version=2
    headers:
       Accept: application/json
       Content-Type: application/xml
    sensor:
      - name: "Melbourne Pollen test"
        value_template: "OK"
        json_attributes:
          - "forecastpage"
          - "div5"
          - "share"

Then you get a sensor with the requested attributes that have the massive html text as attributes (I was hoping HA might recognise it and parse it)

Then I was going to try to somehow parse the html from each of the above json_attributes it into some simplified json that could be stored nested and then queried. I dunno if that makes sense.

In template developer tools

{% set myxml = states.sensor.melbourne_pollen_test.attributes.div5 %}
{{ 
myxml 
|replace('\n', '*+*+')
|striptags
|replace(' *+*+ *+*+ *+*+ ', '\n')
|replace('*+*+ *+*+ *+*+ ', '')
|replace('*+*+ *+*+ ', ': ')
|replace('*+*+', '')
}}

Output of above template starting to look a bit like json pairs.

Thunderstorm Asthma Forecast :  
  
 District  Risk of thunderstorm asthma
: Central : low
East Gippsland : low
Mallee : low
North Central : low
North East : low
Northern Country : low
South West : low
West and South Gippsland : low
Wimmera : low

 Note: The above epidemic thunderstorm asthma forecast information was provided by the Victorian Department of Health and Human Services and the Bureau of Meteorology. For more information pertaining to these forecasts visit this website.  Last updated: 2021-11-22 14:00:00; Current date: 2021-11-22

Update #2: On my “steaming pile of poo solution”
With the same rest sensor above, you can then create a template sensor like this to do some dogy parsing of the html into json

sensor:
  - platform: template
    sensors:
      melbourne_pollen_forecast_api_dev:
        friendly_name: Melbourne Pollen Forecast API Dev
        value_template: 'Ok' 
        attribute_templates:
          pollen_forecast: >-
            {% set myxml = states.sensor.melbourne_pollen_test.attributes.forecastpage %}
            {{ 
            '{\n' +
            myxml 
            |replace('Melbourne Pollen Forecast', '"data": [')
            |replace('<H2 ', '*NL*{*NL*"day_name":"<H1 ')
            |replace('</h2>', '</H2>",*NL* ')
            |replace('<P', '"date":"<P')
            |replace('P>', '<\/P>",*NL* ')
            |replace('<div class="pollen-forecast-level', '"pollen_level":"<<div class="pollen-forecast-level')
            |replace('</span>', '"</span>*NL*},*NL* ')
            |striptags
            |replace('*NL*', '\n') + ']\n}'
            }}

Which will look like this:

{
  "data": [
    {
      "day_name": "Monday",
      "date": "22 November 2021",
      "pollen_level": "HIGH"
    },
    {
      "day_name": "Tuesday",
      "date": "23 November 2021",
      "pollen_level": "HIGH"
    },
    {
      "day_name": "Wednesday",
      "date": "24 November 2021",
      "pollen_level": "MODERATE"
    },
    {
      "day_name": "Thursday",
      "date": "25 November 2021",
      "pollen_level": "LOW"
    },
    {
      "day_name": "Friday",
      "date": "26 November 2021",
      "pollen_level": "MODERATE"
    },
    {
      "day_name": "Saturday",
      "date": "27 November 2021",
      "pollen_level": "MODERATE"
    }
  ]
}

Then you can access values like this:

{{states.sensor.melbourne_pollen_forecast_api_dev.attributes.pollen_forecast.data[1].pollen_level}}

Returns "HIGH" in template Developer tool

if it works, it works! you’ve made great progress

1 Like

This is the main post which I will try to keep up to date with a working solution.

The solution has been breaking periodically due to changes in the unofficial API and the pretty fragile nature of my solution. I’m no coding guru I just slapped together something pretty hacky.

But don’t worry I’m pretty invested in keeping it working if possible (self-interest;).

I’ve added change notes at the bottom of this post, so hopefully you can check if you are up to date with changes before flagging an issue.


The main outputs are a bunch sensors and a “card”

image

You need a rest sensor in your config which pulls in chucks of the massive html which is nested in json attributes.

rest:
  - authentication: basic
    scan_interval: 600
    resource: https://api.pollenforecast.com.au/app/json/app_data.php?app=1&version=4
    sensor:
      - name: "Melbourne Pollen API HTML"
        value_template: "OK"
        json_attributes:
          - "forecastpage"
          - "div8"
          # - "div7"

Then two template sensors in your config parses the html with regex (probably fragile and a bad idea).

  1. The ‘melbourne_pollen_forecast_api’ sensor covers the basics and feeds the card.
  2. The ‘melbourne_pollen_forecast_api_6day_summary_stats’ sensor has some summary stats about the 6 days ahead, which you can use to build up alerts and announcments. For example I have this announced when rising in the morning and at bedtime. It helps me plan ahead. It’s still not quite right.

six_day_outlook_description: The 6 day pollen outlook level is Low. There are 1 moderate days, 0 high days and 0 extreme days. Tommorrow is Low, Saturday is Low, and Sunday is Low.

  - platform: template
    sensors:
      melbourne_pollen_forecast_api:
        friendly_name: Melbourne Pollen Forecast via API
        value_template: ''
        attribute_templates:
          melbourne_6day_pollen_forecast: >-
            {% set forecastpageHTML = states.sensor.melbourne_pollen_api_html.attributes.forecastpage %}
            {% set LowerForecastpageHTML = forecastpageHTML|lower  %}
            {{ 
            '{\n' +
            LowerForecastpageHTML
            |replace('monday', 'Mon')
            |replace('tuesday', 'Tue')
            |replace('wednesday', 'Wed')
            |replace('thursday', 'Thu')
            |replace('friday', 'Fri')
            |replace('saturday', 'Sat')
            |replace('sunday', 'Sun')
            |replace('melbourne pollen forecast', '"days": [')
            |replace('<h2 ', '*nl*{*nl*"day_short_name":"<h1 ')
            |replace('</h2>', '</h2>",*nl* ')
            |replace('<p', '"date":"<p')
            |replace('p>', '<\/p>",*nl* ')
            |replace('<div class="pollen-forecast-level', '"pollen_level":"<<div class="pollen-forecast-level')
            |replace('low', 'Low"},')
            |replace('moderate', 'Moderate"},')
            |replace('high', 'High"},')
            |replace('extreme', 'Extreme"},')
            |striptags
            |replace('*nl*', '\n') + ']\n}'
            }}    
            
          my_district_asthma_forecast_today: >-
            {% set myDistrict =  'Central' %}
            {% set asthmaForecastHTML = states.sensor.melbourne_pollen_api_html.attributes.div8  %}
            {% set myDistrictasthmaForecast = asthmaForecastHTML
            |replace('\r\n','')
            |replace('>' + myDistrict  + '</td>', '>x' + myDistrict + 'x<')
            | regex_findall(find='>x' + myDistrict + 'x<'+'([\\s\\S]*?)</p>', ignorecase=False)
            |striptags
            |replace(' ','')
            %}
            {{myDistrictasthmaForecast}}
            #Change myDistrict value above to one of: 
            # Central
            # East Gippsland
            # Mallee
            # North Central
            # North East
            # Northern Country
            # South West
            # West and South Gippsland
            # Wimmera
      melbourne_pollen_forecast_api_6day_summary_stats:
        friendly_name: Melbourne Pollen Forecast 6 Day Summary Stats
        #Todo: Comment code properly
        value_template: >-
          {% set count_low = namespace(count = 0) %}
          {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
              {%- if days.pollen_level == "Low" -%}
                 {% set count_low.count = count_low.count+1 %}
              {%- endif -%}
          {% endfor %}
          {% set count_moderate = namespace(count = 0) %}
          {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
              {%- if days.pollen_level == "Moderate" -%}
                 {% set count_moderate.count = count_moderate.count+1 %}
              {%- endif -%}
          {% endfor %}
          {% set count_high = namespace(count = 0) %}
          {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
              {%- if days.pollen_level == "High" -%}
                 {% set count_high.count = count_high.count+1 %}
              {%- endif -%}
          {% endfor %}
          {% set count_extreme = namespace(count = 0) %}
          {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
              {%- if days.pollen_level == "Extreme" -%}
                 {% set count_extreme.count = count_extreme.count+1 %}
              {%- endif -%}
          {% endfor %}
          {% set overall_pollen_rating =  (count_low.count*1 + count_moderate.count*2 + count_high.count*3 + count_extreme.count*4)/6 %}
          {%- if overall_pollen_rating <= 1 -%}
                {% set overall_pollen_level =  'Low' %}
          {%- elif overall_pollen_rating <= 2 -%}
                {% set overall_pollen_level =  'Moderate' %}
          {%- elif overall_pollen_rating <= 3 -%}
                {% set overall_pollen_level =  'High' %}
          {%- elif overall_pollen_rating <= 4 -%}
                {% set overall_pollen_level =  'Extreme' %}
              {%- endif -%}
           {{overall_pollen_level}}
        attribute_templates:
          count_of_low_days: >-
              {% set count_low = namespace(count = 0) %}
                {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                    {%- if days.pollen_level == "Low" -%}
                      {% set count_low.count = count_low.count+1 %}
                    {%- endif -%}
                {% endfor %}
              {{count_low.count}}
          count_of_moderate_days: >-
              {% set count_moderate = namespace(count = 0) %}
              {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                  {%- if days.pollen_level == "Moderate" -%}
                     {% set count_moderate.count = count_moderate.count+1 %}
                  {%- endif -%}
              {% endfor %}
              {{count_moderate.count}}
          count_of_high_days: >-
              {% set count_high = namespace(count = 0) %}
              {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                  {%- if days.pollen_level == "High" -%}
                     {% set count_high.count = count_high.count+1 %}
                  {%- endif -%}
              {% endfor %}
              {{count_high.count}}
          count_of_extreme_days: >-
            {% set count_extreme = namespace(count = 0) %}
            {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                {%- if days.pollen_level == "Extreme" -%}
                   {% set count_extreme.count = count_extreme.count+1 %}
                {%- endif -%}
            {% endfor %}
            {{count_extreme.count}}
            
          six_day_outlook_description: >-
            The 6 day pollen outlook level is {{states.sensor.melbourne_pollen_forecast_api_6day_summary_stats.state}}. 
            There are {{states.sensor.melbourne_pollen_forecast_api_6day_summary_stats.attributes.count_of_moderate_days}} moderate days, 
            {{states.sensor.melbourne_pollen_forecast_api_6day_summary_stats.attributes.count_of_high_days}} high days and 
            {{states.sensor.melbourne_pollen_forecast_api_6day_summary_stats.attributes.count_of_extreme_days}} extreme days.
            Tommorrow is {{states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days[1].pollen_level}},
            Saturday is 
            {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                {%- if days.day_short_name == "Sat" -%}
                   {{days.pollen_level}}
                {%- endif -%}
            {% endfor %}, and
            Sunday is 
            {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                {%- if days.day_short_name == "Sun" -%}
                   {{days.pollen_level}}
                {%- endif -%}
            {% endfor %}.

Then lots of jiggery-pokery in lovelace using the custom button-card (via HACS):

    # #### Melbourne Pollen Card ##############################################################################################################
          - type: vertical-stack
            cards:
              - type: horizontal-stack
                cards:
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level);]]]
                    label: >
                      [[[return 'Pollen Today';]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 70%
                    aspect_ratio: 2.5/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.8vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0]);]]]
                    label: >
                      [[[return 'Thunderstorm Asthma Today';]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'high')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 70%
                    aspect_ratio: 2.5/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'high')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.8vw
                        - color: white
                      state:
                        - text-transform: uppercase
              - type: horizontal-stack
                cards:
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[
                        return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level);
                      ]]]
                      
                      
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white

And there’s some automation examples here:

Change Notes:

  1. 2022-09-22: Updated for 2022.
  2. 2022-10-06: Fixed breaking change due to pollen forecast in API changing from title case to upper case (Low > LOW etc.)
  3. 2022-10-08: Reversed #2 above as it changed back! lol…
  4. It reversed yet again! So I built an initial handle for either case…
  5. 2022-10-22: Changed API version from 5 to 4 as 5 had asthma forecasts as “unavailable” whereas 4 appears to have them.
  6. Pasted in a fresh copy of the lovelace config.
  7. 2022-11-10: Added some automation examples on request
  8. 2022-11-27 Asthma forecast randomly changed from div7 to div8, breaking the sensor. So that was adjusted in 2 places.
  9. 2023-10-14: It’s broken again with no fix in sight ATM for the 6 day forecast. The API doesn’t seem to contain updated data.
3 Likes

Hey guys, Multiscrape is now also supporting json: Scrape sensor improved - scraping multiple values - #188 by danieldotnl

It might help you to merge your rest and template sensors into one.

1 Like

Appreciate the heads up @danieldotnl .

The thing with the api we are using is it actually has html nested within the JSON.

So we kind of need to be able to first do some JSON type selects and then do some HTML based selects on the results.

Any thoughts on if we can tackle this query chain with just Multi-scrape and the new features?

It would be great if so as our current solutions are clunky.

Thank you.

Thank you so much for this!!

For anyone playing in 2022 this still works :slight_smile:

1 Like

No prob. I’ll be revisiting it closer to spring, as I definitely would like it working.

They seem to change what data they offer almost annually.

I use it to plan my week, alert me about the day, close my windows, turn on my air purifier etc. Basically manage my exposure.

I’ve told the boss I’ll be trying to work from home on Extreme days etc.

Just doing some testing on this. Seems a few minor changes are required for this year.

  1. Change api version from version 2 to version 5.
  2. Add div7. I think you can remove div5. Looks like Thunderstorm asthma moved from div5 to div7.
rest:
  - authentication: basic
    scan_interval: 600
    resource: https://api.pollenforecast.com.au/app/json/app_data.php?app=1&version=5
    sensor:
      - name: "Melbourne Pollen API HTML"
        value_template: "OK"
        json_attributes:
          - "forecastpage"
          - "div5"
          - "div7"
          - "share"

Make the change in this section too:

          my_district_asthma_forecast_today: >-
            {% set myDistrict =  'Central' %}
            {% set asthmaForecastHTML = states.sensor.melbourne_pollen_api_html.attributes.div7  %}
            {% set myDistrictasthmaForecast = asthmaForecastHTML

Then we seem to be running again.
image

Not sure if the Asthma info will becoem availabe as we get into the season.

HI

I have manged to get both the API and HtML working.
But for some reason when I try and add it to Lovelave, the code fails

ButtonCardJSTemplateError: TypeError: Cannot read properties of undefined (reading '0') in 'return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.d...'

I pretty much copied the lovelace card, so not sure what exactly, i am doing wrong

Thanks as always

Could you provide a few more details please and I can help take a look?

A few basic first checks…

Does the sensor.melbourne_pollen_forecast_api look like this?

Can you get a basic custom:button-card working with another unrelated sensor? And are you on the latest version?

Also give this a try in case I debugged something and forgot to update earlier configs. Also try smaller parts of it…

    # #### Melbourne Pollen Card ##############################################################################################################
          - type: vertical-stack
            cards:
              - type: horizontal-stack
                cards:
                   #mother Mode
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level);]]]
                    label: >
                      [[[return 'Pollen Today';]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 70%
                    aspect_ratio: 2.5/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.8vw
                        - color: white
                   #mother Mode
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0]);]]]
                    label: >
                      [[[return 'Thunderstorm Asthma Today';]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'high')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 70%
                    aspect_ratio: 2.5/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'high')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.8vw
                        - color: white
                      state:
                        - text-transform: uppercase
              - type: horizontal-stack
                cards:
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white
                  - type: "custom:button-card"
                    entity: sensor.melbourne_pollen_forecast_api
                    label: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level);]]]
                    state_display: >
                      [[[return (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].day_short_name);]]]
                    icon: >
                      [[[
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Low')
                          return "mdi:emoticon-happy";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Moderate')
                          return "mdi:emoticon-neutral";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'High')
                          return "mdi:emoticon-sad";
                        if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Extreme')
                          return "mdi:emoticon-angry";
                        else
                          return "mdi:help-circle";
                      ]]]
                    show_label: true
                    show_state: true
                    show_name: false                
                    size: 50%
                    aspect_ratio: 1.8/1
                    layout: icon_state
                    styles:
                      name:
                        - font-weight: bold
                        - font-size: 0.5vw
                        - color: grey
                      icon:
                      - color: >
                          [[[
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Low')
                              return 'lime';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Moderate')
                              return 'yellow';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'High')
                              return 'orange';
                            if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Extreme')
                              return 'red';
                            else
                              return 'grey';
                          ]]]
                      label:
                        - font-weight: bold
                        - font-size: 0.6vw
                        - color: white

Thanks for getting back to me

Here is a screenshot of the api sensor

It seems to have a slightly different formatting, which I think might be why the lovelace doesn’t like it.

Here is the code I used for the rest and template sensor

rest:
  - authentication: basic
    scan_interval: 600
    resource: https://api.pollenforecast.com.au/app/json/app_data.php?app=1&version=5
    sensor:
      - name: "Melbourne Pollen API HTML"
        value_template: "OK"
        json_attributes:
          - "forecastpage"
          - "div5"
          - "div7"
          - "share"
sensor:
  - platform: template
    sensors:
      melbourne_pollen_forecast_api:
        friendly_name: Melbourne Pollen Forecast via API
        value_template: ''
        attribute_templates:
          melbourne_6day_pollen_forecast: >-
            {% set forecastpageHTML = states.sensor.melbourne_pollen_api_html.attributes.forecastpage %}
            {{ 
            '{\n' +
            forecastpageHTML
            |replace('Monday', 'Mon')
            |replace('Tuesday', 'Tue')
            |replace('Wednesday', 'Wed')
            |replace('Thursday', 'Thu')
            |replace('Friday', 'Fri')
            |replace('Saturday', 'Sat')
            |replace('Sunday', 'Sun')
            |replace('Melbourne Pollen Forecast', '"days": [')
            |replace('<H2 ', '*NL*{*NL*"day_short_name":"<H1 ')
            |replace('</h2>', '</H2>",*NL* ')
            |replace('<P', '"date":"<P')
            |replace('P>', '<\/P>",*NL* ')
            |replace('<div class="pollen-forecast-level', '"pollen_level":"<<div class="pollen-forecast-level')
            |replace('</span>', '"</span>*NL*},*NL* ')
            |striptags
            |replace('*NL*', '\n') + ']\n}'
            }}
          my_district_asthma_forecast_today: >-
            {% set myDistrict =  'Central' %}
            {% set asthmaForecastHTML = states.sensor.melbourne_pollen_api_html.attributes.div7  %}
            {% set myDistrictasthmaForecast = asthmaForecastHTML
            |replace('\r\n','')
            |replace('>' + myDistrict  + '</td>', '>x' + myDistrict + 'x<')
            | regex_findall(find='>x' + myDistrict + 'x<'+'([\\s\\S]*?)</p>', ignorecase=False)
            |striptags
            |replace(' ','')
            %}
            {{myDistrictasthmaForecast}}
            #Change myDistrict value above to one of: 
            # Central
            # East Gippsland
            # Mallee
            # North Central
            # North East
            # Northern Country
            # South West
            # West and South Gippsland
            # Wimmera

So not sure if I have misconfigured something.

I think I made more changes but didn’t publish/change them.

Try this, then if it works, I’ll update my earlier post…

  - platform: template
    sensors:
      melbourne_pollen_forecast_api:
        friendly_name: Melbourne Pollen Forecast via API
        value_template: ''
        attribute_templates:
          melbourne_6day_pollen_forecast: >-
            {% set forecastpageHTML = states.sensor.melbourne_pollen_api_html.attributes.forecastpage %}
            {{ 
            '{\n' +
            forecastpageHTML
            |replace('Monday', 'Mon')
            |replace('Tuesday', 'Tue')
            |replace('Wednesday', 'Wed')
            |replace('Thursday', 'Thu')
            |replace('Friday', 'Fri')
            |replace('Saturday', 'Sat')
            |replace('Sunday', 'Sun')
            |replace('Melbourne Pollen Forecast', '"days": [')
            |replace('<H2 ', '*NL*{*NL*"day_short_name":"<H1 ')
            |replace('</h2>', '</H2>",*NL* ')
            |replace('<P', '"date":"<P')
            |replace('P>', '<\/P>",*NL* ')
            |replace('<div class="pollen-forecast-level', '"pollen_level":"<<div class="pollen-forecast-level')
            |replace('Low', 'Low"},')
            |replace('Moderate', 'Moderate"},')
            |replace('High', 'High"},')
            |replace('Extreme', 'Extreme"},')
            |striptags
            |replace('*NL*', '\n') + ']\n}'
            }}     
            
          my_district_asthma_forecast_today: >-
            {% set myDistrict =  'Central' %}
            {% set asthmaForecastHTML = states.sensor.melbourne_pollen_api_html.attributes.div7  %}
            {% set myDistrictasthmaForecast = asthmaForecastHTML
            |replace('\r\n','')
            |replace('>' + myDistrict  + '</td>', '>x' + myDistrict + 'x<')
            | regex_findall(find='>x' + myDistrict + 'x<'+'([\\s\\S]*?)</p>', ignorecase=False)
            |striptags
            |replace(' ','')
            %}
            {{myDistrictasthmaForecast}}
            #Change myDistrict value above to one of: 
            # Central
            # East Gippsland
            # Mallee
            # North Central
            # North East
            # Northern Country
            # South West
            # West and South Gippsland
            # Wimmera

Thanks you, that appears to have worked. Thanks…

1 Like

I’ve been playing with some 6day forecast summary stats while I’m active on this.

This template sensor counts the number of low, moderate, high, and extreme days in the next 6 days.

It also assigns a weighting of 1,2,3,4 for each of the levels then calculates an overall rating based on a simple average.

This can be used to trigger alerts and help plan your week. For example I might plan to work-from-home rather than cycle in, and let the boss know that ahead of time etc…

Might be a more concise way to do it, but it works (I think)…

  - platform: template
    sensors:
      melbourne_pollen_forecast_api_6day_summary_stats:
        friendly_name: Melbourne Pollen Forecast 6 Day Summary Stats
        #Todo: Comment code properly
        value_template: >-
          {% set count_low = namespace(count = 0) %}
          {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
              {%- if days.pollen_level == "Low" -%}
                 {% set count_low.count = count_low.count+1 %}
              {%- endif -%}
          {% endfor %}
          {% set count_moderate = namespace(count = 0) %}
          {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
              {%- if days.pollen_level == "Moderate" -%}
                 {% set count_moderate.count = count_moderate.count+1 %}
              {%- endif -%}
          {% endfor %}
          {% set count_high = namespace(count = 0) %}
          {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
              {%- if days.pollen_level == "High" -%}
                 {% set count_high.count = count_high.count+1 %}
              {%- endif -%}
          {% endfor %}
          {% set count_extreme = namespace(count = 0) %}
          {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
              {%- if days.pollen_level == "Extreme" -%}
                 {% set count_extreme.count = count_extreme.count+1 %}
              {%- endif -%}
          {% endfor %}
          {% set overall_pollen_rating =  (count_low.count*1 + count_moderate.count*2 + count_high.count*3 + count_extreme.count*4)/6 %}
          {%- if overall_pollen_rating <= 1 -%}
                {% set overall_pollen_level =  'Low' %}
          {%- elif overall_pollen_rating <= 2 -%}
                {% set overall_pollen_level =  'Moderate' %}
          {%- elif overall_pollen_rating <= 3 -%}
                {% set overall_pollen_level =  'High' %}
          {%- elif overall_pollen_rating <= 4 -%}
                {% set overall_pollen_level =  'Extreme' %}
              {%- endif -%}
           {{overall_pollen_level}}
        attribute_templates:
          count_of_low_days: >-
              {% set count_low = namespace(count = 0) %}
                {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                    {%- if days.pollen_level == "Low" -%}
                      {% set count_low.count = count_low.count+1 %}
                    {%- endif -%}
                {% endfor %}
              {{count_low.count}}
          count_of_moderate_days: >-
              {% set count_moderate = namespace(count = 0) %}
              {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                  {%- if days.pollen_level == "Moderate" -%}
                     {% set count_moderate.count = count_moderate.count+1 %}
                  {%- endif -%}
              {% endfor %}
              {{count_moderate.count}}
          count_of_high_days: >-
              {% set count_high = namespace(count = 0) %}
              {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                  {%- if days.pollen_level == "High" -%}
                     {% set count_high.count = count_high.count+1 %}
                  {%- endif -%}
              {% endfor %}
              {{count_high.count}}
          count_of_extreme_days: >-
            {% set count_extreme = namespace(count = 0) %}
            {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                {%- if days.pollen_level == "Extreme" -%}
                   {% set count_extreme.count = count_extreme.count+1 %}
                {%- endif -%}
            {% endfor %}
            {{count_extreme.count}}
            
          six_day_outlook_description: >-
            The 6 day pollen outlook level is {{states.sensor.melbourne_pollen_forecast_api_6day_summary_stats.state}}. 
            There are {{states.sensor.melbourne_pollen_forecast_api_6day_summary_stats.attributes.count_of_moderate_days}} moderate days, 
            {{states.sensor.melbourne_pollen_forecast_api_6day_summary_stats.attributes.count_of_high_days}} high days and 
            {{states.sensor.melbourne_pollen_forecast_api_6day_summary_stats.attributes.count_of_extreme_days}} extreme days.
            Tommorrow is {{states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days[1].pollen_level}},
            Saturday is 
            {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                {%- if days.day_short_name == "Sat" -%}
                   {{days.pollen_level}}
                {%- endif -%}
            {% endfor %}, and
            Sunday is 
            {% for days in states.sensor.melbourne_pollen_forecast_api.attributes.melbourne_6day_pollen_forecast.days %}
                {%- if days.day_short_name == "Sun" -%}
                   {{days.pollen_level}}
                {%- endif -%}
            {% endfor %}.

Great work @Mahko_Mahko. I set it up a couple of days ago and it was working fine until today when I ran into the same issue with rendering cards as @obrien.craig.

Haven’t changed anything and my sensor.melbourne_pollen_forecast_api looks like this:

friendly_name: Melbourne Pollen Forecast via API
melbourne_6day_pollen_forecast: {
"days": [ 
{
"day_short_name":"Wed",
 "date":"05 October 2022",
 "pollen_level":"LOW 
{
"day_short_name":"Thu",
 "date":"06 October 2022",
 "pollen_level":"MODERATE 
{
"day_short_name":"Fri",
 "date":"07 October 2022",
 "pollen_level":"LOW 
{
"day_short_name":"Sat",
 "date":"08 October 2022",
 "pollen_level":"LOW 
{
"day_short_name":"Sun",
 "date":"09 October 2022",
 "pollen_level":"LOW 
{
"day_short_name":"Mon",
 "date":"10 October 2022",
 "pollen_level":"LOW]
}
my_district_asthma_forecast_today: not-available

My card config:

 - type: vertical-stack
    cards:
      - type: horizontal-stack
        cards:
          - type: custom:button-card
            entity: sensor.melbourne_pollen_forecast_api
            state_display: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level);]]]
            label: |
              [[[return 'Pollen Today';]]]
            icon: |
              [[[
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Low')
                  return "mdi:emoticon-happy";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Moderate')
                  return "mdi:emoticon-neutral";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'High')
                  return "mdi:emoticon-sad";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Extreme')
                  return "mdi:emoticon-angry";
                else
                  return "mdi:help-circle";
              ]]]
            show_label: true
            show_state: true
            show_name: false
            size: 70%
            aspect_ratio: 2.5/1
            layout: icon_state
            color_type: card
            styles:
              name:
                - font-weight: bold
                - font-size: 0.6vw
                - color: black
              icon:
                - color: |
                    [[[
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Low')
                        return 'lime';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Moderate')
                        return 'yellow';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'High')
                        return 'orange';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[0].pollen_level == 'Extreme')
                        return 'red';
                      else
                        return 'grey';
                    ]]]
              label:
                - font-weight: bold
                - font-size: 0.8vw
                - color: black
          - type: custom:button-card
            entity: sensor.melbourne_pollen_forecast_api
            state_display: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0]);]]]
            label: |
              [[[return 'Thunderstorm Asthma Today';]]]
            icon: |
              [[[
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'low')
                  return "mdi:emoticon-happy";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'moderate')
                  return "mdi:emoticon-neutral";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'high')
                  return "mdi:emoticon-sad";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'extreme')
                  return "mdi:emoticon-angry";
                else
                  return "mdi:help-circle";
              ]]]
            show_label: true
            show_state: true
            show_name: false
            size: 70%
            aspect_ratio: 2.5/1
            layout: icon_state
            color_type: card
            styles:
              name:
                - font-weight: bold
                - font-size: 0.5vw
                - color: grey
              icon:
                - color: |
                    [[[
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'low')
                        return 'lime';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'moderate')
                        return 'yellow';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'high')
                        return 'orange';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.my_district_asthma_forecast_today[0] == 'extreme')
                        return 'red';
                      else
                        return 'grey';
                    ]]]
              label:
                - font-weight: bold
                - font-size: 0.8vw
                - color: black
              state:
                - text-transform: capitalize
      - type: horizontal-stack
        cards:
          - type: custom:button-card
            entity: sensor.melbourne_pollen_forecast_api
            label: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level);]]]
            state_display: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].day_short_name);]]]
            icon: |
              [[[
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Low')
                  return "mdi:emoticon-happy";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Moderate')
                  return "mdi:emoticon-neutral";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'High')
                  return "mdi:emoticon-sad";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Extreme')
                  return "mdi:emoticon-angry";
                else
                  return "mdi:help-circle";
              ]]]
            show_label: true
            show_state: true
            show_name: false
            color_type: card
            size: 50%
            aspect_ratio: 1.8/1
            layout: icon_state
            styles:
              name:
                - font-weight: bold
                - font-size: 0.5vw
                - color: grey
              icon:
                - color: |
                    [[[
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Low')
                        return 'lime';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Moderate')
                        return 'yellow';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'High')
                        return 'orange';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Extreme')
                        return 'red';
                      else
                        return 'grey';
                    ]]]
              label:
                - font-weight: bold
                - font-size: 1.0vw
                - color: black
          - type: custom:button-card
            entity: sensor.melbourne_pollen_forecast_api
            label: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level);]]]
            state_display: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].day_short_name);]]]
            icon: |
              [[[
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Low')
                  return "mdi:emoticon-happy";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Moderate')
                  return "mdi:emoticon-neutral";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'High')
                  return "mdi:emoticon-sad";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Extreme')
                  return "mdi:emoticon-angry";
                else
                  return "mdi:help-circle";
              ]]]
            show_label: true
            show_state: true
            show_name: false
            size: 50%
            aspect_ratio: 1.8/1
            layout: icon_state
            color_type: card
            styles:
              name:
                - font-weight: bold
                - font-size: 0.5vw
                - color: grey
              icon:
                - color: |
                    [[[
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Low')
                        return 'lime';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Moderate')
                        return 'yellow';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'High')
                        return 'orange';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[2].pollen_level == 'Extreme')
                        return 'red';
                      else
                        return 'grey';
                    ]]]
              label:
                - font-weight: bold
                - font-size: 1.0vw
                - color: black
          - type: custom:button-card
            entity: sensor.melbourne_pollen_forecast_api
            label: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level);]]]
            state_display: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].day_short_name);]]]
            icon: |
              [[[
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Low')
                  return "mdi:emoticon-happy";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Moderate')
                  return "mdi:emoticon-neutral";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'High')
                  return "mdi:emoticon-sad";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Extreme')
                  return "mdi:emoticon-angry";
                else
                  return "mdi:help-circle";
              ]]]
            show_label: true
            show_state: true
            show_name: false
            size: 50%
            aspect_ratio: 1.8/1
            layout: icon_state
            color_type: card
            styles:
              name:
                - font-weight: bold
                - font-size: 0.5vw
                - color: grey
              icon:
                - color: |
                    [[[
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Low')
                        return 'lime';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Moderate')
                        return 'yellow';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'High')
                        return 'orange';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[3].pollen_level == 'Extreme')
                        return 'red';
                      else
                        return 'grey';
                    ]]]
              label:
                - font-weight: bold
                - font-size: 1.0vw
                - color: black
          - type: custom:button-card
            entity: sensor.melbourne_pollen_forecast_api
            label: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level);]]]
            state_display: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].day_short_name);]]]
            icon: |
              [[[
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Low')
                  return "mdi:emoticon-happy";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Moderate')
                  return "mdi:emoticon-neutral";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'High')
                  return "mdi:emoticon-sad";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Extreme')
                  return "mdi:emoticon-angry";
                else
                  return "mdi:help-circle";
              ]]]
            show_label: true
            show_state: true
            show_name: false
            size: 50%
            aspect_ratio: 1.8/1
            layout: icon_state
            color_type: card
            styles:
              name:
                - font-weight: bold
                - font-size: 0.5vw
                - color: grey
              icon:
                - color: |
                    [[[
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Low')
                        return 'lime';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Moderate')
                        return 'yellow';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'High')
                        return 'orange';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[4].pollen_level == 'Extreme')
                        return 'red';
                      else
                        return 'grey';
                    ]]]
              label:
                - font-weight: bold
                - font-size: 1.0vw
                - color: black
          - type: custom:button-card
            entity: sensor.melbourne_pollen_forecast_api
            label: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level);]]]
            state_display: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].day_short_name);]]]
            icon: |
              [[[
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Low')
                  return "mdi:emoticon-happy";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Moderate')
                  return "mdi:emoticon-neutral";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'High')
                  return "mdi:emoticon-sad";
                if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Extreme')
                  return "mdi:emoticon-angry";
                else
                  return "mdi:help-circle";
              ]]]
            show_label: true
            show_state: true
            show_name: false
            size: 50%
            aspect_ratio: 1.8/1
            layout: icon_state
            color_type: card
            styles:
              name:
                - font-weight: bold
                - font-size: 0.5vw
                - color: grey
              icon:
                - color: |
                    [[[
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Low')
                        return 'lime';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Moderate')
                        return 'yellow';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'High')
                        return 'orange';
                      if (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[5].pollen_level == 'Extreme')
                        return 'red';
                      else
                        return 'grey';
                    ]]]
              label:
                - font-weight: bold
                - font-size: 1.0vw
                - color: black

Mine appears to have broken too. Stay tuned. Seems to just be the card.

I can confirm there was a breaking change due to the API changing from reporting the pollen forecasts in title case to upper case (e.g “Low” is now “LOW”) in the api.

I’ve made the required changes/fixes and it should be ok again. I’ve updated the main solution post with neccessary changes.

The changes are in this section, but it probably wouldn’t hurt to be using my whole config line-for-line, as that may make debugging easier if you need a bit of help from me.

            |replace('<div class="pollen-forecast-level', '"pollen_level":"<<div class="pollen-forecast-level')
            |replace('LOW', 'Low"},')
            |replace('MODERATE', 'Moderate"},')
            |replace('HIGH', 'High"},')
            |replace('EXTREME', 'Extreme"},')
            |striptags
            |replace('*NL*', '\n') + ']\n}'
            }}