1
0
mirror of https://github.com/home-assistant/core.git synced 2026-06-01 13:14:35 +01:00
Files
core/homeassistant/components/fixer/sensor.py
T
2026-04-30 21:14:48 +02:00

119 lines
3.4 KiB
Python

"""Currency exchange rate support that comes from fixer.io."""
from datetime import timedelta
import logging
from typing import Any
from fixerio import Fixerio
from fixerio.exceptions import FixerioException
import voluptuous as vol
from homeassistant.components.sensor import (
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
SensorEntity,
)
from homeassistant.const import CONF_API_KEY, CONF_NAME, CONF_TARGET
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
_LOGGER = logging.getLogger(__name__)
ATTR_EXCHANGE_RATE = "Exchange rate"
ATTR_TARGET = "Target currency"
DEFAULT_BASE = "USD"
DEFAULT_NAME = "Exchange rate"
SCAN_INTERVAL = timedelta(days=1)
PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_API_KEY): cv.string,
vol.Required(CONF_TARGET): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
}
)
def setup_platform(
hass: HomeAssistant,
config: ConfigType,
add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up the Fixer.io sensor."""
api_key = config.get(CONF_API_KEY)
name = config.get(CONF_NAME)
target = config.get(CONF_TARGET)
try:
Fixerio(symbols=[target], access_key=api_key).latest()
except FixerioException:
_LOGGER.error("One of the given currencies is not supported")
return
data = ExchangeData(target, api_key)
add_entities([ExchangeRateSensor(data, name, target)], True)
class ExchangeRateSensor(SensorEntity):
"""Representation of a Exchange sensor."""
_attr_attribution = "Data provided by the European Central Bank (ECB)"
_attr_icon = "mdi:currency-usd"
def __init__(self, data, name, target):
"""Initialize the sensor."""
self.data = data
self._target = target
self._name = name
self._state = None
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def native_unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._target
@property
def native_value(self):
"""Return the state of the sensor."""
return self._state
@property
def extra_state_attributes(self) -> dict[str, Any] | None:
"""Return the state attributes."""
if self.data.rate is not None:
return {
ATTR_EXCHANGE_RATE: self.data.rate["rates"][self._target],
ATTR_TARGET: self._target,
}
return None
def update(self) -> None:
"""Get the latest data and updates the states."""
self.data.update()
self._state = round(self.data.rate["rates"][self._target], 3)
class ExchangeData:
"""Get the latest data and update the states."""
def __init__(self, target_currency, api_key):
"""Initialize the data object."""
self.api_key = api_key
self.rate = None
self.target_currency = target_currency
self.exchange = Fixerio(symbols=[self.target_currency], access_key=self.api_key)
def update(self):
"""Get the latest data from Fixer.io."""
self.rate = self.exchange.latest()