core/homeassistant/components/vasttrafik/sensor.py

159 lines
5.2 KiB
Python
Raw Normal View History

"""Support for Västtrafik public transport."""
2016-10-05 05:37:45 +00:00
from datetime import timedelta
import logging
import vasttrafik
2016-10-05 05:37:45 +00:00
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
2016-10-05 05:37:45 +00:00
from homeassistant.util import Throttle
from homeassistant.util.dt import now
2016-10-05 05:37:45 +00:00
_LOGGER = logging.getLogger(__name__)
2019-07-31 19:25:30 +00:00
ATTR_ACCESSIBILITY = "accessibility"
ATTR_DIRECTION = "direction"
ATTR_LINE = "line"
ATTR_TRACK = "track"
ATTRIBUTION = "Data provided by Västtrafik"
2019-07-31 19:25:30 +00:00
CONF_DEPARTURES = "departures"
CONF_FROM = "from"
CONF_HEADING = "heading"
CONF_LINES = "lines"
CONF_KEY = "key"
CONF_SECRET = "secret"
2016-10-05 05:37:45 +00:00
DEFAULT_DELAY = 0
2019-07-31 19:25:30 +00:00
ICON = "mdi:train"
2016-10-05 05:37:45 +00:00
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=120)
2019-07-31 19:25:30 +00:00
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,
}
],
}
)
2016-10-05 05:37:45 +00:00
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the departure sensor."""
2019-07-31 19:25:30 +00:00
planner = vasttrafik.JournyPlanner(config.get(CONF_KEY), config.get(CONF_SECRET))
2016-10-05 05:37:45 +00:00
sensors = []
2016-10-05 05:37:45 +00:00
for departure in config.get(CONF_DEPARTURES):
sensors.append(
VasttrafikDepartureSensor(
2019-07-31 19:25:30 +00:00
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)
2016-10-05 05:37:45 +00:00
class VasttrafikDepartureSensor(SensorEntity):
2016-10-05 05:37:45 +00:00
"""Implementation of a Vasttrafik Departure Sensor."""
def __init__(self, planner, name, departure, heading, lines, delay):
2016-10-05 05:37:45 +00:00
"""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
2016-10-05 05:37:45 +00:00
self._delay = timedelta(minutes=delay)
self._departureboard = None
self._state = None
self._attributes = None
2016-10-05 05:37:45 +00:00
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
2016-10-05 05:37:45 +00:00
@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):
2016-10-05 05:37:45 +00:00
"""Return the state attributes."""
return self._attributes
2016-10-05 05:37:45 +00:00
@property
def native_value(self):
2016-10-05 05:37:45 +00:00
"""Return the next departure time."""
return self._state
2016-10-05 05:37:45 +00:00
@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,
2019-07-31 19:25:30 +00:00
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",
2019-07-31 19:25:30 +00:00
)
self._state = None
self._attributes = {}
else:
for departure in self._departureboard:
2019-07-31 19:25:30 +00:00
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 = {
2019-07-31 19:25:30 +00:00
ATTR_ACCESSIBILITY: departure.get("accessibility"),
ATTR_ATTRIBUTION: ATTRIBUTION,
2019-07-31 19:25:30 +00:00
ATTR_DIRECTION: departure.get("direction"),
ATTR_LINE: departure.get("sname"),
ATTR_TRACK: departure.get("track"),
}
2019-07-31 19:25:30 +00:00
self._attributes = {k: v for k, v in params.items() if v}
break