Page 6 sur 7

Publié : 07 janv. 2019, 15:17
par iolo
Bon j'ai fait un truc qui tourne mais il faut au préalable:
1) demander un accès par mail (!) pour recevoir un login/password d'accès à l'API
https://data.sncf.com/explore/dataset/a ... formation/

2) avoir en local un fichier de correspondance entre les codes gares (UIC) qui sont utilisés par l'API et le nom réel des gares
On trouve ce fichier ici: https://data.sncf.com/explore/dataset/s ... rt=libelle
(onglet export, puis CSV). Dans mon cas, je l'ai mis dans /home/pi mais peu importe, pensez juste à mettre à jour le code qui donne ce chemin (la ligne contenant file '/home/pi/transilien.csv') suivant l'endroit où vous le mettrez dans votre jeedom. On pourrait envisager un code qui va chercher cette correspondance en ligne mais bon c'est une v1 ;)

Ensuite on peut faire des requêtes dans jeedom (moi j'utilise Telegram via une interaction) avec le nom réel des gares (ou une sous-partie de ce nom) ce qui est quand même plus simple que de mémoriser les codes UIC. Bien sûr si vous faites toujours la même requête, vous pouvez mettre les code UIC en dur dans le code et vous passer de l'étape 2 mais ce n'est pas mon usage.

Le code a besoin des variables jeedom suivantes:
gareDepart
gareArrivee
nbTrain: nombre de trains dans la réponse
inline: =0 si vous voulez avoir la réponse avec un train par ligne ou =1 pour avoir tout sur la même ligne.

Le inline vient de mon usage car j'affiche la réponse soit sur Telegram (inline = 0 pour que ça soit plus lisible) soit sur un afficheur LED qui fait défiler une seule ligne (inline =1 dans ce cas)

Par ailleurs il faut renseigner dans le code les variables
$outputname: nom de la variable Jeedom qui recevra la réponse
et APIuser / APIpasswd avec les valeurs reçues par mail de Transilien.

Code : Tout sélectionner

$scenario->setLog("Début scénario : Prochains Trains Transilien");

$outputname = "NextTrains";
$APIuser = "XXXX";
$APIpasswd = "XXXX";
$nbTrain = $scenario->getData("nbTrain", false, 5);
$inline = $scenario->getData("inline", false, 0);

$gareDepart = $scenario->getData("gareDepart", false, "Montparnasse"); 
$searchDepart = "/".$gareDepart."/i";

$gareArrivee = $scenario->getData("gareArrivee", false, "Rambouillet");
$searchArrivee = "/".$gareArrivee."/i";

// Recherche des codes UIC de départ / arrivée
$codeUICdepart = 0;
$codeUICarrive = 0;

$csv = array_map(function($v){return str_getcsv($v, ";");}, file('/home/pi/transilien.csv'));

foreach($csv as $line){
    if(preg_match($searchDepart, $line[2]) == 1){
      $codeUICdepart = $line[0];
      $codeGAREdepart = $line[2];
      $scenario->setLog("Trouvé code départ: ".$codeGAREdepart.":".$codeUICdepart);
    } 
    if(preg_match($searchArrivee, $line[2]) == 1){
	  $codeUICarrive = $line[0];
	  $codeGAREarrive = $line[2];
      $scenario->setLog("Trouvé code arrivée: ".$codeGAREarrive.":".$codeUICarrive);
    }
}
if ($codeUICdepart == 0){
  $scenario->setData($outputname, "La gare origine ".$gareDepart." n'a pas été trouvée");
  return;
}
if ($codeUICarrive == 0) {
  $scenario->setData($outputname, "La gare destination ".$gareArrivee." n'a pas été trouvée");
  return;
}

$url="http://api.transilien.com/gare/".$codeUICdepart."/depart/".$codeUICarrive;
$scenario->setLog("URL called : ".$url);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $APIuser . ':' . $APIpasswd );
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

if( $info['http_code'] == 200 ) {
    $responseXML = simplexml_load_string($output);
} else {
	$scenario->setData($outputname, "l'API Transilien a renvoyé une erreur ".$info['http_code']);
  	return;
}

