From fcdeba1c20ccb730d9a3e0e458c69daea3346e2d Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Mon, 3 Feb 2025 21:33:00 +0000 Subject: [PATCH 01/12] bump pyfuelprices --- custom_components/fuel_prices/manifest.json | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/fuel_prices/manifest.json b/custom_components/fuel_prices/manifest.json index fab0cb7..9b878f1 100644 --- a/custom_components/fuel_prices/manifest.json +++ b/custom_components/fuel_prices/manifest.json @@ -16,7 +16,7 @@ "xmltodict", "brotli", "these-united-states==1.1.0.21", - "pyfuelprices==2025.1.2" + "pyfuelprices==2025.2.0" ], "ssdp": [], "version": "0.0.0", diff --git a/requirements.txt b/requirements.txt index 9154bd3..a8833fa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ colorlog==6.7.0 homeassistant==2024.11.0 pip>=21.0,<23.2 ruff==0.0.292 -pyfuelprices==2025.1.2 \ No newline at end of file +pyfuelprices==2025.2.0 \ No newline at end of file From 882d280d70516be05a5fc8965f6295b9455077b3 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Mon, 3 Feb 2025 22:28:17 +0000 Subject: [PATCH 02/12] Add PetrolPrices Config wizard updates CheapestFuelSensor entities now only update once per update interval Services now expose optional source parameter All entities can now contain the source config entry Runtime data now contains config entry --- custom_components/fuel_prices/__init__.py | 10 +++++++--- custom_components/fuel_prices/config_flow.py | 9 ++++++--- custom_components/fuel_prices/entity.py | 17 +++++++++++++---- custom_components/fuel_prices/manifest.json | 2 +- custom_components/fuel_prices/sensor.py | 13 +++++++++---- custom_components/fuel_prices/services.yaml | 10 ++++++++++ requirements.txt | 2 +- 7 files changed, 47 insertions(+), 16 deletions(-) diff --git a/custom_components/fuel_prices/__init__.py b/custom_components/fuel_prices/__init__.py index d87c80a..5e932fa 100644 --- a/custom_components/fuel_prices/__init__.py +++ b/custom_components/fuel_prices/__init__.py @@ -39,6 +39,7 @@ class FuelPricesConfig: coordinator: FuelPricesCoordinator areas: list[dict] + config: ConfigEntry type FuelPricesConfigEntry = ConfigEntry[FuelPricesConfig] @@ -92,10 +93,11 @@ async def handle_fuel_lookup(call: ServiceCall) -> ServiceResponse: lat = call.data.get("location", {}).get("latitude", default_lat) long = call.data.get("location", {}).get("longitude", default_long) fuel_type = call.data.get("type") + source = call.data.get("source", "") try: return { "fuels": await fuel_prices.find_fuel_from_point( - (lat, long), radius, fuel_type + (lat, long), radius, fuel_type, source ) } except ValueError as err: @@ -110,9 +112,10 @@ async def handle_fuel_location_lookup(call: ServiceCall) -> ServiceResponse: radius = radius / 1609 lat = call.data.get("location", {}).get("latitude", default_lat) long = call.data.get("location", {}).get("longitude", default_long) + source = call.data.get("source", "") try: locations = await fuel_prices.find_fuel_locations_from_point( - (lat, long), radius + (lat, long), radius, source ) except ValueError as err: raise HomeAssistantError( @@ -140,7 +143,8 @@ async def handle_force_update(call: ServiceCall): hass.services.async_register(DOMAIN, "force_update", handle_force_update) - entry.runtime_data = FuelPricesConfig(coordinator=coordinator, areas=areas) + entry.runtime_data = FuelPricesConfig( + coordinator=coordinator, areas=areas, config=entry) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/custom_components/fuel_prices/config_flow.py b/custom_components/fuel_prices/config_flow.py index 97979e1..ed05228 100644 --- a/custom_components/fuel_prices/config_flow.py +++ b/custom_components/fuel_prices/config_flow.py @@ -64,7 +64,8 @@ ): selector.SelectSelector( selector.SelectSelectorConfig( mode=selector.SelectSelectorMode.DROPDOWN, - options=list(SOURCE_MAP), + options=[k for k, v in SOURCE_MAP.items() if v[1] == + 1 and v[2] == 1], multiple=True, ) ), @@ -288,7 +289,8 @@ async def async_step_finished(self, user_input: dict[str, Any] | None = None): user_input[CONF_SOURCES] = COUNTRY_MAP.get( self.hass.config.country) else: - user_input[CONF_SOURCES] = list(SOURCE_MAP) + user_input[CONF_SOURCES] = [ + k for k, v in SOURCE_MAP.items() if v[1] == 1 and v[2] == 1] user_input[CONF_AREAS] = self.configured_areas user_input[CONF_SCAN_INTERVAL] = self.interval user_input[CONF_TIMEOUT] = self.timeout @@ -502,7 +504,8 @@ async def async_step_finished(self, user_input: dict[str, Any] | None = None): user_input[CONF_SOURCES] = COUNTRY_MAP.get( self.hass.config.country) else: - user_input[CONF_SOURCES] = list(SOURCE_MAP) + user_input[CONF_SOURCES] = [ + k for k, v in SOURCE_MAP.items() if v[1] == 1 and v[2] == 1] user_input[CONF_AREAS] = self.configured_areas user_input[CONF_SCAN_INTERVAL] = self.interval user_input[CONF_TIMEOUT] = self.timeout diff --git a/custom_components/fuel_prices/entity.py b/custom_components/fuel_prices/entity.py index d4c8f73..2360cbb 100644 --- a/custom_components/fuel_prices/entity.py +++ b/custom_components/fuel_prices/entity.py @@ -4,17 +4,25 @@ from homeassistant.helpers.entity import Entity from homeassistant.helpers.update_coordinator import CoordinatorEntity +from homeassistant.config_entries import ConfigEntry from .coordinator import FuelPricesCoordinator -class FuelStationEntity(CoordinatorEntity): +class FuelPriceEntity: + """Top level entity type.""" + + config: ConfigEntry + + +class FuelStationEntity(FuelPriceEntity, CoordinatorEntity): """Represents a fuel station.""" def __init__( - self, coordinator: FuelPricesCoordinator, fuel_station_id, entity_id, source, area, state_value + self, coordinator: FuelPricesCoordinator, fuel_station_id, entity_id, source, area, state_value, config: ConfigEntry ) -> None: """Initialize.""" + self.config = config super().__init__(coordinator) self.coordinator: FuelPricesCoordinator = coordinator self._fuel_station_id = fuel_station_id @@ -36,13 +44,14 @@ def unique_id(self) -> str | None: return f"fuelprices_{self._fuel_station_id}_{self._entity_id}" -class CheapestFuelEntity(Entity): +class CheapestFuelEntity(FuelPriceEntity, Entity): """Represents a fuel.""" def __init__( - self, coordinator: FuelPricesCoordinator, count: str, area: str, fuel: str, coords: tuple, radius: float): + self, coordinator: FuelPricesCoordinator, count: str, area: str, fuel: str, coords: tuple, radius: float, config: ConfigEntry): """Initialize.""" self.coordinator: FuelPricesCoordinator = coordinator + self.config = config self._count = count self._area = area self._coords = coords diff --git a/custom_components/fuel_prices/manifest.json b/custom_components/fuel_prices/manifest.json index 9b878f1..23d3738 100644 --- a/custom_components/fuel_prices/manifest.json +++ b/custom_components/fuel_prices/manifest.json @@ -16,7 +16,7 @@ "xmltodict", "brotli", "these-united-states==1.1.0.21", - "pyfuelprices==2025.2.0" + "pyfuelprices==2025.2.2" ], "ssdp": [], "version": "0.0.0", diff --git a/custom_components/fuel_prices/sensor.py b/custom_components/fuel_prices/sensor.py index eedbe2d..2678bd6 100644 --- a/custom_components/fuel_prices/sensor.py +++ b/custom_components/fuel_prices/sensor.py @@ -11,7 +11,7 @@ from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor.const import SensorDeviceClass -from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS, CONF_NAME, STATE_UNKNOWN +from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS, CONF_NAME, STATE_UNKNOWN, CONF_SCAN_INTERVAL from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from pyfuelprices.const import PROP_FUEL_LOCATION_SOURCE @@ -47,7 +47,8 @@ async def async_setup_entry( entity_id="devicetracker", source=station["props"][PROP_FUEL_LOCATION_SOURCE], area=area[CONF_NAME], - state_value=state_value + state_value=state_value, + config=entry ) ) found_entities.append(station["id"]) @@ -62,7 +63,8 @@ async def async_setup_entry( area=area[CONF_NAME], fuel=area[CONF_CHEAPEST_SENSORS_FUEL_TYPE], coords=(area[CONF_LATITUDE], area[CONF_LONGITUDE]), - radius=area[CONF_RADIUS] + radius=area[CONF_RADIUS], + config=entry )) async_add_entities(entities, True) @@ -148,7 +150,10 @@ async def async_update(self) -> None: ) if len(data) >= (int(self._count)-1): self._last_update = datetime.now() - self._next_update = datetime.now() + timedelta(minutes=5) + self._next_update = datetime.now() + timedelta(minutes=self.config.options.get( + CONF_SCAN_INTERVAL, self.config.data.get( + CONF_SCAN_INTERVAL, 1440) + )) if len(data) >= self._count: self._cached_data = data[int(self._count)-1] else: diff --git a/custom_components/fuel_prices/services.yaml b/custom_components/fuel_prices/services.yaml index af32f27..6f21783 100644 --- a/custom_components/fuel_prices/services.yaml +++ b/custom_components/fuel_prices/services.yaml @@ -6,6 +6,11 @@ find_fuel_station: selector: location: radius: true + source: + required: false + selector: + text: + multiline: false find_fuels: fields: location: @@ -18,3 +23,8 @@ find_fuels: selector: text: multiline: false + source: + required: false + selector: + text: + multiline: false diff --git a/requirements.txt b/requirements.txt index a8833fa..10dd188 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ colorlog==6.7.0 homeassistant==2024.11.0 pip>=21.0,<23.2 ruff==0.0.292 -pyfuelprices==2025.2.0 \ No newline at end of file +pyfuelprices==2025.2.2 \ No newline at end of file From 9d09e03a7e7a44c3d1fc1007125c1b544f7ea503 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Mon, 3 Feb 2025 23:02:17 +0000 Subject: [PATCH 03/12] Add documentation to repo --- .github/workflows/documentation.yml | 30 +++++++++++++++++++++++++ docs/docs/.pages | 1 + docs/docs/index.md | 15 +++++++++++++ docs/docs/installation.md | 30 +++++++++++++++++++++++++ docs/docs/services/find_fuel_station.md | 24 ++++++++++++++++++++ docs/docs/services/find_fuels.md | 26 +++++++++++++++++++++ docs/mkdocs.yml | 10 +++++++++ docs/requirements.txt | 2 ++ 8 files changed, 138 insertions(+) create mode 100644 .github/workflows/documentation.yml create mode 100644 docs/docs/.pages create mode 100644 docs/docs/index.md create mode 100644 docs/docs/installation.md create mode 100644 docs/docs/services/find_fuel_station.md create mode 100644 docs/docs/services/find_fuels.md create mode 100644 docs/mkdocs.yml create mode 100644 docs/requirements.txt diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..041b949 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,30 @@ +name: documentation +on: + push: + branches: + - main +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v4 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - name: "Install requirements" + run: python3 -m pip install -r "${{ github.workspace }}/docs/requirements.txt" + - run: cd "${{ github.workspace }}/docs" + - run: mkdocs gh-deploy --force \ No newline at end of file diff --git a/docs/docs/.pages b/docs/docs/.pages new file mode 100644 index 0000000..1ba4682 --- /dev/null +++ b/docs/docs/.pages @@ -0,0 +1 @@ +title: Fuel Prices \ No newline at end of file diff --git a/docs/docs/index.md b/docs/docs/index.md new file mode 100644 index 0000000..45c34f8 --- /dev/null +++ b/docs/docs/index.md @@ -0,0 +1,15 @@ +# Getting Started + +This is a data finder integration to retrieve local (or remote) fuel price data for Home Assistant using the `pyfuelprices` library. This library aims to provide the most extensive set of data sources for fuel prices in the world. + +You can use this service to: + +- Track fuel prices in your local area +- Query for fuel prices in an automation +- Calculate how much it will cost to fill your tank of fuel +- Find the cheapest station near a entity providing latitude and longitude (script required) + +## Warnings + +- Commercial usage of this integration and its Python library is strictly prohibited. +- You may fork and modify as you require or contribute to the project freely. diff --git a/docs/docs/installation.md b/docs/docs/installation.md new file mode 100644 index 0000000..ef7a9f8 --- /dev/null +++ b/docs/docs/installation.md @@ -0,0 +1,30 @@ +# Installation + +1. Add the repository to HACS +1. Install integration +1. Follow prompts to configure integration + +## Configuration Parameters + +The main configuration entry point is provided via a configuration flow. Using a `configuration.yaml` file to configure is not supported and will not be added in the future following Home Assistant's own design principles + +### Area Configuration Options + +| Option | Description | Type | Default | +|-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|---------| +| `name` | (Required) The name of the area. | Text | None | +| `radius` | (Required) The radius of the area in miles. | Number (miles) | 5.0 | +| `latitude` | (Required, with `longitude`) The latitude of the center of the area. Must be used with `longitude`. | Latitude | None | +| `longitude` | (Required, with `latitude`) The longitude of the center of the area. Must be used with `latitude`. | Longitude | None | +| `cheapest_sensors` | (Optional) A boolean value to determine whether cheapest sensors should be created for this area. | Flag | False | +| `cheapest_sensors_count` | (Required, with `cheapest_sensors`) The number of cheapest sensors to create. Only used if `cheapest_sensors` is true. | Number (Min: 1, Max: 10, Step: 1) | 5 | +| `cheapest_sensors_fuel_type` | (Required, with `cheapest_sensors`) The fuel type for which the cheapest sensors should be created. Only used if `cheapest_sensors` is true. | Text | "" | + +### System Configuration Options + +| Option | Description | Type | Default | +|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|---------| +| `sources` | (Required) A list of data sources (fuel price providers) to use. If not provided, the integration will attempt to determine the data source based on your Home Assistant configuration's country setting. | Dropdown, Multiple | None | +| `timeout` | (Optional) The timeout in seconds for requests to the data sources. | Number (Box, Unit: s, Min: 5, Max: 60) | 30 | +| `scan_interval` | (Optional) The interval in minutes between updates of the fuel prices. | Number (Box, Unit: m, Min: 360, Max: 1440) | 1440 | +| `state_value` | (Optional) The attribute to use for the state of the fuel price sensors. Used to select which piece of information from the source data is shown as the sensor's value (e.g., name, B7, E5, address). | Text | name | \ No newline at end of file diff --git a/docs/docs/services/find_fuel_station.md b/docs/docs/services/find_fuel_station.md new file mode 100644 index 0000000..0ae8e2b --- /dev/null +++ b/docs/docs/services/find_fuel_station.md @@ -0,0 +1,24 @@ +# Find fuel stations from locations `find_fuel_station` + +**Name:** Find fuel stations from location + +**Description:** Find all of the available fuel stations, alongside available fuels and cost for a given location. The results are *not* sorted. + +**Fields:** + +| Field | Description | Required | Selector Type | +|------------|---------------------------------|----------|---------------| +| `location` | The location of the area to search. | Yes | Location (with radius) | + +**Example:** + +```yaml +service: fuel_prices.find_fuel_station +data: + location: + latitude: 52.520008 + longitude: 13.404954 + radius: 5 +``` + +This example would find fuel stations within a 5 mile radius of the provided coordinates. diff --git a/docs/docs/services/find_fuels.md b/docs/docs/services/find_fuels.md new file mode 100644 index 0000000..d8c0005 --- /dev/null +++ b/docs/docs/services/find_fuels.md @@ -0,0 +1,26 @@ +# Find fuels from location `find_fuels` + +**Name:** Find fuel prices from location + +**Description:** This service retrieves all fuel prices for a given location, sorted by the cheapest first. + +**Fields:** + +| Field | Description | Required | Selector Type | +|------------|-------------------------------------------------|----------|---------------| +| `location` | The location of the area to search. | Yes | Location (with radius) | +| `type` | The fuel type to search for (such as E5, E10, B7, SDV). | Yes | Text (single line) | + +**Example:** + +```yaml +service: fuel_prices.find_fuels +data: + location: + latitude: 52.520008 + longitude: 13.404954 + radius: 10 + type: E10 +``` + +This example would find prices for E10 fuel within a 10-mile radius of the given latitude and longitude. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml new file mode 100644 index 0000000..086d2f8 --- /dev/null +++ b/docs/mkdocs.yml @@ -0,0 +1,10 @@ +site_name: Home Assistant Fuel Prices +theme: + name: material + features: + - navigation.instant + - navigation.instant.progress +site_url: https://fuelprices.system32.uk +plugins: + - search + - awesome-pages \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..88ca17b --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +mkdocs-material +mkdocs-awesome-pages-plugin \ No newline at end of file From 54b78405603294f3bb225b546f595fcec75e297f Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Mon, 3 Feb 2025 23:12:43 +0000 Subject: [PATCH 04/12] fix Service find_fuel_station has a field source with no name and is not in the translations file --- custom_components/fuel_prices/strings.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/custom_components/fuel_prices/strings.json b/custom_components/fuel_prices/strings.json index 9161804..401729c 100644 --- a/custom_components/fuel_prices/strings.json +++ b/custom_components/fuel_prices/strings.json @@ -81,6 +81,10 @@ "type": { "name": "Fuel Type", "description": "The fuel type to search for (such as E5, E10, B7, SDV)" + }, + "source": { + "name": "Data Source to search", + "description": "The data source ID to search, defaults to 'any' for all data sources." } } }, @@ -91,6 +95,10 @@ "location": { "name": "Location", "description": "The location of the area to search" + }, + "source": { + "name": "Data Source to search", + "description": "The data source ID to search, defaults to 'any' for all data sources." } } } From ad099d0ffa41dc3d6a3304802a6f0329c285c609 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Mon, 3 Feb 2025 23:13:54 +0000 Subject: [PATCH 05/12] Update en translation --- custom_components/fuel_prices/translations/en.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/custom_components/fuel_prices/translations/en.json b/custom_components/fuel_prices/translations/en.json index 9161804..401729c 100644 --- a/custom_components/fuel_prices/translations/en.json +++ b/custom_components/fuel_prices/translations/en.json @@ -81,6 +81,10 @@ "type": { "name": "Fuel Type", "description": "The fuel type to search for (such as E5, E10, B7, SDV)" + }, + "source": { + "name": "Data Source to search", + "description": "The data source ID to search, defaults to 'any' for all data sources." } } }, @@ -91,6 +95,10 @@ "location": { "name": "Location", "description": "The location of the area to search" + }, + "source": { + "name": "Data Source to search", + "description": "The data source ID to search, defaults to 'any' for all data sources." } } } From 9837c3340120d73392b80500df1570568ff1e052 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Tue, 11 Feb 2025 20:06:53 +0000 Subject: [PATCH 06/12] update docs url --- docs/mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 086d2f8..aa9c9f7 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -4,7 +4,7 @@ theme: features: - navigation.instant - navigation.instant.progress -site_url: https://fuelprices.system32.uk +site_url: https://fuelprices.ha.system32.uk plugins: - search - awesome-pages \ No newline at end of file From ee3d5658f20570f285dcd684734b47c5c8e1f606 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Tue, 11 Feb 2025 20:31:10 +0000 Subject: [PATCH 07/12] restructure docs --- .github/workflows/documentation.yml | 7 +++---- docs/{docs => }/.pages | 0 docs/{docs => }/index.md | 0 docs/{docs => }/installation.md | 0 docs/{docs => }/services/find_fuel_station.md | 0 docs/{docs => }/services/find_fuels.md | 0 docs/mkdocs.yml => mkdocs.yml | 0 docs/requirements.txt => requirements.docs.txt | 0 8 files changed, 3 insertions(+), 4 deletions(-) rename docs/{docs => }/.pages (100%) rename docs/{docs => }/index.md (100%) rename docs/{docs => }/installation.md (100%) rename docs/{docs => }/services/find_fuel_station.md (100%) rename docs/{docs => }/services/find_fuels.md (100%) rename docs/mkdocs.yml => mkdocs.yml (100%) rename docs/requirements.txt => requirements.docs.txt (100%) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 041b949..6223081 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: 3.x - - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - uses: actions/cache@v4 with: key: mkdocs-material-${{ env.cache_id }} @@ -25,6 +25,5 @@ jobs: restore-keys: | mkdocs-material- - name: "Install requirements" - run: python3 -m pip install -r "${{ github.workspace }}/docs/requirements.txt" - - run: cd "${{ github.workspace }}/docs" - - run: mkdocs gh-deploy --force \ No newline at end of file + run: python3 -m pip install -r "${{ github.workspace }}/docs/requirements.docs.txt" + - run: mkdocs gh-deploy --force diff --git a/docs/docs/.pages b/docs/.pages similarity index 100% rename from docs/docs/.pages rename to docs/.pages diff --git a/docs/docs/index.md b/docs/index.md similarity index 100% rename from docs/docs/index.md rename to docs/index.md diff --git a/docs/docs/installation.md b/docs/installation.md similarity index 100% rename from docs/docs/installation.md rename to docs/installation.md diff --git a/docs/docs/services/find_fuel_station.md b/docs/services/find_fuel_station.md similarity index 100% rename from docs/docs/services/find_fuel_station.md rename to docs/services/find_fuel_station.md diff --git a/docs/docs/services/find_fuels.md b/docs/services/find_fuels.md similarity index 100% rename from docs/docs/services/find_fuels.md rename to docs/services/find_fuels.md diff --git a/docs/mkdocs.yml b/mkdocs.yml similarity index 100% rename from docs/mkdocs.yml rename to mkdocs.yml diff --git a/docs/requirements.txt b/requirements.docs.txt similarity index 100% rename from docs/requirements.txt rename to requirements.docs.txt From b1d8ce794399ae8af1e54d983331c87f7bb42f15 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Tue, 11 Feb 2025 20:33:06 +0000 Subject: [PATCH 08/12] fix documentation build script --- .github/workflows/documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 6223081..b07a5e9 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -25,5 +25,5 @@ jobs: restore-keys: | mkdocs-material- - name: "Install requirements" - run: python3 -m pip install -r "${{ github.workspace }}/docs/requirements.docs.txt" + run: python3 -m pip install -r "${{ github.workspace }}/requirements.docs.txt" - run: mkdocs gh-deploy --force From f16c5a02e7e17a5a6b5ac9a9843eed5c6362a5c7 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Tue, 11 Feb 2025 20:36:54 +0000 Subject: [PATCH 09/12] jet: available again so remove --- custom_components/fuel_prices/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/custom_components/fuel_prices/__init__.py b/custom_components/fuel_prices/__init__.py index 5e932fa..68a6732 100644 --- a/custom_components/fuel_prices/__init__.py +++ b/custom_components/fuel_prices/__init__.py @@ -184,8 +184,6 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry): _LOGGER.warning("Removing jet and morrisons from config entry.") if "morrisons" in new_data[CONF_SOURCES]: new_data[CONF_SOURCES].remove("morrisons") - if "jet" in new_data[CONF_SOURCES]: - new_data[CONF_SOURCES].remove("jet") hass.config_entries.async_update_entry( config_entry, data=new_data, version=3 ) From bdde2cc9ece1f02583f4fb322e64e0466371ebdb Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Tue, 11 Feb 2025 20:43:31 +0000 Subject: [PATCH 10/12] update coordinator exception handling --- custom_components/fuel_prices/coordinator.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/custom_components/fuel_prices/coordinator.py b/custom_components/fuel_prices/coordinator.py index f6a5da4..f99a1a6 100644 --- a/custom_components/fuel_prices/coordinator.py +++ b/custom_components/fuel_prices/coordinator.py @@ -6,7 +6,7 @@ import async_timeout from homeassistant.core import HomeAssistant -from pyfuelprices import FuelPrices +from pyfuelprices import FuelPrices, UpdateExceptionGroup from pyfuelprices.sources import UpdateFailedError from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -32,11 +32,18 @@ async def _async_update_data(self): async with async_timeout.timeout(240): return await self.api.update() except TimeoutError as err: - _LOGGER.exception("Timeout updating fuel price data: %s", err) + _LOGGER.exception( + "Timeout updating fuel price data, will retry later: %s", err) except TypeError as err: - _LOGGER.exception("Error updating fuel price data: %s", err) + _LOGGER.exception( + "Error updating fuel price data, will retry later: %s", err) except UpdateFailedError as err: _LOGGER.exception( - "Error communicating with service (%s).", err.status, exc_info=err) + "Error communicating with a service %s", err.status, exc_info=err) + except UpdateExceptionGroup as err: + for e, v in err.failed_providers.items(): + _LOGGER.exception( + "Error communicating with service %s - %s", e, v, exc_info=v + ) except Exception as err: raise UpdateFailed(f"Error communicating with API {err}") from err From e62aa02c59897533ac11dd18575941ed212b231b Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Tue, 11 Feb 2025 20:44:11 +0000 Subject: [PATCH 11/12] fix FuelStationTracker spelling --- custom_components/fuel_prices/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/fuel_prices/sensor.py b/custom_components/fuel_prices/sensor.py index 2678bd6..6fef2fa 100644 --- a/custom_components/fuel_prices/sensor.py +++ b/custom_components/fuel_prices/sensor.py @@ -41,7 +41,7 @@ async def async_setup_entry( ): if station["id"] not in found_entities: entities.append( - FeulStationTracker( + FuelStationTracker( coordinator=entry.runtime_data.coordinator, fuel_station_id=station["id"], entity_id="devicetracker", @@ -69,7 +69,7 @@ async def async_setup_entry( async_add_entities(entities, True) -class FeulStationTracker(FuelStationEntity, SensorEntity): +class FuelStationTracker(FuelStationEntity, SensorEntity): """A fuel station entity.""" @property From 2413ea1d6d838580afd6aa7004352d3175310875 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Tue, 11 Feb 2025 20:56:42 +0000 Subject: [PATCH 12/12] auto release creator --- .github/release.yml | 20 ++++++++++++++++++++ .github/workflows/create-release.yml | 24 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 .github/release.yml create mode 100644 .github/workflows/create-release.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..e69886d --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,20 @@ +changelog: + exclude: + labels: + - ignore-for-release + categories: + - title: Breaking Changes 🛠 + labels: + - breaking-change + - title: New Features 🎉 + labels: + - enhancement + - title: Bug Fixes 🛠 + labels: + - bug-fix + - title: 👒 Dependencies + labels: + - dependencies + - title: Other Changes + labels: + - "*" \ No newline at end of file diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 0000000..7542dbd --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,24 @@ +name: Create release + +on: + workflow_dispatch: + push: + tags: "*" + +permissions: + contents: write + +jobs: + publish: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + - uses: cho0o0/calver-release-action@2022.12.14.1 + with: + generate_release_notes: true + dry_run: true + # Do not use GITHUB_TOKEN if you want to trigger other workflows + timezone: "utc" + api_token: ${{secrets.GITHUB_TOKEN}} + release_title: "${version}"