Melbourne Pollen Forecast Scrape Sensor and Lovelace "Card"

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}'
            }}     

Not sure what’s up with the Thunderstorm Asthma forecast for this season.

Also at time of publishing one day of forecast seemed to be missing (from the API).

Will monitor that.

image

1 Like

I’ve also noticed that the API and the webpage can report different results.

image

The webpage is also consistent with the app.

Possibly they use different versions of the API or have different update intervals.

Not sure “who is right”…

Mine’s broken again lol. Stay tuned…

And so hilariously this has now changed back to lower case and so I’ll revert back to previous code. If it happens again I might do something smarter…

Updated solution post.

Sorry - accidentally turned off all email notifications from the forum so just saw your replies. It actually started working again miraculously - likely due to them reverting the change to case. Will circle back here if it happens again! Thanks for looking into it though :slight_smile:

1 Like

I wonder what other data is lurking around in other app/api versions.

Edit:
I think this one is for Melbourne
https://api.pollenforecast.com.au/app/json/app_data.php?app=1&version=5
I think this one is for Canberra
https://api.pollenforecast.com.au/app/json/app_data.php?app=2&version=4
I think this one is for Sydney
https://api.pollenforecast.com.au/app/json/app_data.php?app=3&version=4

I’ve noticed that the pollen forecasts via the API are not consistent with what’s in the app. And so am becoming skeptical as to whether the data source we are using for this is still valid.

1 Like

Can you please confirm if the code snippets are the latest? Not working for me and I see there was a breaking change around capitalisation in the API but that’s not in the code snippets?

For me, that issue changed, and then changed back!

But mine has also changed yet again so it looks like the breaking change has returned…

Fix will be confirmed soonish… It is expected to be as per config snippet in this post.

I’ve built an intial handle for the intermittent breaking change where the api fllips between upper and title case.

The main solution post has bee updated and the change noted at the bottom. It should be working again and a bit more reliable now.

The change is in this part.

          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}'
            }} 

I’m still not convinced the API is giving us valid forecasts this year, but that’s another matter…

FYI I think the card widget code also may need updating to have flexibility in the uppercase/sentence case values coming through. I tested with a simple || addition and seemed to fix it.

EDIT: Sorry just saw that you already mentioned thunderstorm asthma alerts aren’t working via the API :slight_smile:

e.g.:
((states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'LOW') || (states['sensor.melbourne_pollen_forecast_api'].attributes.melbourne_6day_pollen_forecast.days[1].pollen_level == 'Low'))

I think it should be ok. Because I now process upper or title case to be title case. So the upstream card doesn’t need adjusting.

I just validated this against the app. So maybe forecasts are still ok.
image