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:

  1. Registrieren
  2. Im Dashboard einen API-Key erstellen
  3. 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);
}

marcus

Name: Marcus von Wilamowitz-Moellendorff Birth Year: 1981 Material Status: Married Hobbies: Blogging, Technology, Photography Education Industrial Electronic Technician Dipl. Inf. (FH) MSc (Practical Computer Science) MBA (Focus on Engineering Management) Focus of Work: Be a good example as elected team lead from/for my team Agile Development processes for safety relevant EE Systems (ISO 26262) EE System Development Tool Development Working Groups: VDV IP-KOM-ÖV WG for EN13149 7-9 ITxPT Professions: Autonomous Vehicle EE Architecture related (somehow the same or similar Project) Since 01/2018 Head of R&D/CTO @ HFM (Technical Focus on EE Architectur and Software for Self Driving Mobility Vehicles) 07/2017-01/2018 EE System Architect @ IBEO 07/2016-07/2017 Head off EE for Olli Project/Local Motors, technical lead in Germany Vehicle EE Architecture and Software Development 10/2011-07/2016 EE System Architect Lead CV and Product Manager 01/2003-10/2011 Hard and Software Developer @ Epislon Focus on Consulting/Vehicle Integration
Close Menu