Melbourne Pollen Forecast Scrape Sensor and Lovelace "Card"

I have just updated to 2021.9.2 and am now getting ‘unknown’ for all the pollen entities.

It was working fine from the Canberra site just before the update and the data on the site is still available.

Any ideas ?

Gaz

Hey. I had a quick tinker and had the same behaviour (using Canberra site) but couldn’t quickly diagnose/resolve.

Inrerestingly you can still scrape the forecast value as an attribute (maybe you can work with that?)

      - unique_id: melbourne_pollen_forecast_fc1
        name: Pollen fc1
        select: '#fc1'
        attributes:
          - name: Forecast Day
            select: "#dy1"
            value_template: "{{ value[:3] }}"
          - name: Forecast Date
            select: "#dt1"
            #################NEW#################
          - name: Forecast Value
            select: "#fc1"
            #####################################
        value_template: "{{ value.strip() }}"
        icon: >-
          {% if is_state("sensor.melbourne_pollen_forecast_fc1", "Low") %}
            mdi:emoticon-happy
          {% elif is_state("sensor.melbourne_pollen_forecast_fc1", "Moderate")  %}
            mdi:emoticon-neutral
          {% elif is_state("binary_sensor.melbourne_pollen_forecast_fc1", "High")  %}
            mdi:emoticon-sad
          {% elif is_state("binary_sensor.melbourne_pollen_forecast_fc1", "Extreme")  %}
            mdi:emoticon-angry
          {% else %}
            mdi:help-circle
          {% endif %}

It’s looking unlikely the Melbourne site will return, and I so I won’t be very active in developing/maintaining work to date.

You may get some assistance on the Multiscape thread, or have a go at tinkering with the scaping. It’s easy once you know how. See the Multiscrape wiki.

Hope that is of some help.

Thanks for taking a look.

The Melbourne site states that they will start again in October and I also noticed that there is an Android app but it does not support the data from Canberra.

Just noticed your edit at the top, no longer free is a bugger.

Gaz

Issue is as per here.

Solution is post after…

After upgrading to V5.5 of multiscrape it is working again.

Gaz

1 Like

Revised sensor for “today” based on what is currently available for Victoria.

image

This is where it scrapes from.

If you want another area, take a look at some of the multiscrape tutorials. It’s easy once you know how. If you try and fail, I can help.

In config…

############################################################################
##Melbourne Pollen Forecast
############################################################################
multiscrape:
  - resource: https://www.melbournepollen.com.au/
    scan_interval: 3600 #3600 sec = hr
    name: Pollen Forecast
    sensor:
      - unique_id: melbourne_pollen_forecast_today
        name: Pollen Forecast Today
        select: '#district-pollen-div > div > div > div > div > div > div.uk-grid-match.uk-child-width-1-2\@s.uk-text-center.uk-grid-collapse.uk-grid > div:nth-child(2) > div:nth-child(1) > div:nth-child(2) > div'
        value_template: '{{ value| trim}}'
        attributes:
          - name: Website Last Updated
            select: '#district-pollen-div > div > div > div > div > div > div.uk-grid-match.uk-child-width-1-2\@s.uk-text-center.uk-grid-collapse.uk-grid > div:nth-child(1) > div.ta-notice'
            value_template: "{{ value| replace('Last updated:', '')}}"
        icon: >-
          {% if value == 'Low' %}
            mdi:emoticon-happy
          {% elif value == 'Moderate' %}
            mdi:emoticon-neutral
          {% elif value == 'High' %}
            mdi:emoticon-sad
          {% elif value == 'Extreme' %}
            mdi:emoticon-angry
          {% else %}
            mdi:help-circle
          {% endif %}

in lovelace…

          - type: custom:button-card
            entity: sensor.melbourne_pollen_forecast_today
            name: Pollen Forecast
            label: >
              [[[return
              (states['sensor.melbourne_pollen_forecast_today'].attributes.website_last_updated);]]]
            tap_action:
              action: more-info
            show_label: true
            show_state: true
            color: auto
            size: 150%
            aspect_ratio: 3/1
            layout: icon_state
            state:
              - value: Low
                color: rgb(16, 140, 10)
              - value: Moderate
                color: rgb(235, 235, 52)
              - value: High
                color: rgb(235, 147, 52)
              - value: Extreme
                color: rgb(235, 52, 52)
            styles:
              name:
                - font-weight: bold
                - font-size: 0.7vw
                - color: white
              state:
                - font-weight: bold
                - font-size: 3vw
                - color: white
              label:
                - font-weight: bold
                - font-size: 0.5vw
                - color: grey

@obrien.craig the above post may interest you. Cheers.

Thanks for that @Mahko_Mahko I have set it up. Works well. I did see that they didn’t answer you question on facebook about if the 5 day forecast would now be a paid for feature. I guess that non-answer probably means it will be.

Thanks again.

1 Like

Hi - great work maintaining this - I find the pollen card very helpful.

I would love to scrape the thunderstorm asthma warning from the same page as well - I’ve tried (and failed) using the css selector in chrome to replicate what you’ve done but I’m out of my depth.

I had a quick go but failed too. I think I’d failed previously too which is why I didn’t put it up.
I feel like this is right but it’s not working for me.

      - unique_id: melbourne_thunderstorm_asthma_today
        name: Thunderstorm Asthma Forecast Today
        select: '#tae-div > div > div > div > div > div > div.uk-grid-match.uk-child-width-1-2\@s.uk-text-center.uk-grid-collapse.uk-grid > div.uk-first-column > div:nth-child(1) > div:nth-child(2) > div'
        value_template: '{{ value| trim}}'
        attributes:
          - name: Website Last Updated
            select: '#district-pollen-div > div > div > div > div > div > div.uk-grid-match.uk-child-width-1-2\@s.uk-text-center.uk-grid-collapse.uk-grid > div:nth-child(1) > div.ta-notice'
            value_template: "{{ value| replace('Last updated:', '')}}"
        icon: >-
          {% if value == 'Low' %}
            mdi:emoticon-happy
          {% elif value == 'Moderate' %}
            mdi:emoticon-neutral
          {% elif value == 'High' %}
            mdi:emoticon-sad
          {% elif value == 'Extreme' %}
            mdi:emoticon-angry
          {% else %}
            mdi:help-circle
          {% endif %}

thanks for trying. that looks similar to what I was doing

1 Like

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.

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