Queensland Fuel Prices Integration

Hey all

Would anyone be interested in helping me get data from the FuelPricesQld API into an integration? I don’t know how to start the process.

I have access to the API (free for data consumers), and have retrieved the data I would like to build into HA via Postman (daily prices for my fuel type for all local service stations). The data comes back in json format… Looking at this I think it may be fairly straight forward for someone who knows what they are doing…

The following request provides the data I want
https://fppdirectapi-prod.fuelpricesqld.com.au/Price/GetSitesPrices?countryId=21&geoRegionLevel=2&geoRegionId=16

This would need to be combined with this request to get friendly names for the site ids
https://fppdirectapi-prod.fuelpricesqld.com.au/Subscriber/GetFullSiteDetails?countryId=21&geoRegionLevel=2&geoRegionId=16

I imagine the end result could be set up via the gui, users add in their API after applying for one, and then set their GeoRegionLevel / GeoRegionID / FuelID (could add multiple) etc and it can create entities for each station / price.

Cheers

Hi, found this old post. I have actually written and integration for Qld but the datafeed/API I was using has been shutdown. I’d be happy to work with you on using the feed you spoke about, I tried your links but they failed to return a response. -Tony.

Hey

Those links don’t work outside of using Postman or something to interrogate the API with authorisation.

To get access to the API start here - https://www.fuelpricesqld.com.au/. Can fill in the following form and you’ll get an email with API access and instructions to get the data in Postman. I can’t get the swagger stuff to do anything.

anyone progress further here? I saw someone in the Australian FB group get it going but didnt’ share the code only screenshots… I have my API from https://www.fuelpricesqld.com.au/ but not sure how to progress… very green on all this stuff.

hhey @tbgoose @tonymyatt I created this sensor and it seems to work… I need to watch it over the next few days if it change… one monitored servo did so it’s looking positive…

you need to use postman to work out what servo’s you want to monitor and what fuel type.

1 Like

yes it works and I’ve run it for a few days now
image

2 Likes

So this is my implementation, which is a little different, but I think it gets to the same end. I couldn’t use the geoRegionID, as I have multiple service stations that I am interested in with the same geoRegionID.

First I access the fuel set of fuel prices through the API, the following is in my configuration.yaml.

rest:
  - scan_interval: 3001
    resource: https://fppdirectapi-prod.fuelpricesqld.com.au/Price/GetSitesPrices?countryId=21&geoRegionLevel=3&geoRegionId=1
    headers:
      Authorization: FPDAPI SubscriberToken= *token stuff goes here*
      Content-Type: application/json
    sensor:
      - name: fuel_prices_all
        value_template: "prices"
        json_attributes:
          - SitePrices

Then I created a number of InputNumber Helpers, via “Settings > Devices & Services > Helpers”
Add a helper and set them up like this:

I had to manually go back into each input and set the Area, as this wasn’t part of the initial setup of the helper.

Then I set up an Automation, like this:

alias: Fuel_Price_Automation
description: >-
  Define and automate the extraction of the price of e10 at the Taigum Liberty
  Servo
trigger:
  - platform: state
    entity_id:
      - sensor.fuel_prices_all
condition: []
action:
  - service: input_number.set_value
    metadata: {}
    data:
      value: |-
        {% set data = 
          state_attr('sensor.fuel_prices_all', 'SitePrices') %}
          {% set filtered_prices = data | selectattr('SiteId', 'eq', 61402386) | selectattr('FuelId', 'in', [12]) %}
            {% set price = filtered_prices | first %}
            {{ price.Price /1000}}
    target:
      entity_id: input_number.fuel_price_liberty_taigum_e10
  - service: input_number.set_value
    metadata: {}
    data:
      value: |-
        {% set data = 
          state_attr('sensor.fuel_prices_all', 'SitePrices') %}
          {% set filtered_prices = data | selectattr('SiteId', 'eq', 61402386) | selectattr('FuelId', 'in', [3,14]) %}
            {% set price = filtered_prices | first %}
            {{ price.Price /1000}}
    target:
      entity_id: input_number.fuel_price_liberty_taigum_diesel
