Goufablog

Geek, nouvelles technologies, société et jeux vidéos!
16
juil.
2019
Trajet optimum avec l'API Tisseo
Technique - par Goufalite - 364 hits

Ah Toulouse ! La ville rose... Une ville où on l'on aime bien se balader et, non en fait on va principalement devoir attendre dans les bouchons le matin et le soir. Bref, rien de tel que les transports en commun pour palier à ces embouteillages, mais comment bien optimiser son trajet ? Toulouse n'est pas comparable à Paris, ville où se trouve une bouche de métro tous les 50 mètres... À Toulouse il faut souvent marcher ou faire de la voiture avant de trouver un arrêt de bus. Donc on a beau avoir les horaires des prochains passages, il faut anticiper le temps d'arriver à l'arrêt qui peut se chiffrer en minutes !

L'existant

Widget officiel Tisseo
Widget officiel Tisseo

L'application Tisseo et son site web sont très bien faits. Cependant ils ne répondent qu'à un besoin standard : quand passe mon bus ? Au vu des fréquences de passages ils ont prévu d'afficher les deux prochains passages d'une ligne mais surtout de les organiser par localisation.

C'est certes très pratique mais il faudra quand même faire le calcul du temps d'arrivée à l'arrêt, surtout si l'on doit traverser tout le métro avant d'y arriver...

L'API Tisseo

Il s'agit d'une API standard qui permet qui permet de faire beaucoup de choses si l'on s'y plonge dedans, comme par exemple lister les lignes existantes, leurs arrêts, les prochains passages à ces arrêts, mais aussi de la plannification d'ititnéraire et de la recherche par zone géographique !

Une documentation est disponible ici. Mais avant de bien l'exploiter il va falloir mettre à plat les données que l'on veut.

La clef

L'API Tisseo est soumise à une licence ObDL qu'il vous faudra mentionner si vous faites un site web par exemple, et pour éviter les appels abusifs, une clef vous sera demandée à chaque requête. Cette clef peut s'obtenir en envoyant un mail à opendata(at)tisseo.fr et en spécifiant votre besoin.

Le long de cet article, je vous mettrai à disposition des sorties JSON tronquées que vous pourrez essayer d'appeler avec vos scripts.

Récupération des lignes

Passage obligé, au moins pour le tout début, ce service va vous récupérer les lignes en fonction d'un critère.

Filtrez votre requête par shortName et voilà

https://api.tisseo.fr/v1/lines.json?key=clef&shortName=47
{"expirationDate": "2018-03-20 03:45", "lines": {"line": [ {"bgXmlColor": "#db001b", "color": "(219,0,27)", "fgXmlColor": "#FFFFFF", "id": "11821949021891642", "name": "Basso Cambo / Portet Gare SNCF", "network": "Tisséo", "reservationMandatory": "0", "shortName": "47", "transportMode": {"article": "le", "id": "13792273858822585", "name": "bus"} } ] } }

Notez l'identifiant de la ligne (ici : 11821949021891642) dans un coin.

Comble du sublime : l'API vous donne même la couleur de la ligne dans plusieurs formats, pratique pour styliser les numéros !

"bgXmlColor": "#db001b", "color": "(219,0,27)", "fgXmlColor": "#FFFFFF",

Pour information si vous travaillez sur Chrome, faites F12 pour afficher la console développeurs, allez à l'onglet Réseau et vous aurez un meilleur aperçu du retour des services.

Récupération des arrêts

Maintenant que vous avez la ligne, vous pouvez interroger le service de récupération des arrêts physiques de cette ligne. En effet, l'API vous interdit de récupérer tous les arrêts d'un coup.

Dans un premier temps recherchez textuellement les arrêts par nom, mais surtout surveillez le sens !

