Integration von Abfahrtszeiten ÖPNV in der Schweiz (wobei die API vom VDV Europa weit in Gebrauch ist/VDV431).
Die Grundlegende Idee ist den ÖPNV attraktiver zu machen in dem aktuelle/Echtzeitdaten zu Verfügung gestellt werden und so auch direkt zuhause mit dem Blick auf ein E-Paper Display (gerade in Arbeit) zu sehen ob man hetzen sollte oder ob man sich Zeit lassen kann….
(Auch wenn ich hier kommerziellen Produkte erwähne werde ich weder dafür bezahlt, oder habe sonstige Vorteile, nur für den Fall das einer weint).
Verwendete Tools:
IP-Symcon ist eine Smart Home Software von der Symcon GmbH (IP-Symcon :: Automatisierungssoftware). Das gesamt Scripting basiert auf PHP.
Visualisierung mit IPSStudio IPSStudio – Die alternative Visualisierung für IP-Symcon (brownson.at)
Dank der Open Data Projekten wie Open-Data-Plattform Mobilität Schweiz stehen viel Daten als Service zu Verfügung, ein Service der SBB. In Deutschland sei hier Willkommen – OpenData ÖPNV (opendata-oepnv.de) erwähnt, leider ist in Deutschland durch den ÖPNV Flickenteppich keine Möglichkeit die Daten beim einem Zentralen Service abzufangen.
In der Schweiz ist zwar eine Registrierung notwendig, solange man aber nicht tausende Anfragen pro Tag hat ist das ganze kostenfrei. Die Schnittstelle ist im Cookbook beschrieben.
Vorgehen:
- Registrieren
- Im Dashboard einen API-Key erstellen
- Im Skript anpassen.
Die Datenstruktur ist unter Abfahrts-/Ankunftsanzeiger (TRIAS 2020) beschrieben. Im PHP Script wird in der parseData Funktion daraus eine Tabelle in HTML erstellt (ohne große Formatierung). Da die Daten in Form von XML in einem
Die relativ Einfache Implementierung ist erst mal quick and dirty, wird aber demnächst upgedated. (Stärkere Trennung von Abruf und Darstellung etc.)
<?php
$accesstoken="put your access token in here";
$deptime=date("Y-m-d\TH:i:s",time());
$station="8503855";
$doc=requestData($accesstoken,$deptime,$station,5);
$data=parseData($doc);
$station="8503204";
$doc=requestData($accesstoken,$deptime,$station,5);
$data=$data."<p/>".parseData($doc);
$station="8503672";
$doc=requestData($accesstoken,$deptime,$station,5);
$data=$data."<p/>".parseData($doc);
SetValueString(37523,$data);
function requestData($accesstoken,$deptime,$station,$num)
{
$reqtime=gmdate("Y-m-d\TH:i:s\Z");
//Not a nice way to create XML but for a fast test fine ...
$postcont='<?xml version="1.0" encoding="UTF-8"?>
<Trias version="1.1" xmlns="http://www.vdv.de/trias" xmlns:siri="http://www.siri.org.uk/siri" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceRequest>
<siri:RequestTimestamp>'.$reqtime.'</siri:RequestTimestamp>
<siri:RequestorRef>API-Explorer</siri:RequestorRef>
<RequestPayload>
<StopEventRequest>
<Location>
<LocationRef>
<StopPointRef>'.$station.'</StopPointRef>
</LocationRef>
<DepArrTime>'.$deptime.'</DepArrTime>
</Location>
<Params>
<NumberOfResults>'.$num.'</NumberOfResults>
<StopEventType>departure</StopEventType>
<IncludePreviousCalls>false</IncludePreviousCalls>
<IncludeOnwardCalls>false</IncludeOnwardCalls>
<IncludeRealtimeData>true</IncludeRealtimeData>
</Params>
</StopEventRequest>
</RequestPayload>
</ServiceRequest>
</Trias>';
$len=strlen($postcont);
$headr[] = 'Content-length: '.$len;
$headr[] = 'Content-type: text/XML';
$headr[] = 'Authorization:'.$accesstoken;
$ch=curl_init("https://api.opentransportdata.swiss/trias2020");
curl_setopt($ch, CURLOPT_HTTPHEADER,$headr);
curl_setopt($ch, CURLOPT_POST,true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); //for security this should always be set to true.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //for security this should always be set to 2.
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$postcont);
$rest = curl_exec($ch);
curl_close($ch);
$doc = new DOMDocument();
$doc->loadXML($rest);
return($doc);
}
function parseData($doc)
{
$res=($doc->getElementsByTagName('Trias')->item(0)->getElementsByTagName('ServiceDelivery')->item(0)->getElementsByTagName('DeliveryPayload')->item(0)->getElementsByTagName('StopEventResponse')->item(0)->getElementsByTagName('StopEventResult'));
$data="<table width='100%'><tr><td width='30%'><b>Linie</b></td><td width='20%'><b>Bucht/Gleis</b></td><td width='25%'><b>Geplant</b></td><td width='25%'><b>Aktuell</b></td></tr>";
foreach($res as $re)
{
$se=$re->getElementsByTagName('StopEvent')->item(0);
$cas=$re->getElementsByTagName('StopEvent')->item(0)->getElementsByTagName('ThisCall')->item(0)->getElementsByTagName('CallAtStop')->item(0);
$station = $cas->getElementsByTagName('StopPointName')->item(0)->getElementsByTagName('Text')->item(0)->nodeValue;
$bay="unbekannt";
if($cas->getElementsByTagName('PlannedBay')->length!=0)
{
$bay = $cas->getElementsByTagName('PlannedBay')->item(0)->getElementsByTagName('Text')->item(0)->nodeValue;
}
$pland = $cas->getElementsByTagName('ServiceDeparture')->item(0)->getElementsByTagName('TimetabledTime')->item(0)->nodeValue;
$esti="Keine Daten vorhanden";
if($cas->getElementsByTagName('ServiceDeparture')->item(0)->getElementsByTagName('EstimatedTime')->length!=0)
{
$est = $cas->getElementsByTagName('ServiceDeparture')->item(0)->getElementsByTagName('EstimatedTime')->item(0)->nodeValue;
$dt = DateTime::createFromFormat('Y-m-d\TH:i:s+', $est,new DateTimeZone('UTC'));
$dt->setTimezone(new DateTimeZone('Europe/Berlin'));
$esti = $dt->format("H:i:s");
}
$type = $se->getElementsByTagName('Service')->item(0)->getElementsByTagName('Mode')->item(0)->getElementsByTagName('Name')->item(0)->getElementsByTagName('Text')->item(0)->nodeValue;
$line = $se->getElementsByTagName('Service')->item(0)->getElementsByTagName('PublishedLineName')->item(0)->getElementsByTagName('Text')->item(0)->nodeValue;
$dest = $se->getElementsByTagName('Service')->item(0)->getElementsByTagName('DestinationText')->item(0)->getElementsByTagName('Text')->item(0)->nodeValue;
$dt = DateTime::createFromFormat('Y-m-d\TH:i:s+', $pland,new DateTimeZone('UTC'));
$dt->setTimezone(new DateTimeZone('Europe/Berlin'));
$plan = $dt->format("H:i:s");
$data=$data."<tr><td>".$type." ".$line." nach ".$dest."</td><td>".$bay."</td><td>".$plan."</td><td>".$esti."</td></tr>";
}
$data=$data."</table>";
return($data);
}