1
mirror of https://github.com/home-assistant/core synced 2024-08-02 23:40:32 +02:00
ha-core/homeassistant/components/vasttrafik/sensor.py
Erik Montnemery ae507aeed1
Move temperature conversions to sensor base class (8/8) (#54483)
* Move temperature conversions to entity base class (8/8)

* Fix wallbox sensor

* Fix tests
2021-08-11 21:17:16 +02:00

159 lines
5.2 KiB
Python

"""Support for Västtrafik public transport."""
from datetime import timedelta
import logging
import vasttrafik
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.const import ATTR_ATTRIBUTION, CONF_DELAY, CONF_NAME
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle
from homeassistant.util.dt import now
_LOGGER = logging.getLogger(__name__)
ATTR_ACCESSIBILITY = "accessibility"
ATTR_DIRECTION = "direction"
ATTR_LINE = "line"
ATTR_TRACK = "track"
ATTRIBUTION = "Data provided by Västtrafik"
CONF_DEPARTURES = "departures"
CONF_FROM = "from"
CONF_HEADING = "heading"
CONF_LINES = "lines"
CONF_KEY = "key"
CONF_SECRET = "secret"
DEFAULT_DELAY = 0
ICON = "mdi:train"
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=120)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_KEY): cv.string,
vol.Required(CONF_SECRET): cv.string,
vol.Optional(CONF_DEPARTURES): [
{
vol.Required(CONF_FROM): cv.string,
vol.Optional(CONF_DELAY, default=DEFAULT_DELAY): cv.positive_int,
vol.Optional(CONF_HEADING): cv.string,
vol.Optional(CONF_LINES, default=[]): vol.All(
cv.ensure_list, [cv.string]
),
vol.Optional(CONF_NAME): cv.string,
}
],
}
)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the departure sensor."""
planner = vasttrafik.JournyPlanner(config.get(CONF_KEY), config.get(CONF_SECRET))
sensors = []
for departure in config.get(CONF_DEPARTURES):
sensors.append(
VasttrafikDepartureSensor(
planner,
departure.get(CONF_NAME),
departure.get(CONF_FROM),
departure.get(CONF_HEADING),
departure.get(CONF_LINES),
departure.get(CONF_DELAY),
)
)
add_entities(sensors, True)
class VasttrafikDepartureSensor(SensorEntity):
"""Implementation of a Vasttrafik Departure Sensor."""
def __init__(self, planner, name, departure, heading, lines, delay):
"""Initialize the sensor."""
self._planner = planner
self._name = name or departure
self._departure = self.get_station_id(departure)
self._heading = self.get_station_id(heading) if heading else None
self._lines = lines if lines else None
self._delay = timedelta(minutes=delay)
self._departureboard = None
self._state = None
self._attributes = None
def get_station_id(self, location):
"""Get the station ID."""
if location.isdecimal():
station_info = {"station_name": location, "station_id": location}
else:
station_id = self._planner.location_name(location)[0]["id"]
station_info = {"station_name": location, "station_id": station_id}
return station_info
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def icon(self):
"""Return the icon for the frontend."""
return ICON
@property
def extra_state_attributes(self):
"""Return the state attributes."""
return self._attributes
@property
def native_value(self):
"""Return the next departure time."""
return self._state
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the departure board."""
try:
self._departureboard = self._planner.departureboard(
self._departure["station_id"],
direction=self._heading["station_id"] if self._heading else None,
date=now() + self._delay,
)
except vasttrafik.Error:
_LOGGER.debug("Unable to read departure board, updating token")
self._planner.update_token()
if not self._departureboard:
_LOGGER.debug(
"No departures from departure station %s " "to destination station %s",
self._departure["station_name"],
self._heading["station_name"] if self._heading else "ANY",
)
self._state = None
self._attributes = {}
else:
for departure in self._departureboard:
line = departure.get("sname")
if "cancelled" in departure:
continue
if not self._lines or line in self._lines:
if "rtTime" in departure:
self._state = departure["rtTime"]
else:
self._state = departure["time"]
params = {
ATTR_ACCESSIBILITY: departure.get("accessibility"),
ATTR_ATTRIBUTION: ATTRIBUTION,
ATTR_DIRECTION: departure.get("direction"),
ATTR_LINE: departure.get("sname"),
ATTR_TRACK: departure.get("track"),
}
self._attributes = {k: v for k, v in params.items() if v}
break