Skip to content

Commit

Permalink
Local stop: adding offset and filter using realtime
Browse files Browse the repository at this point in the history
  • Loading branch information
vingerha committed Apr 18, 2024
1 parent bbac0f0 commit b6d034d
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 18 deletions.
5 changes: 4 additions & 1 deletion custom_components/gtfs2/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Manage the options."""
errors: dict[str, str] = {}
if user_input is not None:
if self.config_entry.data.get(CONF_DEVICE_TRACKER_ID, None):
_data = user_input
Expand All @@ -428,11 +429,13 @@ async def async_step_init(
vol.Optional(CONF_LOCAL_STOP_REFRESH_INTERVAL, default=self.config_entry.options.get(CONF_LOCAL_STOP_REFRESH_INTERVAL, DEFAULT_LOCAL_STOP_REFRESH_INTERVAL)): int,
vol.Optional(CONF_RADIUS, default=self.config_entry.options.get(CONF_RADIUS, DEFAULT_LOCAL_STOP_RADIUS)): vol.All(vol.Coerce(int), vol.Range(min=50, max=5000)),
vol.Optional(CONF_TIMERANGE, default=self.config_entry.options.get(CONF_TIMERANGE, DEFAULT_LOCAL_STOP_TIMERANGE)): vol.All(vol.Coerce(int), vol.Range(min=15, max=120)),
vol.Optional(CONF_OFFSET, default=self.config_entry.options.get(CONF_OFFSET, DEFAULT_OFFSET)): int,
vol.Optional(CONF_REAL_TIME, default=self.config_entry.options.get(CONF_REAL_TIME)): selector.BooleanSelector()
}
return self.async_show_form(
step_id="init",
data_schema=vol.Schema(opt1_schema)
data_schema=vol.Schema(opt1_schema),
errors = errors
)

else:
Expand Down
1 change: 1 addition & 0 deletions custom_components/gtfs2/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
DEFAULT_OFFSET = 0
DEFAULT_LOCAL_STOP_REFRESH_INTERVAL = 15
DEFAULT_LOCAL_STOP_TIMERANGE = 30
DEFAULT_LOCAL_STOP_TIMERANGE_HISTORY = 15
DEFAULT_LOCAL_STOP_RADIUS = 400
DEFAULT_MAX_LOCAL_STOPS = 15

Expand Down
1 change: 1 addition & 0 deletions custom_components/gtfs2/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ async def _async_update_data(self) -> dict[str, str]:
"gtfs_dir": DEFAULT_PATH,
"name": data["name"],
"file": data["file"],
"offset": options["offset"] if "offset" in options else 0,
"timerange": options.get("timerange", DEFAULT_LOCAL_STOP_TIMERANGE),
"radius": options.get("radius", DEFAULT_LOCAL_STOP_RADIUS),
"device_tracker_id": data["device_tracker_id"],
Expand Down
53 changes: 36 additions & 17 deletions custom_components/gtfs2/gtfs_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from .const import (
DEFAULT_PATH_GEOJSON,
DEFAULT_LOCAL_STOP_TIMERANGE,
DEFAULT_LOCAL_STOP_TIMERANGE_HISTORY,
DEFAULT_LOCAL_STOP_RADIUS,
DEFAULT_PATH_RT,
ICON,
Expand Down Expand Up @@ -737,13 +738,19 @@ def get_local_stop_list(hass, schedule, data):


def get_local_stops_next_departures(self):
if self.hass.config.time_zone is None:
_LOGGER.error("Timezone is not set in Home Assistant configuration")
timezone = "UTC"
else:
timezone=dt_util.get_time_zone(self.hass.config.time_zone)
_LOGGER.debug("Get local stop departure with data: %s", self._data)
if check_extracting(self.hass, self._data['gtfs_dir'],self._data['file']):
_LOGGER.warning("Cannot get next depurtures on this datasource as still unpacking: %s", self._data["file"])
return {}
"""Get next departures from data."""
schedule = self._data["schedule"]
now = dt_util.now().replace(tzinfo=None)
offset = self._data["offset"]
now = dt_util.now().replace(tzinfo=None) + datetime.timedelta(minutes=offset)
now_date = now.strftime(dt_util.DATE_STR_FORMAT)
now_time = now.strftime(TIME_STR_FORMAT)
tomorrow = now + datetime.timedelta(days=1)
Expand All @@ -753,8 +760,9 @@ def get_local_stops_next_departures(self):
longitude = device_tracker.attributes.get("longitude", None)
include_tomorrow = self._data["include_tomorrow"]
tomorrow_select = tomorrow_select2 = tomorrow_where = tomorrow_order = ""
tomorrow_calendar_date_where = f"AND (calendar_date_today.date = date('now'))"
tomorrow_calendar_date_where = f"AND (calendar_date_today.date = date(:now_offset))"
time_range = str('+' + str(self._data.get("timerange", DEFAULT_LOCAL_STOP_TIMERANGE)) + ' minute')
time_range_history = str('-' + str(self._data.get("timerange_history", DEFAULT_LOCAL_STOP_TIMERANGE_HISTORY)) + ' minute')
radius = self._data.get("radius", DEFAULT_LOCAL_STOP_RADIUS) / 130000
if not latitude or not latitude:
_LOGGER.error("No latitude and/or longitude for : %s", self._data['device_tracker_id'])
Expand All @@ -763,8 +771,8 @@ def get_local_stops_next_departures(self):
_LOGGER.debug("Includes Tomorrow")
tomorrow_name = tomorrow.strftime("%A").lower()
tomorrow_select = f"calendar.{tomorrow_name} AS tomorrow,"
tomorrow_calendar_date_where = f"AND (calendar_date_today.date = date('now') or calendar_date_today.date = date('now','+1 day'))"
tomorrow_select2 = f"CASE WHEN date('now') < calendar_date_today.date THEN '1' else '0' END as tomorrow,"
tomorrow_calendar_date_where = f"AND (calendar_date_today.date = date(:now_offset) or calendar_date_today.date = date(:now_offset,'+1 day'))"
tomorrow_select2 = f"CASE WHEN date(:now_offset) < calendar_date_today.date THEN '1' else '0' END as tomorrow,"
sql_query = f"""
SELECT * FROM (
SELECT stop.stop_id, stop.stop_name,stop.stop_lat as latitude, stop.stop_lon as longitude, trip.trip_id, trip.trip_headsign, trip.direction_id, time(st.departure_time) as departure_time,
Expand All @@ -773,7 +781,7 @@ def get_local_stops_next_departures(self):
{tomorrow_select}
calendar.start_date AS start_date,
calendar.end_date AS end_date,
date('now') as calendar_date,
date(:now_offset) as calendar_date,
0 as today_cd,
route.route_id
FROM trips trip
Expand All @@ -786,19 +794,19 @@ def get_local_stops_next_departures(self):
INNER JOIN routes route
ON route.route_id = trip.route_id
WHERE
trip.service_id not in (select service_id from calendar_dates where date = date('now') and exception_type = 2)
and datetime(date('now') || ' ' || time(st.departure_time) ) between datetime('now','localtime') and datetime('now','localtime',:timerange)
AND calendar.start_date <= date('now')
AND calendar.end_date >= date('now')
trip.service_id not in (select service_id from calendar_dates where date = date(:now_offset) and exception_type = 2)
and datetime(date(:now_offset) || ' ' || time(st.departure_time) ) between datetime(:now_offset,:timerange_history) and datetime(:now_offset,:timerange)
AND calendar.start_date <= date(:now_offset)
AND calendar.end_date >= date(:now_offset)
)
UNION ALL
SELECT * FROM (
SELECT stop.stop_id, stop.stop_name,stop.stop_lat as latitude, stop.stop_lon as longitude, trip.trip_id, trip.trip_headsign, trip.direction_id, time(st.departure_time) as departure_time,
route.route_long_name,route.route_short_name,route.route_type,
'0' AS today,
{tomorrow_select2}
date('now') AS start_date,
date('now') AS end_date,
date(:now_offset) AS start_date,
date(:now_offset) AS end_date,
calendar_date_today.date as calendar_date,
calendar_date_today.exception_type as today_cd,
route.route_id
Expand All @@ -813,7 +821,7 @@ def get_local_stops_next_departures(self):
ON trip.service_id = calendar_date_today.service_id
WHERE
today_cd = 1
and datetime(date('now') || ' ' || time(st.departure_time) ) between datetime('now','localtime') and datetime('now','localtime',:timerange)
and datetime(date(:now_offset) || ' ' || time(st.departure_time) ) between datetime(:now_offset,:timerange_history) and datetime(:now_offset,:timerange)
{tomorrow_calendar_date_where}
)
order by stop_id, tomorrow, departure_time
Expand All @@ -824,7 +832,9 @@ def get_local_stops_next_departures(self):
"latitude": latitude,
"longitude": longitude,
"timerange": time_range,
"timerange_history": time_range_history,
"radius": radius,
"now_offset": now
},
)
timetable = []
Expand Down Expand Up @@ -856,7 +866,7 @@ def get_local_stops_next_departures(self):
if row["stop_id"] != prev_stop_id and prev_stop_id != "":
local_stops_list.append(prev_entry)
timetable = []
entry = {"stop_id": row['stop_id'], "stop_name": row['stop_name'], "latitude": row['latitude'], "longitude": row['longitude'], "departure": timetable}
entry = {"stop_id": row['stop_id'], "stop_name": row['stop_name'], "latitude": row['latitude'], "longitude": row['longitude'], "departure": timetable, "offset": offset}
self._icon = ICONS.get(row['route_type'], ICON)
if row["today"] == 1 or (row["today_cd"] == 1 and row["start_date"] == row["calendar_date"]):
self._trip_id = row["trip_id"]
Expand All @@ -871,17 +881,26 @@ def get_local_stops_next_departures(self):
self._get_next_service = {}
_LOGGER.debug("Find rt for local stop route: %s - direction: %s - stop: %s", self._route , self._direction, self._stop_id)
next_service = get_rt_route_trip_statuses(self)
_LOGGER.debug("Next Service: %s", next_service)

