mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 09:47:13 +00:00
Add "station is open" sensor to Tankerkoenig (#68925)
This commit is contained in:
parent
e69450f7ca
commit
c6cd474312
@ -1197,6 +1197,7 @@ omit =
|
|||||||
homeassistant/components/tado/water_heater.py
|
homeassistant/components/tado/water_heater.py
|
||||||
homeassistant/components/tank_utility/sensor.py
|
homeassistant/components/tank_utility/sensor.py
|
||||||
homeassistant/components/tankerkoenig/__init__.py
|
homeassistant/components/tankerkoenig/__init__.py
|
||||||
|
homeassistant/components/tankerkoenig/binary_sensor.py
|
||||||
homeassistant/components/tankerkoenig/const.py
|
homeassistant/components/tankerkoenig/const.py
|
||||||
homeassistant/components/tankerkoenig/sensor.py
|
homeassistant/components/tankerkoenig/sensor.py
|
||||||
homeassistant/components/tapsaff/binary_sensor.py
|
homeassistant/components/tapsaff/binary_sensor.py
|
||||||
|
@ -75,7 +75,7 @@ CONFIG_SCHEMA = vol.Schema(
|
|||||||
extra=vol.ALLOW_EXTRA,
|
extra=vol.ALLOW_EXTRA,
|
||||||
)
|
)
|
||||||
|
|
||||||
PLATFORMS = [Platform.SENSOR]
|
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
@ -170,14 +170,14 @@ class TankerkoenigDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
update_interval=timedelta(minutes=update_interval),
|
update_interval=timedelta(minutes=update_interval),
|
||||||
)
|
)
|
||||||
|
|
||||||
self._api_key = entry.data[CONF_API_KEY]
|
self._api_key: str = entry.data[CONF_API_KEY]
|
||||||
self._selected_stations = entry.data[CONF_STATIONS]
|
self._selected_stations: list[str] = entry.data[CONF_STATIONS]
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
self.stations: dict[str, dict] = {}
|
self.stations: dict[str, dict] = {}
|
||||||
self.fuel_types = entry.data[CONF_FUEL_TYPES]
|
self.fuel_types: list[str] = entry.data[CONF_FUEL_TYPES]
|
||||||
self.show_on_map = entry.options[CONF_SHOW_ON_MAP]
|
self.show_on_map: bool = entry.options[CONF_SHOW_ON_MAP]
|
||||||
|
|
||||||
def setup(self):
|
def setup(self) -> bool:
|
||||||
"""Set up the tankerkoenig API."""
|
"""Set up the tankerkoenig API."""
|
||||||
for station_id in self._selected_stations:
|
for station_id in self._selected_stations:
|
||||||
try:
|
try:
|
||||||
@ -205,7 +205,7 @@ class TankerkoenigDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def _async_update_data(self):
|
async def _async_update_data(self) -> dict:
|
||||||
"""Get the latest data from tankerkoenig.de."""
|
"""Get the latest data from tankerkoenig.de."""
|
||||||
_LOGGER.debug("Fetching new data from tankerkoenig.de")
|
_LOGGER.debug("Fetching new data from tankerkoenig.de")
|
||||||
station_ids = list(self.stations)
|
station_ids = list(self.stations)
|
||||||
|
78
homeassistant/components/tankerkoenig/binary_sensor.py
Normal file
78
homeassistant/components/tankerkoenig/binary_sensor.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
"""Tankerkoenig binary sensor integration."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from homeassistant.components.binary_sensor import (
|
||||||
|
BinarySensorDeviceClass,
|
||||||
|
BinarySensorEntity,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import ATTR_ID, ATTR_LATITUDE, ATTR_LONGITUDE
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
|
from . import TankerkoenigDataUpdateCoordinator
|
||||||
|
from .const import DOMAIN
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
|
) -> None:
|
||||||
|
"""Set up the tankerkoenig binary sensors."""
|
||||||
|
|
||||||
|
coordinator: TankerkoenigDataUpdateCoordinator = hass.data[DOMAIN][entry.unique_id]
|
||||||
|
|
||||||
|
stations = coordinator.stations.values()
|
||||||
|
entities = []
|
||||||
|
for station in stations:
|
||||||
|
sensor = StationOpenBinarySensorEntity(
|
||||||
|
station,
|
||||||
|
coordinator,
|
||||||
|
coordinator.show_on_map,
|
||||||
|
)
|
||||||
|
entities.append(sensor)
|
||||||
|
_LOGGER.debug("Added sensors %s", entities)
|
||||||
|
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
|
class StationOpenBinarySensorEntity(CoordinatorEntity, BinarySensorEntity):
|
||||||
|
"""Shows if a station is open or closed."""
|
||||||
|
|
||||||
|
_attr_device_class = BinarySensorDeviceClass.DOOR
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
station: dict,
|
||||||
|
coordinator: TankerkoenigDataUpdateCoordinator,
|
||||||
|
show_on_map: bool,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the sensor."""
|
||||||
|
super().__init__(coordinator)
|
||||||
|
self._station_id = station["id"]
|
||||||
|
self._attr_name = (
|
||||||
|
f"{station['brand']} {station['street']} {station['houseNumber']} status"
|
||||||
|
)
|
||||||
|
self._attr_unique_id = f"{station['id']}_status"
|
||||||
|
self._attr_device_info = DeviceInfo(
|
||||||
|
identifiers={(ATTR_ID, station["id"])},
|
||||||
|
name=f"{station['brand']} {station['street']} {station['houseNumber']}",
|
||||||
|
model=station["brand"],
|
||||||
|
configuration_url="https://www.tankerkoenig.de",
|
||||||
|
)
|
||||||
|
if show_on_map:
|
||||||
|
self._attr_extra_state_attributes = {
|
||||||
|
ATTR_LATITUDE: station["lat"],
|
||||||
|
ATTR_LONGITUDE: station["lng"],
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool | None:
|
||||||
|
"""Return true if the station is open."""
|
||||||
|
data = self.coordinator.data[self._station_id]
|
||||||
|
return data is not None and "status" in data
|
@ -10,3 +10,12 @@ DEFAULT_RADIUS = 2
|
|||||||
DEFAULT_SCAN_INTERVAL = 30
|
DEFAULT_SCAN_INTERVAL = 30
|
||||||
|
|
||||||
FUEL_TYPES = {"e5": "Super", "e10": "Super E10", "diesel": "Diesel"}
|
FUEL_TYPES = {"e5": "Super", "e10": "Super E10", "diesel": "Diesel"}
|
||||||
|
|
||||||
|
ATTR_BRAND = "brand"
|
||||||
|
ATTR_CITY = "city"
|
||||||
|
ATTR_FUEL_TYPE = "fuel_type"
|
||||||
|
ATTR_HOUSE_NUMBER = "house_number"
|
||||||
|
ATTR_POSTCODE = "postcode"
|
||||||
|
ATTR_STATION_NAME = "station_name"
|
||||||
|
ATTR_STREET = "street"
|
||||||
|
ATTRIBUTION = "Data provided by https://www.tankerkoenig.de"
|
||||||
|
@ -18,22 +18,21 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import TankerkoenigDataUpdateCoordinator
|
from . import TankerkoenigDataUpdateCoordinator
|
||||||
from .const import DOMAIN, FUEL_TYPES
|
from .const import (
|
||||||
|
ATTR_BRAND,
|
||||||
|
ATTR_CITY,
|
||||||
|
ATTR_FUEL_TYPE,
|
||||||
|
ATTR_HOUSE_NUMBER,
|
||||||
|
ATTR_POSTCODE,
|
||||||
|
ATTR_STATION_NAME,
|
||||||
|
ATTR_STREET,
|
||||||
|
ATTRIBUTION,
|
||||||
|
DOMAIN,
|
||||||
|
FUEL_TYPES,
|
||||||
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ATTR_BRAND = "brand"
|
|
||||||
ATTR_CITY = "city"
|
|
||||||
ATTR_FUEL_TYPE = "fuel_type"
|
|
||||||
ATTR_HOUSE_NUMBER = "house_number"
|
|
||||||
ATTR_IS_OPEN = "is_open"
|
|
||||||
ATTR_POSTCODE = "postcode"
|
|
||||||
ATTR_STATION_NAME = "station_name"
|
|
||||||
ATTR_STREET = "street"
|
|
||||||
ATTRIBUTION = "Data provided by https://creativecommons.tankerkoenig.de"
|
|
||||||
|
|
||||||
ICON = "mdi:gas-station"
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
@ -67,79 +66,41 @@ class FuelPriceSensor(CoordinatorEntity, SensorEntity):
|
|||||||
"""Contains prices for fuel in a given station."""
|
"""Contains prices for fuel in a given station."""
|
||||||
|
|
||||||
_attr_state_class = STATE_CLASS_MEASUREMENT
|
_attr_state_class = STATE_CLASS_MEASUREMENT
|
||||||
|
_attr_icon = "mdi:gas-station"
|
||||||
|
|
||||||
def __init__(self, fuel_type, station, coordinator, show_on_map):
|
def __init__(self, fuel_type, station, coordinator, show_on_map):
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self._station = station
|
|
||||||
self._station_id = station["id"]
|
self._station_id = station["id"]
|
||||||
self._fuel_type = fuel_type
|
self._fuel_type = fuel_type
|
||||||
self._latitude = station["lat"]
|
self._attr_name = f"{station['brand']} {station['street']} {station['houseNumber']} {FUEL_TYPES[fuel_type]}"
|
||||||
self._longitude = station["lng"]
|
self._attr_native_unit_of_measurement = CURRENCY_EURO
|
||||||
self._city = station["place"]
|
self._attr_unique_id = f"{station['id']}_{fuel_type}"
|
||||||
self._house_number = station["houseNumber"]
|
self._attr_device_info = DeviceInfo(
|
||||||
self._postcode = station["postCode"]
|
identifiers={(ATTR_ID, station["id"])},
|
||||||
self._street = station["street"]
|
name=f"{station['brand']} {station['street']} {station['houseNumber']}",
|
||||||
self._brand = self._station["brand"]
|
model=station["brand"],
|
||||||
self._price = station[fuel_type]
|
configuration_url="https://www.tankerkoenig.de",
|
||||||
self._show_on_map = show_on_map
|
)
|
||||||
|
|
||||||
@property
|
attrs = {
|
||||||
def name(self):
|
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||||
"""Return the name of the sensor."""
|
ATTR_BRAND: station["brand"],
|
||||||
return f"{self._brand} {self._street} {self._house_number} {FUEL_TYPES[self._fuel_type]}"
|
ATTR_FUEL_TYPE: fuel_type,
|
||||||
|
ATTR_STATION_NAME: station["name"],
|
||||||
|
ATTR_STREET: station["street"],
|
||||||
|
ATTR_HOUSE_NUMBER: station["houseNumber"],
|
||||||
|
ATTR_POSTCODE: station["postCode"],
|
||||||
|
ATTR_CITY: station["place"],
|
||||||
|
}
|
||||||
|
|
||||||
@property
|
if show_on_map:
|
||||||
def icon(self):
|
attrs[ATTR_LATITUDE] = station["lat"]
|
||||||
"""Icon to use in the frontend."""
|
attrs[ATTR_LONGITUDE] = station["lng"]
|
||||||
return ICON
|
self._attr_extra_state_attributes = attrs
|
||||||
|
|
||||||
@property
|
|
||||||
def native_unit_of_measurement(self):
|
|
||||||
"""Return unit of measurement."""
|
|
||||||
return CURRENCY_EURO
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return the state of the device."""
|
"""Return the state of the device."""
|
||||||
# key Fuel_type is not available when the fuel station is closed, use "get" instead of "[]" to avoid exceptions
|
# key Fuel_type is not available when the fuel station is closed, use "get" instead of "[]" to avoid exceptions
|
||||||
return self.coordinator.data[self._station_id].get(self._fuel_type)
|
return self.coordinator.data[self._station_id].get(self._fuel_type)
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self) -> str:
|
|
||||||
"""Return a unique identifier for this entity."""
|
|
||||||
return f"{self._station_id}_{self._fuel_type}"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def device_info(self) -> DeviceInfo | None:
|
|
||||||
"""Return device info."""
|
|
||||||
return DeviceInfo(
|
|
||||||
identifiers={(ATTR_ID, self._station_id)},
|
|
||||||
name=f"{self._brand} {self._street} {self._house_number}",
|
|
||||||
model=self._brand,
|
|
||||||
configuration_url="https://www.tankerkoenig.de",
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def extra_state_attributes(self):
|
|
||||||
"""Return the attributes of the device."""
|
|
||||||
data = self.coordinator.data[self._station_id]
|
|
||||||
|
|
||||||
attrs = {
|
|
||||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
|
||||||
ATTR_BRAND: self._station["brand"],
|
|
||||||
ATTR_FUEL_TYPE: self._fuel_type,
|
|
||||||
ATTR_STATION_NAME: self._station["name"],
|
|
||||||
ATTR_STREET: self._street,
|
|
||||||
ATTR_HOUSE_NUMBER: self._house_number,
|
|
||||||
ATTR_POSTCODE: self._postcode,
|
|
||||||
ATTR_CITY: self._city,
|
|
||||||
}
|
|
||||||
|
|
||||||
if self._show_on_map:
|
|
||||||
attrs[ATTR_LATITUDE] = self._latitude
|
|
||||||
attrs[ATTR_LONGITUDE] = self._longitude
|
|
||||||
|
|
||||||
if data is not None and "status" in data:
|
|
||||||
attrs[ATTR_IS_OPEN] = data["status"] == "open"
|
|
||||||
return attrs
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user