GTFS Realtime Component

I’m happy to announce the beta version of the gtfs realtime component I have been working on. I’ve been using it with my local GTFS feeds for several months now with now issues. The component along with installation instructions are available on github.

I’d love to hear any feedback, and about good gtfs feed sources. If you have trouble finding the feed for your local area, feel free to post, and I (along with others) will try to help.

1 Like

hey im glad you were able to get this as a component. your github readme says that the stopid and the route are optional, however both were required for it to get this far. i’m now getting an error on startup. looks like an import error, see last line.

heres my yaml:

- platform: gtfs_realtime
  trip_update_url: 'http://www.vre.org/gtfs-realtime/TripUpdateFeed'
  vehicle_position_url: 'http://www.vre.org/gtfs-realtime/VehiclePositionFeed'
  departures:
    - name: Leeland Rd to Alexandria
      route: 2 
      stopid: 0000000000000000000000000000000B

and my error:

    2017-06-28 08:52:22 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up platform gtfs_realtime
Traceback (most recent call last):
  File "/srv/hass/lib/python3.4/site-packages/homeassistant/helpers/entity_component.py", line 160, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
  File "/usr/lib/python3.4/asyncio/tasks.py", line 372, in wait_for
    return fut.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/hass/.homeassistant/custom_components/sensor/gtfs_realtime.py", line 68, in setup_platform
    departure.get(CONF_NAME)
  File "/home/hass/.homeassistant/custom_components/sensor/gtfs_realtime.py", line 83, in __init__
    self.update()
  File "/home/hass/.homeassistant/custom_components/sensor/gtfs_realtime.py", line 128, in update
    self.data.update()
  File "/srv/hass/lib/python3.4/site-packages/homeassistant/util/__init__.py", line 303, in wrapper
    result = method(*args, **kwargs)
  File "/home/hass/.homeassistant/custom_components/sensor/gtfs_realtime.py", line 142, in update
    positions = self._get_vehicle_positions() if self._vehicle_position_url else {}
  File "/home/hass/.homeassistant/custom_components/sensor/gtfs_realtime.py", line 184, in _get_vehicle_positions
    from google.transit import gtfs_realtime_pb2
ImportError: No module named 'google.transit'

l

Rather than show the “time until” the next train/bus will arrive can you instead show the expected “arrival time” for example just 2:32pm?

That’s a really good idea, and it would definitely made sense to change that - I haven’t been actively working on this for a while, but feel free to submit a pull request if you have time.

2017-08-06 18:33:52 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.gtfs_realtime
2017-08-06 18:33:53 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up platform gtfs_realtime
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 164, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
  File "/usr/lib/python3.4/asyncio/tasks.py", line 372, in wait_for
    return fut.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 68, in setup_platform
    departure.get(CONF_NAME)
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 83, in __init__
    self.update()
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 128, in update
    self.data.update()
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/util/__init__.py", line 303, in wrapper
    result = method(*args, **kwargs)
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 142, in update
    positions = self._get_vehicle_positions() if self._vehicle_position_url else {}
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 187, in _get_vehicle_positions
    feed.ParseFromString(response.content)
  File "/usr/local/lib/python3.4/dist-packages/google/protobuf/message.py", line 185, in ParseFromString
    self.MergeFromString(serialized)
  File "/usr/local/lib/python3.4/dist-packages/google/protobuf/internal/python_message.py", line 1008, in MergeFromString
    if self._InternalParse(serialized, 0, length) != length:
  File "/usr/local/lib/python3.4/dist-packages/google/protobuf/internal/python_message.py", line 1034, in InternalParse
    new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
  File "/usr/local/lib/python3.4/dist-packages/google/protobuf/internal/decoder.py", line 868, in SkipField
    return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
  File "/usr/local/lib/python3.4/dist-packages/google/protobuf/internal/decoder.py", line 838, in _RaiseInvalidWireType
    raise _DecodeError('Tag had invalid wire type.')
google.protobuf.message.DecodeError: Tag had invalid wire type..

my config

sensor 2:
  - platform: gtfs_realtime
    trip_update_url: 'http://gtfs.ovapi.nl/new/gtfs-realtime-OVapi.proto'
    vehicle_position_url: 'http://gtfs.ovapi.nl/new/gtfs-realtime-OVapi.proto'
    departures:
    - name: 401 to station
      route: 1762
      stopid: 417133
    - name: 402 to station
      route: 1761
      stopid: 417133
    - name: 403 to station
      route: 42344
      stopid: 417133

Worked once (I think by mistake) but after a reboot it never showed again and came up with these error messages…

I am on a completely clean install of 0.53.1 and still no chance. @tom can you please explain how you got it to work?

I get these errors