if next_service:
delays = next_service.get(self._route, {}).get(self._direction, {}).get(self._stop_id, []).get("delays", [])
departures = next_service.get(self._route, {}).get(self._direction, {}).get(self._stop_id, []).get("departures", [])
_LOGGER.debug("ns: %s", delays)
delay_rt = delays[0] if delays else "-"
departure_rt = departures[0] if departures else "-"

_LOGGER.debug("Local stop next rt service1: %s", next_service)
timetable.append({"departure": row["departure_time"], "departure_realtime": departure_rt, "delay_realtime": delay_rt, "date": now_date, "stop_name": row['stop_name'], "route": row["route_short_name"], "route_long": row["route_long_name"], "headsign": row["trip_headsign"], "trip_id": row["trip_id"], "direction_id": row["direction_id"], "icon": self._icon})
if departure_rt != '-':
depart_time_corrected = departures[0]
_LOGGER.debug("Departure time: %s, corrected with delay timestamp: %s", dt_util.parse_datetime(f"{now_date} {row["departure_time"]}").replace(tzinfo=timezone), depart_time_corrected)
else:
depart_time_corrected = dt_util.parse_datetime(f"{now_date} {row["departure_time"]}").replace(tzinfo=timezone)
if delay_rt != '-':
depart_time_corrected = dt_util.parse_datetime(f"{now_date} {row["departure_time"]}").replace(tzinfo=timezone) + datetime.timedelta(seconds=delay_rt)
_LOGGER.debug("Departure time: %s, corrected with delay: %s", dt_util.parse_datetime(f"{now_date} {row["departure_time"]}").replace(tzinfo=timezone), depart_time_corrected)
else:
depart_time_corrected = dt_util.parse_datetime(f"{now_date} {row["departure_time"]}").replace(tzinfo=timezone)

