Add TMB sensor (#27964)

* Add TMB i-Bus sensor

* Raise exception if HTTP error

* Addressed comments

* Fixed format

* Fixed format

* Addressed comments

* Remove guard before add_entities method

* Remove unauthorized exception

* Make CONF_BUS_STOPS option required
This commit is contained in:
Aleix Murtra 2020-01-07 16:22:16 +01:00 committed by Paulus Schoutsen
parent b4d6d238e5
commit 1d1aa06d05
6 changed files with 138 additions and 0 deletions

View file

@ -714,6 +714,7 @@ omit =
homeassistant/components/tikteck/light.py
homeassistant/components/tile/device_tracker.py
homeassistant/components/time_date/sensor.py
homeassistant/components/tmb/sensor.py
homeassistant/components/todoist/calendar.py
homeassistant/components/todoist/const.py
homeassistant/components/tof/sensor.py

View file

@ -337,6 +337,7 @@ homeassistant/components/threshold/* @fabaff
homeassistant/components/tibber/* @danielhiversen
homeassistant/components/tile/* @bachya
homeassistant/components/time_date/* @fabaff
homeassistant/components/tmb/* @alemuro
homeassistant/components/todoist/* @boralyl
homeassistant/components/toon/* @frenck
homeassistant/components/tplink/* @rytilahti

View file

@ -0,0 +1 @@
"""Support for Transports Metropolitans de Barcelona."""

View file

@ -0,0 +1,12 @@
{
"domain": "tmb",
"name": "Transports Metropolitans de Barcelona",
"documentation": "https://www.home-assistant.io/integrations/tmb",
"requirements": [
"tmb==0.0.4"
],
"dependencies": [],
"codeowners": [
"@alemuro"
]
}

View file

@ -0,0 +1,120 @@
"""Support for TMB (Transports Metropolitans de Barcelona) Barcelona public transport."""
from datetime import timedelta
import logging
from requests import HTTPError
from tmb import IBus
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import ATTR_ATTRIBUTION, CONF_NAME
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 Transport Metropolitans de Barcelona"
ICON = "mdi:bus-clock"
CONF_APP_ID = "app_id"
CONF_APP_KEY = "app_key"
CONF_LINE = "line"
CONF_BUS_STOP = "stop"
CONF_BUS_STOPS = "stops"
ATTR_BUS_STOP = "stop"
ATTR_LINE = "line"
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)
LINE_STOP_SCHEMA = vol.Schema(
{
vol.Required(CONF_BUS_STOP): cv.string,
vol.Required(CONF_LINE): cv.string,
vol.Optional(CONF_NAME): cv.string,
}
)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_APP_ID): cv.string,
vol.Required(CONF_APP_KEY): cv.string,
vol.Required(CONF_BUS_STOPS): vol.All(cv.ensure_list, [LINE_STOP_SCHEMA]),
}
)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the sensors."""
ibus_client = IBus(config[CONF_APP_ID], config[CONF_APP_KEY])
sensors = []
for line_stop in config.get(CONF_BUS_STOPS):
line = line_stop[CONF_LINE]
stop = line_stop[CONF_BUS_STOP]
if line_stop.get(CONF_NAME):
name = f"{line} - {line_stop[CONF_NAME]} ({stop})"
else:
name = f"{line} - {stop}"
sensors.append(TMBSensor(ibus_client, stop, line, name))
add_entities(sensors, True)
class TMBSensor(Entity):
"""Implementation of a TMB line/stop Sensor."""
def __init__(self, ibus_client, stop, line, name):
"""Initialize the sensor."""
self._ibus_client = ibus_client
self._stop = stop
self._line = line.upper()
self._name = name
self._unit = "minutes"
self._state = None
@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 unit_of_measurement(self):
"""Return the unit of measurement."""
return self._unit
@property
def unique_id(self):
"""Return a unique, HASS-friendly identifier for this entity."""
return f"{self._stop}_{self._line}"
@property
def state(self):
"""Return the next departure time."""
return self._state
@property
def device_state_attributes(self):
"""Return the state attributes of the last update."""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
ATTR_BUS_STOP: self._stop,
ATTR_LINE: self._line,
}
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the next bus information."""
try:
self._state = self._ibus_client.get_stop_forecast(self._stop, self._line)
except HTTPError:
_LOGGER.error(
"Unable to fetch data from TMB API. Please check your API keys are valid."
)

View file

@ -1965,6 +1965,9 @@ thingspeak==1.0.0
# homeassistant.components.tikteck
tikteck==0.4
# homeassistant.components.tmb
tmb==0.0.4
# homeassistant.components.todoist
todoist-python==8.0.0