Skip to content

Commit

Permalink
Merge pull request #8 from warrior25/gtfs
Browse files Browse the repository at this point in the history
Timetable data from GTFS files
  • Loading branch information
warrior25 committed Apr 8, 2024
2 parents 79a4f8a + 5cc1798 commit 51fd50c
Show file tree
Hide file tree
Showing 6 changed files with 463 additions and 392 deletions.
49 changes: 33 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,45 @@ Each station creates a sensor which contains data for departures from that stati

`realtime` - Indicates if the data is pulled from realtime vehicle monitoring or timetable data

## Frontend example
## Frontend examples

Simple frontend examples using [custom:html-template-card](https://github.com/PiotrMachowski/Home-Assistant-Lovelace-HTML-Jinja2-Template-card)

Simple frontend example using [custom:html-template-card](https://github.com/PiotrMachowski/Home-Assistant-Lovelace-HTML-Jinja2-Template-card)
![Example](https://github.com/warrior25/HA-Nysse/raw/main/docs/frontend_example.jpg)

```yaml
type: custom:html-template-card
title: Keskustori D
ignore_line_breaks: true
content: >
{% set departures = state_attr('sensor.keskustori_d_0015','departures')
%} {% for i in range(0, departures | count, 1) %}
<div style="display:grid; grid-template-columns: 2fr 1fr; font-size: 20px;
padding: 10px 0px 0px 0px"> <div>{{ departures[i].line }} - {{
departures[i].destination }}</div><div style="text-align: right">{% if
departures[i].realtime %}<ha-icon style="color:green; padding: 0px 10px 0px
0px" icon="mdi:signal-variant"></ha-icon>{% endif %} {% if
departures[i].time_to_station | int < 21 %} {{departures[i].time_to_station}}
min {% else %}{{departures[i].departure}}{% endif %}</div></div>
{% endfor %}
{% set departures = state_attr('sensor.keskustori_d_0015','departures')
%} {% for i in range(0, departures | count, 1) %}
<div style="display:grid; grid-template-columns: 2fr 1fr; font-size: 20px;
padding: 10px 0px 0px 0px"> <div>{{ departures[i].line }} - {{
departures[i].destination }}</div><div style="text-align: right">{% if
departures[i].realtime %}<ha-icon style="color:green; padding: 0px 10px 0px
0px" icon="mdi:signal-variant"></ha-icon>{% endif %} {% if
departures[i].time_to_station | int < 21 %} {{departures[i].time_to_station}}
min {% else %}{{departures[i].departure}}{% endif %}</div></div>
{% endfor %}
```

![Service Alerts](https://github.com/warrior25/HA-Nysse/blob/d8fe99019902ee1c8edbfe302f086c5f6c5a6a5c/docs/service_alerts.jpg)

```yaml
type: custom:html-template-card
ignore_line_breaks: true
title: Service Alerts
content: >
{% set alerts = state_attr('sensor.nysse_service_alerts','alerts')
%} {% for i in range(0, alerts | count, 1) %}
<b>{{ alerts[i].start.strftime('%d.%m.%Y') }} - {{ alerts[i].end.strftime('%d.%m.%Y') }}</b><br>
{{ alerts[i].description }}<br><br>
{% endfor %}
```

## Advanced usage
Expand All @@ -63,5 +80,5 @@ content: >

## Known issues / limitations

- Nysse API sometimes functions incorrectly. Errors logged with `Nysse API error` can be resolved on their own over time.
- Line icons are resolved from a hardcoded list of tram lines. If new tram lines are built, the list needs to be updated in `const.py`.
- Nysse API sometimes functions incorrectly. Errors logged with `Nysse API error` can be resolved on their own over time.
- Line icons are resolved from a hardcoded list of tram lines. If new tram lines are built, the list needs to be updated in `const.py`.
30 changes: 24 additions & 6 deletions custom_components/nysse/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,21 @@
DEFAULT_TIMELIMIT,
DOMAIN,
)
from .fetch_api import fetch_lines, fetch_stop_points
from .fetch_api import get_route_ids, get_stops


def format_stops(stops):
"""Format the stops data into a list of dictionaries with label and value."""
return sorted(
[
{
"label": f"{stop['stop_name']} ({stop['stop_id']})",
"value": stop["stop_id"],
}
for stop in stops
],
key=lambda x: x["label"],
)


@config_entries.HANDLERS.register(DOMAIN)
Expand All @@ -32,9 +46,11 @@ def __init__(self) -> None:
async def async_step_user(self, user_input: Optional[dict[str, Any]] = None):
errors = {}

self.stations = await fetch_stop_points(True)
if len(self.stations) == 0:
stops = await get_stops()
# TODO: check error handling
if len(stops) == 0:
errors["base"] = "no_stop_points"
self.stations = format_stops(stops)

data_schema = {
vol.Required(CONF_STATION): selector(
Expand Down Expand Up @@ -75,7 +91,7 @@ async def async_step_user(self, user_input: Optional[dict[str, Any]] = None):
async def async_step_options(self, user_input: Optional[dict[str, Any]] = None):
errors = {}

lines = await fetch_lines(self.data[CONF_STATION])
lines = await get_route_ids(self.data[CONF_STATION])
if len(lines) == 0:
errors["base"] = "no_lines"

Expand Down Expand Up @@ -148,9 +164,11 @@ async def async_step_init(
errors: dict[str, str] = {}

if user_input is not None:
self.stations = await fetch_stop_points(True)
if len(self.stations) == 0:
stops = await get_stops()
# TODO: check error handling
if len(stops) == 0:
errors["base"] = "no_stop_points"
self.stations = format_stops(stops)

for station in self.stations:
if station["value"] == self.config_entry.data[CONF_STATION]:
Expand Down
27 changes: 5 additions & 22 deletions custom_components/nysse/const.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Constants for the Nysse component."""

DOMAIN = "nysse"

PLATFORM_NAME = "Nysse"
Expand All @@ -11,29 +13,10 @@
DEFAULT_ICON = "mdi:bus-clock"
TRAM_LINES = ["1", "3"]

WEEKDAYS = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
]

DEFAULT_TIME_ZONE = "Europe/Helsinki"

JOURNEY = "journey"
DEPARTURE = "departure"
AIMED_ARRIVAL_TIME = "aimedArrivalTime"
AIMED_DEPARTURE_TIME = "aimedDepartureTime"
EXPECTED_ARRIVAL_TIME = "expectedArrivalTime"
EXPECTED_DEPARTURE_TIME = "expectedDepartureTime"

STOP_URL = "https://data.itsfactory.fi/journeys/api/1/stop-monitoring?stops={0}"
STOP_POINTS_URL = "http:https://data.itsfactory.fi/journeys/api/1/stop-points/"
JOURNEYS_URL = "http:https://data.itsfactory.fi/journeys/api/1/journeys?stopPointId={0}&dayTypes={1}&startIndex={2}"
LINES_URL = "https://data.itsfactory.fi/journeys/api/1/lines?stopPointId={0}"
SERVICE_ALERTS_URL = (
"https://data.itsfactory.fi/journeys/api/1/gtfs-rt/service-alerts/json"
)
GTFS_URL = (
"https://data.itsfactory.fi/journeys/files/gtfs/latest/extended_gtfs_tampere.zip"
)
Loading

0 comments on commit 51fd50c

Please sign in to comment.