$listeTrains = "";
$countTrain = 0;

$currTime = strtotime('now');

foreach ($responseXML->train as $train) {
  	// le format officiel ISO pour les dates Fr doit contenir des "-", 
  	// sinon c'est une date US (avec le mois en premier) qui est interprêtée
  	$trainTime = strtotime(str_replace('/', '-', $train->date)); 	
  	$time = date("H:i",$trainTime);
	$diff = floor(($trainTime - $currTime) / 60);

  	if ($inline == 0){
	  	$listeTrains .= "\r\n";
    }
  	if ($train->etat) {
	  $listeTrains .= "ATTENTION Train ";
	  $listeTrains .= $train->etat;
	  $listeTrains .= " ➔ "; 
    }
  
  	$listeTrains .= $time;
  	$listeTrains .= " - "; 
  	$listeTrains .= $diff;
  	$listeTrains .= " min"; 
  	$listeTrains .= " (";
  	$listeTrains .= $train->miss;
  	$listeTrains .= ") "; 
  
  	$countTrain++;
  	if ($countTrain == $nbTrain){
      break;
    }
}

if ($listeTrains == ""){
	$listeTrains = "Aucun train";
}

$tts = "Prochains trains de ".$codeGAREdepart." vers ".$codeGAREarrive.": ".$listeTrains;

$scenario->setData($outputname, $tts);
Et le résultat donne une variable contenant ça (par exemple)

Code : Tout sélectionner

Prochains trains de PARIS MONTPARNASSE (GARE MONTPARNASSE) vers RAMBOUILLET: 
15:35 - 18 min (ROPO) 
16:09 - 52 min (CAPO) 
16:16 - 59 min (RIPI) 
16:24 - 67 min (LEPU) 
16:31 - 74 min (RIPI)
La variable de retour donne aussi les trains supprimés et retardés mais pas les motifs de ces retards / suppressions (qu'on avait auparavant sur le site .mobi)

A noter: le code fait un choix arbitraire quand une des variables d'entrée correspond à un nom de gare ayant plusieurs correspondances possibles dans la base Transilien. C'est la dernière du fichier qui sera retenue. Par exemple si je donne "Michel" comme gare de départ ou d'arrivée, le code va choisir SAINT-MICHELSUR ORGE. Si c'est saint michel notre dame qu'il vous faut, alors il faut être plus explicite en donnant le nom complet ou demander "notre dame" par exemple. En l'occurrence même le seul mot "dame" suffit car c'est la seule gare qui contient ce mot.

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 07 janv. 2019, 16:29
par darksk
Bravo iolo pour ce super script !
Je le testerai ce week-end et si cela ne te dérange pas je le mettrai en lien dans mon 1er post pour remplacer mon vieux script qui ne fonctionne plus.

Re:

Publié : 07 janv. 2019, 17:27
par barzek
iolo a écrit :
07 janv. 2019, 15:17
Bon j'ai fait un truc qui tourne mais il faut au préalable:
1) demander un accès par mail (!) pour recevoir un login/password d'accès à l'API
https://data.sncf.com/explore/dataset/a ... formation/

2) avoir en local un fichier de correspondance entre les codes gares (UIC) qui sont utilisés par l'API et le nom réel des gares
On trouve ce fichier ici: https://data.sncf.com/explore/dataset/s ... rt=libelle
(onglet export, puis CSV). Dans mon cas, je l'ai mis dans /home/pi mais peu importe, pensez juste à mettre à jour le code qui donne ce chemin (la ligne contenant file '/home/pi/transilien.csv') suivant l'endroit où vous le mettrez dans votre jeedom. On pourrait envisager un code qui va chercher cette correspondance en ligne mais bon c'est une v1 ;)

