add swiss public transport sensor
parent
1be50d83dc
commit
a6b7f47d74
|
@ -0,0 +1,148 @@
|
|||
"""
|
||||
homeassistant.components.sensor.swiss_public_transport
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Swiss public transport sensor will give you the next two departure times
|
||||
from a given location to another one. This sensor is limited to Switzerland.
|
||||
|
||||
Configuration:
|
||||
|
||||
To use the Swiss public transport sensor you will need to add something like
|
||||
the following to your config/configuration.yaml
|
||||
|
||||
sensor:
|
||||
platform: swiss_public_transport
|
||||
from: STATION_ID
|
||||
to: STATION_ID
|
||||
|
||||
Variables:
|
||||
|
||||
from
|
||||
*Required
|
||||
Start station/stop of your trip. To search for the ID of the station, use the
|
||||
an URL like this: http://transport.opendata.ch/v1/locations?query=Wankdorf
|
||||
to query for the station. If the score is 100 ("score":"100" in the response),
|
||||
it is a perfect match.
|
||||
|
||||
to
|
||||
*Required
|
||||
Destination station/stop of the trip. Same procedure as for the start station.
|
||||
|
||||
Details for the API : http://transport.opendata.ch
|
||||
"""
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from homeassistant.util import Throttle
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
_RESOURCE = 'http://transport.opendata.ch/v1/'
|
||||
|
||||
# Return cached results if last scan was less then this time ago
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
""" Get the Swiss public transport sensor. """
|
||||
|
||||
if None in (hass.config.latitude, hass.config.longitude):
|
||||
_LOGGER.error("Latitude or longitude not set in Home Assistant config")
|
||||
return False
|
||||
|
||||
try:
|
||||
# pylint: disable=unused-variable
|
||||
from requests import get
|
||||
|
||||
except ImportError:
|
||||
_LOGGER.exception(
|
||||
"Unable to import requests. "
|
||||
"Did you maybe not install the 'Requests' package?")
|
||||
|
||||
return None
|
||||
|
||||
# journal contains [0] Station ID start, [1] Station ID destination
|
||||
# [2] Station name start, and [3] Station name destination
|
||||
journey = []
|
||||
journey.append(config.get('from', None))
|
||||
journey.append(config.get('to', None))
|
||||
try:
|
||||
for location in [config.get('from', None), config.get('to', None)]:
|
||||
# transport.opendata.ch doesn't play nice with requests.Session
|
||||
result = get(_RESOURCE + 'locations?query=%s' % location)
|
||||
journey.append(result.json()['stations'][0]['name'])
|
||||
except KeyError:
|
||||
_LOGGER.error(
|
||||
"Unable to determine stations. "
|
||||
"Check your settings and/or the availability of opendata.ch")
|
||||
|
||||
return None
|
||||
|
||||
dev = []
|
||||
data = PublicTransportData(journey)
|
||||
dev.append(SwissPublicTransportSensor(data, journey))
|
||||
add_devices(dev)
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class SwissPublicTransportSensor(Entity):
|
||||
""" Implements an Swiss public transport sensor. """
|
||||
|
||||
def __init__(self, data, journey):
|
||||
self.data = data
|
||||
self._name = journey[2] + '-' + journey[3]
|
||||
self.update()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
""" Returns the name. """
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
""" Returns the state of the device. """
|
||||
return self._state
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
def update(self):
|
||||
""" Gets the latest data from opendata.ch and updates the states. """
|
||||
times = self.data.update()
|
||||
if times is not None:
|
||||
self._state = times[0] + ', ' + times[1]
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class PublicTransportData(object):
|
||||
""" Class for handling the data retrieval. """
|
||||
|
||||
def __init__(self, journey):
|
||||
self.times = ['n/a', 'n/a']
|
||||
self.start = journey[0]
|
||||
self.destination = journey[1]
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update(self):
|
||||
""" Gets the latest data from opendata.ch. """
|
||||
|
||||
from requests import get
|
||||
|
||||
response = get(
|
||||
_RESOURCE +
|
||||
'connections?' +
|
||||
'from=' + self.start + '&' +
|
||||
'to=' + self.destination + '&' +
|
||||
'fields[]=connections/from/departureTimestamp/&' +
|
||||
'fields[]=connections/')
|
||||
|
||||
try:
|
||||
self.times.insert(0, dt_util.timestamp_to_short_time_str(
|
||||
response.json()['connections'][0]['from']
|
||||
['departureTimestamp']))
|
||||
self.times.insert(1, dt_util.timestamp_to_short_time_str(
|
||||
response.json()['connections'][1]['from']
|
||||
['departureTimestamp']))
|
||||
return self.times
|
||||
|
||||
except KeyError:
|
||||
return self.times
|
Loading…
Reference in New Issue