2017-09-19 13:29:57 INFO (SyncWorker_10) [homeassistant.util.package] Attempting install of https://github.com/google/gtfs-realtime-bindings/archive/619187a2c99d7396cd56bf9c24d302d2373acff2.zip#gtfs-realtime-bindings==0.0.5&egg=gtfs-realtime-bindings&subdirectory=python
2017-09-19 13:29:57 WARNING (MainThread) [homeassistant.setup] Setup of sensor is taking over 10 seconds.
2017-09-19 13:30:23 INFO (SyncWorker_1) [homeassistant.util.package] Attempting install of protobuf==3.0.0a3
2017-09-19 13:31:20 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.gtfs_realtime
2017-09-19 13:31:20 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up platform gtfs_realtime
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_component.py", line 164, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 352, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.6/asyncio/futures.py", line 244, in result
    raise self._exception
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 68, in setup_platform
    departure.get(CONF_NAME)
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 83, in __init__
    self.update()
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 128, in update
    self.data.update()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/util/__init__.py", line 306, in wrapper
    result = method(*args, **kwargs)
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 142, in update
    positions = self._get_vehicle_positions() if self._vehicle_position_url else {}
  File "/var/opt/homeassistant/custom_components/sensor/gtfs_realtime.py", line 187, in _get_vehicle_positions
    feed.ParseFromString(response.content)
  File "/var/opt/homeassistant/deps/lib/python3.6/site-packages/google/protobuf/message.py", line 185, in ParseFromString
    self.MergeFromString(serialized)
  File "/var/opt/homeassistant/deps/lib/python3.6/site-packages/google/protobuf/internal/python_message.py", line 1008, in MergeFromString
    if self._InternalParse(serialized, 0, length) != length:
  File "/var/opt/homeassistant/deps/lib/python3.6/site-packages/google/protobuf/internal/python_message.py", line 1034, in InternalParse
    new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
  File "/var/opt/homeassistant/deps/lib/python3.6/site-packages/google/protobuf/internal/decoder.py", line 868, in SkipField
    return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
  File "/var/opt/homeassistant/deps/lib/python3.6/site-packages/google/protobuf/internal/decoder.py", line 838, in _RaiseInvalidWireType
    raise _DecodeError('Tag had invalid wire type.')
google.protobuf.message.DecodeError: Tag had invalid wire type.
2017-09-19 13:31:20 INFO (MainThread) [homeassistant.setup] Setup of domain sensor took 92.9 seconds.

So I dug into this like a mad dog and got it to work by doing this

- platform: gtfs_realtime
  trip_update_url: 'http://gtfs.ovapi.nl/new/tripUpdates.pb'
  vehicle_position_url: 'http://gtfs.ovapi.nl/new/vehiclePositions.pb'

Problem I now have or noticed is that this component is not timezone aware.

How to make it so?

My bus times shown are exactly one hour behind. Everything else works correct.
As you can see I have the HA display the current time which it takes from the RPi which it runs on.

time

Timezone is set exactly right on the device (also NTP for time sync) and in the configuration.yaml.

  time_zone: Europe/Amsterdam

Suggestions?

Hi @dennisaion, did you ever figured this out? I’d like to display some cards with departure times in Hass but have no idea where to start…

I wanted to get this working with the Transport for NSW real-time GTFS for Sydney, but that requires authentication with an API key. So I’ve forked this component, adding an optional api_key parameter. I’ve also started to add some more error checking and logging, which should hopefully shed some light on the root cause of most of the “Tag had invalid wire type” errors, or at least the ones I experienced.

Not sure about the timezone issues though. Presumably Europe/Amsterdam was at UTC+1 at the time. All I know for sure is that the TfNSW feed I’m looking at shows start times in localtime without an offset. It looks like the code assumes that will be case, so if a feed is sending times in UTC they’ll end up being displayed in UTC.

Anyway, if anybody is interested, my fork is currently at https://github.com/phardy/hass-gtfs-realtime

1 Like

Im trying to find URLs for NYC MTA Subways. I can find their real time GTFS data but I do not see any urls for the train positions etc. What do I do?

Does this still work? I followed the instructions and it can’t find the component. Might be because I’m running hass.io?

I was able to get a little farther. Seems like the file structure has changed, I had to change Sensor/ to gtfs_realtime/ and gtfs_realtime to sensor.py. I also added a blank init.py. Now i’m getting this error which seems similar to the errors above

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 159, in _async_setup_platform
    await asyncio.wait_for(asyncio.shield(task), SLOW_SETUP_MAX_WAIT)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 442, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/gtfs_realtime/sensor.py", line 68, in setup_platform
    departure.get(CONF_NAME)
  File "/config/custom_components/gtfs_realtime/sensor.py", line 83, in __init__
    self.update()
  File "/config/custom_components/gtfs_realtime/sensor.py", line 128, in update
    self.data.update()
  File "/usr/src/homeassistant/homeassistant/util/__init__.py", line 240, in wrapper
    result = method(*args, **kwargs)
  File "/config/custom_components/gtfs_realtime/sensor.py", line 142, in update
    positions = self._get_vehicle_positions() if self._vehicle_position_url else {}
  File "/config/custom_components/gtfs_realtime/sensor.py", line 184, in _get_vehicle_positions
    from google.transit import gtfs_realtime_pb2
ModuleNotFoundError: No module named 'google.transit'