mode: single

All of which gives me the following:

My next step is to figure out how to get the lowest e10 price shown/highlighted green, and the second lowest as yellow.
But simply looking at them is working for the moment.
Hope this helps

2 Likes

A further alternative method, using a script to dynamically update, filtering can probably be done at the rest level using value_template to limit the number / type of fuel. Triggering can be done from an automation.

If the helper is missing, add / enter device for notification.

alias: Fuel Prices
sequence:
  - variables:
      site_data: '{{ state_attr(''sensor.fuel_sites', ''S'') }}'
      price_data: '{{ state_attr(''sensor.fuel_prices'', ''SitePrices'') }}'
      fuel_types: '{{ state_attr(''sensor.fuel_types'', ''Fuels'') }}'
  - repeat:
      count: '{{ site_data | length }}'
      sequence:
        - variables:
            site: '{{ site_data[repeat.index - 1] }}'
            site_id: '{{ site.S }}'
            site_name: '{{ site.N }}'
        - repeat:
            count: >-
              {{ price_data | selectattr('SiteId', 'eq', site_id) | list |
              length }}
            sequence:
              - variables:
                  matched_prices: >-
                    {{ price_data | selectattr('SiteId', 'eq', site_id) | list
                    }}
                  fuel_price: '{{ matched_prices[repeat.index - 1] }}'
                  fuel_id: '{{ fuel_price.FuelId }}'
                  fuel_name: >
                    {{ fuel_types | selectattr('FuelId', 'eq', fuel_id) |
                    map(attribute='Name') | first | slugify }}
                  dynamic_var_name: '{{ ''fuel_price_'' ~ slugify(site_name) ~ ''_'' ~ fuel_name }}'
                  dynamic_var_entity_id: input_number.{{ dynamic_var_name }}
              - choose:
                  - conditions: '{{ not states(dynamic_var_entity_id) }}'
                    sequence:
                      - data:
                          title: Missing Input Number Helper
                          message: >
                            "The input_number helper '{{ dynamic_var_entity_id }}'
                            for Site '{{ site_name }}' and Fuel '{{ fuel_name
                            }}' (Fuel ID: {{ fuel_id }}) is missing."
                        action: notify.test_mobile_phone
              - target:
                  entity_id: '{{ dynamic_var_entity_id }}'
                data:
                  value: '{{ fuel_price.Price }}'
                action: input_number.set_value
description: ''
icon: mdi:fuel

As an extension to this I’m using the below in a markdown card to auto scrape all and provide the lowest price - has to all be on one line for in-card formatting… unless I’m missing something. If anyone knows how to right align in the markdown card, drop a reply ! :

type: markdown
content: >-
  # Cheapest Fuel Prices
  ---
  {% set fuel_types = state_attr('sensor.fuel_types', 'Fuels') %}{% for fuel in
  fuel_types %}{% set fueltype = fuel.Name | lower | slugify%}{% set
  capitalized_fueltype = fueltype.title() |replace('_',' ') %}{% set
  fuel_entities = states.input_number | selectattr('entity_id', 'search',
  fueltype~'$') | list %}{% if fuel_entities | length > 0 %} {{
  capitalized_fueltype }} : {% set values = fuel_entities |
  map(attribute='state') | list %}{% set min_value = values | min %}{% set
  lowest_entities = fuel_entities | selectattr('state', 'equalto', min_value) |
  list %}{% if lowest_entities | length > 0 %}{% for entity in lowest_entities
  %}{% set name_without_fueltype = entity.name.replace(fueltype,
  '').replace(capitalized_fueltype, '') %} {{ name_without_fueltype }} - ${{
  entity.state | float }}{% if not loop.last %}, {% endif %}{% endfor %}{% endif
  %}

  {% else %}{% endif %}{% endfor %}

Welcome any feedback. Hopefully not bad for a 1st post :slight_smile:

1 Like