2019-04-03 15:40:03 +00:00
|
|
|
"""Support for GTFS (Google/General Transport Format Schema)."""
|
2016-03-27 00:41:09 +00:00
|
|
|
import datetime
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
import logging
|
|
|
|
import os
|
2016-05-21 18:04:18 +00:00
|
|
|
import threading
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
from typing import Any, Callable, Optional
|
2016-03-27 00:41:09 +00:00
|
|
|
|
2016-09-04 16:27:19 +00:00
|
|
|
import voluptuous as vol
|
2016-03-27 00:41:09 +00:00
|
|
|
|
2016-09-04 16:27:19 +00:00
|
|
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
from homeassistant.const import (
|
|
|
|
ATTR_ATTRIBUTION, CONF_NAME, CONF_OFFSET, DEVICE_CLASS_TIMESTAMP,
|
|
|
|
STATE_UNKNOWN)
|
2016-09-04 16:27:19 +00:00
|
|
|
import homeassistant.helpers.config_validation as cv
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
from homeassistant.helpers.entity import Entity
|
|
|
|
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
|
|
|
|
from homeassistant.util import slugify
|
2019-03-24 11:15:30 +00:00
|
|
|
import homeassistant.util.dt as dt_util
|
2016-03-27 00:41:09 +00:00
|
|
|
|
2016-09-04 16:27:19 +00:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
2016-03-27 00:41:09 +00:00
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
ATTR_ARRIVAL = 'arrival'
|
|
|
|
ATTR_BICYCLE = 'trip_bikes_allowed_state'
|
|
|
|
ATTR_DAY = 'day'
|
|
|
|
ATTR_FIRST = 'first'
|
|
|
|
ATTR_DROP_OFF_DESTINATION = 'destination_stop_drop_off_type_state'
|
|
|
|
ATTR_DROP_OFF_ORIGIN = 'origin_stop_drop_off_type_state'
|
|
|
|
ATTR_INFO = 'info'
|
|
|
|
ATTR_OFFSET = CONF_OFFSET
|
|
|
|
ATTR_LAST = 'last'
|
|
|
|
ATTR_LOCATION_DESTINATION = 'destination_station_location_type_name'
|
|
|
|
ATTR_LOCATION_ORIGIN = 'origin_station_location_type_name'
|
|
|
|
ATTR_PICKUP_DESTINATION = 'destination_stop_pickup_type_state'
|
|
|
|
ATTR_PICKUP_ORIGIN = 'origin_stop_pickup_type_state'
|
|
|
|
ATTR_ROUTE_TYPE = 'route_type_name'
|
|
|
|
ATTR_TIMEPOINT_DESTINATION = 'destination_stop_timepoint_exact'
|
|
|
|
ATTR_TIMEPOINT_ORIGIN = 'origin_stop_timepoint_exact'
|
|
|
|
ATTR_WHEELCHAIR = 'trip_wheelchair_access_available'
|
|
|
|
ATTR_WHEELCHAIR_DESTINATION = \
|
|
|
|
'destination_station_wheelchair_boarding_available'
|
|
|
|
ATTR_WHEELCHAIR_ORIGIN = 'origin_station_wheelchair_boarding_available'
|
|
|
|
|
2016-09-04 16:27:19 +00:00
|
|
|
CONF_DATA = 'data'
|
|
|
|
CONF_DESTINATION = 'destination'
|
|
|
|
CONF_ORIGIN = 'origin'
|
2019-03-26 04:51:49 +00:00
|
|
|
CONF_TOMORROW = 'include_tomorrow'
|
2016-03-27 00:41:09 +00:00
|
|
|
|
2016-09-04 16:27:19 +00:00
|
|
|
DEFAULT_NAME = 'GTFS Sensor'
|
|
|
|
DEFAULT_PATH = 'gtfs'
|
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
BICYCLE_ALLOWED_DEFAULT = STATE_UNKNOWN
|
|
|
|
BICYCLE_ALLOWED_OPTIONS = {
|
|
|
|
1: True,
|
|
|
|
2: False,
|
|
|
|
}
|
|
|
|
DROP_OFF_TYPE_DEFAULT = STATE_UNKNOWN
|
|
|
|
DROP_OFF_TYPE_OPTIONS = {
|
|
|
|
0: 'Regular',
|
|
|
|
1: 'Not Available',
|
|
|
|
2: 'Call Agency',
|
|
|
|
3: 'Contact Driver',
|
|
|
|
}
|
2016-09-04 16:27:19 +00:00
|
|
|
ICON = 'mdi:train'
|
2019-02-09 03:38:39 +00:00
|
|
|
ICONS = {
|
|
|
|
0: 'mdi:tram',
|
|
|
|
1: 'mdi:subway',
|
|
|
|
2: 'mdi:train',
|
|
|
|
3: 'mdi:bus',
|
|
|
|
4: 'mdi:ferry',
|
|
|
|
5: 'mdi:train-variant',
|
|
|
|
6: 'mdi:gondola',
|
|
|
|
7: 'mdi:stairs',
|
|
|
|
}
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
LOCATION_TYPE_DEFAULT = 'Stop'
|
|
|
|
LOCATION_TYPE_OPTIONS = {
|
|
|
|
0: 'Station',
|
|
|
|
1: 'Stop',
|
|
|
|
2: "Station Entrance/Exit",
|
|
|
|
3: 'Other',
|
|
|
|
}
|
|
|
|
PICKUP_TYPE_DEFAULT = STATE_UNKNOWN
|
|
|
|
PICKUP_TYPE_OPTIONS = {
|
|
|
|
0: 'Regular',
|
|
|
|
1: "None Available",
|
|
|
|
2: "Call Agency",
|
|
|
|
3: "Contact Driver",
|
|
|
|
}
|
|
|
|
ROUTE_TYPE_OPTIONS = {
|
|
|
|
0: 'Tram',
|
|
|
|
1: 'Subway',
|
|
|
|
2: 'Rail',
|
|
|
|
3: 'Bus',
|
|
|
|
4: 'Ferry',
|
|
|
|
5: "Cable Tram",
|
|
|
|
6: "Aerial Lift",
|
|
|
|
7: 'Funicular',
|
|
|
|
}
|
|
|
|
TIMEPOINT_DEFAULT = True
|
|
|
|
TIMEPOINT_OPTIONS = {
|
|
|
|
0: False,
|
|
|
|
1: True,
|
|
|
|
}
|
|
|
|
WHEELCHAIR_ACCESS_DEFAULT = STATE_UNKNOWN
|
|
|
|
WHEELCHAIR_ACCESS_OPTIONS = {
|
|
|
|
1: True,
|
|
|
|
2: False,
|
|
|
|
}
|
|
|
|
WHEELCHAIR_BOARDING_DEFAULT = STATE_UNKNOWN
|
|
|
|
WHEELCHAIR_BOARDING_OPTIONS = {
|
|
|
|
1: True,
|
|
|
|
2: False,
|
|
|
|
}
|
2016-03-27 00:53:46 +00:00
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # type: ignore
|
2016-09-04 16:27:19 +00:00
|
|
|
vol.Required(CONF_ORIGIN): cv.string,
|
|
|
|
vol.Required(CONF_DESTINATION): cv.string,
|
2016-10-05 16:02:45 +00:00
|
|
|
vol.Required(CONF_DATA): cv.string,
|
2017-01-13 22:02:00 +00:00
|
|
|
vol.Optional(CONF_NAME): cv.string,
|
2018-02-17 09:29:14 +00:00
|
|
|
vol.Optional(CONF_OFFSET, default=0): cv.time_period,
|
2019-03-26 04:51:49 +00:00
|
|
|
vol.Optional(CONF_TOMORROW, default=False): cv.boolean,
|
2016-09-04 16:27:19 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
def get_next_departure(schedule: Any, start_station_id: Any,
|
|
|
|
end_station_id: Any, offset: cv.time_period,
|
2019-03-31 21:21:45 +00:00
|
|
|
include_tomorrow: bool = False) -> dict:
|
2016-10-05 16:02:45 +00:00
|
|
|
"""Get the next departure for the given schedule."""
|
2017-06-24 15:45:14 +00:00
|
|
|
now = datetime.datetime.now() + offset
|
2019-03-26 04:51:49 +00:00
|
|
|
now_date = now.strftime(dt_util.DATE_STR_FORMAT)
|
|
|
|
yesterday = now - datetime.timedelta(days=1)
|
|
|
|
yesterday_date = yesterday.strftime(dt_util.DATE_STR_FORMAT)
|
|
|
|
tomorrow = now + datetime.timedelta(days=1)
|
|
|
|
tomorrow_date = tomorrow.strftime(dt_util.DATE_STR_FORMAT)
|
2016-03-27 00:53:46 +00:00
|
|
|
|
2016-03-27 01:47:54 +00:00
|
|
|
from sqlalchemy.sql import text
|
|
|
|
|
2019-03-26 04:51:49 +00:00
|
|
|
# Fetch all departures for yesterday, today and optionally tomorrow,
|
|
|
|
# up to an overkill maximum in case of a departure every minute for those
|
|
|
|
# days.
|
|
|
|
limit = 24 * 60 * 60 * 2
|
|
|
|
tomorrow_select = tomorrow_where = tomorrow_order = ''
|
|
|
|
if include_tomorrow:
|
2019-03-31 21:21:45 +00:00
|
|
|
limit = int(limit / 2 * 3)
|
2019-03-26 04:51:49 +00:00
|
|
|
tomorrow_name = tomorrow.strftime('%A').lower()
|
|
|
|
tomorrow_select = "calendar.{} AS tomorrow,".format(tomorrow_name)
|
|
|
|
tomorrow_where = "OR calendar.{} = 1".format(tomorrow_name)
|
|
|
|
tomorrow_order = "calendar.{} DESC,".format(tomorrow_name)
|
|
|
|
|
|
|
|
sql_query = """
|
|
|
|
SELECT trip.trip_id, trip.route_id,
|
|
|
|
time(origin_stop_time.arrival_time) AS origin_arrival_time,
|
|
|
|
time(origin_stop_time.departure_time) AS origin_depart_time,
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
date(origin_stop_time.departure_time) AS origin_depart_date,
|
2019-03-26 04:51:49 +00:00
|
|
|
origin_stop_time.drop_off_type AS origin_drop_off_type,
|
|
|
|
origin_stop_time.pickup_type AS origin_pickup_type,
|
|
|
|
origin_stop_time.shape_dist_traveled AS origin_dist_traveled,
|
|
|
|
origin_stop_time.stop_headsign AS origin_stop_headsign,
|
|
|
|
origin_stop_time.stop_sequence AS origin_stop_sequence,
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
origin_stop_time.timepoint AS origin_stop_timepoint,
|
2019-03-26 04:51:49 +00:00
|
|
|
time(destination_stop_time.arrival_time) AS dest_arrival_time,
|
|
|
|
time(destination_stop_time.departure_time) AS dest_depart_time,
|
|
|
|
destination_stop_time.drop_off_type AS dest_drop_off_type,
|
|
|
|
destination_stop_time.pickup_type AS dest_pickup_type,
|
|
|
|
destination_stop_time.shape_dist_traveled AS dest_dist_traveled,
|
|
|
|
destination_stop_time.stop_headsign AS dest_stop_headsign,
|
|
|
|
destination_stop_time.stop_sequence AS dest_stop_sequence,
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
destination_stop_time.timepoint AS dest_stop_timepoint,
|
2019-03-26 04:51:49 +00:00
|
|
|
calendar.{yesterday_name} AS yesterday,
|
|
|
|
calendar.{today_name} AS today,
|
|
|
|
{tomorrow_select}
|
|
|
|
calendar.start_date AS start_date,
|
|
|
|
calendar.end_date AS end_date
|
|
|
|
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.{yesterday_name} = 1
|
|
|
|
OR calendar.{today_name} = 1
|
|
|
|
{tomorrow_where}
|
|
|
|
)
|
|
|
|
AND start_station.stop_id = :origin_station_id
|
|
|
|
AND end_station.stop_id = :end_station_id
|
|
|
|
AND origin_stop_sequence < dest_stop_sequence
|
|
|
|
AND calendar.start_date <= :today
|
|
|
|
AND calendar.end_date >= :today
|
|
|
|
ORDER BY calendar.{yesterday_name} DESC,
|
|
|
|
calendar.{today_name} DESC,
|
|
|
|
{tomorrow_order}
|
|
|
|
origin_stop_time.departure_time
|
|
|
|
LIMIT :limit
|
|
|
|
""".format(yesterday_name=yesterday.strftime('%A').lower(),
|
|
|
|
today_name=now.strftime('%A').lower(),
|
|
|
|
tomorrow_select=tomorrow_select,
|
|
|
|
tomorrow_where=tomorrow_where,
|
|
|
|
tomorrow_order=tomorrow_order)
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
result = schedule.engine.execute(text(sql_query),
|
|
|
|
origin_station_id=start_station_id,
|
|
|
|
end_station_id=end_station_id,
|
|
|
|
today=now_date,
|
|
|
|
limit=limit)
|
2019-03-26 04:51:49 +00:00
|
|
|
|
|
|
|
# Create lookup timetable for today and possibly tomorrow, taking into
|
|
|
|
# account any departures from yesterday scheduled after midnight,
|
|
|
|
# as long as all departures are within the calendar date range.
|
|
|
|
timetable = {}
|
|
|
|
yesterday_start = today_start = tomorrow_start = None
|
2019-03-31 21:21:45 +00:00
|
|
|
yesterday_last = today_last = ''
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
|
2016-03-27 00:53:46 +00:00
|
|
|
for row in result:
|
2019-03-26 04:51:49 +00:00
|
|
|
if row['yesterday'] == 1 and yesterday_date >= row['start_date']:
|
|
|
|
extras = {
|
|
|
|
'day': 'yesterday',
|
|
|
|
'first': None,
|
|
|
|
'last': False,
|
|
|
|
}
|
|
|
|
if yesterday_start is None:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
yesterday_start = row['origin_depart_date']
|
|
|
|
if yesterday_start != row['origin_depart_date']:
|
2019-03-26 04:51:49 +00:00
|
|
|
idx = '{} {}'.format(now_date,
|
|
|
|
row['origin_depart_time'])
|
|
|
|
timetable[idx] = {**row, **extras}
|
|
|
|
yesterday_last = idx
|
|
|
|
|
|
|
|
if row['today'] == 1:
|
|
|
|
extras = {
|
|
|
|
'day': 'today',
|
|
|
|
'first': False,
|
|
|
|
'last': False,
|
|
|
|
}
|
|
|
|
if today_start is None:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
today_start = row['origin_depart_date']
|
2019-03-26 04:51:49 +00:00
|
|
|
extras['first'] = True
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
if today_start == row['origin_depart_date']:
|
2019-03-26 04:51:49 +00:00
|
|
|
idx_prefix = now_date
|
|
|
|
else:
|
|
|
|
idx_prefix = tomorrow_date
|
|
|
|
idx = '{} {}'.format(idx_prefix, row['origin_depart_time'])
|
|
|
|
timetable[idx] = {**row, **extras}
|
|
|
|
today_last = idx
|
|
|
|
|
|
|
|
if 'tomorrow' in row and row['tomorrow'] == 1 and tomorrow_date <= \
|
|
|
|
row['end_date']:
|
|
|
|
extras = {
|
|
|
|
'day': 'tomorrow',
|
|
|
|
'first': False,
|
|
|
|
'last': None,
|
|
|
|
}
|
|
|
|
if tomorrow_start is None:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
tomorrow_start = row['origin_depart_date']
|
2019-03-26 04:51:49 +00:00
|
|
|
extras['first'] = True
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
if tomorrow_start == row['origin_depart_date']:
|
2019-03-26 04:51:49 +00:00
|
|
|
idx = '{} {}'.format(tomorrow_date,
|
|
|
|
row['origin_depart_time'])
|
|
|
|
timetable[idx] = {**row, **extras}
|
|
|
|
|
|
|
|
# Flag last departures.
|
2019-04-01 17:49:53 +00:00
|
|
|
for idx in filter(None, [yesterday_last, today_last]):
|
|
|
|
timetable[idx]['last'] = True
|
2019-03-26 04:51:49 +00:00
|
|
|
|
|
|
|
_LOGGER.debug("Timetable: %s", sorted(timetable.keys()))
|
|
|
|
|
2019-03-31 21:21:45 +00:00
|
|
|
item = {} # type: dict
|
2019-03-26 04:51:49 +00:00
|
|
|
for key in sorted(timetable.keys()):
|
|
|
|
if dt_util.parse_datetime(key) > now:
|
|
|
|
item = timetable[key]
|
|
|
|
_LOGGER.debug("Departure found for station %s @ %s -> %s",
|
|
|
|
start_station_id, key, item)
|
|
|
|
break
|
2016-03-27 00:53:46 +00:00
|
|
|
|
2016-12-16 05:40:33 +00:00
|
|
|
if item == {}:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
return {}
|
2016-12-16 05:40:33 +00:00
|
|
|
|
2019-02-26 21:17:20 +00:00
|
|
|
# Format arrival and departure dates and times, accounting for the
|
|
|
|
# possibility of times crossing over midnight.
|
|
|
|
origin_arrival = now
|
|
|
|
if item['origin_arrival_time'] > item['origin_depart_time']:
|
|
|
|
origin_arrival -= datetime.timedelta(days=1)
|
2019-03-24 11:15:30 +00:00
|
|
|
origin_arrival_time = '{} {}'.format(
|
|
|
|
origin_arrival.strftime(dt_util.DATE_STR_FORMAT),
|
|
|
|
item['origin_arrival_time'])
|
2019-02-26 21:17:20 +00:00
|
|
|
|
2019-03-26 04:51:49 +00:00
|
|
|
origin_depart_time = '{} {}'.format(now_date, item['origin_depart_time'])
|
2019-02-26 21:17:20 +00:00
|
|
|
|
|
|
|
dest_arrival = now
|
|
|
|
if item['dest_arrival_time'] < item['origin_depart_time']:
|
|
|
|
dest_arrival += datetime.timedelta(days=1)
|
2019-03-24 11:15:30 +00:00
|
|
|
dest_arrival_time = '{} {}'.format(
|
|
|
|
dest_arrival.strftime(dt_util.DATE_STR_FORMAT),
|
|
|
|
item['dest_arrival_time'])
|
2019-02-26 21:17:20 +00:00
|
|
|
|
|
|
|
dest_depart = dest_arrival
|
|
|
|
if item['dest_depart_time'] < item['dest_arrival_time']:
|
|
|
|
dest_depart += datetime.timedelta(days=1)
|
2019-03-24 11:15:30 +00:00
|
|
|
dest_depart_time = '{} {}'.format(
|
|
|
|
dest_depart.strftime(dt_util.DATE_STR_FORMAT),
|
|
|
|
item['dest_depart_time'])
|
2016-03-27 00:53:46 +00:00
|
|
|
|
2019-03-24 11:15:30 +00:00
|
|
|
depart_time = dt_util.parse_datetime(origin_depart_time)
|
|
|
|
arrival_time = dt_util.parse_datetime(dest_arrival_time)
|
2016-03-27 00:53:46 +00:00
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
origin_stop_time = {
|
2019-02-09 03:47:02 +00:00
|
|
|
'Arrival Time': origin_arrival_time,
|
|
|
|
'Departure Time': origin_depart_time,
|
|
|
|
'Drop Off Type': item['origin_drop_off_type'],
|
|
|
|
'Pickup Type': item['origin_pickup_type'],
|
2019-02-26 21:17:20 +00:00
|
|
|
'Shape Dist Traveled': item['origin_dist_traveled'],
|
2019-02-09 03:47:02 +00:00
|
|
|
'Headsign': item['origin_stop_headsign'],
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
'Sequence': item['origin_stop_sequence'],
|
|
|
|
'Timepoint': item['origin_stop_timepoint'],
|
2016-03-27 00:53:46 +00:00
|
|
|
}
|
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
destination_stop_time = {
|
2019-02-09 03:47:02 +00:00
|
|
|
'Arrival Time': dest_arrival_time,
|
|
|
|
'Departure Time': dest_depart_time,
|
|
|
|
'Drop Off Type': item['dest_drop_off_type'],
|
|
|
|
'Pickup Type': item['dest_pickup_type'],
|
|
|
|
'Shape Dist Traveled': item['dest_dist_traveled'],
|
|
|
|
'Headsign': item['dest_stop_headsign'],
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
'Sequence': item['dest_stop_sequence'],
|
|
|
|
'Timepoint': item['dest_stop_timepoint'],
|
2016-03-27 00:53:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
2019-02-09 03:47:02 +00:00
|
|
|
'trip_id': item['trip_id'],
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
'route_id': item['route_id'],
|
2019-03-26 04:51:49 +00:00
|
|
|
'day': item['day'],
|
|
|
|
'first': item['first'],
|
|
|
|
'last': item['last'],
|
2019-03-24 11:15:30 +00:00
|
|
|
'departure_time': depart_time,
|
2016-09-04 16:27:19 +00:00
|
|
|
'arrival_time': arrival_time,
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
'origin_stop_time': origin_stop_time,
|
|
|
|
'destination_stop_time': destination_stop_time,
|
2016-03-27 00:53:46 +00:00
|
|
|
}
|
|
|
|
|
2016-03-27 00:41:09 +00:00
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
def setup_platform(hass: HomeAssistantType, config: ConfigType,
|
|
|
|
add_entities: Callable[[list], None],
|
2019-03-31 21:21:45 +00:00
|
|
|
discovery_info: Optional[dict] = None) -> None:
|
2016-10-05 16:02:45 +00:00
|
|
|
"""Set up the GTFS sensor."""
|
2016-09-04 16:27:19 +00:00
|
|
|
gtfs_dir = hass.config.path(DEFAULT_PATH)
|
2019-03-31 21:21:45 +00:00
|
|
|
data = config[CONF_DATA]
|
2016-09-04 16:27:19 +00:00
|
|
|
origin = config.get(CONF_ORIGIN)
|
|
|
|
destination = config.get(CONF_DESTINATION)
|
|
|
|
name = config.get(CONF_NAME)
|
2017-06-24 15:45:14 +00:00
|
|
|
offset = config.get(CONF_OFFSET)
|
2019-03-31 21:21:45 +00:00
|
|
|
include_tomorrow = config[CONF_TOMORROW]
|
2016-03-27 01:52:03 +00:00
|
|
|
|
|
|
|
if not os.path.exists(gtfs_dir):
|
2016-03-27 01:53:21 +00:00
|
|
|
os.makedirs(gtfs_dir)
|
2016-03-27 01:52:03 +00:00
|
|
|
|
2016-09-04 16:27:19 +00:00
|
|
|
if not os.path.exists(os.path.join(gtfs_dir, data)):
|
2017-05-02 16:18:47 +00:00
|
|
|
_LOGGER.error("The given GTFS data file/folder was not found")
|
2019-03-31 21:21:45 +00:00
|
|
|
return
|
2016-03-27 01:52:03 +00:00
|
|
|
|
2016-05-21 18:04:18 +00:00
|
|
|
import pygtfs
|
|
|
|
|
2018-12-09 22:32:48 +00:00
|
|
|
(gtfs_root, _) = os.path.splitext(data)
|
2016-05-21 18:04:18 +00:00
|
|
|
|
2018-12-09 22:32:48 +00:00
|
|
|
sqlite_file = "{}.sqlite?check_same_thread=False".format(gtfs_root)
|
2016-05-21 18:04:18 +00:00
|
|
|
joined_path = os.path.join(gtfs_dir, sqlite_file)
|
|
|
|
gtfs = pygtfs.Schedule(joined_path)
|
|
|
|
|
|
|
|
# pylint: disable=no-member
|
2018-07-18 09:54:27 +00:00
|
|
|
if not gtfs.feeds:
|
2016-09-04 16:27:19 +00:00
|
|
|
pygtfs.append_feed(gtfs, os.path.join(gtfs_dir, data))
|
2016-03-27 00:41:09 +00:00
|
|
|
|
2018-08-24 14:37:30 +00:00
|
|
|
add_entities([
|
2019-03-26 04:51:49 +00:00
|
|
|
GTFSDepartureSensor(gtfs, name, origin, destination, offset,
|
|
|
|
include_tomorrow)])
|
2016-03-27 00:53:46 +00:00
|
|
|
|
|
|
|
|
2016-03-27 00:41:09 +00:00
|
|
|
class GTFSDepartureSensor(Entity):
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
"""Implementation of a GTFS departure sensor."""
|
2016-03-27 00:41:09 +00:00
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
def __init__(self, pygtfs: Any, name: Optional[Any], origin: Any,
|
|
|
|
destination: Any, offset: cv.time_period,
|
2019-03-31 21:21:45 +00:00
|
|
|
include_tomorrow: bool) -> None:
|
2016-03-27 00:41:09 +00:00
|
|
|
"""Initialize the sensor."""
|
2016-05-21 18:04:18 +00:00
|
|
|
self._pygtfs = pygtfs
|
2016-03-27 00:41:09 +00:00
|
|
|
self.origin = origin
|
|
|
|
self.destination = destination
|
2019-03-26 04:51:49 +00:00
|
|
|
self._include_tomorrow = include_tomorrow
|
2017-06-24 15:45:14 +00:00
|
|
|
self._offset = offset
|
2016-10-11 05:36:20 +00:00
|
|
|
self._custom_name = name
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
|
|
|
|
self._available = False
|
2019-02-09 03:38:39 +00:00
|
|
|
self._icon = ICON
|
2016-10-11 05:36:20 +00:00
|
|
|
self._name = ''
|
2019-03-31 21:21:45 +00:00
|
|
|
self._state = None # type: Optional[str]
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self._attributes = {} # type: dict
|
|
|
|
|
|
|
|
self._agency = None
|
|
|
|
self._departure = {} # type: dict
|
|
|
|
self._destination = None
|
|
|
|
self._origin = None
|
|
|
|
self._route = None
|
|
|
|
self._trip = None
|
|
|
|
|
2016-05-21 18:04:18 +00:00
|
|
|
self.lock = threading.Lock()
|
2016-03-27 00:41:09 +00:00
|
|
|
self.update()
|
|
|
|
|
|
|
|
@property
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
def name(self) -> str:
|
2016-03-27 00:41:09 +00:00
|
|
|
"""Return the name of the sensor."""
|
|
|
|
return self._name
|
|
|
|
|
|
|
|
@property
|
2019-03-31 21:21:45 +00:00
|
|
|
def state(self) -> Optional[str]: # type: ignore
|
2016-03-27 00:41:09 +00:00
|
|
|
"""Return the state of the sensor."""
|
|
|
|
return self._state
|
|
|
|
|
|
|
|
@property
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
def available(self) -> bool:
|
|
|
|
"""Return True if entity is available."""
|
|
|
|
return self._available
|
|
|
|
|
|
|
|
@property
|
|
|
|
def device_state_attributes(self) -> dict:
|
2016-03-27 00:41:09 +00:00
|
|
|
"""Return the state attributes."""
|
|
|
|
return self._attributes
|
|
|
|
|
|
|
|
@property
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
def icon(self) -> str:
|
2016-03-27 00:41:09 +00:00
|
|
|
"""Icon to use in the frontend, if any."""
|
2019-02-09 03:38:39 +00:00
|
|
|
return self._icon
|
2016-03-27 00:41:09 +00:00
|
|
|
|
2019-03-24 11:15:30 +00:00
|
|
|
@property
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
def device_class(self) -> str:
|
2019-03-24 11:15:30 +00:00
|
|
|
"""Return the class of this device."""
|
|
|
|
return DEVICE_CLASS_TIMESTAMP
|
|
|
|
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
def update(self) -> None:
|
2016-03-27 00:41:09 +00:00
|
|
|
"""Get the latest data from GTFS and update the states."""
|
2016-05-21 18:04:18 +00:00
|
|
|
with self.lock:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
# Fetch valid stop information once
|
|
|
|
if not self._origin:
|
|
|
|
stops = self._pygtfs.stops_by_id(self.origin)
|
|
|
|
if not stops:
|
|
|
|
self._available = False
|
|
|
|
_LOGGER.warning("Origin stop ID %s not found", self.origin)
|
|
|
|
return
|
|
|
|
self._origin = stops[0]
|
|
|
|
|
|
|
|
if not self._destination:
|
|
|
|
stops = self._pygtfs.stops_by_id(self.destination)
|
|
|
|
if not stops:
|
|
|
|
self._available = False
|
|
|
|
_LOGGER.warning("Destination stop ID %s not found",
|
|
|
|
self.destination)
|
|
|
|
return
|
|
|
|
self._destination = stops[0]
|
|
|
|
|
|
|
|
self._available = True
|
|
|
|
|
|
|
|
# Fetch next departure
|
2017-05-02 16:18:47 +00:00
|
|
|
self._departure = get_next_departure(
|
2019-03-26 04:51:49 +00:00
|
|
|
self._pygtfs, self.origin, self.destination, self._offset,
|
|
|
|
self._include_tomorrow)
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
|
|
|
|
# Define the state as a UTC timestamp with ISO 8601 format
|
2016-12-16 05:40:33 +00:00
|
|
|
if not self._departure:
|
2019-02-17 10:46:08 +00:00
|
|
|
self._state = None
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
else:
|
|
|
|
self._state = dt_util.as_utc(
|
|
|
|
self._departure['departure_time']).isoformat()
|
|
|
|
|
|
|
|
# Fetch trip and route details once, unless updated
|
|
|
|
if not self._departure:
|
|
|
|
self._trip = None
|
|
|
|
else:
|
|
|
|
trip_id = self._departure['trip_id']
|
|
|
|
if not self._trip or self._trip.trip_id != trip_id:
|
2019-03-31 21:21:45 +00:00
|
|
|
_LOGGER.debug("Fetching trip details for %s", trip_id)
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self._trip = self._pygtfs.trips_by_id(trip_id)[0]
|
|
|
|
|
|
|
|
route_id = self._departure['route_id']
|
|
|
|
if not self._route or self._route.route_id != route_id:
|
2019-03-31 21:21:45 +00:00
|
|
|
_LOGGER.debug("Fetching route details for %s", route_id)
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self._route = self._pygtfs.routes_by_id(route_id)[0]
|
|
|
|
|
|
|
|
# Fetch agency details exactly once
|
|
|
|
if self._agency is None and self._route:
|
2019-03-31 21:21:45 +00:00
|
|
|
_LOGGER.debug("Fetching agency details for %s",
|
|
|
|
self._route.agency_id)
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
try:
|
|
|
|
self._agency = self._pygtfs.agencies_by_id(
|
|
|
|
self._route.agency_id)[0]
|
|
|
|
except IndexError:
|
|
|
|
_LOGGER.warning(
|
2019-03-31 21:21:45 +00:00
|
|
|
"Agency ID '%s' was not found in agency table, "
|
|
|
|
"you may want to update the routes database table "
|
|
|
|
"to fix this missing reference",
|
|
|
|
self._route.agency_id)
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self._agency = False
|
|
|
|
|
|
|
|
# Assign attributes, icon and name
|
|
|
|
self.update_attributes()
|
|
|
|
|
|
|
|
if self._route:
|
|
|
|
self._icon = ICONS.get(self._route.route_type, ICON)
|
|
|
|
else:
|
|
|
|
self._icon = ICON
|
|
|
|
|
|
|
|
name = '{agency} {origin} to {destination} next departure'
|
|
|
|
if not self._departure:
|
|
|
|
name = '{default}'
|
2016-10-11 05:36:20 +00:00
|
|
|
self._name = (self._custom_name or
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
name.format(agency=getattr(self._agency,
|
|
|
|
'agency_name',
|
|
|
|
DEFAULT_NAME),
|
|
|
|
default=DEFAULT_NAME,
|
|
|
|
origin=self.origin,
|
|
|
|
destination=self.destination))
|
|
|
|
|
|
|
|
def update_attributes(self) -> None:
|
|
|
|
"""Update state attributes."""
|
|
|
|
# Add departure information
|
|
|
|
if self._departure:
|
|
|
|
self._attributes[ATTR_ARRIVAL] = dt_util.as_utc(
|
|
|
|
self._departure['arrival_time']).isoformat()
|
|
|
|
|
|
|
|
self._attributes[ATTR_DAY] = self._departure['day']
|
|
|
|
|
|
|
|
if self._departure[ATTR_FIRST] is not None:
|
|
|
|
self._attributes[ATTR_FIRST] = self._departure['first']
|
2019-03-31 21:21:45 +00:00
|
|
|
elif ATTR_FIRST in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
del self._attributes[ATTR_FIRST]
|
|
|
|
|
|
|
|
if self._departure[ATTR_LAST] is not None:
|
|
|
|
self._attributes[ATTR_LAST] = self._departure['last']
|
2019-03-31 21:21:45 +00:00
|
|
|
elif ATTR_LAST in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
del self._attributes[ATTR_LAST]
|
|
|
|
else:
|
2019-03-31 21:21:45 +00:00
|
|
|
if ATTR_ARRIVAL in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
del self._attributes[ATTR_ARRIVAL]
|
2019-03-31 21:21:45 +00:00
|
|
|
if ATTR_DAY in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
del self._attributes[ATTR_DAY]
|
2019-03-31 21:21:45 +00:00
|
|
|
if ATTR_FIRST in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
del self._attributes[ATTR_FIRST]
|
2019-03-31 21:21:45 +00:00
|
|
|
if ATTR_LAST in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
del self._attributes[ATTR_LAST]
|
|
|
|
|
|
|
|
# Add contextual information
|
|
|
|
self._attributes[ATTR_OFFSET] = self._offset.seconds / 60
|
|
|
|
|
|
|
|
if self._state is None:
|
|
|
|
self._attributes[ATTR_INFO] = "No more departures" if \
|
|
|
|
self._include_tomorrow else "No more departures today"
|
2019-03-31 21:21:45 +00:00
|
|
|
elif ATTR_INFO in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
del self._attributes[ATTR_INFO]
|
|
|
|
|
|
|
|
if self._agency:
|
|
|
|
self._attributes[ATTR_ATTRIBUTION] = self._agency.agency_name
|
2019-03-31 21:21:45 +00:00
|
|
|
elif ATTR_ATTRIBUTION in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
del self._attributes[ATTR_ATTRIBUTION]
|
|
|
|
|
|
|
|
# Add extra metadata
|
|
|
|
key = 'agency_id'
|
2019-03-31 21:21:45 +00:00
|
|
|
if self._agency and key not in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self.append_keys(self.dict_for_table(self._agency), 'Agency')
|
|
|
|
|
|
|
|
key = 'origin_station_stop_id'
|
2019-03-31 21:21:45 +00:00
|
|
|
if self._origin and key not in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self.append_keys(self.dict_for_table(self._origin),
|
|
|
|
"Origin Station")
|
|
|
|
self._attributes[ATTR_LOCATION_ORIGIN] = \
|
|
|
|
LOCATION_TYPE_OPTIONS.get(
|
|
|
|
self._origin.location_type,
|
|
|
|
LOCATION_TYPE_DEFAULT)
|
|
|
|
self._attributes[ATTR_WHEELCHAIR_ORIGIN] = \
|
|
|
|
WHEELCHAIR_BOARDING_OPTIONS.get(
|
|
|
|
self._origin.wheelchair_boarding,
|
|
|
|
WHEELCHAIR_BOARDING_DEFAULT)
|
|
|
|
|
|
|
|
key = 'destination_station_stop_id'
|
2019-03-31 21:21:45 +00:00
|
|
|
if self._destination and key not in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self.append_keys(self.dict_for_table(self._destination),
|
|
|
|
"Destination Station")
|
|
|
|
self._attributes[ATTR_LOCATION_DESTINATION] = \
|
|
|
|
LOCATION_TYPE_OPTIONS.get(
|
|
|
|
self._destination.location_type,
|
|
|
|
LOCATION_TYPE_DEFAULT)
|
|
|
|
self._attributes[ATTR_WHEELCHAIR_DESTINATION] = \
|
|
|
|
WHEELCHAIR_BOARDING_OPTIONS.get(
|
|
|
|
self._destination.wheelchair_boarding,
|
|
|
|
WHEELCHAIR_BOARDING_DEFAULT)
|
|
|
|
|
|
|
|
# Manage Route metadata
|
|
|
|
key = 'route_id'
|
2019-03-31 21:21:45 +00:00
|
|
|
if not self._route and key in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self.remove_keys('Route')
|
2019-03-31 21:21:45 +00:00
|
|
|
elif self._route and (key not in self._attributes or
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self._attributes[key] != self._route.route_id):
|
|
|
|
self.append_keys(self.dict_for_table(self._route), 'Route')
|
|
|
|
self._attributes[ATTR_ROUTE_TYPE] = \
|
|
|
|
ROUTE_TYPE_OPTIONS[self._route.route_type]
|
|
|
|
|
|
|
|
# Manage Trip metadata
|
|
|
|
key = 'trip_id'
|
2019-03-31 21:21:45 +00:00
|
|
|
if not self._trip and key in self._attributes:
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self.remove_keys('Trip')
|
2019-03-31 21:21:45 +00:00
|
|
|
elif self._trip and (key not in self._attributes or
|
Cache GTFS metadata and expose utility attributes (breaking change) (#20966)
## Description:
Current sensor updates run 7 additional SQLite database queries to populate attributes, on top of the bus schedule queries themselves. Double that if you have two sensors. That leads to a lot of slowdowns for everything else when using an SD card!
Considering that some data never changes (agency, routes...) and that others like departure times are good until invalidated, let's fetch such metadata at first then only when relevant changes do occur.
**Breaking Change:**
GTFS sensor attributes are now named using the standard snake_case format.
### Work performed:
- All metadata queries are now cached.
- Metadata queries are now all regrouped in the `update()` method.
- Attributes assembling is now done in ~~`device_state_attributes()` where it belongs.~~ in a utility method called from `update()`, for code clarity and since there is potential I/O from SQLAlchemy.
- As a bonus, many metadata entries with cryptic values have complementary entries added that provide easier to use data:
- .\* Stop Drop Off Type: .\* Stop Drop Off Type **State** -> (string, unknown)
- .\* Stop Pickup Type: .\* Stop Pickup Type **State** -> (string, unknown)
- .\* Stop Timepoint: .\* Stop Timepoint **Exact** -> boolean
- .\* Station Location Type: .\* Station Location Type **Name** -> string
- .\* Wheelchair Boarding: .\* Wheelchair Boarding **Available** -> (boolean, unknown)
- Route Type: Route Type **Name** (string)
- Trip Bikes Allowed: Trip Bikes Allowed **State** -> (boolean, unknown)
- Trip Wheelchair Access: Trip Wheelchair Access **Available** -> (boolean, unknown)
- Attribute names are now using snake_case.
- Added type hints.
**Related issue (if applicable):** fixes #21222
## Checklist:
- [x] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
2019-03-28 00:58:23 +00:00
|
|
|
self._attributes[key] != self._trip.trip_id):
|
|
|
|
self.append_keys(self.dict_for_table(self._trip), 'Trip')
|
|
|
|
self._attributes[ATTR_BICYCLE] = BICYCLE_ALLOWED_OPTIONS.get(
|
|
|
|
self._trip.bikes_allowed,
|
|
|
|
BICYCLE_ALLOWED_DEFAULT)
|
|
|
|
self._attributes[ATTR_WHEELCHAIR] = WHEELCHAIR_ACCESS_OPTIONS.get(
|
|
|
|
self._trip.wheelchair_accessible,
|
|
|
|
WHEELCHAIR_ACCESS_DEFAULT)
|
|
|
|
|
|
|
|
# Manage Stop Times metadata
|
|
|
|
prefix = 'origin_stop'
|
|
|
|
if self._departure:
|
|
|
|
self.append_keys(self._departure['origin_stop_time'], prefix)
|
|
|
|
self._attributes[ATTR_DROP_OFF_ORIGIN] = DROP_OFF_TYPE_OPTIONS.get(
|
|
|
|
self._departure['origin_stop_time']['Drop Off Type'],
|
|
|
|
DROP_OFF_TYPE_DEFAULT)
|
|
|
|
self._attributes[ATTR_PICKUP_ORIGIN] = PICKUP_TYPE_OPTIONS.get(
|
|
|
|
self._departure['origin_stop_time']['Pickup Type'],
|
|
|
|
PICKUP_TYPE_DEFAULT)
|
|
|
|
self._attributes[ATTR_TIMEPOINT_ORIGIN] = TIMEPOINT_OPTIONS.get(
|
|
|
|
self._departure['origin_stop_time']['Timepoint'],
|
|
|
|
TIMEPOINT_DEFAULT)
|
|
|
|
else:
|
|
|
|
self.remove_keys(prefix)
|
|
|
|
|
|
|
|
prefix = 'destination_stop'
|
|
|
|
if self._departure:
|
|
|
|
self.append_keys(self._departure['destination_stop_time'], prefix)
|
|
|
|
self._attributes[ATTR_DROP_OFF_DESTINATION] = \
|
|
|
|
DROP_OFF_TYPE_OPTIONS.get(
|
|
|
|
self._departure['destination_stop_time']['Drop Off Type'],
|
|
|
|
DROP_OFF_TYPE_DEFAULT)
|
|
|
|
self._attributes[ATTR_PICKUP_DESTINATION] = \
|
|
|
|
PICKUP_TYPE_OPTIONS.get(
|
|
|
|
self._departure['destination_stop_time']['Pickup Type'],
|
|
|
|
PICKUP_TYPE_DEFAULT)
|
|
|
|
self._attributes[ATTR_TIMEPOINT_DESTINATION] = \
|
|
|
|
TIMEPOINT_OPTIONS.get(
|
|
|
|
self._departure['destination_stop_time']['Timepoint'],
|
|
|
|
TIMEPOINT_DEFAULT)
|
|
|
|
else:
|
|
|
|
self.remove_keys(prefix)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def dict_for_table(resource: Any) -> dict:
|
|
|
|
"""Return a dictionary for the SQLAlchemy resource given."""
|
|
|
|
return dict((col, getattr(resource, col))
|
|
|
|
for col in resource.__table__.columns.keys())
|
|
|
|
|
|
|
|
def append_keys(self, resource: dict, prefix: Optional[str] = None) -> \
|
|
|
|
None:
|
|
|
|
"""Properly format key val pairs to append to attributes."""
|
|
|
|
for attr, val in resource.items():
|
|
|
|
if val == '' or val is None or attr == 'feed_id':
|
|
|
|
continue
|
|
|
|
key = attr
|
|
|
|
if prefix and not key.startswith(prefix):
|
|
|
|
key = '{} {}'.format(prefix, key)
|
|
|
|
key = slugify(key)
|
|
|
|
self._attributes[key] = val
|
|
|
|
|
|
|
|
def remove_keys(self, prefix: str) -> None:
|
|
|
|
"""Remove attributes whose key starts with prefix."""
|
|
|
|
self._attributes = {k: v for k, v in self._attributes.items() if
|
|
|
|
not k.startswith(prefix)}
|