With the recent launch of Ottawa’s long-awaited light rail transit, I thought it would be useful to have a sensor to tell me when the next bus is arriving. Fortunately, I was able to implement this without a PR using the RESTful and Template sensors. I also put together a TTS script, which I plan to use to automate announcements.
If you’d like to do the same, just register for access to the API here, and plug your application ID, API key, stop number, and route number into the resource
URL in the snippet below.
If you have any trouble, let me know.
sensor:
- platform: rest
name: oc_transpo
resource: >
https://api.octranspo1.com/v2.0/GetNextTripsForStop
?appID=XXXXXX
&apiKey=XXXXXX
&routeNo=XX
&stopNo=XXXX
&format=json
method: POST
value_template: 'OK'
json_attributes:
- GetNextTripsForStopResult
- platform: template
sensors:
next_bus:
friendly_name: "Next Bus"
unit_of_measurement: "min"
value_template: >
'{{ states.sensor.oc_transpo.attributes["GetNextTripsForStopResult"]
["Route"]["RouteDirection"]["Trips"]["Trip"][0]["AdjustedScheduleTime"] }}'
script:
next_bus_tts:
alias: Next Bus TTS
sequence:
- service: tts.amazon_polly_say
data_template:
message: 'The next bus will arrive in {{ states("sensor.next_bus") }} minutes.'
4 Likes
Hi I had problem with my google saying “…unknown minutes”, but I solved the issue by making both resource & value_template as one single line solved the problem!
thanks for this post!
Just wanted to say thanks, I’ve been using this for several months now. However, I received an email from the City today regarding API changes coming this month. I’m not technical enough to know if the above is impacted by it.
Here is the link to the new API documentation.
https://www.octranspo.com/en/plan-your-trip/travel-tools/developers/dev-doc/beta-documentation-api-version-2-0
I tested the new version, and it seems to still work if you switch 1.3
to 2.0
and the JSON
to json
. I’ve updated the post above to reflect this. Please test this out and let me know how it goes.
Thanks! That was fast. I didn’t think their API changes were going to be in effect for a couple more weeks. I’ll update it next week. Very appreciated.
1 Like
@michaeldavie Does this still work ??? I keep getting error to retrieve routes? eg: route 72 and stop id 7754. then it will say error
I haven’t used this in years, so it’s entirely possible that it doesn’t work any more.
The current documentation is below.
https://www.octranspo.com/en/plan-your-trip/travel-tools/developers/dev-doc/
I’m new to HA but here’s my attempt at the current API of OC transpo. This will give a state of “OK” (as otherwise the JSON is too large) and then saves off the attributes for the next bus (if any), the last time the schedule was updated, whether it’s the last of the day, how many minutes from “now” the bus is due (don’t laugh, Ottawans) and the destination.
There’s other options for actual location and speed but my bus route doesn’t have any of those (although apparently this fiscal they’re getting kitted out).
I’m going to try some of the other options on here for varying the update interval with a script so this can be polled a bit more often during the day and stop overnight, but that’s a slower job.
- platform: rest
resource: "https://api.octranspo1.com/v2.0/GetNextTripsForStop"
scan_interval: 900
params:
format: JSON
appID: !secret octranspo_appid
apiKey: !secret octranspo_apikey
stopNo: xxx
routeNo: yyy
name: octranspo_bus_info
icon: directions_bus
value_template: OK
json_attributes_path: '$.GetNextTripsForStopResult.Route.RouteDirection.Trips.Trip[0]'
json_attributes:
- TripStartTime
- AdjustmentAge
- LastTripOfSchedule
- AdjustedScheduleTime
- TripDestination
1 Like
The time from that API is the scheduled time, OCtranspo is a bit infamous for not actually keeping to that schedule, but they appear to be improving in reporting it. I’m using a helper to apply the AdjustedScheduleTime (which is helpfully in minutes from this API call) if the AdjustmentAge is set (it’s in decimal fractions of minutes, obviously).
{% if state_attr("sensor.octranspo_bus_info",
"AdjustmentAge") != -1 -%}
{{ states.sensor.octranspo_bus_info.last_updated + timedelta(minutes=int(state_attr("sensor.octranspo_bus_info", "AdjustedScheduleTime"))) }}
{% elif state_attr("sensor.octranspo_bus_info",
"TripStartTime") %}
{{ today_at(state_attr("sensor.octranspo_bus_info",
"TripStartTime")).isoformat() }}
{%- else -%}
unavailable
{%- endif %}
I’ve had some ideas of when to refresh more often but I’ve settled on just giving my wife a button on the dash that does it so she can press it when she’s actually waiting for a bus.
1 Like