https://api.tisseo.fr/v1/stop_points.json?key=clef&lineId=11821949021891642&displayDestinations=1
{"expirationDate": "2018-03-20 03:45", "physicalStops": {"physicalStop": [ {"destinations": [{"cityName": "PORTET-SUR-GARONNE", "id": "1970324837184685", "name": "Portet Gare SNCF"}], "handicappedCompliance": "1", "id": "3377699723269553", "lines": [{"short_name": "47"}], "name": "Basso Cambo", "operatorCodes": [{"operatorCode": {"network": "Tisséo", "value": "366"}}, {"operatorCode": {"network": "Tisséo", "value": "526"}}], "stopArea": {"cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}}, {"destinations": [{"cityName": "PORTET-SUR-GARONNE", "id": "1970324837184685", "name": "Portet Gare SNCF"}], "handicappedCompliance": "1", "id": "3377699720883563", "lines": [{"short_name": "47"}, {"short_name": "48"}, {"short_name": "57"}, {"short_name": "58"}], "name": "De Croutte", "operatorCodes": [{"operatorCode": {"network": "Tisséo", "value": "2150"}}], "stopArea": {"cityName": "TOULOUSE", "id": "1970324837186339", "name": "De Croutte"}}, {"destinations": [{"cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}], "handicappedCompliance": "1", "id": "3377699720883562", "lines": [{"short_name": "47"}, {"short_name": "48"}, {"short_name": "57"}, {"short_name": "58"}], "name": "De Croutte", "operatorCodes": [{"operatorCode": {"network": "Tisséo", "value": "2151"}}], "stopArea": {"cityName": "TOULOUSE", "id": "1970324837186339", "name": "De Croutte"}}, {"destinations": [{"cityName": "PORTET-SUR-GARONNE", "id": "1970324837184685", "name": "Portet Gare SNCF"}], "handicappedCompliance": "1", "id": "3377699720883560", "lines": [{"short_name": "21"}, {"short_name": "47"}, {"short_name": "48"}, {"short_name": "57"}, {"short_name": "58"}], "name": "Mounède", "operatorCodes": [{"operatorCode": {"network": "Tisséo", "value": "4500"}}], "stopArea": {"cityName": "TOULOUSE", "id": "1970324837186338", "name": "Mounède"}}, {"destinations": [{"cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}], "handicappedCompliance": "1", "id": "3377699720883561", "lines": [{"short_name": "21"}, {"short_name": "47"}, {"short_name": "48"}, {"short_name": "57"}, {"short_name": "58"}], "name": "Mounède", "operatorCodes": [{"operatorCode": {"network": "Tisséo", "value": "4501"}}], "stopArea": {"cityName": "TOULOUSE", "id": "1970324837186338", "name": "Mounède"}} ] } }

Maintenant que vous avez les arrêts physiques faites vous une liste avec les lignes et leur sens qui vous intéressent.

11821949021891642 47 3377699723269553 47 Basso -> Portet 3377699720883562 47,48,57,58 De croutte -> Basso

Vous remarquerez un champ stopArea, c'est un ensemble d'arrêts qui fonctionne comme un seul. Notez-le il sera utile pour tout à l'heure.

Récupération des passages, avec filtre sur la ligne

Avec votre liste, vous pouvez demander les passages des bus à ces arrêts. Mais attention il y a une petite subtilité : plusieurs bus peuvent passer par un seul arrêt !

https://api.tisseo.fr/v1/stops_schedules.json?key=clef&stopsList=3377704015495611
{"departures": {"departure": [ {"dateTime": "2018-03-20 11:56:46", "destination": [{"cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}], "line": {"color": "(87,47,8)", "name": "Basso Cambo / Frouzins JP Sabatier", "network": "Tisséo", "shortName": "57"}, "realTime": "yes"}, {"dateTime": "2018-03-20 11:59:22", "destination": [{"cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}], "line": {"color": "(219,0,27)", "name": "Basso Cambo / Portet Gare SNCF", "network": "Tisséo", "shortName": "47"}, "realTime": "yes"} ], "stop": {"id": "3377704015495611", "name": "La Ramée", "operatorCode": "27701"}, "stopArea": {"cityId": "1688849860531493", "cityName": "TOURNEFEUILLE", "id": "1970324837186911", "name": "La Ramée"}}, "expirationDate": "2018-03-20 11:54"}

Il vous faudra donc filtrer par ligne, et éventuellement par terminus

https://api.tisseo.fr/v1/stops_schedules.json?key=clef&stopsList=3377704015495611|11821949021891642
{"departures": {"departure": [ {"dateTime": "2018-03-20 11:59:22", "destination": [{"cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}], "line": {"color": "(219,0,27)", "name": "Basso Cambo / Portet Gare SNCF", "network": "Tisséo", "shortName": "47"}, "realTime": "yes"}, {"dateTime": "2018-03-20 12:17:39", "destination": [{"cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}], "line": {"color": "(219,0,27)", "name": "Basso Cambo / Portet Gare SNCF", "network": "Tisséo", "shortName": "47"}, "realTime": "yes"} ], "stop": {"id": "3377704015495611", "name": "La Ramée", "operatorCode": "27701"}, "stopArea": {"cityId": "1688849860531493", "cityName": "TOURNEFEUILLE", "id": "1970324837186911", "name": "La Ramée"} }, "expirationDate": "2018-03-20 11:58"}

Vous pouvez coupler plusieurs arrêts ou zones d'arrêts en une seule requête séparés par des virgules, afin de centraliser les résultats, la clef est la suivante :

<arrêt ou zone 1>|<filtre de ligne>|<filtre de terminus>,<arrêt ou zone 2>|<filtre de ligne>|<filtre de terminus>

Une fois que vous avez la bonne requête, mettez-la de côté pour la lier à un contexte ("Je pars de Basso Cambo",...)

Je vous ai parlé ci-dessus du cas de plusieurs bus passant par un arrêt. Il existe aussi le cas de plusieurs arrêts dans une zone géographique restreinte : les stop areas ! Basso Cambo est un terminus de métro, et possède donc une grande quantité d'arrêts de bus. Grâce à l'API, ils sont centralisés dans un espace qu'est le stop area :

https://api.tisseo.fr/v1/stops_schedules.json?key=clef&number=15&stopsList=1970324837184808
{"departures": {"departure": [ {"dateTime": "2018-10-17 22:01:00", "destination": [{"cityName": "BALMA", "id": "1970324837185612", "name": "Balma-Gramont"}], "line": {"color": "(219,0,27)", "name": "Basso Cambo / Balma - Gramont", "network": "Tisséo", "shortName": "A"}, "realTime": "no"}, {"dateTime": "2018-10-17 22:06:00", "destination": [{"cityName": "TOULOUSE", "id": "1970324837184995", "name": "Cours Dillon"}], "line": {"color": "(0,124,82)", "name": "Basso Cambo / Cours Dillon", "network": "Tisséo", "shortName": "12"}, "realTime": "yes"} ], "stop": {"id": "3377699720880977", "name": "Basso Cambo", "operatorCode": "40001"}, "stopArea": {"cityId": "1688849860531491", "cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}}, "expirationDate": "2018-10-17 22:00"}

Ce service équivaut à l'affiche du départ/passage de toutes les lignes sur l'écran de la station, mais on peut par conséquent isoler par ligne avec la même technique !

https://api.tisseo.fr/v1/stops_schedules.json?key=clef&number=15&stopsList=1970324837184808|11821949021891642
{"departures": {"departure": [ {"dateTime": "2018-10-18 06:00:00", "destination": [{"cityName": "PORTET-SUR-GARONNE", "id": "1970324837184685", "name": "Portet Gare SNCF"}], "line": {"color": "(219,0,27)", "name": "Basso Cambo / Portet Gare SNCF", "network": "Tisséo", "shortName": "47"}, "realTime": "no"}, {"dateTime": "2018-10-18 06:30:00", "destination": [{"cityName": "PORTET-SUR-GARONNE", "id": "1970324837184685", "name": "Portet Gare SNCF"}], "line": {"color": "(219,0,27)", "name": "Basso Cambo / Portet Gare SNCF", "network": "Tisséo", "shortName": "47"}, "realTime": "no"}, ], "stop": {"id": "3377699723269553", "name": "Basso Cambo", "operatorCode": "366,526"}, "stopArea": {"cityId": "1688849860531491", "cityName": "TOULOUSE", "id": "1970324837184808", "name": "Basso Cambo"}}, "expirationDate": "2018-10-17 21:55"}

Bonus : messages d'information

Avec l'appli standard, j'ai des alertes en temps réel sur l'état du trafic, mais si j'ai oublié je peux appeler un service qui me donnera les derniers messages importants.

https://api.tisseo.fr/v1/messages.json?key=clef&displayImportantOnly=1
{"expirationDate": "2019-07-02 15:22", "messages": [ {"message": {"content": "ARRÊT TRAM LIGNE T1 - LIGNE T2Ligne T1 et Ligne T2 : le service tram est interrompu en raison d'un objet abandonné situé aux abords de la station Palais de Justice.\r\nUne intervention des forces de sécurité est en cours.", "id": "prehome", "importanceLevel": "important", "scope": "global", "title": "ARRÊT TRAM LIGNE T1 - LIGNE T2", "type": "trafic", "url": "https://www.tisseo.fr/se-deplacer/info-reseau/id/prehome"}} ] }

Application

Et maintenant place à mon application récapitulative ! Pour coder tout ça, j'ai choisi le pack Raspberry pi/lighttpd/SQLite/PHP/Pushbullet.

Le code est disponible sous Github.

Page web récapitulative

Page web
Page web

Avant toute chose, mettez dans une base ou un fichier une liste des requêtes HTTP que vous avez construites ci-dessus et donnez leur un identifiant, un libellé et le temps d'arrivée à l'arrêt en question que vous pourrez donc lister facilement.

Vous vous souvenez de la couleur de ligne ? Eh bien vous allez pouvoir l'appliquer facilement avec du style.

style='background-color:rgb".$d->line->color."'

Notification et rappel automatique

Notification et rappel
Notification et rappel

Avant de partir quelque part, je n'ai pas envie d'ouvrir une page web et d'attendre un résultat... L'idée est donc d'utiliser Pushbullet afin d'avoir un message immédiat sur mon téléphone.

Téléchargez l'application et créez-vous un compte, ensuite créez un petit script pour publier les données :

#!/bin/bash mydate="`date +%H:%M:%S`" curl -s -S --header 'Access-Token: <token>' --request POST --header 'Content-Type: application/json' --data-binary '{"type":"note","body":"'"[$mydate] $2"'","title":"'"$1"'"}' https://api.pushbullet.com/v2/pushes -o curlout.txt

Pour temporiser une commande, créez une tâche en utilisant le combo sleep et screen

$cmd = "screen -dm -S remindTisseo".$id." bash -c 'sleep ".($mins*60)." && (cd /path/to/app ; php -q notif.php ".$id.")' >/dev/null 2>&1"; exec($cmd);

Voilà, bon courage pour la mise en place de tout ça et bon voyage !


Vous pouvez aussi lire :

GoufaliteGoufalite - Site Web - Steam - Twitter
Rédacteur et programmeur principal du Goufablog. Ingénieur de profession et avide de connaissances technologiques et scientifiques il partage son savoir à travers ces différents articles. Plus de renseignements sur la page de contact.
RSS Voir ses articles...
CC-BY-SACet article est protégé par une licence CC-BY-SA.


Tags : api, tisseo, transports
Delicious   Facebook   Commentaires(0) | Permalink
Sans commentaires!
Votre avis?
(Obligatoire)

Site et style réalisé par Goufalite
Reproduction interdite sans l'accord de l'auteur.