-
Compteur de contenus
2 501 -
Inscription
-
Dernière visite
-
Jours gagnés
28
Tout ce qui a été posté par MAM78
-
Voici une nouvelle version 0.7 Cette nouvelle version apporte : Possibilité de paramétrer 2 icônes Pour un trafic normal Pour un trafic avec des perturbations (retard au départ ou à l'arrivée) Possibilité de définir (en option) un horaire à partir duquel la recherche doit être effectuée. Si l'horaire demandé est dépassé la recherche est faite pour le jour suivant Voir variable (api_heure_depart) ci-dessous. Possibilité de mixer les itinéraires en utilisant les lignes de trains, de bus et de métro, et l'indication de trajet à pied lors de transferts entre 2 stations/gares/bus Cette nouvelle fonctionnalité est disponible en paramétrant une autre API (https://api.navitia.io/v1) qui utilise la même structure que celle utilisé par la SNCF. Pour cela, il convient de se créer un compte sur le site https://www.navitia.io sur lequel vous obtiendrez un nouveau code API Nota : Cette seconde API présente néanmoins un inconvénient. Elle ne dispose pas des information sur les perturbations sur le trafic. Il conviendra donc de faire le choix entre les 2 API selon vos besoins. Du coup j'ai intégré dans les paramètres des trajets (VD) des nouvelles variables (en rouge), voir chapitre sur la scène : 1) Veuillez installer le nouveau VD ci-dessous : Itinéraire_SNCF.vfib.json Attention de bien modifier sur chacun des 4 boutons : l'icônes qui correspond au trafic normal (fournie ci-dessus) La variable : SceneID_Horaires_Transports par l'ID de la Scène Itinéraire SNCF La variable : IconeID_TraficOk par l'ID de l'icône qui correspond au trafic normal (fournit ci-dessus) J'espère à ne plus avoir à faire de modifications du VD hein @Sakkhho 2) Veuillez charger le nouveau code de la scène : Il convient de : modifier/compléter la liste des variables utilisateur (nouvelles variables créée en rouge, ci-dessous) : VD_Id = Id du VD de pilotage de votre Trajet Traj_Titre = Désignation du trajet pour le répéter dans le mode debug code_api_from = Code de votre point de départ, soit de type (stop_area et stop_station) attention les codes stop_area et stop_station ne sont pas les mêmes selon que l'on utilise API data.sncf.com ou navitia.io code_api_to = Code de votre point d'arrivée, soit de type (stop_area et stop_station) attention les codes stop_area et stop_station ne sont pas les mêmes selon que l'on utilise API data.sncf.com ou navitia.io User_code_API = Code obtenu sur les 2 sites suivants : (sans encodage 64) et selon celui utilisé pour le trajet. https://data.sncf.com/api (API de la SNCF) https://www.navitia.io (API que permet d'avoir les lignes METRO et BUS) api_url = "https://api.sncf.com/v1" (si utilisation API data.sncf.com) "https://api.navitia.io/v1" (si utilisation API navitia.io) api_coverage = "sncf" ou (si utilisation API data.sncf.com) code région (ex: fr-idf) (si utilisation API navitia.io) dans ce cas la france est découpée en plusieurs régions : voir détail sur le lien : https://navitia.opendatasoft.com/explore/?sort=modified&refine.geographicarea=France "fr-idf" = Ile-de-France, France, Paris "fr-ne" = Nord-est (régions Alsace, Bourgogne, Picardie, Nord-Pas-de-Calais) "fr-sw" = Sud-ouest (régions Poitou-Charentes, Limousin, Aquitaine, Midi-Pyrénées) "fr-nw" = Nord-Ouest (régions Bretagne, Pays de la Loire, Centre, Normandie) "fr-se" = Sud-Est (régions Provence-Alpes-Côtes d'Azur, Rhône-Alpes, Languedoc-Roussillon) "fr-bre" = Bretagne en double avec "fr-nw" ? à tester api_heure_depart = Horaire à partir duquel le recherche doit être faite (option). si non renseigné ce sera le prochain trajet disponible (idem précédemment) Msg_Sonos = Indication si souhaitez envoyer un message sur votre Sonos Volume_Sonos = Niveau du volume du message Msg_Depart = Non en phonétique de votre point de départ, pour message Sonos Msg_Arrivee = Non en phonétique de votre point d'arrivée, pour message Sonos si vous utilisez plusieurs trajets (plusieurs VD), vous devez compléter/dupliquer cette liste pour chacun des VD modifier la variable : IconeID_TraficOk par l'ID de l'icône qui correspond au trafic normal (fournit ci-dessus) modifier la variable : IconeID_TraficNOk par l'ID de l'icône qui correspond au trafic perturbé (fournit ci-dessus) 3) Bons tests PS : Les étapes suivantes du projet seront probablement consacré à Mise en place d'une notification par mail, sms, push lors de perturbations (retards au départ ou à l'arrivée) la recherche s'il y a des perturbations sur l'une des lignes utilisées par le trajet. Je n'ai pas encore trouvé la bonne solution, puisqu'il s'agirait de désigner une ligne en particulier et de chercher s'il y a une perturbation en cour. Si vous avez d'autres idées, vous pouvez toujours faire vos demandes Voici le nouveau code de la scène : --[[ %% properties %% events %% globals --]] ---------------------------------------------------------------------------------- -- Name : HC2 Horaire Transport en commun -- Type : Virtual Device & Scene ---------------------------------------------------------------------------------- -- Cette scène permet d'obtenir l'horaire du prochain départ des transports -- en communs, que ce soit en Train, en Bus, en Metro -- depuis un lieu (localité) ou une station (gare, métro, bus) ---------------------------------------------------------------------------------- -- Evolution du Projet à venir : -- l'identification des perturbations sur une des lignes du trajet ---------------------------------------------------------------------------------- -- Version : 0.7 -- Création : MAM78 -- Date MAJ : 15/07/2017 -- -- Evolutions : -- V0.1 09/07/2017 : 1) Initialisation du projet -- -- V0.2 10/07/2017 : 1) Association de la scène à un VD qui appel la scène en -- passant les paramètres de la recherche d'itinéraire -- -- V0.3 12/07/2017 : 1) Ajouts de boutons de navigation pour parcourir les diférents -- itinéraires par odre chronologique des départs -- -- V0.4 13/07/2017 : 1) La décomposition du parcours sur chacune des étapes -- (changements) Maximum 9 étapes pour le moment. -- 2) Le temps de trajet global, ainsi que par étape -- 3) Le mode de circulation pour chacune des étape -- (La ligne à utiliser, Trajet à pied, Attente en gare, ... -- 4) La possibilité de choisir le mode retour (inversion entre -- le point de départ et d'arrivé). -- -- V0.5 13/07/2017 : 1) Possibilité d'utiliser les flèches de navigation que ce -- soit pour un trajet Aller ou Retour -- -- V0.6 14/07/2017 : 1) affichage d'alertes sur les retards au départ/arrivée -- avec la cause (si disponible) -- 2) Consolidation de l'ensemble des paramètres des trajets -- dans la scène pour simplifier leur mise à jour et les -- rassembler à un seul et même endroit -- 3) Possibilité d'utiliser plusieurs trajets au travers -- de plusieurs VD et consolider les informations -- au niveau de la scène -- 4) Il n'est plus nécessaire d'encoder le code d'accès à -- l'API SNCF. La scène le fait tout seule -- 5) Indication qu'il n'y a plus de trajets disponible -- lors de la navigation dans les trajets (inférieur à 5) -- 6) Possibilité d'ultiliser comme point de départ -- ou d'arrivée, soit un : -- - stop_points (lieu d'arrêt Gare) -- - stop_areas (lieu tel qu'une localité) c'est utile -- lorsqu'il y a plusieurs gares dans une localité -- V0.7 14/07/2017 : 1) Possibilité de mixer les itinéraires en utilisant les -- lignes de trains, de bus et de métro, et à pied. -- Cette fonctionnalité est disponible en paramétrant une -- autre API (https://api.navitia.io/v1) -- 2) Possibilité de définir (en option) un horaire à partir -- duquel la recherche doit être effectuée. Si l'horaire -- demandé est dépassé la recherche est faite pour le -- jour suivant ---------------------------------------------------------------------------------- ---------------------------------------------------------------------------------- -- Pour pouvoir utiliser l'API, vous devez vous créer un compte sur : -- https://data.sncf.com/api (API de la SNCF) -- https://www.navitia.io (API que permet d'avoir les lignes METRO et BUS) ---------------------------------------------------------------------------------- ---------------------------------------------------------------------------------- -- User variables : ---------------------------------------------------------------------------------- -- Les variables ci-dessous (code_api_from & code_api_to) détermine le trajet -- que vous souhaitez utiliser -- Ces codes sont récupérables sur le site : -- http://canaltp.github.io/navitia-playground/play.html -- Saisir dans champs : -- API = soit : https://api.sncf.com/v1 ou https://api.navitia.io/v1 -- Token = le code obtenu sur l'un des 2 sites -- coverage = sncf si utilisation de api.sncf.com -- code région (ex: fr-idf) si utilisation de api.navitia.io -- stop_points ou stop_areas = saisir le nom de votre point de départ -- -> Votre saisie va se transformer en un code -- Recopier ce code dans la variable code_api_from -- stop_points ou stop_areas = saisir le nom de votre point d'arrivée -- -> Votre saisie va se transformer en un code -- Recopier ce code dans la variable code_api_to -- empty feature = departures -- Cliquer sur le bouton SUBMIT -- vous devriez obtenir la liste des prochains départ ---------------------------------------------------------------------------------- -- La structure Trajet ci-dessous vous permet de définir l'ensemble des trajets -- que vous souhaitez créer. Chacune des ces structures correspond un VD -- qui permet de piloter vos trajets. Un Trajet = Un VD -- VD_Id ci-dessous permet de faire la correspondance avec les paramètres ci-dessous ---------------------------------------------------------------------------------- -- Description des variables : -- VD_Id = Id du VD de pilotage de votre Trajet -- Traj_Titre = Désignation du trajet pour le répérer dans en mode debug -- code_api_from = Code de votre station de départ évoqué ci-dessus -- code_api_to = Code de votre station d'arrivée évoqué ci-dessus -- User_code_API = Code obtenu sur l'un des 2 sites suivants : -- https://data.sncf.com/api (API de la SNCF) -- https://www.navitia.io (API que permet d'avoir les lignes METRO et BUS) -- api_url = "https://api.sncf.com/v1" ou "https://api.navitia.io/v1" -- api_coverage = "sncf" ou code région (ex: fr-idf) si utilisation de api.navitia.io -- api_heure_depart = Horaire à partir duquel le recherche doit être faite (option) -- si non renseigné ce sera le prochain trajet disponible -- Msg_Sonos = Indication si souhaitez envoyer un message sur votre Sonos -- Volume_Sonos = Niveau du volume du message -- Msg_Depart = Nom en phonétique de votre point de départ, pour message Sonos -- Msg_Arrivee = Nom en phonétique de votre point d'arrivée, pour message Sonos ---------------------------------------------------------------------------------- local Trajets = { { ["VD_Id"] = 245, ["Traj_Titre"] = "Trajet A", ["code_api_from"] = "stop_area:OCE:SA:87725002", --"stop_point:OCE:SP:TrainTER-87761007", ["code_api_to"] = "stop_area:OCE:SA:87713040", --"stop_point:OCE:SP:TrainTER-87725689", ["User_code_API"] = "placé ici votre code API SNCF ou Navitia", ["api_url"] = "https://api.sncf.com/v1", ["api_coverage"] = "sncf", ["api_heure_depart"] = "08:10", ["Msg_Sonos"] = "Non", ["Volume_Sonos"] = 10, ["Msg_Depart"] = "letan la ville", -- écriture phonétique pour TTS ["Msg_Arrivee"] = "La Défense" -- écriture phonétique pour TTS }, { ["VD_Id"] = 247, ["Traj_Titre"] = "Trajet Metro", ["code_api_from"] = "stop_area:OIF:SA:8738247", ["code_api_to"] = "stop_area:OIF:SA:59:6263515", ["User_code_API"] = "placé ici votre code API SNCF ou Navitia", ["api_url"] = "https://api.navitia.io/v1", ["api_coverage"] = "fr-idf", ["api_heure_depart"] = "", ["Msg_Sonos"] = "Non", ["Volume_Sonos"] = 10, ["Msg_Depart"] = "letan la ville", -- écriture phonétique pour TTS ["Msg_Arrivee"] = "La Défense" -- écriture phonétique pour TTS } } ---------------------------------------------------------------------------------- -- Id de l'icone représentant un trafic normal -- Id de l'icone représentant un trafic avec du retard ou perturbé ---------------------------------------------------------------------------------- local IconeID_TraficOk = 1091 local IconeID_TraficNOk = 1092 local modetrace = true local modedebug = true ---------------------------------------------------------------------------------- -- Ne pas modifier le code ci-dessous, sinon pour l'adapter à votre usage ---------------------------------------------------------------------------------- local TimeOut = 3000 ---------------------------------------------------------------------------------- -- Message pour mode Trace ---------------------------------------------------------------------------------- function Trace(color, message) if modetrace then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end ---------------------------------------------------------------------------------- -- Message pour mode Debug ---------------------------------------------------------------------------------- function Debug(color, message) if modedebug then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end function SetUI(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".value", value); end function SetUI_label(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".label", value); end ---------------------------------------------------------------------------------- -- encoding to base64 ---------------------------------------------------------------------------------- -- character table string -- encoding to base64 function encode64(data) local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' return ((data:gsub('.', function(x) local r,b='',x:byte() for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end return r; end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x) if (#x < 6) then return '' end local c=0 for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end return b:sub(c+1,c+1) end)..({ '', '==', '=' })[#data%3+1]) end ---------------------------------------------------------------------------------- -- Retourne le jour de la semaine en clair ---------------------------------------------------------------------------------- function josdGetJourSemaine(jour) josdGetJourSemaineTab={[0]="Dimanche",[1]="Lundi",[2]="Mardi",[3]="Mercredi",[4]="Jeudi",[5]="Vendredi",[6]="Samedi"} return josdGetJourSemaineTab[tonumber(jour)] end ---------------------------------------------------------------------------------- -- Conversion un nombre de seconde en texte xhxmin ou xmin ---------------------------------------------------------------------------------- function Conversion_Seconde_en_Texte(NbSec) local NbH=math.floor(NbSec/60/60) NbSec = NbSec - NbH * 60 * 60 local NbM=math.floor(NbSec/60) NbSec = NbSec - NbH * 60 if NbH > 0 then return NbH.."h"..NbM.."min" else return NbM.."min" end end function CalculJourSuivantSelonHeure(heure) local Aujourdhui = os.date("*t") Aujourdhui.hour = string.sub (heure, 1, 2) Aujourdhui.min = string.sub (heure, 4, 5) if os.time() <= os.time(Aujourdhui) then return (os.time(Aujourdhui)) else return (os.time(Aujourdhui) + (24*60*60)) -- ajout d'1 jour end end ---------------------------------------------------------------------------------- -- Conversion format date "aaaammjjThhmmss" en format date ---------------------------------------------------------------------------------- function Conversion_Date(dateheure) local TableDate = os.date("*t") TableDate.day = string.sub (dateheure, 7, 8) TableDate.month = string.sub (dateheure, 5, 6) TableDate.year = string.sub (dateheure, 1, 4) TableDate.hour = string.sub (dateheure, 10, 11) TableDate.min = string.sub (dateheure, 12, 13) return (os.time(TableDate)) end ---------------------------------------------------------------------------------- -- Conversion format date "aaaammjjThhmmss" en format date ---------------------------------------------------------------------------------- function Conversion_Date(dateheure) local TableDate = os.date("*t") TableDate.day = string.sub (dateheure, 7, 8) TableDate.month = string.sub (dateheure, 5, 6) TableDate.year = string.sub (dateheure, 1, 4) TableDate.hour = string.sub (dateheure, 10, 11) TableDate.min = string.sub (dateheure, 12, 13) return (os.time(TableDate)) end function Effacement_Data() SetUI(VD_Id, "lblFromTo", "") SetUI(VD_Id, "lblDepArr", "") SetUI(VD_Id, "lblNum", "") SetUI(VD_Id, "lblTraficDepart", "") SetUI(VD_Id, "lblTraficArrivee", "") SetUI(VD_Id, "lblTraficCause", "") for i = 1, 9 do SetUI(VD_Id, "lblIti"..i, " ") end end function Traitement_Retard(Status, Perturbations, First_stop_point, Last_stop_point) Debug("grey","First_stop_point="..First_stop_point) Debug("grey","Last_stop_point="..Last_stop_point) if Status == "" then fibaro:call(VD_Id , "setProperty", "currentIcon", IconeID_TraficOk) SetUI(VD_Id, "lblTraficDepart", "ras") SetUI(VD_Id, "lblTraficArrivee", "ras") SetUI(VD_Id, "lblTraficCause", "ras") else fibaro:call(VD_Id , "setProperty", "currentIcon", IconeID_TraficNOk) SetUI(VD_Id, "lblTraficDepart", "") SetUI(VD_Id, "lblTraficArrivee", "") SetUI(VD_Id, "lblTraficCause", "") if Status == "SIGNIFICANT_DELAYS" then local Perdu_Lib_Depart = "" local Perdu_Lib_Arrivee = "" for Num_Pertu = 1 , #Perturbations do Debug("grey", "Trace 1 / status="..Perturbations[Num_Pertu].status.." / "..Perturbations[Num_Pertu].cause) SetUI(VD_Id, "lblTraficCause", Perturbations[Num_Pertu].cause) local impacted_objects = Perturbations[Num_Pertu].impacted_objects Debug("grey", "Trace 2 / impacted_objects ="..#impacted_objects) for Num_impacted_objects = 1 , #impacted_objects do local impacted_stops = impacted_objects[Num_impacted_objects].impacted_stops Debug("grey", "Trace 3 / impacted_stops ="..#impacted_stops) for Num_impacted_stops = 1 , #impacted_stops do local stop_point = impacted_stops[Num_impacted_stops].stop_point Debug("grey", "Trace 4 / stop_point ="..Num_impacted_stops) Debug("grey", "Trace 5 / First_stop_point=".."*"..First_stop_point.."*") Debug("grey", "Trace 6 / First_stop_point=".."*"..stop_point.id.."*") if stop_point.id == First_stop_point then Debug("grey","Trouve First_stop_point="..stop_point.id) if impacted_stops[Num_impacted_stops].departure_status == "delayed" then Perdu_Lib_Depart = Conversion_Seconde_en_Texte(tonumber(impacted_stops[Num_impacted_stops].amended_departure_time) - tonumber(impacted_stops[Num_impacted_stops].base_departure_time)) SetUI(VD_Id, "lblTraficDepart", "Retard de "..Perdu_Lib_Depart) end break end end for Num_impacted_stops = 1 , #impacted_stops do local stop_point = impacted_stops[Num_impacted_stops].stop_point Debug("grey", "Trace 7 / stop_point ="..Num_impacted_stops) Debug("grey", "Trace 5 / Last_stop_point=".."*"..Last_stop_point.."*") Debug("grey", "Trace 6 / Last_stop_point=".."*"..stop_point.id.."*") if stop_point.id == Last_stop_point then Debug("grey","Trouve Last_stop_point="..stop_point.id) if impacted_stops[Num_impacted_stops].departure_status == "delayed" then Perdu_Lib_Arrivee = Conversion_Seconde_en_Texte(tonumber(impacted_stops[Num_impacted_stops].amended_arrival_time) - tonumber(impacted_stops[Num_impacted_stops].base_arrival_time)) end break end end end end if Perdu_Lib_Depart == "" then SetUI(VD_Id, "lblTraficDepart", "ras") else SetUI(VD_Id, "lblTraficDepart", "Retard de "..Perdu_Lib_Depart) end if Perdu_Lib_Arrivee == "" then SetUI(VD_Id, "lblTraficArrivee", "ras") else SetUI(VD_Id, "lblTraficArrivee", "Retard de "..Perdu_Lib_Arrivee) end else SetUI(VD_Id, "lblTraficCause", Status) end end end function Affiche_Iti(Sections, Status, Perturbations, Traj_Num, From) local Last_PT = nil local Max_Nb_Iti= 0 local Nb_Iti = 0 if #Sections > 9 then Max_Nb_Iti = 9 else Max_Nb_Iti = #Sections end Debug("grey","Nb_Section, Max_Nb_Iti="..#Sections..", "..Max_Nb_Iti) local First_stop_point = "" local Last_stop_point = "" for Num_Iti = 1 , Max_Nb_Iti do local Itineraire = Sections[Num_Iti] if Itineraire.type == "waiting" then Debug("grey","Traitement Trajet-Itinéraire, type : "..Traj_Num.."-"..Num_Iti.." ,"..Itineraire.type) else Debug("grey","Traitement Trajet-Itinéraire, type, embedded_type : "..Traj_Num.."-"..Num_Iti.." ,"..Itineraire.type.." , "..Itineraire.to.embedded_type) end if Itineraire.type == "public_transport" then Last_PT = Num_Iti end local Date_Time = Conversion_Date(Itineraire.departure_date_time) local Heure_Depart = os.date("%H:%M", Date_Time) local Date_Time = Conversion_Date(Itineraire.arrival_date_time) local Duree = "("..Conversion_Seconde_en_Texte(tonumber(Itineraire.duration))..")" local Heure_Arrivee = os.date("%H:%M", Date_Time) local Mode_Depl = "" local Moyen_Depl if Itineraire.type == "waiting" then Mode_Depl = "attendre" elseif Itineraire.type == "walking" then if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if Itineraire.from.embedded_type == "stop_point" then First_stop_point = Itineraire.from.stop_point.id else First_stop_point = Itineraire.from.stop_area.id end else Der_Dest = Itineraire.to.stop_area.name end Mode_Depl = "marcher" elseif Itineraire.type == "transfer" then if Itineraire.transfer_type == "walking" then if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if Itineraire.from.embedded_type == "stop_point" then First_stop_point = Itineraire.from.stop_point.id else First_stop_point = Itineraire.from.stop_area.id end else Der_Dest = Itineraire.to.stop_area.name end Mode_Depl = "marcher" end elseif Itineraire.type == "street_network" then if Itineraire.mode == "walking" then if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if Itineraire.from.embedded_type == "stop_point" then First_stop_point = Itineraire.from.stop_point.id else First_stop_point = Itineraire.from.stop_area.id end else Der_Dest = Itineraire.to.stop_area.name end Mode_Depl = "marcher" end elseif Itineraire.type == "crow_fly" then if Itineraire.mode == "walking" then if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if First_stop_point == "" then if Itineraire.from.embedded_type == "stop_point" then First_stop_point = Itineraire.from.stop_point.id else First_stop_point = Itineraire.from.stop_area.id end end else Der_Dest = Itineraire.to.stop_area.name end Mode_Depl = "marcher" end else if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if Itineraire.from.embedded_type == "stop_point" then First_stop_point = Itineraire.from.stop_point.id else First_stop_point = Itineraire.from.stop_area.id end else Der_Dest = Itineraire.to.stop_area.name end Mode_Depl = "prendre" Moyen_Depl = Itineraire.display_informations.physical_mode if Itineraire.display_informations.code ~= "" then Moyen_Depl = Moyen_Depl .. " / ligne "..Itineraire.display_informations.code end if Itineraire.display_informations.headsign ~= "" and Itineraire.display_informations.network ~= "METRO" and Itineraire.display_informations.physical_mode ~= "Bus" then Moyen_Depl = Moyen_Depl .. " / "..Itineraire.display_informations.headsign end end local Lbl_message ="" if Mode_Depl == "prendre" or Mode_Depl == "marcher" then Lbl_message = "à "..Heure_Depart --.." -> "..Date_Arrivee Lbl_message = Lbl_message.." "..Mode_Depl if Mode_Depl == "prendre" then Lbl_message = Lbl_message.." "..Moyen_Depl end Lbl_message = Lbl_message.." "..Duree Lbl_message = Lbl_message.." vers "..Der_Dest Lbl_message = Lbl_message.." arrivée à "..Heure_Arrivee elseif Mode_Depl == "attendre" then Lbl_message = "à "..Heure_Depart Lbl_message = Lbl_message.." "..Mode_Depl Lbl_message = Lbl_message.." à "..Der_Dest Lbl_message = Lbl_message.." "..Duree Lbl_message = Lbl_message.." jusqu'à "..Heure_Arrivee end if tonumber(Itineraire.duration) == 0 then Max_Nb_Iti = Max_Nb_Iti -1 else Nb_Iti = Nb_Iti + 1 SetUI(VD_Id, "lblIti"..Nb_Iti, Lbl_message) end end if Nb_Iti < 9 then for i = Nb_Iti + 1, 9 do SetUI(VD_Id, "lblIti"..i, " ") end end SetUI(VD_Id, "lblFromTo", From.. " -> " ..Der_Dest) ------------------------------------------------------------------------------- -- Traitement des retards ------------------------------------------------------------------------------- Traitement_Retard(Status, Perturbations, First_stop_point, Last_stop_point) return Der_Dest end function Affiche_Traj(data) local Traj_Num = tonumber(string.sub(fibaro:get(VD_Id, "ui.lblNum.value"), -1)) local Trajet = data.journeys local From = "" if #Trajet < Traj_Num then local Traj_Text = fibaro:get(VD_Id, "ui.lblNum.value") local Traj_Sens = string.sub(Traj_Text, 1, 1) Effacement_Data() SetUI(VD_Id, "lblDepArr", "Plus de trajets disponibles") Traj_Num = Traj_Num - 1 if Traj_Sens == "A" then fibaro:call(VD_Id, "setProperty", "ui.lblNum.value", "Aller N° "..Traj_Num) else fibaro:call(VD_Id, "setProperty", "ui.lblNum.value", "Retour N° "..Traj_Num) end Der_Dest = "" else Trace("blue","Traitement Trajet : "..Traj_Num) if data.journeys[Traj_Num].sections[1].from.embedded_type == "stop_point" then From = data.journeys[Traj_Num].sections[1].from.stop_point.name else From = data.journeys[Traj_Num].sections[1].from.stop_area.name end local Date_Time = Conversion_Date(data.journeys[Traj_Num].departure_date_time) local Lbl_message = os.date("%H:%M", Date_Time) local Date_Time = Conversion_Date(data.journeys[Traj_Num].arrival_date_time) Lbl_message = Lbl_message .." -> "..os.date("%H:%M", Date_Time).." ("..Conversion_Seconde_en_Texte(tonumber(data.journeys[Traj_Num].duration))..")" SetUI(VD_Id, "lblDepArr", Lbl_message) local Der_Dest = Affiche_Iti(data.journeys[Traj_Num].sections, data.journeys[Traj_Num].status, data.disruptions, Traj_Num, From) end return Der_Dest end ---------------------------------------------------------------------------------- -- Traitement des données en provenance de l'IPA SNCF ---------------------------------------------------------------------------------- function GetData() fibaro:call(VD_Id , "setProperty", "currentIcon", IconeID_TraficOk) Debug("grey","T1".." - "..Traj_Titre) -- local api_url = "https://api.sncf.com/v1" -- local api_coverage = "sncf" local api_fonction = "journeys?" local Traj_Sens = string.sub(fibaro:get(VD_Id, "ui.lblNum.value"), 1, 1) local api_from = "" local api_to = "" if Traj_Sens == "A" then api_from = code_api_from api_to = code_api_to else api_from = code_api_to api_to = code_api_from end local api_datetime if api_heure_depart == "" then api_datetime = os.date("%Y%m%dT%H%M%S", os.time()) else api_datetime = os.date("%Y%m%dT%H%M00", CalculJourSuivantSelonHeure(api_heure_depart)) end local api_datetime_represents = "departure" local api_min_nb_journeys = "9" local Query = api_url local Query = Query .. "/coverage/" .. api_coverage local Query = Query .. "/" .. api_fonction local Query = Query .. "from=" .. api_from.."&" local Query = Query .. "to=" .. api_to.."&" local Query = Query .. "datetime=" .. api_datetime.."&" local Query = Query .. "datetime_represents=" .. api_datetime_represents.."&" local Query = Query .. "min_nb_journeys=" .. api_min_nb_journeys Debug("grey","T2".." - "..Traj_Titre) local http = net.HTTPClient({ timeout = TimeOut }) Debug("grey","T3".." - "..Traj_Titre) Debug("grey",Query) local ok = pcall(function() http:request(Query, { options = { method = 'GET', headers ={ ["Content-Type"] = "application/json", ["Authorization"] = "BASIC "..User_code_API_Encode64}, data = body }, success = function(response) Debug("grey","T4".." - "..Traj_Titre) if response.status == 200 then Debug("grey","T5".." - "..Traj_Titre) Trace("blue","Traitement ok : "..Traj_Titre) local status, data = pcall(json.decode, response.data) if (status and data) then local Der_Dest = Affiche_Traj(data) if Der_Dest == "" then Debug("grey","Plus de trajet à afficher") else if data.journeys[1].sections[1].from.embedded_type == "stop_point" then Trace("green","Départ : "..data.journeys[1].sections[1].from.stop_point.name) else Trace("green","Départ : "..data.journeys[1].sections[1].from.stop_area.name) end Trace("green","Direction : "..Der_Dest) local Date_Time = Conversion_Date(data.journeys[1].sections[1].departure_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", MonHeure)) -- Test pour vérifier si le prochain départ est pour le jour même if os.date("%Y/%m/%d",Date_Time) == os.date("%Y/%m/%d",time) then Prochain_Depart = "aujourd'hui" else Prochain_Depart = JourSemaine end Trace("green", "Prochain départ "..Prochain_Depart.." à " ..os.date("%H:%M", Date_Time)) message = "Prochain départ" message = message .. " "..Prochain_Depart message = message .. " de "..Msg_Depart message = message .. " pour "..Msg_Arrivee message = message .. " a ".. Horaire local Date_Time = Conversion_Date(data.journeys[1].sections[1].arrival_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", Date_Time)) message = message .. " Arrivée à "..Horaire Trace("green", "Arrivée à " ..os.date("%H:%M", Date_Time)) -- Envoi d'un message sur l'enceinte SONOS if Msg_Sonos == "OUI" then Debug("grey", "Envoi Message sur enceinte SONOS") fibaro:startScene(SceneID_Sonos, {{msg = message}, {vol = Volume_Sonos}}) end end else Trace("orange"," Attention : Aucunes données à traiter") Effacement_Data() SetUI(VD_Id, "lblDepArr", "Erreur =".."aucune données") end else Debug("grey","T6".." - "..Traj_Titre) Trace("yellow","Traitement ko : "..Traj_Titre) Effacement_Data() SetUI(VD_Id, "lblDepArr", "Erreur ="..response.status) if response.status == 500 or response.status == 503 then Trace("orange","Erreur d'indisponibilité du serveur") else Trace("orange","Erreur requête serveur, response.status = "..response.status) end end end, error = function(err) Debug("grey","T7".." - "..Traj_Titre) Trace("orange","Erreur de reception de données, Erreur = ".. err) Effacement_Data() SetUI(VD_Id, "lblDepArr", "Erreur ="..err) end }) end) if not(ok) then Trace("orange","Erreur dans l'exécution de fhttp:request(Query") end Debug("grey","T9".." - "..Traj_Titre) end function Start() Debug("grey","VD_Id="..VD_Id.." / Volume_Sonos="..Volume_Sonos.." / Msg_Sonos="..Msg_Sonos) -- test pour vérifier si le module virtuel exist ou pas local ip = fibaro:get(VD_Id, 'IPAddress') if ip == nil then Debug("orange","Warning : Le module virtuel : "..VD_Id.." n'existe pas. Vous devez le créer !") else -- Lancement du traitement de l'itinéraire GetData() end end ------------------------------------------------------------------------------- -- Begining off Scène ------------------------------------------------------------------------------- local params = fibaro:args() Trace("orange","Début de traitement de la scène") if (params) then for k, v in ipairs(params) do if (v.VD_Id) then VD_Id = v.VD_Id end end local Trouve_VD_Id = false for i = 1, #Trajets do if VD_Id == Trajets[i].VD_Id then Debug("grey","VD_Id="..VD_Id.." ("..fibaro:getName(VD_Id)..") a bien été trouvé") Traj_Titre = Trajets[i].Traj_Titre code_api_from = Trajets[i].code_api_from code_api_to = Trajets[i].code_api_to api_url = Trajets[i].api_url api_coverage = Trajets[i].api_coverage api_heure_depart = Trajets[i].api_heure_depart Msg_Sonos = Trajets[i].Msg_Sonos Volume_Sonos = Trajets[i].Volume_Sonos Msg_Depart = Trajets[i].Msg_Depart Msg_Arrivee = Trajets[i].Msg_Arrivee User_code_API = Trajets[i].User_code_API Trouve_VD_Id = true break end end User_code_API_Encode64 = encode64(User_code_API) if Trouve_VD_Id then Start() else Trace("orange","Erreur : Votre VD n'a pas été trouvé dans le tableau Trajets") end else Trace("orange","Erreur : Cette scène fonctionne par appel depuis un VD avec un passage de paramètres") end Trace("orange","Fin de traitement de la scène")
-
Pour ce faire il faut programmer une mise à jour du VD (clic sur le premier bouton) à un moment précis qui précède l'heure de départ théorique du train que l'on veut prendre. Sinon si l'on actualise régulièrement le VD, nous seront pollué par des messages (dès lors qu'un trajet présente un retard). Je suis entrain de regarder la possibilité de définir une fonction qui permettrait de rechercher un prochain trajet à partir d'un horaire précis qui serait paramétrable. Et dans ce cas il n'y aurait plus de risque de pollution de message et il serait donc possible à tout moment de faire la recherche. Par exemple dès la veille. Après, il conviendra de déterminer le mode d'envoi des messages (mail, sms, notification, TTS, ...)
-
un petit avant gout d'un itinéraire utilisant le train et le métro avec un peu de marche entre les stations
-
Merci pour ce test et cette confirmation du bon fonctionnement des retards dans les trajets. J'ai ajouté comme demandé le n° de train (voir ci-dessous). Ce sera disponible dans la prochaine version. Cette nouvelle version va également apporter la possibilité de se connecter à une autre base API (api.navitia.io) qui contient les lignes de Metro et de Bus (mais sans les indication sur les retards, dommage).
-
C'est bon j'ai intégré les icônes paramétrables. Ce sera dispo. dans la prochaine MAJ. Mais du coup, il faudra repasser par un chargement de VD
-
Voici une nouvelle version 0.6 Cette nouvelle version apporte : Affichage d'alertes sur les retards au départ/arrivée avec la cause (si disponible) Consolidation de l'ensemble des paramètres des trajets dans la scène pour simplifier leur mise à jour et les rassemblent à un seul et même endroit Possibilité d'utiliser plusieurs trajets au travers de plusieurs VD et consolider les informations au niveau de la scène Il n'est plus nécessaire d'encoder le code d'accès à l'API SNCF. La scène le fait tout seule Indication qu'il n'y a plus de trajets disponible lors de la navigation dans les trajets (inférieur à 5) Possibilité d'utiliser comme point de départ ou d'arrivée, soit un : stop_points (lieu d'arrêt dans une Gare) stop_areas (lieu tel qu'une localité) c'est utile lorsqu'il y a plusieurs gares dans une localité et ne pas avoir à choisir une gare en particulier. C'est notamment pénible lorsqu'il faut choisir entre les gares TGV, Corail, RER, Francilien, ... 1) Veuillez installer le nouveau VD ci-dessous : Itinéraire_SNCF.vfib.json Spéciale dédicace pour @Sakkhho maintenant que les codes (stop_points ou stop_areas) sont intégré dans la scène. il sera moins nécéssaire de rechercher le VD lors de mise à jours. plus de modification des boutons sur le VD et répercussion des modifications dans le code de chacun des boutons. Reste néanmoins à modifier pour cette fois la variable SceneID_Traj_SNCF par l'ID de la Scène Itinéraire SNCF. Enfin, jusqu'à la prochaine livraison d'un nouveau VD. 2) Veuillez charger le nouveau code de la scène : Il convient de : modifier le contenu de la variable User_API_Sncf par votre code obtenu par mail par la SNCF. Mais cette en le laissant sans encodage 64. modifier/compléter la liste des variables utilisateur : VD_Id = Id du VD de pilotage de votre Trajet Traj_Titre = Désignation du trajet pour le répéter des le mode debug code_api_from = Code de votre station de départ évoqué ci-dessus code_api_to = Code de votre station d'arrivée évoqué ci-dessus Msg_Sonos = Indication si souhaitez envoyer un message sur votre Sonos Volume_Sonos = Niveau du volume du message Msg_Depart = Non en phonétique de votre point de départ, pour message Sonos Msg_Arrivee = Non en phonétique de votre point d'arrivée, pour message Sonos si vous utilisez plusieurs trajets (plusieurs VD), vous devez compléter/dupliquer cette liste pour chacun des VD 3) Bons tests PS : Les étapes suivantes du projet seront probablement consacré à la mixité des modes de transport entre (Trains, RER, BUS, Metro) la recherche s'il y a des perturbations sur l'une des lignes utilisées par le trajet. Si vous avez d'autres idées, vous pouvez toujours faire vos demandes --[[ %% properties %% events %% globals --]] ---------------------------------------------------------------------------------- -- Name : HC2 SNCF Itinéraire -- Type : Virtual Device & Scene -- Cette scène permet d'obtenir l'horaire du prochain train au départ d'une gare ---------------------------------------------------------------------------------- -- Evolution du Projet à venir : -- l'identification des incidents sur le trafic (retard) -- la mixité des modes de transport entre (Trains, RER, BUS, Metro) ---------------------------------------------------------------------------------- -- Version : 0.6 -- Création : MAM78 -- Date MAJ : 15/07/2017 -- -- Evolutions : -- V0.1 09/07/2017 : 1) Initialisation du projet -- -- V0.2 10/07/2017 : 1) Association de la scène à un VD qui appel la scène en -- passant les paramètres de la recherche d'itinéraire -- -- V0.3 12/07/2017 : 1) Ajouts de boutons de navigation pour parcourir les diférents -- itinéraires par odre chronologique des départs -- -- V0.4 13/07/2017 : 1) La décomposition du parcours sur chacune des étapes -- (changements) Maximum 9 étapes pour le moment. -- 2) Le temps de trajet global, ainsi que par étape -- 3) Le mode de circulation pour chacune des étape -- (La ligne à utiliser, Trajet à pied, Attente en gare, ... -- 4) La possibilité de choisir le mode retour (inversion entre -- le point de départ et d'arrivé). -- -- V0.5 13/07/2017 : 1) Possibilité d'utiliser les flèches de navigation que ce -- soit pour un trajet Aller ou Retour -- -- V0.6 14/07/2017 : 1) affichage d'alertes sur les retards au départ/arrivée -- avec la cause (si disponible) -- 2) Consolidation de l'ensemble des paramètres des trajets -- dans la scène pour simplifier leur mise à jour et les -- rassembler à un seul et même endroit -- 3) Possibilité d'utiliser plusieurs trajets au travers -- de plusieurs VD et consolider les informations -- au niveau de la scène -- 4) Il n'est plus nécessaire d'encoder le code d'accès à -- l'API SNCF. La scène le fait tout seule -- 5) Indication qu'il n'y a plus de trajets disponible -- lors de la navigation dans les trajets (inférieur à 5) -- 6) Possibilité d'ultiliser comme point de départ -- ou d'arrivée, soit un : -- - stop_points (lieu d'arrêt Gare) -- - stop_areas (lieu tel qu'une localité) c'est utile -- lorsqu'il y a plusieurs gares dans une localité ---------------------------------------------------------------------------------- ---------------------------------------------------------------------------------- -- Pour pouvoir utiliser l'API de la SNCF, vous devez vous créer un compte sur : -- https://data.sncf.com/api -- Une fois votre compte créé vous recevrez un mail avec une clé d’authentification ---------------------------------------------------------------------------------- local User_API_Sncf = "placé ici votre code API SNCF" ---------------------------------------------------------------------------------- -- User variables ---------------------------------------------------------------------------------- -- Les variables ci-dessous (code_api_from & code_api_to) détermine le trajet -- que vous souhaitez utiliser -- Ces codes sont récupérables sur le site : -- http://canaltp.github.io/navitia-playground/play.html -- Saisir dans champs : -- API = https://api.sncf.com/v1 -- Token = le contenu de la variable User_API_Sncf renseigné ci-dessus -- coverage = sncf -- stop_points ou stop_areas = saisir le nom de votre point de départ -- -> Votre saisie va se transformer en un code -- Recopier ce code dans la variable code_api_from -- stop_points ou stop_areas = saisir le nom de votre point d'arrivée -- -> Votre saisie va se transformer en un code -- Recopier ce code dans la variable code_api_to -- empty feature = departures -- Cliquer sur le bouton SUBMIT -- vous devriez obtenir la liste des prochains départ ---------------------------------------------------------------------------------- -- La structure Trajet ci-dessous vous permet de définir l'ensemble des trajets -- que vous souhaitez créer. Chacune des ces structures correspond un VD -- qui permet de piloter vos trajets. Un Trajet = Un VD -- VD_Id ci-dessous permet de faire la correspondance avec les paramètres ci-dessous ---------------------------------------------------------------------------------- -- Description des variables : -- VD_Id = Id du VD de pilotage de votre Trajet -- Traj_Titre = Désignation du trajet pour le répérer dans en mode debug -- code_api_from = Code de votre station de départ évoqué ci-dessus -- code_api_to = Code de votre station d'arrivée évoqué ci-dessus -- Msg_Sonos = Indication si souhaitez envoyer un message sur votre Sonos -- Volume_Sonos = Niveau du volume du message -- Msg_Depart = Non en phonétique de votre point de départ, pour message Sonos -- Msg_Arrivee = Non en phonétique de votre point d'arrivée, pour message Sonos ---------------------------------------------------------------------------------- local Trajets = { { ["VD_Id"] = 245, ["Traj_Titre"] = "Trajet A", ["code_api_from"] = "stop_point:OCE:SP:TrainTER-87761007", ["code_api_to"] = "stop_point:OCE:SP:TrainTER-87725689", ["Msg_Sonos"] = "Non", ["Volume_Sonos"] = 10, ["Msg_Depart"] = "letan la ville", -- écriture phonétique pour TTS ["Msg_Arrivee"] = "La Défense" -- écriture phonétique pour TTS }, { ["VD_Id"] = 999, ["Traj_Titre"] = "Trajet A", ["code_api_from"] = "stop_area:OCE:SA:87386573", ["code_api_to"] = "stop_point:OCE:SP:Transilien-87382218&", ["Msg_Sonos"] = "Non", ["Volume_Sonos"] = 10, ["Msg_Depart"] = "letan la ville", -- écriture phonétique pour TTS ["Msg_Arrivee"] = "La Défense" -- écriture phonétique pour TTS } } local modetrace = true local modedebug = true ---------------------------------------------------------------------------------- -- Ne pas modifier le code ci-dessous, sinon pour l'adapter à votre usage ---------------------------------------------------------------------------------- local TimeOut = 3000 ---------------------------------------------------------------------------------- -- Message pour mode Trace ---------------------------------------------------------------------------------- function Trace(color, message) if modetrace then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end ---------------------------------------------------------------------------------- -- Message pour mode Debug ---------------------------------------------------------------------------------- function Debug(color, message) if modedebug then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end function SetUI(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".value", value); end function SetUI_label(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".label", value); end ---------------------------------------------------------------------------------- -- encoding to base64 ---------------------------------------------------------------------------------- -- character table string -- encoding to base64 function encode64(data) local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' return ((data:gsub('.', function(x) local r,b='',x:byte() for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end return r; end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x) if (#x < 6) then return '' end local c=0 for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end return b:sub(c+1,c+1) end)..({ '', '==', '=' })[#data%3+1]) end ---------------------------------------------------------------------------------- -- Retourne le jour de la semaine en clair ---------------------------------------------------------------------------------- function josdGetJourSemaine(jour) josdGetJourSemaineTab={[0]="Dimanche",[1]="Lundi",[2]="Mardi",[3]="Mercredi",[4]="Jeudi",[5]="Vendredi",[6]="Samedi"} return josdGetJourSemaineTab[tonumber(jour)] end ---------------------------------------------------------------------------------- -- Conversion un nombre de seconde en texte xhxmin ou xmin ---------------------------------------------------------------------------------- function Conversion_Seconde_en_Texte(NbSec) local NbH=math.floor(NbSec/60/60) NbSec = NbSec - NbH * 60 * 60 local NbM=math.floor(NbSec/60) NbSec = NbSec - NbH * 60 if NbH > 0 then return NbH.."h"..NbM.."min" else return NbM.."min" end end ---------------------------------------------------------------------------------- -- Conversion format date "aaaammjjThhmmss" en format date ---------------------------------------------------------------------------------- function Conversion_Date(dateheure) local TableDate = os.date("*t") TableDate.day = string.sub (dateheure, 7, 8) TableDate.month = string.sub (dateheure, 5, 6) TableDate.year = string.sub (dateheure, 1, 4) TableDate.hour = string.sub (dateheure, 10, 11) TableDate.min = string.sub (dateheure, 12, 13) return (os.time(TableDate)) end function Effacement_Data() SetUI(VD_Id, "lblFromTo", "") SetUI(VD_Id, "lblDepArr", "") SetUI(VD_Id, "lblNum", "") SetUI(VD_Id, "lblTraficDepart", "") SetUI(VD_Id, "lblTraficArrivee", "") for i = 1, 9 do SetUI(VD_Id, "lblIti"..i, " ") end end function Traitement_Retard(Status, Perturbations, First_stop_point, Last_stop_point) Debug("grey","First_stop_point="..First_stop_point) Debug("grey","Last_stop_point="..Last_stop_point) Debug("grey","Status=".."*"..Status.."*") if Status == "" then SetUI(VD_Id, "lblTraficDepart", "RAS") SetUI(VD_Id, "lblTraficArrivee", "RAS") else SetUI(VD_Id, "lblTraficDepart", "") SetUI(VD_Id, "lblTraficArrivee", "") if Status == "SIGNIFICANT_DELAYS" then local Perdu_Lib_Depart = "" local Perdu_Lib_Arrivee = "" for Num_Pertu = 1 , #Perturbations do Debug("grey", "Trace 1 / status="..Perturbations[Num_Pertu].status.." / "..Perturbations[Num_Pertu].cause) SetUI(VD_Id, "lblTraficCause", Perturbations[Num_Pertu].cause) local impacted_objects = Perturbations[Num_Pertu].impacted_objects Debug("grey", "Trace 2 / impacted_objects ="..#impacted_objects) for Num_impacted_objects = 1 , #impacted_objects do local impacted_stops = impacted_objects[Num_impacted_objects].impacted_stops Debug("grey", "Trace 3 / impacted_stops ="..#impacted_stops) for Num_impacted_stops = 1 , #impacted_stops do local stop_point = impacted_stops[Num_impacted_stops].stop_point Debug("grey", "Trace 4 / stop_point ="..Num_impacted_stops) Debug("grey", "Trace 5 / First_stop_point=".."*"..First_stop_point.."*") Debug("grey", "Trace 6 / First_stop_point=".."*"..stop_point.id.."*") if stop_point.id == First_stop_point then Debug("grey","Trouve First_stop_point="..stop_point.id) if impacted_stops[Num_impacted_stops].departure_status == "delayed" then Perdu_Lib_Depart = Conversion_Seconde_en_Texte(tonumber(impacted_stops[Num_impacted_stops].amended_departure_time) - tonumber(impacted_stops[Num_impacted_stops].base_departure_time)) SetUI(VD_Id, "lblTraficDepart", "Retard de "..Perdu_Lib_Depart) end break end end for Num_impacted_stops = 1 , #impacted_stops do local stop_point = impacted_stops[Num_impacted_stops].stop_point Debug("grey", "Trace 7 / stop_point ="..Num_impacted_stops) Debug("grey", "Trace 5 / Last_stop_point=".."*"..Last_stop_point.."*") Debug("grey", "Trace 6 / Last_stop_point=".."*"..stop_point.id.."*") if stop_point.id == Last_stop_point then Debug("grey","Trouve Last_stop_point="..stop_point.id) if impacted_stops[Num_impacted_stops].departure_status == "delayed" then Perdu_Lib_Arrivee = Conversion_Seconde_en_Texte(tonumber(impacted_stops[Num_impacted_stops].amended_arrival_time) - tonumber(impacted_stops[Num_impacted_stops].base_arrival_time)) end break end end end end if Perdu_Lib_Depart == "" then SetUI(VD_Id, "lblTraficDepart", "RAS") else SetUI(VD_Id, "lblTraficDepart", "Retard de "..Perdu_Lib_Depart) end if Perdu_Lib_Arrivee == "" then SetUI(VD_Id, "lblTraficArrivee", "RAS") else SetUI(VD_Id, "lblTraficArrivee", "Retard de "..Perdu_Lib_Arrivee) end else SetUI(VD_Id, "lblTraficDepart", Status) end end end function Affiche_Iti(Sections, Status, Perturbations, Traj_Num) local Last_PT = nil local Max_Nb_Iti= 0 local Nb_Iti = 0 if #Sections > 9 then Max_Nb_Iti = 9 else Max_Nb_Iti = #Sections end Debug("grey","Nb_Section, Max_Nb_Iti="..#Sections..", "..Max_Nb_Iti) local First_stop_point = "" local Last_stop_point = "" for Num_Iti = 1 , Max_Nb_Iti do local Itineraire = Sections[Num_Iti] if Itineraire.type == "waiting" then Debug("grey","Traitement Trajet-Itinéraire, type : "..Traj_Num.."-"..Num_Iti.." ,"..Itineraire.type) else Debug("grey","Traitement Trajet-Itinéraire, type, embedded_type : "..Traj_Num.."-"..Num_Iti.." ,"..Itineraire.type.." , "..Itineraire.to.embedded_type) end if Itineraire.type == "public_transport" then Last_PT = Num_Iti end local Date_Time = Conversion_Date(Itineraire.departure_date_time) local Lbl_message = "("..Conversion_Seconde_en_Texte(tonumber(Itineraire.duration))..")" local Date_Time = Conversion_Date(Itineraire.arrival_date_time) Lbl_message = Lbl_message.." -> "..os.date("%H:%M", Date_Time) if Itineraire.type == "waiting" then Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." -> " .."[En ATTENTE]" elseif Itineraire.type == "walking" then if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if First_stop_point == "" then First_stop_point = Itineraire.from.stop_point.id end else Der_Dest = Itineraire.to.stop_area.name end Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." -> " .."[à PIED]" elseif Itineraire.type == "transfer" then if Itineraire.transfer_type == "walking" then if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if First_stop_point == "" then First_stop_point = Itineraire.from.stop_point.id end else Der_Dest = Itineraire.to.stop_area.name end Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." -> " .."[à PIED]" end elseif Itineraire.type == "crow_fly" then if Itineraire.mode == "walking" then if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if First_stop_point == "" then First_stop_point = Itineraire.from.stop_point.id end else Der_Dest = Itineraire.to.stop_area.name end Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." -> " .."[à PIED]" end else if Itineraire.to.embedded_type == "stop_point" then Der_Dest = Itineraire.to.stop_point.name Last_stop_point = Itineraire.to.stop_point.id if First_stop_point == "" then First_stop_point = Itineraire.from.stop_point.id end else Der_Dest = Itineraire.to.stop_area.name end Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." ["..Itineraire.display_informations.commercial_mode .." / "..Itineraire.display_informations.code.."]" end if tonumber(Itineraire.duration) == 0 then Max_Nb_Iti = Max_Nb_Iti -1 else Nb_Iti = Nb_Iti + 1 SetUI(VD_Id, "lblIti"..Nb_Iti, Lbl_message) end end if Nb_Iti < 9 then for i = Nb_Iti + 1, 9 do SetUI(VD_Id, "lblIti"..i, " ") end end SetUI(VD_Id, "lblFromTo", fibaro:get(VD_Id, "ui.lblFromTo.value").. " -> " ..Der_Dest) ------------------------------------------------------------------------------- -- Traitement des retards ------------------------------------------------------------------------------- Traitement_Retard(Status, Perturbations, First_stop_point, Last_stop_point) return Der_Dest end function Affiche_Traj(data) local Traj_Num = tonumber(string.sub(fibaro:get(VD_Id, "ui.lblNum.value"), -1)) local Trajet = data.journeys if #Trajet < Traj_Num then local Traj_Text = fibaro:get(VD_Id, "ui.lblNum.value") local Traj_Sens = string.sub(Traj_Text, 1, 1) Effacement_Data() SetUI(VD_Id, "lblDepArr", "Plus de trajets disponibles") Traj_Num = Traj_Num - 1 if Traj_Sens == "A" then fibaro:call(VD_Id, "setProperty", "ui.lblNum.value", "Aller N° "..Traj_Num) else fibaro:call(VD_Id, "setProperty", "ui.lblNum.value", "Retour N° "..Traj_Num) end Der_Dest = "" else Trace("blue","Traitement Trajet : "..Traj_Num) if data.journeys[Traj_Num].sections[1].from.embedded_type == "stop_point" then SetUI(VD_Id, "lblFromTo", data.journeys[Traj_Num].sections[1].from.stop_point.name) else SetUI(VD_Id, "lblFromTo", data.journeys[Traj_Num].sections[1].from.stop_area.name) end local Date_Time = Conversion_Date(data.journeys[Traj_Num].departure_date_time) local Lbl_message = "à "..os.date("%H:%M", Date_Time) local Date_Time = Conversion_Date(data.journeys[Traj_Num].arrival_date_time) Lbl_message = Lbl_message .." -> "..os.date("%H:%M", Date_Time).." ("..Conversion_Seconde_en_Texte(tonumber(data.journeys[Traj_Num].duration))..")" SetUI(VD_Id, "lblDepArr", Lbl_message) local Der_Dest = Affiche_Iti(data.journeys[Traj_Num].sections, data.journeys[Traj_Num].status, data.disruptions, Traj_Num) end return Der_Dest end ---------------------------------------------------------------------------------- -- Traitement des données en provenance de l'IPA SNCF ---------------------------------------------------------------------------------- function GetData() Debug("grey","T1".." - "..Traj_Titre) local api_url = "https://api.sncf.com/v1" local api_coverage = "sncf" local api_fonction = "journeys?" local Traj_Sens = string.sub(fibaro:get(VD_Id, "ui.lblNum.value"), 1, 1) local api_from = "" local api_to = "" if Traj_Sens == "A" then api_from = code_api_from api_to = code_api_to else api_from = code_api_to api_to = code_api_from end local api_datetime = os.date("%Y%m%dT%H%M00", os.time()) local api_datetime_represents = "departure" local api_min_nb_journeys = "5" local Query = api_url local Query = Query .. "/coverage/" .. api_coverage local Query = Query .. "/" .. api_fonction local Query = Query .. "from=" .. api_from.."&" local Query = Query .. "to=" .. api_to.."&" local Query = Query .. "datetime=" .. api_datetime.."&" local Query = Query .. "datetime_represents=" .. api_datetime_represents.."&" local Query = Query .. "min_nb_journeys=" .. api_min_nb_journeys Debug("grey","T2".." - "..Traj_Titre) local http = net.HTTPClient({ timeout = TimeOut }) Debug("grey","T3".." - "..Traj_Titre) Debug("grey",Query) local ok = pcall(function() http:request(Query, { options = { method = 'GET', headers ={ ["Content-Type"] = "application/json", ["Authorization"] = "BASIC "..User_API_Sncf_Encode64}, data = body }, success = function(response) Debug("grey","T4".." - "..Traj_Titre) if response.status == 200 then Debug("grey","T5".." - "..Traj_Titre) Trace("blue","Traitement ok : "..Traj_Titre) local status, data = pcall(json.decode, response.data) if (status and data) then local Der_Dest = Affiche_Traj(data) if Der_Dest == "" then Debug("grey","Plus de trajet à afficher") else if data.journeys[1].sections[1].from.embedded_type == "stop_point" then Trace("green","Départ : "..data.journeys[1].sections[1].from.stop_point.name) else Trace("green","Départ : "..data.journeys[1].sections[1].from.stop_area.name) end Trace("green","Direction : "..Der_Dest) local Date_Time = Conversion_Date(data.journeys[1].sections[1].departure_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", MonHeure)) -- Test pour vérifier si le prochain départ est pour le jour même if os.date("%Y/%m/%d",Date_Time) == os.date("%Y/%m/%d",time) then Prochain_Depart = "aujourd'hui" else Prochain_Depart = JourSemaine end Trace("green", "Prochain départ "..Prochain_Depart.." à " ..os.date("%H:%M", Date_Time)) message = "Prochain départ" message = message .. " "..Prochain_Depart message = message .. " de "..Msg_Depart message = message .. " pour "..Msg_Arrivee message = message .. " a ".. Horaire local Date_Time = Conversion_Date(data.journeys[1].sections[1].arrival_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", Date_Time)) message = message .. " Arrivée à "..Horaire Trace("green", "Arrivée à " ..os.date("%H:%M", Date_Time)) -- Envoi d'un message sur l'enceinte SONOS if Msg_Sonos == "OUI" then Debug("grey", "Envoi Message sur enceinte SONOS") fibaro:startScene(SceneID_Sonos, {{msg = message}, {vol = Volume_Sonos}}) end end else Trace("orange"," Attention : Aucunes données à traiter") Effacement_Data() SetUI(VD_Id, "lblDepArr", "Erreur =".."aucune données") end else Debug("grey","T6".." - "..Traj_Titre) Trace("yellow","Traitement ko : "..Traj_Titre) Effacement_Data() SetUI(VD_Id, "lblDepArr", "Erreur ="..response.status) if response.status == 500 or response.status == 503 then Trace("orange","Erreur d'indisponibilité du serveur") else Trace("orange","Erreur requête serveur, response.status = "..response.status) end end end, error = function(err) Debug("grey","T7".." - "..Traj_Titre) Trace("orange","Erreur de reception de données, Erreur = ".. err) Effacement_Data() SetUI(VD_Id, "lblDepArr", "Erreur ="..err) end }) end) if not(ok) then Trace("orange","Erreur dans l'exécution de fhttp:request(Query") end Debug("grey","T9".." - "..Traj_Titre) end function Start() Debug("grey","VD_Id="..VD_Id.." / Volume_Sonos="..Volume_Sonos.." / Msg_Sonos="..Msg_Sonos) -- test pour vérifier si le module virtuel exist ou pas local ip = fibaro:get(VD_Id, 'IPAddress') if ip == nil then Debug("orange","Warning : Le module virtuel : "..VD_Id.." n'existe pas. Vous devez le créer !") else -- Lancement du traitement de l'itinéraire GetData() end end ------------------------------------------------------------------------------- -- Begining off Scène ------------------------------------------------------------------------------- local params = fibaro:args() Trace("orange","Début de traitement de la scène") if (params) then for k, v in ipairs(params) do if (v.VD_Id) then VD_Id = v.VD_Id end end local Trouve_VD_Id = false for i = 1, #Trajets do if VD_Id == Trajets[i].VD_Id then Debug("grey","VD_Id="..VD_Id.." ("..fibaro:getName(VD_Id)..") a bien été trouvé") Traj_Titre = Trajets[i].Traj_Titre code_api_from = Trajets[i].code_api_from code_api_to = Trajets[i].code_api_to Msg_Sonos = Trajets[i].Msg_Sonos Volume_Sonos = Trajets[i].Volume_Sonos Msg_Depart = Trajets[i].Msg_Depart Msg_Arrivee = Trajets[i].Msg_Arrivee Trouve_VD_Id = true break end end User_API_Sncf_Encode64 = encode64(User_API_Sncf) if Trouve_VD_Id then Start() else Trace("orange","Erreur : Votre VD n'a pas été trouvé dans le tableau Trajets") end else Trace("orange","Erreur : Cette scène fonctionne par appel depuis un VD avec un passage de paramètres") end Trace("orange","Fin de traitement de la scène")
-
C'est ce que j'ai fait, mais ce n'est pas très esthétique waf
-
Merci pour l'info. Effectivement, je recherche une solution qui fait ça de manière dynamique (en temps réel). Dommage, j'aurais bien aimé utiliser cette fonctionnalité pour ajouter/supprimer des boutons sur mon VD permettant de visualiser le prochain itinéraire SNCF. Voir RAPT, Bus, mixte ?
-
Pas besoin de tasser ou macrodroid, tu utilises GEA dans lequel tu programmes un événement qui va simuler un clic sur le bouton de ton choix (Aller ou Retour) Tu peux même faire cela régulièrement (5 min.) pour rafraichir les données. Ok je vais regarder cette histoire de notification. Mais une fois que j'aurais trouvé le moyen de détecter les retards. Concernant les différents numéros, il s'agit d'étapes (changements) lors d'un trajet.
-
oui probablement. Je ne pense pas pouvoir identifier les trains annulés. Le principe même de l'API est de trouver le prochain train au départ. Donc celui qui est annulé, ne sera pas proposé. Je vais donc regarder le sujet les retards, puisqu'il semble que l'info est disponible. Il me faut trouver des exemples pour pouvoir faire de tests.
-
Je vais me focaliser pour le moment sur mon VD Itinéraire SNCF
-
Oui mais sur cette dernière version, j'ai changé une image d'un label. Donc import
-
Voici une nouvelle version 0.5 Cette nouvelle version apporte : La possibilité de choisir le mode retour (inversion entre le point de départ et d'arrivé) Il n'est plus nécessaire de modifier les variables (from et to) sur le bouton retour. Spécial dédicace @Sakkhho Possibilité d'utiliser les flèches de navigation que ce soit pour un trajet Aller ou Retour Il suffit d'utiliser les 4 boutons du VD : 1er bouton recherche du prochain train au départ 2ème bouton recherche du train en mode retour 3ème bouton recherche du train suivant 4ème bouton recherche du train précédent si l'itinéraire courant est supérieur à 1 Le label sous les bouton indique le Nième itinéraire courant avec précision du sens du trajet. Pour le moment, j'ai limité à 5 départs. Mais cela pourra être modifié facilement, si nécessaire. 1) Veuillez installer le nouveau VD ci-dessous : Itinéraire_SNCF.vfib.json Trop compliqué de fournir le code du VD (en mode texte) avec ses différents boutons qui contiennent chacun leur code. Désolé @Sakkhho Attention de bien : copier vos codes Station de départ et d'arrivée dans chacun des 3 boutons modifier la variable SceneID_Traj_SNCF par l'ID de la Scène Itinéraire SNCF 2) Veuillez charger le nouveau code de la scène : Attention de bien : modifier le contenu de la variable User_API_Sncf par votre identifiant encodé en 64 dans la scène modifier l'ID de votre Scène Sonos dans la variable SceneID_Sonos (si vous en possédez une enceinte) 3) Bons tests PS : Les étapes suivantes du projet seront probablement consacré à la mixité des modes de transport entre (Trains, RER, BUS, Metro) l'identification des incidents sur le trafic (retard) Si vous avez d'autres idées, vous pouvez toujours faire vos demandes --[[ %% properties %% events %% globals --]] ---------------------------------------------------------------------------------- -- Name : HC2 SNCF Itinéraire -- Type : Virtual Device & Scene -- Cette scène permet d'obtenir l'horaire du prochain train au départ d'une gare ---------------------------------------------------------------------------------- -- Le Projet : -- Construire Virtual Device Affichant les données reccupérées -- avec en option une notification vocale sur une enceinte SONOS en mode TTS ---------------------------------------------------------------------------------- -- Version : 0.5 -- Création : MAM78 -- Date MAJ : 09/07/2017 -- -- Evolutions : -- V0.1 09/07/2017 : Initialisation du projet -- V0.2 10/07/2017 : Association de la scène à un VD qui appel la scène en -- passant les paramètres de la recherche d'itinéraire -- V0.3 12/07/2017 : Ajouts de boutons de navigation pour parcourir les diférents -- itinéraires par odre chronologique des départs -- V0.4 13/07/2017 : La décomposition du parcours sur chacune des étapes -- (changements) Maximum 9 étapes pour le moment. -- Le temps de trajet global, ainsi que par étape -- Le mode de circulation pour chacune des étape -- (La ligne à utiliser, Trajet à pied, Attente en gare, ... -- La possibilité de choisir le mode retour (inversion entre -- le point de départ et d'arrivé). Attention pour le moment -- les flèches de navigation ne fonctionne pas pour le mode -- retour. -- Possibilité d'utiliser les flèches de navigation que ce -- soit pour un trajet Aller ou Retour ---------------------------------------------------------------------------------- -- User variables local SceneID_Sonos = 61 local modetrace = true local modedebug = true ---------------------------------------------------------------------------------- -- Pour pouvoir utiliser l'API de la SNCF, vous devez vous créer un compte sur : -- https://data.sncf.com/api -- Une fois votre compte créé vous recevrez un mail avec une clé d’authentification -- Puis, vous devez vous connecter au site : -- https://www.base64encode.org -- Puis, encoder la clef reçu dans le mail ci-dessus -- Copier ce code dans la vadiable ci-dessous (User_API_Sncf) ---------------------------------------------------------------------------------- local User_API_Sncf = "placé ici votre code API SNCF encodé en 64" ---------------------------------------------------------------------------------- -- Ne pas modifier le code ci-dessous, sinon pour l'adapter à votre usage ---------------------------------------------------------------------------------- local TimeOut = 3000 ---------------------------------------------------------------------------------- -- Message pour mode Trace ---------------------------------------------------------------------------------- function Trace(color, message) if modetrace then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end ---------------------------------------------------------------------------------- -- Message pour mode Debug ---------------------------------------------------------------------------------- function Debug(color, message) if modedebug then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end function SetUI(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".value", value); end function SetUI_label(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".label", value); end ---------------------------------------------------------------------------------- -- Retourne le jour de la semaine en clair ---------------------------------------------------------------------------------- function josdGetJourSemaine(jour) josdGetJourSemaineTab={[0]="Dimanche",[1]="Lundi",[2]="Mardi",[3]="Mercredi",[4]="Jeudi",[5]="Vendredi",[6]="Samedi"} return josdGetJourSemaineTab[tonumber(jour)] end ---------------------------------------------------------------------------------- -- Conversion un nombre de seconde en texte xhxmin" en format date ---------------------------------------------------------------------------------- function Conversion_Seconde_en_Texte(NbSec) Debug("grey","NbSec="..NbSec) local NbH=math.floor(NbSec/60/60) NbSec = NbSec - NbH * 60 * 60 local NbM=math.floor(NbSec/60) NbSec = NbSec - NbH * 60 if NbH > 0 then return NbH.."h"..NbM.."min" else return NbM.."min" end end ---------------------------------------------------------------------------------- -- Conversion format date "aaaammjjThhmmss" en format date ---------------------------------------------------------------------------------- function Conversion_Date(dateheure) local TableDate = os.date("*t") TableDate.day = string.sub (dateheure, 7, 8) TableDate.month = string.sub (dateheure, 5, 6) TableDate.year = string.sub (dateheure, 1, 4) TableDate.hour = string.sub (dateheure, 10, 11) TableDate.min = string.sub (dateheure, 12, 13) return (os.time(TableDate)) end function Affiche_Iti(data, Traj_Num) local Last_PT = nil local Nb_Iti = 0 local Nb_Section = data.journeys[Traj_Num].sections local Max_Nb_Iti= 0 if #Nb_Section > 9 then Max_Nb_Iti = 9 else Max_Nb_Iti = #Nb_Section end Debug("grey","Nb_Section, Max_Nb_Iti="..#Nb_Section..", "..Max_Nb_Iti) for Num_Iti = 1 , Max_Nb_Iti do Debug("grey","Traitement Trajet-Itinéraire, type : "..Traj_Num.."-"..Num_Iti.." ,"..data.journeys[Traj_Num].sections[Num_Iti].type) if data.journeys[Traj_Num].sections[Num_Iti].type == "public_transport" then Last_PT = Num_Iti end local Date_Time = Conversion_Date(data.journeys[Traj_Num].sections[Num_Iti].departure_date_time) local Lbl_message = "("..Conversion_Seconde_en_Texte(tonumber(data.journeys[Traj_Num].sections[Num_Iti].duration))..")" local Date_Time = Conversion_Date(data.journeys[Traj_Num].sections[Num_Iti].arrival_date_time) Lbl_message = Lbl_message.." -> "..os.date("%H:%M", Date_Time) if data.journeys[Traj_Num].sections[Num_Iti].type == "waiting" then Der_Dest = data.journeys[Traj_Num].sections[Num_Iti-1].to.stop_point.name Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." -> " .."[En ATTENTE]" else if data.journeys[Traj_Num].sections[Num_Iti].type == "walking" then Der_Dest = data.journeys[Traj_Num].sections[Num_Iti].to.stop_point.name Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." -> " .."[à PIED]" else if data.journeys[Traj_Num].sections[Num_Iti].type == "transfer" then if data.journeys[Traj_Num].sections[Num_Iti].transfer_type == "walking" then Der_Dest = data.journeys[Traj_Num].sections[Num_Iti].to.stop_point.name Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." -> " .."[à PIED]" end else if data.journeys[Traj_Num].sections[Num_Iti].type == "crow_fly" then if data.journeys[Traj_Num].sections[Num_Iti].mode == "walking" then Der_Dest = data.journeys[Traj_Num].sections[Num_Iti].to.stop_point.name Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." -> " .."[à PIED]" end else Der_Dest = data.journeys[Traj_Num].sections[Num_Iti].to.stop_point.name Lbl_message = Lbl_message.." à " ..Der_Dest Lbl_message = Lbl_message.." ["..data.journeys[Traj_Num].sections[Num_Iti].display_informations.commercial_mode .." / "..data.journeys[Traj_Num].sections[Num_Iti].display_informations.code.."]" end end end end Nb_Iti = Nb_Iti + 1 SetUI(VD_Id, "lblIti"..Num_Iti, Lbl_message) end if Max_Nb_Iti < 9 then for i = Max_Nb_Iti + 1, 9 do SetUI(VD_Id, "lblIti"..i, " ") end end SetUI(VD_Id, "lblFromTo", fibaro:get(VD_Id, "ui.lblFromTo.value").. " -> " ..Der_Dest) end function Affiche_Traj(data) local Traj_Num = tonumber(string.sub(fibaro:get(VD_Id, "ui.lblNum.value"), -1)) Trace("blue","Traitement Trajet : "..Traj_Num) --fibaro:call(VD_Id, "setProperty", "ui.lblDep2.label", "♈") --fibaro:call(VD_Id, "setProperty", "ui.lblDep2.label", "XX\00000aXX") SetUI(VD_Id, "lblFromTo", data.journeys[Traj_Num].sections[1].from.stop_point.name) --SetUI(VD_Id, "lblDir", data.journeys[Num_Traj].sections[1].display_informations.direction) if data.journeys[Traj_Num].status =="" then SetUI(VD_Id, "lblTrafic", "normal") else SetUI(VD_Id, "lblTrafic", data.journeys[Traj_Num].status) end local Date_Time = Conversion_Date(data.journeys[Traj_Num].departure_date_time) local Lbl_message = "à "..os.date("%H:%M", Date_Time) local Date_Time = Conversion_Date(data.journeys[Traj_Num].arrival_date_time) Lbl_message = Lbl_message .." -> "..os.date("%H:%M", Date_Time).." ("..Conversion_Seconde_en_Texte(tonumber(data.journeys[Traj_Num].duration))..")" SetUI(VD_Id, "lblDepArr", Lbl_message) Affiche_Iti(data, Traj_Num) end ---------------------------------------------------------------------------------- -- Traitement des données en provenance de l'IPA SNCF ---------------------------------------------------------------------------------- function GetData() Debug("grey","T1".." - "..Traj_Titre) -- https://api.sncf.com/v1/coverage/sncf -- /journeys? -- from=stop_area:OCE:SA:87382473& -- to=stop_area:OCE:SA:87382218& -- datetime='20170716T040000'& -- datetime_represents=departure& -- min_nb_journeys=4 local api_url = "https://api.sncf.com/v1" local api_coverage = "sncf" local api_fonction = "journeys?" local Traj_Sens = string.sub(fibaro:get(VD_Id, "ui.lblNum.value"), 1, 1) local api_from = "" local api_to = "" if Traj_Sens == "A" then api_from = code_api_from api_to = code_api_to else api_from = code_api_to api_to = code_api_from end local api_datetime = os.date("%Y%m%dT%H%M00", os.time()) local api_datetime_represents = "departure" local api_min_nb_journeys = "5" local Query = api_url local Query = Query .. "/coverage/" .. api_coverage local Query = Query .. "/" .. api_fonction local Query = Query .. "from=" .. api_from.."&" local Query = Query .. "to=" .. api_to.."&" local Query = Query .. "datetime=" .. api_datetime.."&" local Query = Query .. "datetime_represents=" .. api_datetime_represents.."&" local Query = Query .. "min_nb_journeys=" .. api_min_nb_journeys Debug("grey","T2".." - "..Traj_Titre) local http = net.HTTPClient({ timeout = TimeOut }) Debug("grey","T3".." - "..Traj_Titre) Debug("grey",Query) local ok = pcall(function() http:request(Query, { options = { method = 'GET', headers ={ ["Content-Type"] = "application/json", ["Authorization"] = "BASIC "..User_API_Sncf}, data = body }, success = function(response) Debug("grey","T4".." - "..Traj_Titre) if response.status == 200 then Debug("grey","T5".." - "..Traj_Titre) Trace("blue","Traitement ok : "..Traj_Titre) local status, data = pcall(json.decode, response.data) if (status and data) then Affiche_Traj(data) Trace("green","Départ : "..data.journeys[1].sections[1].from.stop_point.name) Trace("green","Direction : "..data.journeys[1].sections[1].to.stop_point.name) local Date_Time = Conversion_Date(data.journeys[1].sections[1].departure_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", MonHeure)) -- Test pour vérifier si le prochain départ est pour le jour même if os.date("%Y/%m/%d",Date_Time) == os.date("%Y/%m/%d",time) then Prochain_Depart = "aujourd'hui" else Prochain_Depart = JourSemaine end Trace("green", "Prochain départ "..Prochain_Depart.." à " ..os.date("%H:%M", Date_Time)) message = "Prochain départ" message = message .. " "..Prochain_Depart message = message .. " de "..Msg_Depart message = message .. " pour "..Msg_Arrivee message = message .. " a ".. Horaire local Date_Time = Conversion_Date(data.journeys[1].sections[1].arrival_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", Date_Time)) message = message .. " Arrivée à "..Horaire Trace("green", "Arrivée à " ..os.date("%H:%M", Date_Time)) -- Envoi d'un message sur l'enceinte SONOS if Msg_Sonos == "OUI" then Debug("grey", "Envoi Message sur enceinte SONOS") fibaro:startScene(SceneID_Sonos, {{msg = message}, {vol = Volume_Sonos}}) end else Trace("orange"," Attention : Aucunes données à traiter") end else Debug("grey","T6".." - "..Traj_Titre) Trace("yellow","Traitement ko : "..Traj_Titre) if response.status == 500 or response.status == 503 then Trace("orange","Erreur d'indisponibilité du serveur") else Trace("orange","Erreur requête serveur, response.status = "..response.status) end end end, error = function(err) Debug("grey","T7".." - "..Traj_Titre) Trace("orange","Erreur de reception de données, Erreur = ".. err) end }) end) if not(ok) then Trace("orange","Erreur dans l'exécution de fhttp:request(Query") end Debug("grey","T9".." - "..Traj_Titre) end function Start() Debug("grey","VD_Id="..VD_Id.." / Volume_Sonos="..Volume_Sonos.." / Msg_Sonos="..Msg_Sonos) -- test pour vérifier si le module virtuel exist ou pas local ip = fibaro:get(VD_Id, 'IPAddress') if ip == nil then Debug("orange","Warning : Le module virtuel : "..VD_Id.." n'existe pas. Vous devez le créer !") else -- Lancement du traitement de l'itinéraire GetData() end end ------------------------------------------------------------------------------- -- Begining off Scène ------------------------------------------------------------------------------- local params = fibaro:args() Trace("orange","Début de traitement de la scène") if (params) then for k, v in ipairs(params) do if (v.Traj_Titre) then Traj_Titre = v.Traj_Titre end if (v.code_api_to) then code_api_to = v.code_api_to end if (v.code_api_from) then code_api_from = v.code_api_from end if (v.Msg_Arrivee) then Msg_Arrivee = v.Msg_Arrivee end if (v.Msg_Depart) then Msg_Depart = v.Msg_Depart end if (v.Msg_Sonos) then Msg_Sonos = v.Msg_Sonos end if (v.Volume_Sonos) then Volume_Sonos = v.Volume_Sonos end if (v.VD_Id) then VD_Id = v.VD_Id end end Start() else Trace("orange","Erreur : Cette scène fonctionne par appel depuis un VD avec un passage de paramètres") end Trace("orange","Fin de traitement de la scène")
-
Bizarre, Chez-moi toujours le même problème. Je pense que je vais le réadapter en utilisant mon projet Itinéraire SNCF. Quand j'aurais le temps, évidement. Ca corrigera au passage les problèmes de plantage que nous avions déjà précédemment
-
C'est fait. Voici une nouvelle version 0.4. Cette nouvelle version apporte : La décomposition du parcours sur chacune des étapes (changements) Maximum 9 étapes pour le moment. Le temps de trajet global, ainsi que par étape Le mode de circulation pour chacune des étape (La ligne à utiliser, Trajet à pied, Attente en gare, ... La possibilité de choisir le mode retour (inversion entre le point de départ et d'arrivé). Attention pour le moment les flèches de navigation ne fonctionne pas pour le mode retour. Ca viendra. Il suffit d'utiliser les 4 boutons du VD : 1er bouton recherche du prochain train au départ 2ème bouton recherche du train en mode retour 3ème bouton recherche du train suivant 4ème bouton recherche du train précédent si l'itinéraire courant est supérieur à 1 Le label sous les bouton indique le Nième itinéraire courant. Pour le moment, j'ai limité à 5 départs. Mais cela pourra être modifié facilement, si nécessaire. 1) Veuillez installer le nouveau VD ci-dessous : Itinéraire_SNCF.vfib.json Trop compliqué de fournir le code du VD (en mode texte) avec ses différents boutons qui contiennent chacun leur code. Attention de bien : copier vos codes Station de départ et d'arrivée dans chacun des 3 boutons modifier la variable SceneID_Iti_SNCF par l'ID de la Scène Itinéraire SNCF 2) Veuillez charger le nouveau code de la scène : Attention de bien : modifier le contenu de la variable User_API_Sncf par votre identifiant encodé en 64 dans la scène modifier l'ID de votre Scène Sonos dans la variable SceneID_Sonos (si vous en possédez une enceinte) 3) Bons tests PS : Les étapes suivantes du projet seront probablement consacré à la mixité des modes de transport entre (Trains, RER, BUS, Metro) l'identification des incidents sur le trafic Si vous avez d'autres idées, vous pouvez toujours faire vos demandes --[[ %% properties %% events %% globals --]] ---------------------------------------------------------------------------------- -- Name : HC2 SNCF Itinéraire -- Type : Virtual Device & Scene -- Cette scène permet d'obtenir l'horaire du prochain train au départ d'une gare ---------------------------------------------------------------------------------- -- Le Projet : -- Construire Virtual Device Affichant les données reccupérées -- avec en option une notification vocale sur une enceinte SONOS en mode TTS ---------------------------------------------------------------------------------- -- Version : 0.4 -- Création : MAM78 -- Date MAJ : 13/07/2017 -- -- Evolutions : -- V0.1 09/07/2017 : Initialisation du projet -- V0.2 10/07/2017 : Association de la scène à un VD qui appel la scène en -- passant les paramètres de la recherche d'itinéraire -- V0.3 12/07/2017 : Ajouts de boutons de navigation pour parcourir les diférents -- itinéraires par odre chronologique des départs -- V0.4 13/07/2017 : La décomposition du parcours sur chacune des étapes -- (changements) Maximum 9 étapes pour le moment. -- Le temps de trajet global, ainsi que par étape -- Le mode de circulation pour chacune des étape -- (La ligne à utiliser, Trajet à pied, Attente en gare, ... -- La possibilité de choisir le mode retour (inversion entre -- le point de départ et d'arrivé). Attention pour le moment -- les flèches de navigation ne fonctionne pas pour le mode -- retour. ---------------------------------------------------------------------------------- -- User variables local SceneID_Sonos = 61 local modetrace = true local modedebug = true ---------------------------------------------------------------------------------- -- Pour pouvoir utiliser l'API de la SNCF, vous devez vous créer un compte sur : -- https://data.sncf.com/api -- Une fois votre compte créé vous recevrez un mail avec une clé d’authentification -- Puis, vous devez vous connecter au site : -- https://www.base64encode.org -- Puis, encoder la clef reçu dans le mail ci-dessus -- Copier ce code dans la vadiable ci-dessous (User_API_Sncf) ---------------------------------------------------------------------------------- -- local User_API_Sncf = "placé ici votre code API SNCF encodé en 64" ---------------------------------------------------------------------------------- -- Ne pas modifier le code ci-dessous, sinon pour l'adapter à votre usage ---------------------------------------------------------------------------------- local TimeOut = 3000 ---------------------------------------------------------------------------------- -- Message pour mode Trace ---------------------------------------------------------------------------------- function Trace(color, message) if modetrace then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end ---------------------------------------------------------------------------------- -- Message pour mode Debug ---------------------------------------------------------------------------------- function Debug(color, message) if modedebug then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end function SetUI(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".value", value); end function SetUI_label(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".label", value); end ---------------------------------------------------------------------------------- -- Retourne le jour de la semaine en clair ---------------------------------------------------------------------------------- function josdGetJourSemaine(jour) josdGetJourSemaineTab={[0]="Dimanche",[1]="Lundi",[2]="Mardi",[3]="Mercredi",[4]="Jeudi",[5]="Vendredi",[6]="Samedi"} return josdGetJourSemaineTab[tonumber(jour)] end ---------------------------------------------------------------------------------- -- Conversion un nombre de seconde en texte xhxmin" en format date ---------------------------------------------------------------------------------- function Conversion_Seconde_en_Texte(NbSec) Debug("grey","NbSec="..NbSec) local NbH=math.floor(NbSec/60/60) NbSec = NbSec - NbH * 60 * 60 local NbM=math.floor(NbSec/60) NbSec = NbSec - NbH * 60 if NbH > 0 then return NbH.."h"..NbM.."min" else return NbM.."min" end end ---------------------------------------------------------------------------------- -- Conversion format date "aaaammjjThhmmss" en format date ---------------------------------------------------------------------------------- function Conversion_Date(dateheure) local TableDate = os.date("*t") TableDate.day = string.sub (dateheure, 7, 8) TableDate.month = string.sub (dateheure, 5, 6) TableDate.year = string.sub (dateheure, 1, 4) TableDate.hour = string.sub (dateheure, 10, 11) TableDate.min = string.sub (dateheure, 12, 13) return (os.time(TableDate)) end function Affiche_Iti(data, Num_Traj) local Last_PT = nil local Nb_Iti = 0 local Nb_Section = data.journeys[Num_Traj].sections local Max_Nb_Iti= 0 if #Nb_Section > 9 then Max_Nb_Iti = 9 else Max_Nb_Iti = #Nb_Section end Debug("grey","Nb_Section, Max_Nb_Iti="..#Nb_Section..", "..Max_Nb_Iti) for Num_Iti = 1 , Max_Nb_Iti do Debug("grey","Traitement Trajet-Itinéraire, type : "..Num_Traj.."-"..Num_Iti.." ,"..data.journeys[Num_Traj].sections[Num_Iti].type) if data.journeys[Num_Traj].sections[Num_Iti].type == "public_transport" then Last_PT = Num_Iti end local Date_Time = Conversion_Date(data.journeys[Num_Traj].sections[Num_Iti].departure_date_time) local Lbl_message = "("..Conversion_Seconde_en_Texte(tonumber(data.journeys[Num_Traj].sections[Num_Iti].duration))..")" local Date_Time = Conversion_Date(data.journeys[Num_Traj].sections[Num_Iti].arrival_date_time) Lbl_message = Lbl_message.." -> "..os.date("%H:%M", Date_Time) if data.journeys[Num_Traj].sections[Num_Iti].type == "waiting" then Lbl_message = Lbl_message.." à " ..data.journeys[Num_Traj].sections[Num_Iti-1].to.stop_point.name Lbl_message = Lbl_message.." -> " .."[En ATTENTE]" else if data.journeys[Num_Traj].sections[Num_Iti].type == "walking" then Lbl_message = Lbl_message.." -> " ..data.journeys[Num_Traj].sections[Num_Iti].to.stop_point.name Lbl_message = Lbl_message.." -> " .."[à PIED]" else if data.journeys[Num_Traj].sections[Num_Iti].type == "transfer" then if data.journeys[Num_Traj].sections[Num_Iti].transfer_type == "walking" then Lbl_message = Lbl_message.." -> " ..data.journeys[Num_Traj].sections[Num_Iti].to.stop_point.name Lbl_message = Lbl_message.." -> " .."[à PIED]" end else if data.journeys[Num_Traj].sections[Num_Iti].type == "crow_fly" then if data.journeys[Num_Traj].sections[Num_Iti].mode == "walking" then Lbl_message = Lbl_message.." -> " ..data.journeys[Num_Traj].sections[Num_Iti].to.stop_point.name Lbl_message = Lbl_message.." -> " .."[à PIED]" end else Lbl_message = Lbl_message.." -> " ..data.journeys[Num_Traj].sections[Num_Iti].to.stop_point.name Lbl_message = Lbl_message.." ["..data.journeys[Num_Traj].sections[Num_Iti].display_informations.commercial_mode .." / "..data.journeys[Num_Traj].sections[Num_Iti].display_informations.code.."]" end end end end Nb_Iti = Nb_Iti + 1 SetUI(VD_Id, "lblIti"..Num_Iti, Lbl_message) end if Max_Nb_Iti < 9 then for i = Max_Nb_Iti + 1, 9 do SetUI(VD_Id, "lblIti"..i, " ") end end SetUI(VD_Id, "lblFromTo", fibaro:get(VD_Id, "ui.lblFromTo.value").. " -> " ..data.journeys[Num_Traj].sections[Last_PT].to.stop_point.name) end function Affiche_Traj(data) local Num_Traj = fibaro:get(VD_Id, "ui.lblNum.value") Num_Traj = tonumber(Num_Traj) Trace("blue","Traitement Trajet : "..Num_Traj) --fibaro:call(VD_Id, "setProperty", "ui.lblDep2.label", "♈") --fibaro:call(VD_Id, "setProperty", "ui.lblDep2.label", "XX\00000aXX") SetUI(VD_Id, "lblFromTo", data.journeys[Num_Traj].sections[1].from.stop_point.name) --SetUI(VD_Id, "lblDir", data.journeys[Num_Traj].sections[1].display_informations.direction) if data.journeys[Num_Traj].status =="" then SetUI(VD_Id, "lblTrafic", "normal") else SetUI(VD_Id, "lblTrafic", data.journeys[Num_Traj].status) end local Date_Time = Conversion_Date(data.journeys[Num_Traj].departure_date_time) local Lbl_message = "à "..os.date("%H:%M", Date_Time) local Date_Time = Conversion_Date(data.journeys[Num_Traj].arrival_date_time) Lbl_message = Lbl_message .." -> "..os.date("%H:%M", Date_Time).." ("..Conversion_Seconde_en_Texte(tonumber(data.journeys[Num_Traj].duration))..")" SetUI(VD_Id, "lblDepArr", Lbl_message) Affiche_Iti(data, Num_Traj) end ---------------------------------------------------------------------------------- -- Traitement des données en provenance de l'IPA SNCF ---------------------------------------------------------------------------------- function GetData() Debug("grey","T1".." - "..Iti_Titre) -- https://api.sncf.com/v1/coverage/sncf -- /journeys? -- from=stop_area:OCE:SA:87382473& -- to=stop_area:OCE:SA:87382218& -- datetime='20170716T040000'& -- datetime_represents=departure& -- min_nb_journeys=4 local api_url = "https://api.sncf.com/v1" local api_coverage = "sncf" local api_fonction = "journeys?" local api_from = code_api_from local api_to = code_api_to local api_datetime = os.date("%Y%m%dT%H%M00", os.time()) local api_datetime_represents = "departure" local api_min_nb_journeys = "5" local Query = api_url local Query = Query .. "/coverage/" .. api_coverage local Query = Query .. "/" .. api_fonction local Query = Query .. "from=" .. api_from.."&" local Query = Query .. "to=" .. api_to.."&" local Query = Query .. "datetime=" .. api_datetime.."&" local Query = Query .. "datetime_represents=" .. api_datetime_represents.."&" local Query = Query .. "min_nb_journeys=" .. api_min_nb_journeys Debug("grey","T2".." - "..Iti_Titre) local http = net.HTTPClient({ timeout = TimeOut }) Debug("grey","T3".." - "..Iti_Titre) Debug("grey",Query) local ok = pcall(function() http:request(Query, { options = { method = 'GET', headers ={ ["Content-Type"] = "application/json", ["Authorization"] = "BASIC "..User_API_Sncf}, data = body }, success = function(response) Debug("grey","T4".." - "..Iti_Titre) if response.status == 200 then Debug("grey","T5".." - "..Iti_Titre) Trace("blue","Traitement ok : "..Iti_Titre) local status, data = pcall(json.decode, response.data) if (status and data) then Affiche_Traj(data) Trace("green","Départ : "..data.journeys[1].sections[1].from.stop_point.name) Trace("green","Direction : "..data.journeys[1].sections[1].to.stop_point.name) local Date_Time = Conversion_Date(data.journeys[1].sections[1].departure_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", MonHeure)) -- Test pour vérifier si le prochain départ est pour le jour même if os.date("%Y/%m/%d",Date_Time) == os.date("%Y/%m/%d",time) then Prochain_Depart = "aujourd'hui" else Prochain_Depart = JourSemaine end Trace("green", "Prochain départ "..Prochain_Depart.." à " ..os.date("%H:%M", Date_Time)) message = "Prochain départ" message = message .. " "..Prochain_Depart message = message .. " de "..Msg_Depart message = message .. " pour "..Msg_Arrivee message = message .. " a ".. Horaire local Date_Time = Conversion_Date(data.journeys[1].sections[1].arrival_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", Date_Time)) message = message .. " Arrivée à "..Horaire Trace("green", "Arrivée à " ..os.date("%H:%M", Date_Time)) -- Envoi d'un message sur l'enceinte SONOS if Msg_Sonos == "OUI" then Debug("grey", "Envoi Message sur enceinte SONOS") fibaro:startScene(SceneID_Sonos, {{msg = message}, {vol = Volume_Sonos}}) end else Trace("orange"," Attention : Aucunes données à traiter") end else Debug("grey","T6".." - "..Iti_Titre) Trace("yellow","Traitement ko : "..Iti_Titre) if response.status == 500 or response.status == 503 then Trace("orange","Erreur d'indisponibilité du serveur") else Trace("orange","Erreur requête serveur, response.status = "..response.status) end end end, error = function(err) Debug("grey","T7".." - "..Iti_Titre) Trace("orange","Erreur de reception de données, Erreur = ".. err) end }) end) if not(ok) then Trace("orange","Erreur dans l'exécution de fhttp:request(Query") end Debug("grey","T9".." - "..Iti_Titre) end function Start() Debug("grey","VD_Id="..VD_Id.." / Volume_Sonos="..Volume_Sonos.." / Msg_Sonos="..Msg_Sonos) -- test pour vérifier si le module virtuel exist ou pas local ip = fibaro:get(VD_Id, 'IPAddress') if ip == nil then Debug("orange","Warning : Le module virtuel : "..VD_Id.." n'existe pas. Vous devez le créer !") else -- Lancement du traitement de l'itinéraire GetData() end end ------------------------------------------------------------------------------- -- Begining off Scène ------------------------------------------------------------------------------- local params = fibaro:args() Trace("orange","Début de traitement de la scène") if (params) then for k, v in ipairs(params) do if (v.Iti_Titre) then Iti_Titre = v.Iti_Titre end if (v.code_api_to) then code_api_to = v.code_api_to end if (v.code_api_from) then code_api_from = v.code_api_from end if (v.Msg_Arrivee) then Msg_Arrivee = v.Msg_Arrivee end if (v.Msg_Depart) then Msg_Depart = v.Msg_Depart end if (v.Msg_Sonos) then Msg_Sonos = v.Msg_Sonos end if (v.Volume_Sonos) then Volume_Sonos = v.Volume_Sonos end if (v.VD_Id) then VD_Id = v.VD_Id end end Start() else Trace("orange","Erreur : Cette scène fonctionne par appel depuis un VD avec un passage de paramètres") end Trace("orange","Fin de traitement de la scène")
-
Lorsque tu saisis le nom de ta gare, tu dois probablement avoir plusieurs lignes qui s'affichent dont l'une doit être la gare TGV. C'est celle là que tu dois sélectionner. Sinon indiques nous ton point de départ et d'arrivée
-
Concernant le trajet retour, je propose d'ajouter un bouton qui permettra d'inverser le sens de l'itinéraire. Concernant l'affichage des différents disponibles. Le problème est la quantité d'infos à afficher dans le VD. Ca risque de devenir un sapin de noël. L'objectif pour moi c'est d'afficher la décomposition des trajets avec chacun des changements Concernant l'info trafic. Pour le moment je n'ai pas encore trouver les bonnes infos J'envisage également de me connecter à une autre API pour avoir les lignes de métro et bus.
-
Concernant les label 1, 2, 3 ils sont prévu pour contenir les étapes lors de trajets indirects. Mais ca c'est pour plus tard
-
Pour le retour, c'est très simple. Tu fais un deuxième VD dans lequel tu inverses les codes de départ et d'arrivée.
-
C'est fait. Voici une nouvelle version 0.3. Cette nouvelle version apporte la possibilité de parcourir les différents itinéraire selon leur ordre de départ. Il suffit d'utiliser les 3 boutons du VD : 1er bouton recherche du prochain train au départ 2ème bouton recherche du train suivant 3ème bouton recherche du train précédent si l'itinéraire courant est supérieur à 1 Le premier label indique le Nième itinéraire courant. Pour le moment, j'ai limité à 5 départs. Mais cela pourra être modifié facilement, si nécessaire. 1) Veuillez installer le nouveau VD ci-dessous : Itinéraire_SNCF.vfib.json Attention de bien : copier vos codes Station de départ et d'arrivée dans chacun des 3 boutons modifier la variable SceneID_Iti_SNCF par l'ID de la Scène Itinéraire SNCF 2) Veuillez charger le nouveau code de la scène : Attention de bien : modifier le contenu de la variable User_API_Sncf par votre identifiant encodé en 64 dans la scène modifier l'ID de votre Scène Sonos dans la variable SceneID_Sonos (si vous en possédez une enceinte) 3) Bons tests PS : Les étapes suivantes du projet seront probablement consacré à la décomposition du parcours par étape si le trajet n'est pas direct la mixité des modes de transport entre (Trains, RER, BUS, Metro) l'identification des incidents sur le trafic Si vous avez d'autres idées, vous pouvez toujours faire vos demandes --[[ %% properties %% events %% globals --]] ---------------------------------------------------------------------------------- -- Name : HC2 SNCF Itinéraire -- Type : Virtual Device & Scene -- Cette scène permet d'obtenir l'horaire du prochain train au départ d'une gare ---------------------------------------------------------------------------------- -- Le Projet : -- Construire Virtual Device Affichant les données reccupérées -- avec en option une notification vocale sur une enceinte SONOS en mode TTS ---------------------------------------------------------------------------------- -- Version : 0.3 -- Création : MAM78 -- Date MAJ : 12/07/2017 -- -- Evolutions : -- V0.1 09/07/2017 : Initialisation du projet -- V0.2 10/07/2017 : Association de la scène à un VD qui appel la scène en -- passant les paramètres de la recherche d'itinéraire -- V0.3 12/07/2017 : Ajouts de boutons de navigation pour parcourir les diférents -- itinéraires par odre chronologique des départs ---------------------------------------------------------------------------------- -- User variables local SceneID_Sonos = 61 local modetrace = true local modedebug = true ---------------------------------------------------------------------------------- -- Pour pouvoir utiliser l'API de la SNCF, vous devez vous créer un compte sur : -- https://data.sncf.com/api -- Une fois votre compte créé vous recevrez un mail avec une clé d’authentification -- Puis, vous devez vous connecter au site : -- https://www.base64encode.org -- Puis, encoder la clef reçu dans le mail ci-dessus -- Copier ce code dans la vadiable ci-dessous (User_API_Sncf) ---------------------------------------------------------------------------------- local User_API_Sncf = "placé ici votre code API SNCF encodé en 64" ---------------------------------------------------------------------------------- -- Ne pas modifier le code ci-dessous, sinon pour l'adapter à votre usage ---------------------------------------------------------------------------------- local TimeOut = 3000 ---------------------------------------------------------------------------------- -- Message pour mode Trace ---------------------------------------------------------------------------------- function Trace(color, message) if modetrace then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end ---------------------------------------------------------------------------------- -- Message pour mode Debug ---------------------------------------------------------------------------------- function Debug(color, message) if modedebug then if color and color ~= "" then fibaro:debug('<span style="color:'..color..';">'..message..'</span>') else fibaro:debug(message) end end end function SetUI(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".value", value); end function SetUI_label(id, target, value) fibaro:call(id, "setProperty", "ui."..target..".label", value); end ---------------------------------------------------------------------------------- -- Retourne le jour de la semaine en clair ---------------------------------------------------------------------------------- function josdGetJourSemaine(jour) josdGetJourSemaineTab={[0]="Dimanche",[1]="Lundi",[2]="Mardi",[3]="Mercredi",[4]="Jeudi",[5]="Vendredi",[6]="Samedi"} return josdGetJourSemaineTab[tonumber(jour)] end ---------------------------------------------------------------------------------- -- Conversion format date "aaaammjjThhmmss" en format date ---------------------------------------------------------------------------------- function Conversion_Date(dateheure) local TableDate = os.date("*t") TableDate.day = string.sub (dateheure, 7, 8) TableDate.month = string.sub (dateheure, 5, 6) TableDate.year = string.sub (dateheure, 1, 4) TableDate.hour = string.sub (dateheure, 10, 11) TableDate.min = string.sub (dateheure, 12, 13) return (os.time(TableDate)) end function Affiche_Iti(data) local Num_Iti = fibaro:get(VD_Id, "ui.lblNum.value") Num_Iti = tonumber(Num_Iti) Trace("blue","Traitement Iti : "..Num_Iti) --fibaro:call(VD_Id, "setProperty", "ui.lblDep2.label", "♈") --fibaro:call(VD_Id, "setProperty", "ui.lblDep2.label", "XX\00000aXX") SetUI(VD_Id, "lblLigne", data.journeys[Num_Iti].sections[1].display_informations.commercial_mode .." / "..data.journeys[Num_Iti].sections[1].display_informations.code) SetUI(VD_Id, "lblFrom", data.journeys[Num_Iti].sections[1].from.stop_point.name) SetUI(VD_Id, "lblTo", data.journeys[Num_Iti].sections[1].to.stop_point.name) SetUI(VD_Id, "lblDir", data.journeys[Num_Iti].sections[1].display_informations.direction) if data.journeys[Num_Iti].status =="" then SetUI(VD_Id, "lblTrafic", "normal") else SetUI(VD_Id, "lblTrafic", data.journeys[Num_Iti].status) end local Date_Time = Conversion_Date(data.journeys[Num_Iti].sections[1].departure_date_time) local Lbl_message = "Départ à "..os.date("%H:%M", Date_Time) local Date_Time = Conversion_Date(data.journeys[1].sections[1].arrival_date_time) Lbl_message = Lbl_message .." Arrivée à "..os.date("%H:%M", Date_Time) SetUI(VD_Id, "lblDep1", Lbl_message) end ---------------------------------------------------------------------------------- -- Traitement des données en provenance de l'IPA SNCF ---------------------------------------------------------------------------------- function GetData() Debug("grey","T1".." - "..Iti_Titre) -- https://api.sncf.com/v1/coverage/sncf -- /journeys? -- from=stop_area:OCE:SA:87382473& -- to=stop_area:OCE:SA:87382218& -- datetime='20170716T040000'& -- datetime_represents=departure& -- min_nb_journeys=4 local api_url = "https://api.sncf.com/v1" local api_coverage = "sncf" local api_fonction = "journeys?" local api_from = code_api_from local api_to = code_api_to local api_datetime = os.date("%Y%m%dT%H%M00", os.time()) local api_datetime_represents = "departure" local api_min_nb_journeys = "5" local Query = api_url local Query = Query .. "/coverage/" .. api_coverage local Query = Query .. "/" .. api_fonction local Query = Query .. "from=" .. api_from.."&" local Query = Query .. "to=" .. api_to.."&" local Query = Query .. "datetime=" .. api_datetime.."&" local Query = Query .. "datetime_represents=" .. api_datetime_represents.."&" local Query = Query .. "min_nb_journeys=" .. api_min_nb_journeys Debug("grey","T2".." - "..Iti_Titre) local http = net.HTTPClient({ timeout = TimeOut }) Debug("grey","T3".." - "..Iti_Titre) Debug("grey",Query) local ok = pcall(function() http:request(Query, { options = { method = 'GET', headers ={ ["Content-Type"] = "application/json", ["Authorization"] = "BASIC "..User_API_Sncf}, data = body }, success = function(response) Debug("grey","T4".." - "..Iti_Titre) if response.status == 200 then Debug("grey","T5".." - "..Iti_Titre) Trace("blue","Traitement ok : "..Iti_Titre) local status, data = pcall(json.decode, response.data) if (status and data) then Affiche_Iti(data) Trace("green","Départ : "..data.journeys[1].sections[1].from.stop_point.name) Trace("green","Direction : "..data.journeys[1].sections[1].to.stop_point.name) local Date_Time = Conversion_Date(data.journeys[1].sections[1].departure_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", MonHeure)) -- Test pour vérifier si le prochain départ est pour le jour même if os.date("%Y/%m/%d",Date_Time) == os.date("%Y/%m/%d",time) then Prochain_Depart = "aujourd'hui" else Prochain_Depart = JourSemaine end Trace("green", "Prochain départ "..Prochain_Depart.." à " ..os.date("%H:%M", Date_Time)) message = "Prochain départ" message = message .. " "..Prochain_Depart message = message .. " de "..Msg_Depart message = message .. " pour "..Msg_Arrivee message = message .. " a ".. Horaire local Date_Time = Conversion_Date(data.journeys[1].sections[1].arrival_date_time) local Horaire = tostring(tonumber(os.date("%H", Date_Time))) .. " heure ".. tostring(tonumber(os.date("%M", Date_Time))) local JourSemaine = josdGetJourSemaine(os.date("%w", Date_Time)) message = message .. " Arrivée à "..Horaire Trace("green", "Arrivée à " ..os.date("%H:%M", Date_Time)) -- Envoi d'un message sur l'enceinte SONOS if Msg_Sonos == "OUI" then Debug("grey", "Envoi Message sur enceinte SONOS") fibaro:startScene(SceneID_Sonos, {{msg = message}, {vol = Volume_Sonos}}) end else Trace("orange"," Attention : Aucunes données à traiter") end else Debug("grey","T6".." - "..Iti_Titre) Trace("yellow","Traitement ko : "..Iti_Titre) if response.status == 500 or response.status == 503 then Trace("orange","Erreur d'indisponibilité du serveur") else Trace("orange","Erreur requête serveur, response.status = "..response.status) end end end, error = function(err) Debug("grey","T7".." - "..Iti_Titre) Trace("orange","Erreur de reception de données, Erreur = ".. err) end }) end) if not(ok) then Trace("orange","Erreur dans l'exécution de fhttp:request(Query") end Debug("grey","T9".." - "..Iti_Titre) end function Start() Debug("grey","VD_Id="..VD_Id.." / Volume_Sonos="..Volume_Sonos.." / Msg_Sonos="..Msg_Sonos) -- test pour vérifier si le module virtuel exist ou pas local ip = fibaro:get(VD_Id, 'IPAddress') if ip == nil then Debug("orange","Warning : Le module virtuel : "..VD_Id.." n'existe pas. Vous devez le créer !") else -- Lancement du traitement de l'itinéraire GetData() end end ------------------------------------------------------------------------------- -- Begining off Scène ------------------------------------------------------------------------------- local params = fibaro:args() Trace("orange","Début de traitement de la scène") if (params) then for k, v in ipairs(params) do if (v.Iti_Titre) then Iti_Titre = v.Iti_Titre end if (v.code_api_to) then code_api_to = v.code_api_to end if (v.code_api_from) then code_api_from = v.code_api_from end if (v.Msg_Arrivee) then Msg_Arrivee = v.Msg_Arrivee end if (v.Msg_Depart) then Msg_Depart = v.Msg_Depart end if (v.Msg_Sonos) then Msg_Sonos = v.Msg_Sonos end if (v.Volume_Sonos) then Volume_Sonos = v.Volume_Sonos end if (v.VD_Id) then VD_Id = v.VD_Id end end Start() else Trace("orange","Erreur : Cette scène fonctionne par appel depuis un VD avec un passage de paramètres") end Trace("orange","Fin de traitement de la scène")
-
tutoriel IPX800 V4 : Utilisation du mode Push
MAM78 a répondu à un(e) sujet de MAM78 dans GCE Electronics
De rien. Si ça peut être utile -
Ok je pense avoir compris ton problèmes. Le VD te propose le prochain train disponible qui passe à Chalon, soit celui de 05:52 Toi tu voudrais voir dès à présent le train suivants, soit celui 06:37 Dans la logique actuelle du VD tu seras le train de 06:37 demain matin lorsqu'il sera 05:53 (soit après le départ du premier train) Afin de pouvoir satisfaire ta demande, il me faut modifier le VD pour pourvoir balayer les différents itinéraires et pas seulement le prochain. Je vais essayer d'intégrer cette fonctionnalité. Ce ne devrait pas être trop compliqué à mettre en place avec l'utilisation de 2 boutons (Train Suivant et Train Précédent). Au boulot
-
c'est quel itinéraire que tu souhaiterais te voir proposé dans les cas que tu sites ?
-
Je n'ai pas encore pu vérifier des cas précis sur le perturbations de trafics.
-
Pourrais-tu nous indiquer un exemple avec des horaires précis en prenant 2 trains qui correspondent aux cas que tu sites.