[DISCONTINUED] OzPoll - Australian Pollen Forecast (Integration)

Maybe try this link.

http://api.pollenforecast.com.au/app/json/app_data.php?app=1&version=2

1 Like

Oh wow. What’s the deal? :slight_smile:

No deal. Just an unofficial api that can easily be found if you know how to :wink:

Legend. I actually had a dig around for it too but couldn’t figure it out.

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.

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

1 Like

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.

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

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.

Thanks you, that appears to have worked. Thanks…

1 Like

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.

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

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.