Hi All,
I just came across an unofficial TransPerth API which gives access to Train, Bus and Ferry times as well as the ability to check your SmartRider balance.
I’m no developer but perhaps someone out there has the ability to integrate this to HA…
Hi All,
I just came across an unofficial TransPerth API which gives access to Train, Bus and Ferry times as well as the ability to check your SmartRider balance.
I’m no developer but perhaps someone out there has the ability to integrate this to HA…
You should be able to use rest sensor for what you want.
Yeah, I found another site talking about REST sensors but the links it had to an official API didn’t work. I’ll have to investigate it further.
Hi Dave
Did you have any success with this?
No, unfortunately not.
I’ve been using the following rest command for a while to get train schedules for a given train line and station.
rest_command:
get_next_train_time:
url: "https://www.transperth.wa.gov.au/API/TrainLiveTimes/LiveStatus/{{ line_name }}/{{ station_name }}"
method: GET
headers:
ModuleId: 5111
TabId: 248
I then have a script with a couple fields with the expected station/line names which make it easier to use in automations.
get_next_train_times:
alias: Get Next Train Times
sequence:
- service: rest_command.get_next_train_time
metadata: {}
data:
line_name: '{{ line }}'
station_name: '{{ station }}'
response_variable: api_result
- variables:
trips: "{% set script_ns = namespace(to_perth=[], from_perth=[]) %} \n{% if
api_result.content.result == 'success' %}\n {% for trip in api_result.content.data.StatusDetailList
%}\n {% set departure_hours, departure_mins = trip.Departure.split(':')
%}\n {% set departure_time = now().replace(hour=departure_hours|int, minute=departure_mins|int)
%}\n {% set diff_seconds = as_timestamp(departure_time) - as_timestamp(now())
%}\n {% set diff_minutes = max((diff_seconds / 60) | round(0, 'ceil'),
0) %}\n {% set trip = dict(trip, **{'mins_away': diff_minutes}) %}\n {%
if trip.Destination == 'Perth' %}\n {% set script_ns.to_perth = script_ns.to_perth
+ [trip] %}\n {% elif trip.Destination != 'Perth' %}\n {% set script_ns.from_perth
= script_ns.from_perth + [trip] %}\n {% endif %}\n {% endfor %}\n{% endif
%}\n{ \"to_perth\": {{ script_ns.to_perth }}, \"from_perth\": {{ script_ns.from_perth
}} }\n"
- stop: ''
response_variable: trips
mode: single
icon: mdi:train
fields:
line:
selector:
select:
options:
- All
- Airport Line
- Armadale Line
- Fremantle Line
- Yanchep Line
- Mandurah Line
- Midland Line
- Thornlie Line
name: Line
description: Which train line?
required: true
station:
selector:
select:
options:
- Airport Central Stn
- Armadale Stn
- Ashfield Stn
- Aubin Grove Stn
- Bassendean Stn
- Bayswater Stn
- Beckenham Stn
- Bull Creek Stn
- Burswood Stn
- Butler Stn
- Canning Bridge Stn
- Cannington Stn
- Carlisle Stn
- Challis Stn
- City West Stn
- Claisebrook Stn
- Claremont Stn
- Clarkson Stn
- Cockburn Central Stn
- Cottesloe Stn
- Currambine Stn
- Daglish Stn
- East Guildford Stn
- East Perth Stn
- Edgewater Stn
- Elizabeth Quay Stn
- Fremantle Stn
- Glendalough Stn
- Gosnells Stn
- Grant Street Stn
- Greenwood Stn
- Guildford Stn
- High Wycombe Stn
- Joondalup Stn
- Karrakatta Stn
- Kelmscott Stn
- Kenwick Stn
- Kwinana Stn
- Lakelands Stn
- Leederville Stn
- Loch Street Stn
- Maddington Stn
- Mandurah Stn
- Maylands Stn
- McIver Stn
- Meltham Stn
- Midland Stn
- Mosman Park Stn
- Mt Lawley Stn
- Murdoch Stn
- North Fremantle Stn
- Oats Street Stn
- Perth Stadium Stn
- Perth Stn
- Perth Underground Stn
- Queens Park Stn
- Redcliffe Stn
- Rockingham Stn
- Seaforth Stn
- Shenton Park Stn
- Sherwood Stn
- Showgrounds Stn
- Stirling Stn
- Subiaco Stn
- Success Hill Stn
- Swanbourne Stn
- Thornlie Stn
- Victoria Park Stn
- Victoria Street Stn
- Warnbro Stn
- Warwick Stn
- Wellard Stn
- Welshpool Stn
- West Leederville Stn
- Whitfords Stn
- Woodbridge Stn
name: Station
description: Which station?
required: true
Hope that helps someone do something cool.
I finally got around to implementing this code and it seems to work, but where does the response end up? The script runs without issue but nothing else happens and I can’t find any entity with the response data.
How are you displaying it?
Thank you so much for this. I have added this rest_command and some custom sentences to my voice assistant pipeline, and now I can ask my assist when the next train to Perth departs my local station. I like that the API tells you if there are delays.
Would you mind sharing the sentences etc so I can try to implement the same thing? Sounds handy
I have an automation that triggers when I arrive at my local station and it runs the script then sends me a notification with how many minutes until the next train so I know if i need to go quickly or if I’ve got some time.
I thought about some interface or dashboard that said I need to leave in the next x minutes to make the train but they come so frequently and I have no real start time for work so there wasn’t any benefit.
alias: Notification - Train Time
description: ""
mode: single
triggers:
- entity_id: person.chris
zone: zone.edgewater_train_station
event: enter
id: Chris Arrived At Station
trigger: zone
conditions:
- condition: time
after: "06:00:00"
before: "10:30:00"
weekday:
- fri
- wed
- mon
- tue
- thu
actions:
- choose:
- conditions:
- condition: trigger
id:
- Chris Arrived At Station
sequence:
- repeat:
sequence:
- metadata: {}
data:
line: Yanchep Line
station: Edgewater Stn
response_variable: train_times_response
action: script.get_next_train_times
- variables:
next_train: "{{ train_times_response.to_perth | first }}"
second_train: "{{ train_times_response.to_perth[1] }}"
- metadata: {}
data:
title: Next Train To Perth
message: |-
{% if next_train is defined %}
Next train at {{ next_train.Departure }} in {{ next_train.mins_away }} mins ({{ next_train.StatusDetail }})
{% if next_train.mins_away | int <= 5 %}
The train after that is due at {{ second_train.Departure }} in {{ second_train.mins_away }} mins ({{ second_train.StatusDetail }})
{% endif %}
{% else %}
There are no trains to Perth on the Yanchep Line scheduled.
{% endif %}
action: notify.mobile_app_chris_mobile
- if:
- condition: template
value_template: "{{ train_times_response.to_perth | length == 0 }}"
then:
- stop: No trains scheduled
- delay:
hours: 0
minutes: >-
{{ max(train_times_response.to_perth[0].mins_away | int,
1.5 ) }}
seconds: 0
milliseconds: 0
while:
- condition: zone
entity_id: person.chris
zone: zone.edgewater_train_station
enabled: true
Awesome work @Chris112 - love it. I’ve been wanting to add this and you’ve made it super easy for me to do it! Working nicely.
where did you get the info for this? any idea how to get info for buses also?
I clicked around the transperth website to check out if they had some kind of API for train or bus times: Bus Route 209 Timetable
I’ve been messing around with the Transperth live bus time APIs to try and see if the information is available and it looks like most of it is, here’s a breakdown of what I did to load the data. It requires a bit more work than the trains.
I created a python service you can add to HA and call within some kind of automation to load bus stops by bus number or next bus times at a bus stop