Skip to content

Commit

Permalink
2023.12.0
Browse files Browse the repository at this point in the history
first release
  • Loading branch information
pantherale0 committed Dec 20, 2023
1 parent 70b24b4 commit c34eee9
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 13 deletions.
6 changes: 6 additions & 0 deletions config/configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ logger:
default: info
logs:
custom_components.fuel_prices: debug
pyfuelprices: debug

# Enable VSCode debugging
debugpy:
start: true
wait: true
31 changes: 27 additions & 4 deletions custom_components/fuel_prices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from .coordinator import FuelPricesCoordinator

_LOGGER = logging.getLogger(__name__)
PLATFORMS = []
PLATFORMS = [Platform.DEVICE_TRACKER]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
Expand All @@ -45,11 +45,27 @@ async def update_listener(hass: HomeAssistant, entry: ConfigEntry):

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

def handle_fuel_lookup(call: ServiceCall) -> ServiceResponse:
"""Handle a fuel lookup call."""
radius = call.data.get("location", {}).get(
"radius", 8046.72
) # this is in meters
radius = radius / 1609
lat = call.data.get("location", {}).get("latitude", 0.0)
long = call.data.get("location", {}).get("longitude", 0.0)
fuel_type = call.data.get("type")
return {
"fuels": fuel_prices.find_fuel_from_point((lat, long), radius, fuel_type)
}

def handle_fuel_location_lookup(call: ServiceCall) -> ServiceResponse:
"""Handle a fuel location lookup call."""
radius = call.data.get("radius", 5.0)
lat = call.data.get("latitude")
long = call.data.get("longitude")
radius = call.data.get("location", {}).get(
"radius", 8046.72
) # this is in meters
radius = radius / 1609
lat = call.data.get("location", {}).get("latitude", 0.0)
long = call.data.get("location", {}).get("longitude", 0.0)
location_ids = fuel_prices.find_fuel_locations_from_point((lat, long), radius)
locations = []
for loc_id in location_ids:
Expand All @@ -75,6 +91,13 @@ def handle_fuel_location_lookup(call: ServiceCall) -> ServiceResponse:
supports_response=SupportsResponse.ONLY,
)

hass.services.async_register(
DOMAIN,
"find_fuels",
handle_fuel_lookup,
supports_response=SupportsResponse.ONLY,
)

return True


Expand Down
14 changes: 7 additions & 7 deletions custom_components/fuel_prices/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from homeassistant.helpers import config_validation as cv
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS, CONF_NAME

from .const import DOMAIN, NAME
from .const import DOMAIN, NAME, CONF_AREAS, CONF_SOURCES

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -72,22 +72,22 @@ async def async_step_main_menu(self, _: None = None):
step_id="main_menu",
menu_options={
"area_menu": "Configure areas to create devices/sensors",
"sources": "Configure data collector sources",
CONF_SOURCES: "Configure data collector sources",
"finished": "Complete setup",
},
)