Ensuite on peut faire des requêtes dans jeedom (moi j'utilise Telegram via une interaction) avec le nom réel des gares (ou une sous-partie de ce nom) ce qui est quand même plus simple que de mémoriser les codes UIC. Bien sûr si vous faites toujours la même requête, vous pouvez mettre les code UIC en dur dans le code et vous passer de l'étape 2 mais ce n'est pas mon usage.

Le code a besoin des variables jeedom suivantes:
gareDepart
gareArrivee
nbTrain: nombre de trains dans la réponse
inline: =0 si vous voulez avoir la réponse avec un train par ligne ou =1 pour avoir tout sur la même ligne.

Le inline vient de mon usage car j'affiche la réponse soit sur Telegram (inline = 0 pour que ça soit plus lisible) soit sur un afficheur LED qui fait défiler une seule ligne (inline =1 dans ce cas)

Par ailleurs il faut renseigner dans le code les variables
$outputname: nom de la variable Jeedom qui recevra la réponse
et APIuser / APIpasswd avec les valeurs reçues par mail de Transilien.

Code : Tout sélectionner

$scenario->setLog("Début scénario : Prochains Trains Transilien");

$outputname = "NextTrains";
$APIuser = "XXXX";
$APIpasswd = "XXXX";
$nbTrain = $scenario->getData("nbTrain", false, 5);
$inline = $scenario->getData("inline", false, 0);

$gareDepart = $scenario->getData("gareDepart", false, "Montparnasse"); 
$searchDepart = "/".$gareDepart."/i";

$gareArrivee = $scenario->getData("gareArrivee", false, "Rambouillet");
$searchArrivee = "/".$gareArrivee."/i";

// Recherche des codes UIC de départ / arrivée
$codeUICdepart = 0;
$codeUICarrive = 0;

$csv = array_map(function($v){return str_getcsv($v, ";");}, file('/home/pi/transilien.csv'));

foreach($csv as $line){
    if(preg_match($searchDepart, $line[2]) == 1){
      $codeUICdepart = $line[0];
      $codeGAREdepart = $line[2];
      $scenario->setLog("Trouvé code départ: ".$codeGAREdepart.":".$codeUICdepart);
    } 
    if(preg_match($searchArrivee, $line[2]) == 1){
	  $codeUICarrive = $line[0];
	  $codeGAREarrive = $line[2];
      $scenario->setLog("Trouvé code arrivée: ".$codeGAREarrive.":".$codeUICarrive);
    }
}
if ($codeUICdepart == 0){
  $scenario->setData($outputname, "La gare origine ".$gareDepart." n'a pas été trouvée");
  return;
}
if ($codeUICarrive == 0) {
  $scenario->setData($outputname, "La gare destination ".$gareArrivee." n'a pas été trouvée");
  return;
}

$url="http://api.transilien.com/gare/".$codeUICdepart."/depart/".$codeUICarrive;
$scenario->setLog("URL called : ".$url);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $APIuser . ':' . $APIpasswd );
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

if( $info['http_code'] == 200 ) {
    $responseXML = simplexml_load_string($output);
} else {
	$scenario->setData($outputname, "l'API Transilien a renvoyé une erreur ".$info['http_code']);
  	return;
}

$listeTrains = "";
$countTrain = 0;

$currTime = strtotime('now');

foreach ($responseXML->train as $train) {
  	// le format officiel ISO pour les dates Fr doit contenir des "-", 
  	// sinon c'est une date US (avec le mois en premier) qui est interprêtée
  	$trainTime = strtotime(str_replace('/', '-', $train->date)); 	
  	$time = date("H:i",$trainTime);
	$diff = floor(($trainTime - $currTime) / 60);

  	if ($inline == 0){
	  	$listeTrains .= "\r\n";
    }
  	if ($train->etat) {
	  $listeTrains .= "ATTENTION Train ";
	  $listeTrains .= $train->etat;
	  $listeTrains .= " ➔ "; 
    }
  
  	$listeTrains .= $time;
  	$listeTrains .= " - "; 
  	$listeTrains .= $diff;
  	$listeTrains .= " min"; 
  	$listeTrains .= " (";
  	$listeTrains .= $train->miss;
  	$listeTrains .= ") "; 
  
  	$countTrain++;
  	if ($countTrain == $nbTrain){
      break;
    }
}

if ($listeTrains == ""){
	$listeTrains = "Aucun train";
}

