Transports en commun (GTFS) smart home integration, free and open source

Next departures and traffic alerts for any French transit network, from open data.
The next departures at your stops and the disruptions of their lines, for any French public transport network that publishes its timetable as GTFS on transport.data.gouv.fr: TER and TGV (SNCF), Naolib (Nantes), STAR (Rennes), TaM (Montpellier), M (Grenoble), Ilévia (Lille), Stan (Nancy), and hundreds more. Real time (GTFS-RT) is used when the network publishes it, about 220 datasets. For about twenty networks without GTFS-RT, SIRI real time is used instead (see "SIRI real time"). Everything comes from open data: no account, and an API key only for some SIRI feeds.
For Toulouse, Lyon, Île-de-France or Bordeaux, prefer the dedicated integrations (Tisséo, TCL, IDFM, TBM): they go further (bikes, metro in real time…). Île-de-France is too big for this integration anyway.
This integration is a community project, not affiliated with transport.data.gouv.fr, SNCF or any transport network.
What you get
- One device per watched stop: for each line and direction, the minutes before the next departure and before the following one; the three soonest departures as text; the traffic info of its lines.
- "Next departures" widget: the board of a stop, departures tracked in real time in green, timetable times marked "≈".
- "Disruption on a followed line" scene trigger: a new traffic alert on a line of your stops, or on the whole network.
- "Read the next departures" scene action, with a sentence ready to send ("Tram 1 towards François Mitterrand at Commerce: in 3 and 7 min").
- Up to 3 networks and 20 stops (for example the urban network of your city and SNCF for the station).
Real time or timetable? When the network publishes a GTFS-RT "TripUpdates" feed, departures are corrected (delays, cancellations, skipped stops) and shown without "≈". Otherwise, or for the vehicles not tracked, they are the planned times, marked "≈" or "scheduled". The network search tells what each one publishes.
Requirements
- Gladys 5.1 or later, with Internet access.
- To list the stops around your home: the position of your house in
Gladys (Settings → Houses). The integration asks for it at installation
(
location): it reads the coordinates of your houses, nothing else, and only to sort the stops by distance. Without it, search by name. - From 1 to 80 MB of disk under
/dataper network (the timetable archive, updated once a day): 6 MB for SNCF, 26 MB for Naolib.
Installation
- In Gladys, go to Integrations → Install from GitHub and enter
https://github.com/guim31/gladys-gtfs. - Open the Configuration tab of the integration and choose the language of the texts (French by default).
- Add your network, then your stops, with the actions of the same screen (below), and create their devices in the Discover tab.
Configuration
Settings
-
Language of the texts: feature names, line names, scene sentences. Names are set when a device is created: change the language first, create the devices next.
-
Refresh interval: 30 seconds, 1 minute (default), 2 or 5 minutes.
-
Real time: on by default. Off, the integration only uses the timetable and no longer downloads the realtime feeds.
-
SIRI API keys (secret, optional): only for a network whose real time is SIRI and needs a key (see "SIRI real time").
Add a network
- Find a network: a network name, a city or a region ("Naolib",
"Rennes", "TER"…). Each result gives its name, its identifier and the real
time it publishes, for example
• Naolib [tdg84101] — … — real time : departures. Some networks publish two files (current and upcoming timetable): take the current one. - Add a network: its identifier (
tdg…), or its name when it is unique. The integration downloads its timetable and reads it: up to a minute for a big network.
A network outside the catalog: give the address of its GTFS file
(https://….zip) in Identifier, name or GTFS URL and, if you know them,
the addresses of its GTFS-RT feeds in GTFS-RT URLs. Name shown
replaces the name put before the stop names.
SIRI or SIRI Lite URL (optional): the SIRI real time of a network outside the catalog, used when it has no GTFS-RT.
Add a stop
- Find a stop: type a name ("hotel dieu" finds "Hôtel Dieu", accents and
case do not matter), or leave it empty to list the 10 stops closest to
your home. Each result gives its lines, its distance and its identifier in
brackets, for example
• Commerce [20] — 1, 2, 3, C2, C3 — 90 m. With several networks, the Network field narrows the search. - Add a stop: its name, or its identifier when several stops share a name. Lines is optional: "1, C2" keeps these two lines only; empty, every line. A big station has dozens of lines: pick yours (a device keeps 12 lines and directions at most).
- Open the Discover tab and create the device.
Adding a stop already watched changes its lines: Gladys then offers to update the device in the Discover tab.
SIRI identifier (optional, SIRI networks only): when "Show what is
watched" says the SIRI server does not know the stop, its MonitoringRef
(one per stop point, separated by commas).
Remove, check the feeds
- Remove a stop or a network: its name or identifier. Removing a network also removes its stops and deletes its timetable. Devices stay in Gladys until you delete them.
- Show what is watched: for each network, the date of the timetable, the age of the realtime data, the number of trips tracked, the volume downloaded per hour, the watched stops, and the last error if any.
Devices
Stop
For each line and direction served (or the chosen lines):
| Feature | Type | Value |
|---|---|---|
| Tram 1 → François Mitterrand | duration (min) | minutes before the next departure |
| Tram 1 → François Mitterrand (next) | duration (min) | minutes before the following one |
And two texts for the whole stop:
- Next departures: the three soonest, e.g.
1 → Jamet 2 min · C2 → Gare Sud ≈4 min("≈" = timetable). - Traffic info: the titles of the current disruptions on its lines, or "No disruption".
0 means the vehicle is at the stop or arriving (less than a minute);
1440 means no departure in the next 24 hours (night, a line not running
that day). These values keep no history: a countdown re-read every minute
would fill the database for nothing.
The device name starts with the network name ("Naolib · Commerce"). The direction of a train is its terminus: SNCF puts the train number there, the integration replaces it.
Dashboard widget
Next departures: choose a stop. One row per line and direction (ten at most, those with a departure first): "3 · 7 min" in green when it is real time, "≈ 3 · 7 min" in blue for the timetable. The caption lists the disruptions of its lines (⚠), or recalls what "≈" means.
Scene trigger
Disruption on a followed line: a new traffic alert appears on a line of your watched stops (the line filter of a stop narrows it), or on the whole network (strike, closures). Filters: scope (a followed line, the whole network, or empty for both) and line (as written by the network: A, C1, 15). Variables: scope, network, line, title, details (plain text), link. An alert is announced once; those already there when you add a stop are not. It needs a network publishing its alerts as GTFS-RT ("alerts" in the network search).
For "the next bus is less than 5 minutes away", use the Gladys "Device state change" trigger on the countdown of the stop: it already compares values.
Scene action
Read the next departures: a watched stop and, optionally, a line. Outputs: sentence (up to four lines and directions, soonest first), stop, line and direction of the next departure, minutes to wait, minutes to the following one, real time (1) or timetable (0), number of lines with a departure. The sentences follow the language of the configuration.
Scene examples
- Time to go: at 7:45 on weekdays, "Read the next departures" at your
stop for line C2, then send
{{sentence}}by Telegram or announce it on a speaker. - My TER is disrupted: trigger "Disruption on a followed line", scope "a followed line", on the station added with your TER line: send the title and the details to your phone.
- Leave when the bus comes: trigger "Device state change", countdown of your bus below 4, condition "someone at home" and before 8:30: blink the hall light.
Data, refresh and bandwidth
| Data | Source | When |
|---|---|---|
| Catalog of networks | transport.data.gouv.fr (public API) | when a network is searched or added, kept a day |
| Timetable (GTFS) | the network, via transport.data.gouv.fr | once a day at most, kept in /data |
| Real time (GTFS-RT) | the network, or the catalog's proxy | at each refresh, every 15 min when nothing runs |
| Real time (SIRI) | the SIRI server of the network | per stop, at each refresh when a departure nears |
Real time is the heaviest: from a few kB to 2 MB per feed and per read. At one read a minute, Tisséo is about 100 MB per hour and SNCF about 90 MB per hour, during service hours; the Show what is watched action gives the volume of your networks. At night, with no departure within 90 minutes at your stops, the feeds are read every 15 minutes only, and a network without a watched stop is never read. Choose 2 or 5 minutes, or turn real time off, on a metered connection. The catalog and the open feeds set no quota; the transport.data.gouv.fr proxy accepts one read per feed every 30 seconds, and the integration keeps to it.
Licences: timetables are published under the Licence Ouverte (Etalab) or the ODbL depending on the network; adding a network shows its own, and transport.data.gouv.fr states it on the page of each dataset.
SIRI real time
About twenty networks publish their real time as SIRI or SIRI Lite rather than GTFS-RT: Ginko (Besançon), CTS (Strasbourg), the Pays de la Loire aggregate, Idelis, TUB, évolitY, Tanlib, Calibus, Tréma, R'Bus, Evalys, ARVI, TuT, Dordogne, BlaBlaCar Bus… The integration uses it when the network has no GTFS-RT; the search shows it as "real time : departures stop by stop (SIRI)". TCL and IDFM, which publish it too, have their dedicated integrations.
- Without a key: when the catalog publishes the access key of the server (the public "RequestorRef" of some SIRI servers) or the server is open, there is nothing to do.
- With a key: many servers ask for one, free, from the network; the page
of the dataset on transport.data.gouv.fr tells whom to ask (Ginko: its
support, by email; CTS: an account on its developer portal). Type it in
SIRI API keys in the configuration, as
Ginko = your-key; one per line (or separated by ";") when several networks need one; alone, a key serves them all. It never shows in the logs, in "Show what is watched" or in/data. The integration puts it where the server expects it:RequestorReffor SIRI, HTTP authentication for the CTS, theAccountKeyparameter for Mecatran servers. If your network wants it elsewhere, writename=key(URL parameter) orHeader-Name: key(HTTP header). - Stops: SIRI names the stops with its own identifiers. The integration asks the server for its list of stops (once a day) and links them to those of the timetable (same code, else same name within 100 m); without a list, it tries the public code of the stop, then its GTFS identifier. If "Show what is watched" reports a stop unknown to the server, give its SIRI identifier in SIRI identifier of "Add a stop".
- What changes: nothing on the device, the widget or the scenes. The departures given by the server replace the timetable of their line and direction, without "≈" when the vehicle is tracked. The disruptions (GeneralMessage, else SituationExchange) feed the traffic info and the scene trigger.
- Networks on the Okina gateway (Pays de la Loire, Tanlib, Calibus, Tréma, R'Bus, Evalys, TuT, Dordogne, CC Sud Gironde): Okina takes about one request every 30 seconds per address, for all these networks together. The integration keeps to it (35 s), so each watched stop point is read again every 35 s × the number of stop points: with one stop of two stop points, about every 70 s; beyond 2 or 3 stops, the real time comes too late to be useful. Watch one or two stops, and give if needed the SIRI identifier of the one stop point of your direction.
- Particular servers: a server answering without any stop nor departure almost always wants a key ("Show what is watched" says so). A server that offers no next departures by stop (only the estimated timetable of whole lines, like BlaBlaCar Bus) is not read: timetable only.
- Restraint: one request per stop point (four at most per stop) at each refresh, only for the stops with a departure within 90 minutes (every 15 minutes otherwise), and the disruptions every 5 minutes. Two stops of two stop points, one refresh a minute: about 250 requests per hour in the day, a few kB each. A server answering "too many requests" (429) is left alone for the delay it asks (5 minutes by default), the transport.data.gouv.fr proxy is asked once per 30 seconds at most. If your network sets a lower quota (see the page of its dataset), choose a refresh every 2 or 5 minutes.
Troubleshooting
- "… is too big for the 256 MB of the integration": the network exceeds what the Gladys container can read (Île-de-France, more than 400,000 trips a week, archive above 80 MB). Use the dedicated integration, or a smaller dataset of the same network.
- "Several matches": add the stop by its identifier, given by "Find a stop", or fill in the Network.
- Every time of a stop is marked ≈: the network publishes no real time, or not for these vehicles, or the feed is down (the "Show what is watched" action gives the last error). The timetable keeps working.
- "Real time (SIRI): access refused by the server": the key is missing
or wrong (SIRI API keys field). A key given in another form (URL
parameter, header) is written
name=keyorHeader-Name: key. - A line reads 1440: no departure in the next 24 hours (night service, a line not running that day, a diversion).
- No device in the Discover tab: add a network first, then a stop.
- The network moved (HTTP 404 error in "Show what is watched"): remove the network and add it again from the search.
- Logs: in Gladys, the integration logs tell which feed failed and why (never the full address, which may hold a key).
Limitations
- Networks publishing a GTFS: most French networks, but not all; three networks and twenty stops at most.
- Too big: Île-de-France (IDFM); the heaviest regional aggregates may be refused too.
- Real time depends on the network: some only publish alerts, or only track part of their vehicles.
- Line and direction names are those of the network's file (SNCF line codes such as "P2" or "C30", for example).
- A countdown is as precise as the refresh interval.
- Developed and tested with the real data (SNCF, Naolib, Tisséo, Aix-Marseille) and the SDK's fake Gladys, without a real Gladys instance: feedback welcome on the forum.
Credits
- Data: the transport networks, via transport.data.gouv.fr (Licence Ouverte or ODbL depending on the dataset).
- Reuses the code of the Tisséo integration by the same author; inspired by the TCL integration by prohand and the GTFS integrations of Home Assistant.
- Code under the Apache 2.0 licence.
Configuration settings
These are the settings Transports en commun (GTFS) asks for in its configuration screen in Gladys.
| Setting | Type | Required | Description |
|---|---|---|---|
| How it works | section | No | Add your network with the actions below (search the national catalog of transport.data.gouv.fr, or give the URL of a GTFS file), then your stops (by name, or around your home), and create their devices in the Discover tab. No account; a key only for some SIRI feeds. |
| Language of the texts | select | No | Language of the feature names, of the line names and of the sentences sent to your scenes. Feature names are set when a device is created. |
| Refresh interval | select | No | How often the departures are refreshed. Each refresh downloads the realtime feeds of your networks: from a few kB to 2 MB each (Tisséo: about 100 MB per hour at 1 minute). The integration status shows the volume of yours. At night, every 15 minutes only. |
| Real time | boolean | No | Correct the timetable with the vehicles tracked live and read the traffic alerts, when your network publishes them (GTFS-RT, else SIRI). Off: timetable only, no download at each refresh. |
| SIRI API keys | secret | No | Only for a network whose realtime is SIRI and needs a key (e.g. Ginko, CTS): one per line or separated by ";", as network = key (name or identifier). A single key alone serves every SIRI network. Never shown in the logs. |
How to install Transports en commun (GTFS) in Gladys
- In Gladys, open Integrations: Transports en commun (GTFS) appears in the catalog, next to the native integrations, with a community badge.
- Click Install. Gladys pulls the Docker image (
ghcr.io/guim31/gladys-gtfs:1.1.0), starts it in a sandbox isolated from the core, and generates the integration's interface (devices, discovery and configuration). - Open the Configuration screen of the integration, fill in the settings, and save.
- You can also install it directly from its repository URL: https://github.com/guim31/gladys-gtfs.
Transports en commun (GTFS) requires Gladys >=5.1.0. The catalog inside Gladys refreshes every hour, so a new version becomes available at most one hour after its release.
Not running Gladys yet? It is free and open source: follow the installation guide to get started.
About external integrations
Transports en commun (GTFS) is an external integration: a community integration packaged as a Docker container and published on GitHub, that Gladys installs in one click and runs in a sandbox isolated from its core. It is published and maintained by guim31, not by the Gladys core team.
- Browse all integrations, native and community
- Build and publish your own external integration
- Source code on GitHub — source of this documentation