diff --git a/homeassistant/components/sensor/gtfs.py b/homeassistant/components/sensor/gtfs.py index 9271df28820..16d7268afa3 100644 --- a/homeassistant/components/sensor/gtfs.py +++ b/homeassistant/components/sensor/gtfs.py @@ -9,7 +9,6 @@ import logging import datetime from homeassistant.helpers.entity import Entity -from homeassistant.util import Throttle _LOGGER = logging.getLogger(__name__) @@ -21,101 +20,109 @@ ICON = "mdi:train" TIME_FORMAT = "%Y-%m-%d %H:%M:%S" +# pylint: disable=too-many-locals + + def get_next_departure(sched, start_station_id, end_station_id): - origin_station = sched.stops_by_id(start_station_id)[0] - destination_station = sched.stops_by_id(end_station_id)[0] + """Get the next departure for the given sched.""" + origin_station = sched.stops_by_id(start_station_id)[0] + destination_station = sched.stops_by_id(end_station_id)[0] - now = datetime.datetime.now() - day_name = now.strftime("%A").lower() - now_str = now.strftime("%H:%M:%S") + now = datetime.datetime.now() + day_name = now.strftime("%A").lower() + now_str = now.strftime("%H:%M:%S") - sql_query = """ - SELECT trip.trip_id, trip.route_id, - time(origin_stop_time.departure_time), - time(destination_stop_time.arrival_time), - time(origin_stop_time.arrival_time), - time(origin_stop_time.departure_time), - origin_stop_time.drop_off_type, - origin_stop_time.pickup_type, - origin_stop_time.shape_dist_traveled, - origin_stop_time.stop_headsign, - origin_stop_time.stop_sequence, - time(destination_stop_time.arrival_time), - time(destination_stop_time.departure_time), - destination_stop_time.drop_off_type, - destination_stop_time.pickup_type, - destination_stop_time.shape_dist_traveled, - destination_stop_time.stop_headsign, - destination_stop_time.stop_sequence - FROM trips trip - INNER JOIN calendar calendar - ON trip.service_id = calendar.service_id - INNER JOIN stop_times origin_stop_time - ON trip.trip_id = origin_stop_time.trip_id - INNER JOIN stops start_station - ON origin_stop_time.stop_id = start_station.stop_id - INNER JOIN stop_times destination_stop_time - ON trip.trip_id = destination_stop_time.trip_id - INNER JOIN stops end_station - ON destination_stop_time.stop_id = end_station.stop_id - WHERE calendar.{} = 1 AND time(origin_stop_time.departure_time) > time('{}') - AND start_station.stop_id = '{}' AND end_station.stop_id = '{}' - ORDER BY origin_stop_time.departure_time LIMIT 1;"""\ - .format(day_name, now_str, origin_station.id, destination_station.id) - result = sched.engine.execute(sql_query) - item = {} - for row in result: - item = row + sql_query = """ + SELECT trip.trip_id, trip.route_id, + time(origin_stop_time.departure_time), + time(destination_stop_time.arrival_time), + time(origin_stop_time.arrival_time), + time(origin_stop_time.departure_time), + origin_stop_time.drop_off_type, + origin_stop_time.pickup_type, + origin_stop_time.shape_dist_traveled, + origin_stop_time.stop_headsign, + origin_stop_time.stop_sequence, + time(destination_stop_time.arrival_time), + time(destination_stop_time.departure_time), + destination_stop_time.drop_off_type, + destination_stop_time.pickup_type, + destination_stop_time.shape_dist_traveled, + destination_stop_time.stop_headsign, + destination_stop_time.stop_sequence + FROM trips trip + INNER JOIN calendar calendar + ON trip.service_id = calendar.service_id + INNER JOIN stop_times origin_stop_time + ON trip.trip_id = origin_stop_time.trip_id + INNER JOIN stops start_station + ON origin_stop_time.stop_id = start_station.stop_id + INNER JOIN stop_times destination_stop_time + ON trip.trip_id = destination_stop_time.trip_id + INNER JOIN stops end_station + ON destination_stop_time.stop_id = end_station.stop_id + WHERE calendar.{} = 1 + AND time(origin_stop_time.departure_time) > time('{}') + AND start_station.stop_id = '{}' AND end_station.stop_id = '{}' + ORDER BY origin_stop_time.departure_time LIMIT 1;"""\ + .format(day_name, now_str, origin_station.id, destination_station.id) + result = sched.engine.execute(sql_query) + item = {} + for row in result: + item = row - today = datetime.datetime.today().strftime("%Y-%m-%d") - departure_time_string = "{} {}".format(today, item[2]) - arrival_time_string = "{} {}".format(today, item[3]) - departure_time = datetime.datetime.strptime(departure_time_string, + today = datetime.datetime.today().strftime("%Y-%m-%d") + departure_time_string = "{} {}".format(today, item[2]) + arrival_time_string = "{} {}".format(today, item[3]) + departure_time = datetime.datetime.strptime(departure_time_string, + TIME_FORMAT) + arrival_time = datetime.datetime.strptime(arrival_time_string, TIME_FORMAT) - arrival_time = datetime.datetime.strptime(arrival_time_string, - TIME_FORMAT) - seconds_until = (departure_time-datetime.datetime.now()).total_seconds() - minutes_until = int(seconds_until / 60) + seconds_until = (departure_time-datetime.datetime.now()).total_seconds() + minutes_until = int(seconds_until / 60) - route = sched.routes_by_id(item[1])[0] + route = sched.routes_by_id(item[1])[0] - origin_stop_time_arrival_time = "{} {}".format(today, item[4]) + origin_stoptime_arrival_time = "{} {}".format(today, item[4]) - origin_stop_time_departure_time = "{} {}".format(today, item[5]) + origin_stoptime_departure_time = "{} {}".format(today, item[5]) - destination_stop_time_arrival_time = "{} {}".format(today, item[11]) + dest_stoptime_arrival_time = "{} {}".format(today, item[11]) - destination_stop_time_departure_time = "{} {}".format(today, item[12]) + dest_stoptime_depart_time = "{} {}".format(today, item[12]) - origin_stop_time_dict = { - "Arrival Time": origin_stop_time_arrival_time, - "Departure Time": origin_stop_time_departure_time, - "Drop Off Type": item[6], "Pickup Type": item[7], - "Shape Dist Traveled": item[8], "Headsign": item[9], - "Sequence": item[10] - } + origin_stop_time_dict = { + "Arrival Time": origin_stoptime_arrival_time, + "Departure Time": origin_stoptime_departure_time, + "Drop Off Type": item[6], "Pickup Type": item[7], + "Shape Dist Traveled": item[8], "Headsign": item[9], + "Sequence": item[10] + } - destination_stop_time_dict = { - "Arrival Time": destination_stop_time_arrival_time, - "Departure Time": destination_stop_time_departure_time, - "Drop Off Type": item[13], "Pickup Type": item[14], - "Shape Dist Traveled": item[15], "Headsign": item[16], - "Sequence": item[17] - } + destination_stop_time_dict = { + "Arrival Time": dest_stoptime_arrival_time, + "Departure Time": dest_stoptime_depart_time, + "Drop Off Type": item[13], "Pickup Type": item[14], + "Shape Dist Traveled": item[15], "Headsign": item[16], + "Sequence": item[17] + } + + return { + "trip_id": item[0], + "trip": sched.trips_by_id(item[0])[0], + "route": route, + "agency": sched.agencies_by_id(route.agency_id)[0], + "origin_station": origin_station, + "departure_time": departure_time, + "destination_station": destination_station, + "arrival_time": arrival_time, + "seconds_until_departure": seconds_until, + "minutes_until_departure": minutes_until, + "origin_stop_time": origin_stop_time_dict, + "destination_stop_time": destination_stop_time_dict + } - return { - "trip_id": item[0], - "trip": sched.trips_by_id(item[0])[0], - "route": route, - "agency": sched.agencies_by_id(route.agency_id)[0], - "origin_station": origin_station, "departure_time": departure_time, - "destination_station": destination_station, "arrival_time": arrival_time, - "seconds_until_departure": seconds_until, - "minutes_until_departure": minutes_until, - "origin_stop_time": origin_stop_time_dict, - "destination_stop_time": destination_stop_time_dict - } def setup_platform(hass, config, add_devices, discovery_info=None): """Get the GTFS sensor.""" @@ -136,7 +143,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): config["origin"], config["destination"])) add_devices(dev) -# pylint: disable=too-few-public-methods +# pylint: disable=too-many-instance-attributes,too-few-public-methods + + class GTFSDepartureSensor(Entity): """Implementation of an GTFS departures sensor.""" @@ -186,9 +195,10 @@ class GTFSDepartureSensor(Entity): sqlite_file = "{}.sqlite".format(split_file_name[0]) gtfs = pygtfs.Schedule(os.path.join(self._gtfs_folder, sqlite_file)) + # pylint: disable=no-member if len(gtfs.feeds) < 1: - pygtfs.append_feed(gtfs, os.path.join(self._gtfs_folder, - self._data_source)) + pygtfs.append_feed(gtfs, os.path.join(self._gtfs_folder, + self._data_source)) self._departure = get_next_departure(gtfs, self.origin, self.destination) @@ -211,26 +221,29 @@ class GTFSDepartureSensor(Entity): self._attributes = {} - def dictForTable(resource): - return dict((col, getattr(resource, col)) \ - for col in resource.__table__.columns.keys()) + def dict_for_table(resource): + """Return a dict for the SQLAlchemy resource given.""" + return dict((col, getattr(resource, col)) + for col in resource.__table__.columns.keys()) - def appendKeys(resource, prefix=None): - for key, val in resource.items(): - if val == "" or val is None or key == "feed_id": - continue - prettyKey = key.replace("_", " ") - prettyKey = prettyKey.title() - prettyKey = prettyKey.replace("Id", "ID") - prettyKey = prettyKey.replace("Url", "URL") - if prefix is not None and prettyKey.startswith(prefix) is False: - prettyKey = "{} {}".format(prefix, prettyKey) - self._attributes[prettyKey] = val + def append_keys(resource, prefix=None): + """Properly format key val pairs to append to attributes""" + for key, val in resource.items(): + if val == "" or val is None or key == "feed_id": + continue + pretty_key = key.replace("_", " ") + pretty_key = pretty_key.title() + pretty_key = pretty_key.replace("Id", "ID") + pretty_key = pretty_key.replace("Url", "URL") + if prefix is not None and \ + pretty_key.startswith(prefix) is False: + pretty_key = "{} {}".format(prefix, pretty_key) + self._attributes[pretty_key] = val - appendKeys(dictForTable(agency), "Agency") - appendKeys(dictForTable(route), "Route") - appendKeys(dictForTable(trip), "Trip") - appendKeys(dictForTable(origin_station), "Origin Station") - appendKeys(dictForTable(destination_station), "Destination Station") - appendKeys(origin_stop_time, "Origin Stop") - appendKeys(destination_stop_time, "Destination Stop") + append_keys(dict_for_table(agency), "Agency") + append_keys(dict_for_table(route), "Route") + append_keys(dict_for_table(trip), "Trip") + append_keys(dict_for_table(origin_station), "Origin Station") + append_keys(dict_for_table(destination_station), "Destination Station") + append_keys(origin_stop_time, "Origin Stop") + append_keys(destination_stop_time, "Destination Stop")