I wanted to create a tracker for a local petrol station prices on my HA dashboard one which showed when the prices were high and low over time.
petrolprices.com has some really good data but no API.
for example https://www.petrolprices.com/locations/london/caledonian-road/593?m=1
So I ended up doing the following:
Step 1 – Install the Python dependencies (once only)
Open Terminal & SSH add-on and run:
Bash
pip3 install requests beautifulsoup4 --break-system-packages
Step 2 – Create the scraper script
File → File editor → create folder /config/scripts/ → new file fetch_fuel_prices.py
Python
#!/usr/bin/env python3
import requests
from bs4 import BeautifulSoup
import re
url = 'https://www.petrolprices.com/locations/st-davids/haverfordwest-road/8443'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
text = soup.get_text()
# Extract prices using regex (matches page structure from logs)
unleaded = re.search(r'UNLEADED\s*([0-9]+\.[0-9]+)p', text)
super_unleaded = re.search(r'SUPER UNLEADED\s*([0-9]+\.[0-9]+)p', text)
diesel = re.search(r'DIESEL\s*([0-9]+\.[0-9]+)p', text)
premium_diesel = re.search(r'PREMIUM DIESEL\s*([0-9]+\.[0-9]+)p', text)
# Output as pipe-separated string (safe, short)
prices = [
unleaded.group(1) if unleaded else 'N/A',
super_unleaded.group(1) if super_unleaded else 'N/A',
diesel.group(1) if diesel else 'N/A',
premium_diesel.group(1) if premium_diesel else 'N/A'
]
print('|'.join(prices))
Save → Terminal → test it:
Bash
chmod +x /config/scripts/fetch_fuel_prices.py
python3 /config/scripts/fetch_fuel_prices.py
# → should return: 134.9|152.9|144.9|164.9
Step 3 – Add to configuration.yaml (exact copy-paste)
YAML
command_line:
- sensor:
name: "St Davids Fuel Prices Raw"
unique_id: fuel_prices_raw_st_davids
command: "python3 /config/scripts/fetch_fuel_prices.py"
scan_interval: 7200 # 2 hours (86400 = once per day)
value_template: "{{ value }}"
template:
- sensor:
- name: "St Davids Unleaded"
unique_id: fuel_st_davids_unleaded
unit_of_measurement: "ppl"
device_class: monetary
state_class: measurement
icon: mdi:gas-station
state: >
{% set p = states('sensor.st_davids_fuel_prices_raw').split('|') %}
{{ p[0] | trim | float(default=0) if p|length >= 4 and p[0] != 'N/A' else none }}
- name: "St Davids Super Unleaded"
unique_id: fuel_st_davids_super_unleaded
unit_of_measurement: "ppl"
device_class: monetary
state_class: measurement
icon: mdi:gas-station
state: >
{% set p = states('sensor.st_davids_fuel_prices_raw').split('|') %}
{{ p[1] | trim | float(default=0) if p|length >= 4 and p[1] != 'N/A' else none }}
- name: "St Davids Diesel"
unique_id: fuel_st_davids_diesel
unit_of_measurement: "ppl"
device_class: monetary
state_class: measurement
icon: mdi:gas-station
state: >
{% set p = states('sensor.st_davids_fuel_prices_raw').split('|') %}
{{ p[2] | trim | float(default=0) if p|length >= 4 and p[2] != 'N/A' else none }}
- name: "St Davids Premium Diesel"
unique_id: fuel_st_davids_premium_diesel
unit_of_measurement: "ppl"
device_class: monetary
state_class: measurement
icon: mdi:gas-station
state: >
{% set p = states('sensor.st_davids_fuel_prices_raw').split('|') %}
{{ p[3] | trim | float(default=0) if p|length >= 4 and p[3] != 'N/A' else none }}
Step 4 – Test then Reload or restart
Check configuration → Restart Home Assistant (or just reload command_line and template integrations).
Wait 30 seconds → Developer Tools → States → you will see four perfect price sensors.
Want another station?
Just copy the Python script, change the URL, and duplicate the YAML blocks with new names/IDs.
Hope this helps.