mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
New sensor viaggiatreno. (#10522)
* New sensor viaggiatreno. I've messed up the previous PR so here it is in a new one. Should include also all corrections from @pvizeli * fixes from PR 10522 * fixed import order * requested changes from MartinHjelmare
This commit is contained in:
parent
17cd64966d
commit
b2ab4443a7
@ -583,6 +583,7 @@ omit =
|
||||
homeassistant/components/sensor/upnp.py
|
||||
homeassistant/components/sensor/ups.py
|
||||
homeassistant/components/sensor/vasttrafik.py
|
||||
homeassistant/components/sensor/viaggiatreno.py
|
||||
homeassistant/components/sensor/waqi.py
|
||||
homeassistant/components/sensor/whois.py
|
||||
homeassistant/components/sensor/worldtidesinfo.py
|
||||
|
187
homeassistant/components/sensor/viaggiatreno.py
Normal file
187
homeassistant/components/sensor/viaggiatreno.py
Normal file
@ -0,0 +1,187 @@
|
||||
"""
|
||||
Support for information about the Italian train system using ViaggiaTreno API.
|
||||
|
||||
For more details about this platform please refer to the documentation at
|
||||
https://home-assistant.io/components/sensor.viaggiatreno
|
||||
"""
|
||||
import logging
|
||||
|
||||
import asyncio
|
||||
import async_timeout
|
||||
import aiohttp
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import ATTR_ATTRIBUTION
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_ATTRIBUTION = "Powered by ViaggiaTreno Data"
|
||||
VIAGGIATRENO_ENDPOINT = ("http://www.viaggiatreno.it/viaggiatrenonew/"
|
||||
"resteasy/viaggiatreno/andamentoTreno/"
|
||||
"{station_id}/{train_id}")
|
||||
|
||||
REQUEST_TIMEOUT = 5 # seconds
|
||||
ICON = 'mdi:train'
|
||||
MONITORED_INFO = [
|
||||
'categoria',
|
||||
'compOrarioArrivoZeroEffettivo',
|
||||
'compOrarioPartenzaZeroEffettivo',
|
||||
'destinazione',
|
||||
'numeroTreno',
|
||||
'orarioArrivo',
|
||||
'orarioPartenza',
|
||||
'origine',
|
||||
'subTitle',
|
||||
]
|
||||
|
||||
DEFAULT_NAME = "Train {}"
|
||||
|
||||
CONF_NAME = 'train_name'
|
||||
CONF_STATION_ID = 'station_id'
|
||||
CONF_STATION_NAME = 'station_name'
|
||||
CONF_TRAIN_ID = 'train_id'
|
||||
|
||||
ARRIVED_STRING = 'Arrived'
|
||||
CANCELLED_STRING = 'Cancelled'
|
||||
NOT_DEPARTED_STRING = "Not departed yet"
|
||||
NO_INFORMATION_STRING = "No information for this train now"
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_TRAIN_ID): cv.string,
|
||||
vol.Required(CONF_STATION_ID): cv.string,
|
||||
vol.Optional(CONF_NAME): cv.string,
|
||||
})
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config,
|
||||
async_add_devices, discovery_info=None):
|
||||
"""Setup the ViaggiaTreno platform."""
|
||||
train_id = config.get(CONF_TRAIN_ID)
|
||||
station_id = config.get(CONF_STATION_ID)
|
||||
name = config.get(CONF_NAME)
|
||||
if not name:
|
||||
name = DEFAULT_NAME.format(train_id)
|
||||
async_add_devices([ViaggiaTrenoSensor(train_id, station_id, name)])
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_http_request(hass, uri):
|
||||
"""Perform actual request."""
|
||||
try:
|
||||
session = hass.helpers.aiohttp_client.async_get_clientsession(hass)
|
||||
with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
|
||||
req = yield from session.get(uri)
|
||||
if req.status != 200:
|
||||
return {'error': req.status}
|
||||
else:
|
||||
json_response = yield from req.json()
|
||||
return json_response
|
||||
except (asyncio.TimeoutError, aiohttp.ClientError) as exc:
|
||||
_LOGGER.error("Cannot connect to ViaggiaTreno API endpoint: %s", exc)
|
||||
except ValueError:
|
||||
_LOGGER.error("Received non-JSON data from ViaggiaTreno API endpoint")
|
||||
|
||||
|
||||
class ViaggiaTrenoSensor(Entity):
|
||||
"""Implementation of a ViaggiaTreno sensor."""
|
||||
|
||||
def __init__(self, train_id, station_id, name):
|
||||
"""Initialize the sensor."""
|
||||
self._state = None
|
||||
self._attributes = {}
|
||||
self._unit = ''
|
||||
self._icon = ICON
|
||||
self._station_id = station_id
|
||||
self._name = name
|
||||
|
||||
self.uri = VIAGGIATRENO_ENDPOINT.format(
|
||||
station_id=station_id,
|
||||
train_id=train_id)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Icon to use in the frontend, if any."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return self._unit
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return extra attributes."""
|
||||
self._attributes[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
|
||||
return self._attributes
|
||||
|
||||
@staticmethod
|
||||
def has_departed(data):
|
||||
"""Check if the train has actually departed."""
|
||||
try:
|
||||
first_station = data['fermate'][0]
|
||||
if data['oraUltimoRilevamento'] or first_station['effettiva']:
|
||||
return True
|
||||
except ValueError:
|
||||
_LOGGER.error("Cannot fetch first station: %s", data)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def has_arrived(data):
|
||||
"""Check if the train has already arrived."""
|
||||
last_station = data['fermate'][-1]
|
||||
if not last_station['effettiva']:
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def is_cancelled(data):
|
||||
"""Check if the train is cancelled."""
|
||||
if data['tipoTreno'] == 'ST' and data['provvedimento'] == 1:
|
||||
return True
|
||||
return False
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_update(self):
|
||||
"""Update state."""
|
||||
uri = self.uri
|
||||
res = yield from async_http_request(self.hass, uri)
|
||||
if res.get('error', ''):
|
||||
if res['error'] == 204:
|
||||
self._state = NO_INFORMATION_STRING
|
||||
self._unit = ''
|
||||
else:
|
||||
self._state = "Error: {}".format(res['error'])
|
||||
self._unit = ''
|
||||
else:
|
||||
for i in MONITORED_INFO:
|
||||
self._attributes[i] = res[i]
|
||||
|
||||
if self.is_cancelled(res):
|
||||
self._state = CANCELLED_STRING
|
||||
self._icon = 'mdi:cancel'
|
||||
self._unit = ''
|
||||
elif not self.has_departed(res):
|
||||
self._state = NOT_DEPARTED_STRING
|
||||
self._unit = ''
|
||||
elif self.has_arrived(res):
|
||||
self._state = ARRIVED_STRING
|
||||
self._unit = ''
|
||||
else:
|
||||
self._state = res.get('ritardo')
|
||||
self._unit = 'min'
|
||||
self._icon = ICON
|
Loading…
x
Reference in New Issue
Block a user