if depart_time_corrected > now.replace(tzinfo=timezone):
timetable.append({"departure": row["departure_time"], "departure_realtime": departure_rt, "delay_realtime": delay_rt, "date": now_date, "stop_name": row['stop_name'], "route": row["route_short_name"], "route_long": row["route_long_name"], "headsign": row["trip_headsign"], "trip_id": row["trip_id"], "direction_id": row["direction_id"], "icon": self._icon})

if (
"tomorrow" in row
Expand Down
3 changes: 3 additions & 0 deletions custom_components/gtfs2/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ def _update_attrs(self): # noqa: C901 PLR0911
"gtfs_updated_at"]
self._attributes["device_tracker_id"] = self.coordinator.data[
"device_tracker_id"]
self._attributes["offset"] = self.coordinator.data[
"offset"]

# Add next departures with their lines
self._attributes["next_departures_lines"] = {}
Expand All @@ -522,6 +524,7 @@ def _update_attrs(self): # noqa: C901 PLR0911
self._attributes["next_departures_lines"] = stop["departure"]
self._attributes["latitude"] = stop["latitude"]
self._attributes["longitude"] = stop["longitude"]


self._attr_extra_state_attributes = self._attributes
return self._attr_extra_state_attributes
1 change: 1 addition & 0 deletions custom_components/gtfs2/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"stop_incorrect": "Start and/or End destination incorrect, possibly no transport 'today' or not in same direction, check logs",
"generic_failure": "Overall failure, check logs",
"no_data_file": "Data collection issue: URL incorrect or filename not in the correct folder",
"stop_limit_reached": "More than 15 stops found for this radius. \n Risking an impact on system performance. \n Please select a smaller radius",
"no_zip_file": "Data collection issue: ZIP file not in the correct folder"
},
"abort": {
Expand Down

0 comments on commit b6d034d

Please sign in to comment.