$tts = "Prochains trains de ".$codeGAREdepart." vers ".$codeGAREarrive.": ".$listeTrains;

$scenario->setData($outputname, $tts);
Et le résultat donne une variable contenant ça (par exemple)

Code : Tout sélectionner

Prochains trains de PARIS MONTPARNASSE (GARE MONTPARNASSE) vers RAMBOUILLET: 
15:35 - 18 min (ROPO) 
16:09 - 52 min (CAPO) 
16:16 - 59 min (RIPI) 
16:24 - 67 min (LEPU) 
16:31 - 74 min (RIPI)
La variable de retour donne aussi les trains supprimés et retardés mais pas les motifs de ces retards / suppressions (qu'on avait auparavant sur le site .mobi)

A noter: le code fait un choix arbitraire quand une des variables d'entrée correspond à un nom de gare ayant plusieurs correspondances possibles dans la base Transilien. C'est la dernière du fichier qui sera retenue. Par exemple si je donne "Michel" comme gare de départ ou d'arrivée, le code va choisir SAINT-MICHELSUR ORGE. Si c'est saint michel notre dame qu'il vous faut, alors il faut être plus explicite en donnant le nom complet ou demander "notre dame" par exemple. En l'occurrence même le seul mot "dame" suffit car c'est la seule gare qui contient ce mot.

beau boulot, merci ! j’attends mes identifiant SNCF

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 07 janv. 2019, 17:55
par iolo
darksk a écrit :
07 janv. 2019, 16:29
Bravo iolo pour ce super script !
Je le testerai ce week-end et si cela ne te dérange pas je le mettrai en lien dans mon 1er post pour remplacer mon vieux script qui ne fonctionne plus.
Bien sûr, pas de problème (et merci à toi pour le script d'origine qui nous a tous été très utile jusqu'ici!).

Et merci d'avance pour vos retours et améliorations!

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 08 janv. 2019, 14:37
par CKD77
Salut

Merci pour cette version. J'ai demandé un compte, et j'ai un token a la place d'un nom d'utilisateur et mot de passe.
Et je n'arrive pas a faire fonctionner le token avec ton script.

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 08 janv. 2019, 15:06
par iolo
CKD77 a écrit :
08 janv. 2019, 14:37
Salut

Merci pour cette version. J'ai demandé un compte, et j'ai un token a la place d'un nom d'utilisateur et mot de passe.
Et je n'arrive pas a faire fonctionner le token avec ton script.
Le token c'est pour l'accès à l'API SNCF grandes lignes, pas Transilien. Il faut suivre le lien que j'ai donné, la demande se fait exclusivement par mail auprès de Transilien et c'est possiblement un humain qui répond. Ce n'est clairement pas très pratique et si on est 20000 à demander cet accès, ça risque de devenir compliqué pour eux mais pour le moment c'est comme ça.

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 09 janv. 2019, 18:33
par CKD77
iolo a écrit :
08 janv. 2019, 15:06
CKD77 a écrit :
08 janv. 2019, 14:37
Salut

Merci pour cette version. J'ai demandé un compte, et j'ai un token a la place d'un nom d'utilisateur et mot de passe.
Et je n'arrive pas a faire fonctionner le token avec ton script.
Le token c'est pour l'accès à l'API SNCF grandes lignes, pas Transilien. Il faut suivre le lien que j'ai donné, la demande se fait exclusivement par mail auprès de Transilien et c'est possiblement un humain qui répond. Ce n'est clairement pas très pratique et si on est 20000 à demander cet accès, ça risque de devenir compliqué pour eux mais pour le moment c'est comme ça.
J'ai fais hier matin via ton lien, et rien du tout, et l'après midi oui en effet pas fait gaffe que c'était pour les grandes lignes. Ce matin j'ai refais avec une autre adresse mail, 1h après je recois un mail de bienvenue sur l'api de transilien avec des liens sur la documentation, mais aucun nom d'utilisateur et mot de passe :/ Et sur mon premier mail, rien reçu, ni dans le dossier spam. Tu as tes accès toi?

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 09 janv. 2019, 18:52
par Jeandhom
Mail envoyé le 07/01/2019 à 19:37.
Pas de réponse à ce jour.

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 09 janv. 2019, 19:53
par iolo
Oui j'ai eu une réponse en 2j ouvrés mais bon je suppose qu'il va y avoir une petite montée en charge du fait de ce forum et peut-être d'autres qui ont eu le même problème que nous. C'est très certainement un traitement manuel de leur coté. Donc patience!

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 10 janv. 2019, 09:27
par CKD77
iolo a écrit :
09 janv. 2019, 19:53
Oui j'ai eu une réponse en 2j ouvrés mais bon je suppose qu'il va y avoir une petite montée en charge du fait de ce forum et peut-être d'autres qui ont eu le même problème que nous. C'est très certainement un traitement manuel de leur coté. Donc patience!
Tout juste reçu, et fonctionne du 1er coup, good job iolo, MERCI :roll:

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 10 janv. 2019, 19:32
par Jeandhom
Jeandhom a écrit :
09 janv. 2019, 18:52
Mail envoyé le 07/01/2019 à 19:37.
Pas de réponse à ce jour.
Identifiants reçus.
Ton script fonctionne sans problème.
Merci pour le boulot !!! 8-)

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 12 janv. 2019, 17:10
par mulb
Top, ça fonctionne, merci iolo

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 23 janv. 2019, 12:37
par barzek
vous pensez que c'est trop complexe d'utiliser cette api pour avoir les bus? :)

