Hello Daniel,
I am working on a gas module to find the cheapest gas station around. I use the viamichelin.fr that track 95000 station all over Europe, so it could may be useful to others here.
They refresh the data every hour or so and looks very accurate since its mandatory in France to declare the gas price to the government.
We could also track the money spent on gas each month, track the gas prices, …
I love multiscrape, its amazing fast, since there is only one page to scrape. Multiscrape works great with a table, but here some station have the E10 but others wont carry GPL for exemple. So for some stations I will have up to 6 gas type and some others just 3.
Here is how I extract the data (not the full code, I have one sensor per gas type)
multiscrape:
- name: gas_provider_michelin
resource: "https://www.viamichelin.fr/web/Stations-service?tid=city-1338248&fuelsLastUpdate=72&fuelsType=5"
scan_interval: 3600
list_separator: '|'
sensor:
- unique_id: gas_provider_michelin
name: "Gas prices via Michelin"
value_template: 0.0
unit_of_measurement: '€/L'
icon: mdi:gas-station
attributes:
- name: max_station
value_template: 20
- name: selected
value_template: 5
- name: city_code
value_template: "city-1338248"
- name: gas_name
value_template: "1,B7,Gazole,b7_gazole_price|2,E5,SP 95,e5_sp95_price|3,E85,Ethanol,e85_price|4,GPL,LPG,lpg_gpl_price|5,E10,SP 95-E10,e10_sp95_price|6,E5,SP 98,e5_sp98_price"
- name: city
select_list: ".shared_address_search .searchbox .truncate"
attribute: value
value_template: |
{{value|title}}
- name: station
select_list: ".poi-item-gasStation .poi-item-name"
value_template: |
{%-set value = value.split("|")-%}
{%-for station in value-%}
{%- if loop.index <= 20 -%}
{{station|title}}|
{%- endif -%}
{%-endfor-%}
- name: address
select_list: ".poi-item-gasStation .poi-item-details-address"
value_template: |
{%-set value = value.split("|")-%}
{%-for add in value-%}
{%- if loop.index <= 20 -%}
{{add | title}}|
{%- endif -%}
{%-endfor-%}
- name: zip_code
select_list: ".poi-item-gasStation .poi-item-details-address"
value_template: |
{%-set value = value.split("|")-%}
{%-for zip in value-%}
{%- if loop.index <= 20 -%}
{%- set list1 = zip.split(',') -%}
{%- if list1[1] -%}
{{list1[1] | title}}|
{%- else-%}
| -
{%- endif -%}
{%- endif -%}
{%-endfor-%}
- name: e10_sp95_price
select_list: ".poi-item-fuel-price-5 .poi-item-fuel-value"
value_template: |
{%- set value = value.split("|") -%}
{%- for p in value -%}
{%- if loop.index <= 20 -%}
{%- set price = p | replace(',','.') | float(0) -%}
{{'%0.3f'|format(price|float)}}|
{%- endif -%}
{%- endfor -%}
- name: lpg_gpl_price
select_list: ".poi-item-fuel-price-4 .poi-item-fuel-value"
value_template: |
{%- set value = value.split("|") -%}
{%- for p in value -%}
{%- if loop.index <= 20 -%}
{%- set price = p | replace(',','.') | float(0) -%}
{{'%0.3f'|format(price|float)}}|
{%- endif -%}
{%- endfor -%}
- name: dte_update
select_list: ".poi-item-fuel-price-update em"
value_template: |
{%- set value = value.split("|") -%}
{%- for d in value -%}
{%- if loop.index <= 20 -%}
{{d | replace(' · ', '')}}|
{%- endif -%}
{%- endfor -%}
- unique_id: gas_e10_sp95_min
name: "Essence E10 prix minimum"
select_list: ".poi-item-fuel-price-5 .poi-item-fuel-value"
value_template: |
{%- set ns = namespace(min_p = 999.0 | float ) -%}
{%- set value = value.split("|") -%}
{%- for x in value -%}
{% if loop.index <= 20 %}
{%- set price = x | replace(',','.') | float(0) -%}
{%- if price < ns.min_p -%}
{%- set ns.min_p = price -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{{ns.min_p}}
unit_of_measurement: '€/L'
icon: mdi:gas-station
attributes:
- name: station_index
select_list: ".poi-item-fuel-price-5 .poi-item-fuel-value"
value_template: |
{%- set ns = namespace(min_p = 999.0 | float, index=0 ) -%}
{%- set value = value.split("|") -%}
{%- for x in value -%}
{% if loop.index <= 20 %}
{%- set price = x | replace(',','.') | float(0) -%}
{%- if price < ns.min_p -%}
{%- set ns.min_p = price -%}
{%- set ns.index = loop.index -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{{ns.index}}
- name: station_name
value_template: |
{%- set arr_str = state_attr('sensor.gas_provider_michelin', 'e10_sp95_price') -%}
{%- set prices = arr_str.split("|") -%}
{%- set ns = namespace(min_p = 0.0, index = -1 ) -%}
{%- for price in prices -%}
{%- if price|float(0) < ns.min_p|float(0) -%}
{%- set ns.min_p = price -%}
{%- set ns.index = loop.index -%}
{%- endif -%}
{%- endfor -%}
{%- if ns.index > -1 -%}
{%- set arr_str = state_attr('sensor.gas_provider_michelin', 'station_name') -%}
{%- set stations = arr_str.split("|") -%}
{{ stations[ns.index]}}
{%- endif -%}
- name: station_adress
value_template: |
{%- set arr_str = state_attr('sensor.gas_provider_michelin', 'e10_sp95_price') -%}
{%- set prices = arr_str.split("|") -%}
{%- set ns = namespace(min_p = 0.0, index = -1 ) -%}
{%- for price in prices -%}
{%- if price|float(0) < ns.min_p|float(0) -%}
{%- set ns.min_p = price -%}
{%- set ns.index = loop.index -%}
{%- endif -%}
{%- endfor -%}
{%- if ns.index > -1 -%}
{%- set arr_str = state_attr('sensor.gas_provider_michelin', 'address') -%}
{%- set stations = arr_str.split("|") -%}
{{ stations[ns.index]}}
{%- endif -%}
Is that possible to use an array in select_list:
select_list: ".poi-item-fuel-price-4 .poi-item-fuel-value", ".poi-item-fuel-price-update em"
I could then match the ID of the store with each gas prices, then I can only show the stations that has GPL for exemple. So in one select list and x queries, I could have x arrays in return, that would allow to keep the context and make it safe.
Or mat be there is an other way ?
Is there any global variable I could use between queries, to limit the number of station for exemple, its hard codded to 20 and it sucks.
Thanks