core/homeassistant/components/trafikverket_weatherstation/sensor.py

189 lines
5.1 KiB
Python

"""Weather information for air and road temperature (by Trafikverket)."""
import asyncio
from datetime import timedelta
import logging
import aiohttp
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (
ATTR_ATTRIBUTION,
CONF_API_KEY,
CONF_MONITORED_CONDITIONS,
CONF_NAME,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
TEMP_CELSIUS,
)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
_LOGGER = logging.getLogger(__name__)
ATTRIBUTION = "Data provided by Trafikverket"
ATTR_MEASURE_TIME = "measure_time"
ATTR_ACTIVE = "active"
CONF_STATION = "station"
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10)
SCAN_INTERVAL = timedelta(seconds=300)
SENSOR_TYPES = {
"air_temp": [
"Air temperature",
TEMP_CELSIUS,
"air_temp",
"mdi:thermometer",
DEVICE_CLASS_TEMPERATURE,
],
"road_temp": [
"Road temperature",
TEMP_CELSIUS,
"road_temp",
"mdi:thermometer",
DEVICE_CLASS_TEMPERATURE,
],
"precipitation": [
"Precipitation type",
None,
"precipitationtype",
"mdi:weather-snowy-rainy",
None,
],
"wind_direction": [
"Wind direction",
"°",
"winddirection",
"mdi:flag-triangle",
None,
],
"wind_direction_text": [
"Wind direction text",
None,
"winddirectiontext",
"mdi:flag-triangle",
None,
],
"wind_speed": ["Wind speed", "m/s", "windforce", "mdi:weather-windy", None],
"humidity": [
"Humidity",
"%",
"humidity",
"mdi:water-percent",
DEVICE_CLASS_HUMIDITY,
],
"precipitation_amount": [
"Precipitation amount",
"mm",
"precipitation_amount",
"mdi:cup-water",
None,
],
"precipitation_amountname": [
"Precipitation name",
None,
"precipitation_amountname",
"mdi:weather-pouring",
None,
],
}
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_API_KEY): cv.string,
vol.Required(CONF_STATION): cv.string,
vol.Required(CONF_MONITORED_CONDITIONS, default=[]): [vol.In(SENSOR_TYPES)],
}
)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the Trafikverket sensor platform."""
from pytrafikverket.trafikverket_weather import TrafikverketWeather
sensor_name = config[CONF_NAME]
sensor_api = config[CONF_API_KEY]
sensor_station = config[CONF_STATION]
web_session = async_get_clientsession(hass)
weather_api = TrafikverketWeather(web_session, sensor_api)
dev = []
for condition in config[CONF_MONITORED_CONDITIONS]:
dev.append(
TrafikverketWeatherStation(
weather_api, sensor_name, condition, sensor_station
)
)
if dev:
async_add_entities(dev, True)
class TrafikverketWeatherStation(Entity):
"""Representation of a Trafikverket sensor."""
def __init__(self, weather_api, name, sensor_type, sensor_station):
"""Initialize the sensor."""
self._client = name
self._name = SENSOR_TYPES[sensor_type][0]
self._type = sensor_type
self._state = None
self._unit = SENSOR_TYPES[sensor_type][1]
self._station = sensor_station
self._weather_api = weather_api
self._icon = SENSOR_TYPES[sensor_type][3]
self._device_class = SENSOR_TYPES[sensor_type][4]
self._weather = None
@property
def name(self):
"""Return the name of the sensor."""
return f"{self._client} {self._name}"
@property
def icon(self):
"""Icon to use in the frontend."""
return self._icon
@property
def device_state_attributes(self):
"""Return the state attributes of Trafikverket Weatherstation."""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
ATTR_ACTIVE: self._weather.active,
ATTR_MEASURE_TIME: self._weather.measure_time,
}
@property
def device_class(self):
"""Return the device class of the sensor."""
return self._device_class
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._unit
@Throttle(MIN_TIME_BETWEEN_UPDATES)
async def async_update(self):
"""Get the latest data from Trafikverket and updates the states."""
try:
self._weather = await self._weather_api.async_get_weather(self._station)
self._state = getattr(self._weather, SENSOR_TYPES[self._type][2])
except (asyncio.TimeoutError, aiohttp.ClientError, ValueError) as error:
_LOGGER.error("Could not fetch weather data: %s", error)