async def async_step_sources(self, user_input: dict[str, Any] | None = None):
"""Sources configuration step."""
if user_input is not None:
self.configured_sources = user_input["sources"]
self.configured_sources = user_input[CONF_SOURCES]
return await self.async_step_main_menu(None)
return self.async_show_form(
step_id="sources",
step_id=CONF_SOURCES,
data_schema=vol.Schema(
{
vol.Optional(
"sources", default=self.configured_sources
CONF_SOURCES, default=self.configured_sources
): selector.SelectSelector(
selector.SelectSelectorConfig(
mode=selector.SelectSelectorMode.DROPDOWN,
Expand Down Expand Up @@ -232,12 +232,12 @@ async def async_step_finished(self, user_input: dict[str, Any] | None = None):
"""Final confirmation step."""
errors: dict[str, str] = {}
if user_input is not None:
user_input["sources"] = (
user_input[CONF_SOURCES] = (
self.configured_sources
if len(self.configured_sources) > 0
else [k for k in SOURCE_MAP]
)
user_input["areas"] = self.configured_areas
user_input[CONF_AREAS] = self.configured_areas
return self.async_create_entry(title=NAME, data=user_input)
return self.async_show_form(
step_id="finished",
Expand Down
3 changes: 3 additions & 0 deletions custom_components/fuel_prices/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@

DOMAIN = "fuel_prices"
NAME = "Fuel Prices"

CONF_AREAS = "areas"
CONF_SOURCES = "sources"
108 changes: 108 additions & 0 deletions custom_components/fuel_prices/device_tracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""Device tracker for fuel prices."""
from __future__ import annotations

import logging
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS, CONF_NAME
from homeassistant.components.device_tracker.config_entry import (
BaseTrackerEntity,
SourceType,
ATTR_SOURCE_TYPE,
ATTR_LATITUDE,
ATTR_LONGITUDE,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from .const import CONF_AREAS, DOMAIN
from .entity import FeulStationEntity
from .coordinator import FuelPricesCoordinator

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Setup fuel prices device tracker component."""
cooridinator: FuelPricesCoordinator = hass.data[DOMAIN][entry.entry_id]
areas = entry.data[CONF_AREAS]
entities = []
for area in areas:
_LOGGER.debug("Registering entities for area %s", area[CONF_NAME])
for station_id in cooridinator.api.find_fuel_locations_from_point(
point=(area[CONF_LATITUDE], area[CONF_LONGITUDE]), radius=area[CONF_RADIUS]
):
entities.append(
FeulStationTracker(
coordinator=cooridinator,
fuel_station_id=station_id,
entity_id="devicetracker",
)
)

async_add_entities(entities, True)


class FeulStationTracker(FeulStationEntity, BaseTrackerEntity):
"""A fuel station tracker entity."""

@property
def name(self) -> str:
"""Return the name of the entity."""
return self._fuel_station.name

@property
def location_accuracy(self) -> int:
"""Return the location accuracy of the device.
Value in meters.
"""
return 0

@property
def state(self) -> str | None:
"""Return the state of the device."""
if self.location_name is not None:
return self.location_name

@property
def _get_fuels(self) -> dict:
"""Return list of fuels."""
output = {}
for fuel in self._fuel_station.available_fuels:
output[fuel.fuel_type] = fuel.cost
return output

@property
def latitude(self) -> float:
"""Return the latitude."""
return self._fuel_station.lat

@property
def longitude(self) -> float:
"""Return the longitude."""
return self._fuel_station.long

@property
def location_name(self) -> str:
"""Return the name of the location."""
return self._fuel_station.name

@property
def source_type(self) -> SourceType:
"""Return the source type."""
return SourceType.GPS

@property
def state_attributes(self) -> dict[str, StateType]:
"""Return the fuel location prices."""
attr: dict[str, StateType] = {
ATTR_SOURCE_TYPE: self.source_type,
**self._get_fuels,
}
if self.latitude is not None and self.longitude is not None:
attr[ATTR_LATITUDE] = self.latitude
attr[ATTR_LONGITUDE] = self.longitude

return attr
29 changes: 29 additions & 0 deletions custom_components/fuel_prices/entity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Fuel Price entity base type."""
from __future__ import annotations

from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .coordinator import FuelPricesCoordinator


class FeulStationEntity(CoordinatorEntity):
"""Represents a fuel station."""

def __init__(
self, coordinator: FuelPricesCoordinator, fuel_station_id, entity_id
) -> None:
"""Initialize."""
super().__init__(coordinator)
self.coordinator: FuelPricesCoordinator = coordinator
self._fuel_station_id = fuel_station_id
self._entity_id = entity_id

@property
def _fuel_station(self):
"""Return the fuel station."""
return self.coordinator.api.get_fuel_location(self._fuel_station_id)

@property
def unique_id(self) -> str | None:
"""Return unique ID."""
return f"fuelprices_{self._fuel_station_id}_{self._entity_id}"
2 changes: 1 addition & 1 deletion custom_components/fuel_prices/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/pantherale0/ha-fuelprices/issues",
"requirements": [
"pyfuelprices==0.0.0",
"pyfuelprices==1.1.1",
"geopy"
],
"ssdp": [],
Expand Down
20 changes: 20 additions & 0 deletions custom_components/fuel_prices/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Find Fuel Locations service
find_fuel_station:
fields:
location:
required: true
selector:
location:
radius: true
find_fuels:
fields:
location:
required: true
selector:
location:
radius: true
type:
required: true
selector:
text:
multiline: false
26 changes: 26 additions & 0 deletions custom_components/fuel_prices/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,31 @@
}
}
}
},
"services": {
"find_fuels": {
"name": "Find fuel prices from location",
"description": "This will retrieve all fuel prices for a given location sorted by the cheapest first.",
"fields": {
"location": {
"name": "Location",
"description": "The location of the area to search"
},
"type": {
"name": "Fuel Type",
"description": "The fuel type to search for (such as E5, E10, B7, SDV)"
}
}
},
"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": {
"location": {
"name": "Location",
"description": "The location of the area to search"
}
}
}
}
}
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ colorlog==6.7.0
homeassistant==2023.8.0
pip>=21.0,<23.2
ruff==0.0.292
pyfuelprices==0.0.0
pyfuelprices==1.1.1

0 comments on commit c34eee9

Please sign in to comment.