https://data.iledefrance.fr/explore/dat ... i/?lang=fr

Merci

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 26 janv. 2019, 01:58
par barbo77
Bonjour
Merci beaucoup pour le partage de la solution !
Je vais pouvoir avoir de nouveaux les horaires par sms ! trop coo.

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 30 janv. 2019, 15:13
par solid
Bonjour,

Merci pour ce code, il fonctionne très bien.
Par contre, j'ai un problème d'affichage dans Virtuel. Les informations s'affichent uniquement lorsque "inline = 1"....
Avez-vous ce problème ?

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 03 févr. 2019, 14:01
par solid
En fait, dans ma configuration, il semblerait que les "/r/n" ne fonctionnent pas ... si je les laisse, la variable ne s'affiche pas dans le Virtuel :|

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 08 févr. 2019, 10:18
par havock
Bonjour , j'ai le même problème que solid quand je veux créer un virtuel je met bien info numérique et la commande variable(nom de la variable ) celle ci s'affiche bien Quand je lance le script mais sur le virtuel j'ai un 0

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 10 févr. 2019, 11:53
par iolo
Bonjour,

Je viens enfin de trouver le temps de regarder ça.
Alors déjà, ce n'est pas un type "numérique" qu'il faut mettre mais un type "autre" car c'est une chaine de caractère.
Mais je viens d'essayer de mon coté et en effet les virtuels n'aiment pas les retour ligne dans les string. Je n'ai pas encore trouvé de solution simple.
Il faudrait sans doute créer un widget dédié à ça. On pourrait par exemple construire une string avec une caractère bidon dedans et remplacer ce caractère par une retour ligne dans le widget... bon c'est du bricolage mais ça devrait marcher.

J'ai regardé le reste du forum mais je n'ai rien trouvé de probant concernant l'affichage de string dans un virtuel.

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 02 mars 2019, 16:29
par Shakto
solid a écrit :
03 févr. 2019, 14:01
En fait, dans ma configuration, il semblerait que les "/r/n" ne fonctionnent pas ... si je les laisse, la variable ne s'affiche pas dans le Virtuel :|
Change par <br />

Re: [Tuto] Horaires de passage des prochains trains Transilien

Publié : 09 mars 2019, 18:01
par solid
Shakto a écrit :
02 mars 2019, 16:29
solid a écrit :
03 févr. 2019, 14:01
En fait, dans ma configuration, il semblerait que les "/r/n" ne fonctionnent pas ... si je les laisse, la variable ne s'affiche pas dans le Virtuel :|
Change par <br />
Merci ! Ca fonctionne ! ;)