[CLASS] Abfahrtstafeln von bahn.de auslesen

@ffmspider

Kannst du mal testweise „Riederwald Schaefflestrasse, Frankfurt am Main“ probieren?

@sysrun ist geblieben,

was mir noch aufgefallen ist

es fehlt in der CASE anweisung der fall für die UBahn und das Bild… liegt vieleicht daran das man in Hanover nicht so tief boren kann sonst ist LandUnter :stuck_out_tongue:

case "UBAHN":
              $eintrag[0] = "<img src=/user/bahn/Ubahn_24x24.gif>";
              break;

Ah, ok!

Naja, wir haben hier in hannover nen Kombisystem aus U- und Straßenbahn. Im Zetrum fahren alle Bahnen unter der Erde. In den Radgebieten kommen die dann „ans Licht“ und fahren oberirdisch weiter.

Habt wohl nicht genug Platz bei euch was? :stuck_out_tongue:

Hallo und Danke für diese Scripte und vielen Dank an alle, die mir in den vergangenen Wochen bei allen Problemen und „dummen“ Fragen zu Seite stenden.

Hier in einer aktualisierten Form incl. Icons und behobenen Fehlern.
Die Icons kommen ins Verzeichnis webfront user „bahn“.

Es gibt immer noch Probleme wenn der Bahnhofsname mit Klammern versehen ist. Die DB verwendet jedoch für jeden Bahnhof eindeutige Nummern, die auch hier im Script anstatt des Namens eingetragen werden können.

Wie kommt mann an diese Nummer?
Wenn im Script Abfrage der eigene Bahnhofsname etwas falsch eingegeben wird, erscheint im Scriptausgabefenster eine Lister der möglichen Bahnhöfe mit diesen eindeutigen Kennnummern. Die richtige dann auswählen - und schon funktioniert es.

Korrigiertes Abfragescript:

<?
require_once("class.bahn.php"); // Klasse einbinden

//Ab hier nichts mehr ändern
$object = IPS_GetObject($IPS_SELF);
$parentID = $object['ParentID'];

// abfragenamen verändern
//IPS_SetName($parentID, "Bahnverbindung von ".date("H:i",time()));

// Neue Instanz
//Parameter 1 ist der Bahnhof oder die Haltestelle
//(es muss kein Bahnhof sein, Bushaltestelle gehen auch)
// Parameter 2 ist die Art der Tafel: "Abfahrt" oder "Ankunft"
// TODO: Anpassen
$bahn=new bahn("008003280","abfahrt");


// Hier werden Verkehrsmittel ausgeschlossen
/*
$bahn->TypeBUS(false);
$bahn->TypeTRAM(false);
$bahn->TypeICE(false);
$bahn->TypeIC(false);
$bahn->TypeRE(false);
$bahn->TypeSBAHN(false);
$bahn->TypeUBAHN(false);
$bahn->TypeFAEHRE(false);
*/

// Hier werden Datum und Zeit gesetzt.
// Werden die nicht gesetzt wird die/das aktuelle Zeit/Datum genommen
/*
$bahn->datum("17.5.2010");
$bahn->zeit("1:00");
*/

// Jetzt das Ergebniss holen!
$abfragestatus=$bahn->fetch();
if($abfragestatus){
    // Array mit den Informationen ausgeben:
    //print_r($bahn->timetable);
    // TODO: Anpassen
    AnzeigeAufbereiten($bahn,"Abfahrt Kirchheim Teck",$parentID,20);
}

// zweite Anzeigentafel
// TODO: Anpassen
$bahn=new bahn("008003280","ankunft");
$abfragestatus=$bahn->fetch();
if($abfragestatus){
    // Array mit den Informationen ausgeben:
    //print_r($bahn->timetable);
    // TODO: Anpassen
    AnzeigeAufbereiten($bahn,"Ankunft Kirchheim Teck",$parentID,0);
}

// anzeige aufbereiten in eine html box
// $bahn - ergebnis der class.bahn.php
// $name - Variablen Bezeichnung. Muss für ein Object identisch sein
// $parentID - oberklasse oder dummy object id
// $wegezeit - eine wegezeit in minuten zum bahnhof. oder =0
function AnzeigeAufbereiten($bahn, $name,$parentID, $wegezeit)
{
    $VARIABLEN_TEXT=$name;
    $WEGEZEIT = $wegezeit; //in minuten, wenn 0 dann nicht farblich markieren

    // Anzeige aufbereiten
    $str = "<table width='90%' align='center'>"; // Farbe anpassen oder style entfernen
    $str .= "<tr><td></td><td><b>Zug</b></td><td><b>Zeit</b></td><td><b>Diff.</b></td><td><b>Richtung</b></td><td><b>Gleis</b></td><td><b>Aktuelles</b></td></tr>";

    $pos = 0;
    for($i=0; $i<sizeof($bahn->timetable); $i++)
    {
        //$eintrag = explode(";", $bahn->timetable[$i]);
        $caller = $bahn->timetable[$i]["type"];
        switch($caller) {
           case "SBAHN":
              $eintrag[0] = "<img src=/user/bahn/sbahn_24x24.gif>";
              break;
           case "BUS":
              $eintrag[0] = "<img src=/user/bahn/bus_24x24.gif>";
              break;
           case "RE":
              $eintrag[0] = "<img src=/user/bahn/re_24x24.gif>";
              break;
           case "ICE":
              $eintrag[0] = "<img src=/user/bahn/ice_24x24.gif>";
              break;
           case "TRAM":
              $eintrag[0] = "<img src=/user/bahn/tram_24x24.gif>";
              break;
            default:
               $eintrag[0] = "";
               break;
        }
        $colour="white"; // yellow or red, white ist der normalfall
        $eintrag[1] = $bahn->timetable[$i]["train"];
        $eintrag[2] = $bahn->timetable[$i]["time"];

        // differenz zur aktuellen zeit ausrechnen.
        $timestampField = strtotime($bahn->timetable[$i]["time"]);
        $timestampNow = time();//+1*60*60;
        //echo date("H:i",$timestampNow)."-";
        //echo date("H:i",$timestampField)."/";

        $diff = $timestampField - $timestampNow;
        //echo $diff." * ";
        if ($diff >0)
        {
            $eintrag[3] = $uhrzeit = date("H:i",$diff-1*60*60);
            if ($diff > $WEGEZEIT*60)
            {
               $colour="white";
               // einfach keine farbe definieren
            }
            else
            {
               $colour="yellow";
               $eintrag[3]="<font color='#FFFF00'>".$eintrag[3];
            }
        }
        else
        {
          // nicht mehr zu schaffen da zeit abgelaufen
          $eintrag[3] = "--:--";
          if ($WEGEZEIT <>0)
              $eintrag[3]="<font color='#FF0000'>".$eintrag[3];
        }
        $eintrag[4] = $bahn->timetable[$i]["route_ziel"];
        $eintrag[5] = $bahn->timetable[$i]["platform"];
        $eintrag[6] = $bahn->timetable[$i]["ris"];

            $str .= "<tr>";
            foreach($eintrag as $data)
                $str .= '<td>'.$data.'</td>';
            $str .= "</tr>";

            $pos++;

        if($pos >= 6)
            break;
    }
    $str .= "</table>";

    $vid = CreateVariableByName($parentID, $VARIABLEN_TEXT, 3);
    IPS_SetIcon($vid, "Distance");
    IPS_SetVariableCustomProfile($vid, "~HTMLBox");
    SetValue($vid, $str);
}

function CreateVariableByName($id, $name, $type)
{
    global $IPS_SELF;
    $vid = @IPS_GetVariableIDByName($name, $id);
    if($vid === false)
    {
        $vid = IPS_CreateVariable($type);
        IPS_SetParent($vid, $id);
        IPS_SetName($vid, $name);
        IPS_SetInfo($vid, "this variable was created by script #$IPS_SELF");
    }
    return $vid;
}

?>

Hier die PHP Klasse:
Hinweis: Neues Script anlegen und den Dateinamen auf „class.bahn.php“ setzten.

<?
/*
Author: Frederik Granna (sysrun)
Version 0.1
*/


class bahn{
    var $_BASEURL="http://reiseauskunft.bahn.de/bin/bhftafel.exe/dn?";
    var $_PARAMS=array();
    var $timetable=array();
    var $bahnhof=false;
    var $_FETCHMETHOD;
    function bahn($bahnhof=null,$type="abfahrt"){
       $type=strtolower($type);


       if(!$bahnhof)
          $bahnhof="008003280";
        $this->_init($bahnhof);
        $this->fetchMethodCURL(true);
        $this->boardType($type);

        //$this->_query();
    }

    function TypeBUS($state=true){$this->_PARAMS['GUIREQProduct_5'] = ($state) ? "on" : false;}
    function TypeICE($state=true){$this->_PARAMS['GUIREQProduct_0'] = ($state) ? "on" : false;}
    function TypeIC($state=true){$this->_PARAMS['GUIREQProduct_1'] = ($state) ? "on" : false;}
    function TypeRE ($state=true){$this->_PARAMS['GUIREQProduct_3'] = ($state) ? "on" : false;} // NV genannt
    function TypeSBAHN ($state=true){$this->_PARAMS['GUIREQProduct_4'] = ($state) ? "on" : false;}
    function TypeFAEHRE ($state=true){$this->_PARAMS['GUIREQProduct_6'] = ($state) ? "on" : false;}   // UBAHN
    function TypeTRAM ($state=true){$this->_PARAMS['GUIREQProduct_8'] = ($state) ? "on" : false;}   // STrassenbahn
    function TypeUBAHN ($state=true){$this->_PARAMS['GUIREQProduct_7'] = ($state) ? "on" : false;}   // UBAHN



    function boardType($type){
        if($type=="ankunft")
            $this->_PARAMS['boardType']="arr";
        else
            $this->_PARAMS['boardType']="dep";

    }

    function datum($datum){
        $this->_PARAMS['date']=$datum;
    }

    function zeit($zeit){
        $this->_PARAMS['time']=$zeit;

    }

    /**
     *
     **/
    function fetch($html=null){
       if($html){
          return $this->_parse($html);
       }else if($this->_FETCHMETHOD=="CURL"){
            return $this->_queryCurl();
        }
    }


    function _queryCurl(){
        $this->buildQueryURL();
        $result=$this->_call();
        return $this->_parse($result);
    }

    function buildQueryURL(){
       $fields_string="";
        foreach($this->_PARAMS as $key=>$value){
           if($value)
                $fields_string .= $key.'='.urlencode($value).'&';
        };
        rtrim($fields_string,'&');

        $this->_URL=$this->_BASEURL.$fields_string;
        return $this->_URL;
    }

    function _parse($data){
        $dom = new DOMDocument();
        @$dom->loadHTML($data);

        $select=$dom->getElementById("rplc0");
        if($select->tagName=="select"){
            $options=$select->getElementsByTagName("option");
            foreach($options AS $op){
                echo utf8_decode($op->getAttribute("value")."-".$op->nodeValue)."n";
            }
            return false;
        }else{
           $this->bahnhof=utf8_decode($select->getAttribute("value"));
            $this->_process_dom($dom);
            return true;
        }
    }

    function _process_dom($dom){
            $test=$dom->getElementById("sqResult")->getElementsByTagName("tr");
            $data=array();
            foreach($test as $k=>$t){
                $tds=$t->getElementsByTagName("td");
                foreach($tds AS $td){
                   $dtype=$td->getAttribute("class");
                    switch($dtype){
                        case 'train':
                            if($a=$td->getElementsByTagName("a")->item(0)){
                                $data[$k]['train']=str_replace(" ","",$a->nodeValue);
                                if($img=$a->getElementsByTagName("img")->item(0)){
                                    if (preg_match('%/([a-z]*)_%', $img->getAttribute("src"), $regs)) {
                                       switch($regs[1]){
                                          case 'EC':
                                             $data[$k]['type']="IC";
                                          break;
                                            default:
                                                $data[$k]['type']=strtoupper($regs[1]);
                                            break;
                                        }
                                    }
                                }
                            }

                        break;
                        case 'route':
                           if($span=@$td->getElementsByTagName("span")->item(0)){
                              $data[$k]['route_ziel']=$span->nodeValue;
                            }

                            preg_match_all('/(.*)s*([0-9:]{5})/', $td->nodeValue, $result, PREG_PATTERN_ORDER);
                            $tmp=array();
                            foreach($result[1] AS $rk=>$rv){
                                $tmp[$result[2][$rk]]=utf8_decode(trim(html_entity_decode(str_replace("n","",$rv))));
                            }
                            $data[$k]['route']=$tmp;
                            //print_r($tmp);
                            /*

                            $data[$k]['route']=explode("-",$td->nodeValue);
                            foreach($data[$k]['route'] AS $dk=>$dv)
                               $data[$k]['route'][$dk]=utf8_decode(trim(html_entity_decode(str_replace("n","",$dv))));
                            */
                        break;
                        case 'time':
                        case 'platform':
                        case 'ris':
                           $data[$k][$dtype]=$td->nodeValue;
                        break;


                    }
                    //echo "n";
                }
            }

            foreach($data AS $d){
                if(array_key_exists("train",$d)){
                   foreach($d AS $dk=>$dv)
                      if(!is_array($dv))
                          $d[$dk]=ltrim(str_replace("
","",utf8_decode(trim(html_entity_decode($dv)))),"-");
                    $d['route_start']=$this->bahnhof;
                    $this->timetable[]=$d;
             }
            }
    }

    function fetchMethodCURL($state){
        if($state){
            $this->_FETCHMETHOD="CURL";
        }else{
            $this->_FETCHMETHOD="OTHER";
        }
    }


    function _call(){
        $this->_CH = curl_init();
        curl_setopt($this->_CH,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($this->_CH,CURLOPT_URL,$this->_URL);
        $result = curl_exec($this->_CH);
        curl_close($this->_CH);
        return $result;
    }

    function _init($bahnhof){
        $this->_PARAMS=array(
            'country'=>'DEU',
            'rt'=>1,
            'GUIREQProduct_0'=>'on',    // ICE
            'GUIREQProduct_1'=>'on',   // Intercity- und Eurocityzüge
            'GUIREQProduct_2'=>'on',   // Interregio- und Schnellzüge
            'GUIREQProduct_3'=>'on',   // Nahverkehr, sonstige Züge
            'GUIREQProduct_4'=>'on',    // S-Bahn
            'GUIREQProduct_5'=>'on',    // BUS
            'GUIREQProduct_6'=>'on',    // Schiffe
            'GUIREQProduct_7'=>'on', // U-Bahn
            'GUIREQProduct_8'=>'on', // Strassenbahn
            'REQ0JourneyStopsSID'=>'',
            'REQTrain_name'=>'',
            'REQTrain_name_filterSelf'=>'1',
            'advancedProductMode'=>'',
            'boardType'=>'dep', // dep oder arr
            'date'=>date("d.m.Y"),
            'input'=>$bahnhof,
            'start'=>'Suchen',
            'time'=>date("H:i")
        );


    }

}

?>

ubahn_24x24.zip (3.34 KB)

Ich hab noch eine Ergänzung. Mir war die Anzahl der Zeilen zu gering.

Wenn man die URL mit dem Parameter „maxJourneys=20“
anreichert und die aufbereitung der Anzeige an der Stelle if($pos >= 12)
modifiziert bekommt man mehr Zeilen angezeigt.

Auch kann man nun mit 2.4 entweder weitere „Reiter“ anlegen oder ich habe einfach eine weitere Integer Variable angelegt und die HTML Anzeigeelemente ein und ausgeblendet.

Hallo Mäc,

zeid doch bitte mal Deine Staumeldungen. Wie machst Du das?

Gr, Stromer

Siehe neuen Post unter: http://www.ip-symcon.de/forum/f53/verkehrsmeldungen-xte-14756/#post126273

Hallo,
kann man in dem Script ohne große Änderungen den Zielort eingrenzen?

Gruß
Eddi

:confused:

// Parameter 2 ist die Art der Tafel: "Abfahrt" oder "Ankunft"
$bahn=new bahn("Hannover Hbf","abfahrt");

Du kannst also auch am Zielort die Ankunft nehmen.

Wahrscheinlich meinst du Startort UND Zielort, um an eine Strecke zu kommen. Dazu müsste der „Code-Erzeuger“ antworten :slight_smile:

bin zwar nicht der code erzeuger. aber sowie ich mir das angeschaut habe geht es nicht über den link: bhftafel.exe

vielleicht kann man das umbauen und nicht die tafeln nehmen sondern die reiseauskuft über den link. DB BAHN - Verbindungen - Ihre Anfrage

z.B. bei google gefunden: http://wiki.serchilo.net/Deutsche_Bahn_Fahrplanauskunft

Naja, falls er die Abfahrtstafel ab Startort für bestimmte Zielorte gewünscht ist, müssen halt die Ergebnisse mit PHP auf den Zielort reduziert werden.

Hallo,
genau ich wollte nur den einen Zielort „Richtung“ wie Frankfurt(Main)Hbf rausfiltern.

Gruß Eddi

Hallo

nach 15 Minuten php Neuland habe ich eine andere Lösung für mein Problem gefunden. Die gewünschte Richtung wird einfach rot markiert.

Hier die Änderung

// gewünschte Richtung mit rot hervorheben
         if($eintrag[4] == "Frankfurt(Main)Hbf"){
           
            $eintrag[4]="<font color='#FF0000'>".$eintrag[4];

            }

Hat den Vorteil das man für verschieden Personen und Zielorte eine bessere Übersicht bieten kann. Bitte nicht steinigen wen die Auswertung auch einfacher ginge. Es funktioniert wenigstens :smiley:

Gruß Eddi

Hallo mäc,

da ich Anfänger bin, war alles etwas schwierig für mich, insbesondere die Einbindung der richtigen Version der „php_curl.dll“. Aber es funktioniert jetzt perfekt. Wie und wo genau muss ich denn den von dir vorgeschlagenen Parameter „maxJourneys=20“ zur Anzeigenerweiterung andocken ? Auch Deine charmante Lösung mit den HTML- Anzeigeelementen würde mich sehr interessieren. Man lernt hier im Forum wirklich viel !!!

Beste Grüße

Elias

In der class.bahn.php in der Zeile

var $_BASEURL="http://reiseauskunft.bahn.de/bin/bhftafel.exe/dn?maxJourneys=20";

Da die Anzeigetafeln in jeweils eine Variablen steht blende ich einfach per script den gewünschten Teil ein.


  	//Je nach Status die jeweilige anzeigetafel einblenden.
  	// dies verfahren ndert die anzeige fr alle clients

	// wenn der Wet von aussen gesetzt wird und nocht ber variablen update.
	SetValue($IPS_VARIABLE,  $IPS_VALUE);
	
	if ($IPS_VALUE==1)
	{
	   // abfahrt
	   IPS_SetHidden(16307 /*[Reise\Bahn\Bahnverbindung\Ankunft Lehrte]*/, false);
	   IPS_SetHidden(26499 /*[Reise\Bahn\Bahnverbindung\Abfahrt Lehrte]*/, true);
	}
	else
	{
	   // ankunft
	   IPS_SetHidden(26499 /*[Reise\Bahn\Bahnverbindung\Abfahrt Lehrte]*/, false);
	   IPS_SetHidden(16307 /*[Reise\Bahn\Bahnverbindung\Ankunft Lehrte]*/, true);
   }

Sieht bei mir aus wie in den Bildern

Hallo…

ich nutze seit einiger Zeit das Skript „Abfahrtstafeln von bahn.de auslesen“. Es lief bisher super und tat gute Dienste … dafür an dieser Stelle vielen Dank an den Ersteller … :loveips:

Leider hat sich seit der Umstellung auf den Winterfahrplan wohl etwas am Internetangebot der Bahn geändert; mit der Folge, dass das Skript bei mir nicht mehr läuft. Die „Anzeigetafeln“ in IPS bleiben leer.

Da meine php Kenntnisse sehr bescheiden sind hier meine Frage. Hat jemand in diesem Forum ein ähnliches Problem und gibt es hierfür ggf. bereits eine Lösung ?

Problem gelöst ! Die DB hat „meinem Bahnhof“ einen neuen Namen verpasst !!!
… Daruf soll nun einer kommen … :confused:

Gruß

Swifty

Hallo
Im Moment hab ich wohl ein Brett vorn Kopf.
Bei mir geht das Script ohne Probleme.
Heute wollte ich die Anzeige erweitern und mir auf
Mausklick die Zwischenstationen anzeigen.
Dafuer benutze ich ein Javascript welches ich per php erstelle.

		$spalte4    = "<div onclick=\"{with(document.getElementById('ebene".$pos."').style){if(display=='none'){display='inline';}else{display='none';}}};\">";
		$spalte4   .= $bahn->timetable[$i]["route_ziel"]."</div>";
		$eintrag[4] = $spalte4;

      $eintrag[5] = substr($route[count($route)-1],-5);
      $eintrag[6] = @$bahn->timetable[$i]["platform"];

      $spalte7    = @$bahn->timetable[$i]["ris"];

		$spalte7 .= "<div id='ebene".$pos."' style='display:none;'><br>";
	 	foreach ( $route as $halt )
		 		{
				$halt = utf8_decode(trim(html_entity_decode(str_replace("
","",$halt))));
				$spalte7 .= substr($halt,-5). " - " .$halt."<br>";
				}
				
		$spalte7 .= "</div>";
      $eintrag[7] = $spalte7;

Jetzt kommt das Problem.
Es funktioniert erst ab Zug Nummer 10.
Wenn ich die ersten 10 Zuege anklicke passiert garnichts.
Erst ab Zug Nummer 11 werden die Zwischenhalts angezeigt.
Hab schon alles probiert. Hab den Inhalt in den Spalten verglichen
sind ausser den Daten identisch.
Kenn mich mit Javascript nicht so aus.
Vielleicht kann mir jemand einen Tipp geben um dies Sache einzukreisen.
Danke

Verdammt ! :wink:
Man muss nur mal ne Nacht drueber schlafen.
Das Problem war die DIV_ID .
Ich hab 4 Kategorien ( Bahnhoefe ) die ich auf einer Seite habe.
Und die IDs gibt es dann ja 4x ( „ebene1“ etc ).
Nur weil ich an einem Bahnhof mehr als 10 Zuege anzeige waren die
da dann nicht doppelt.
Jetzt geht alles auch mit der Formatierung der Zwischenstopps:):loveips:

Wie genau bekomme ich denn die Ankunftszeit für die einzelnen Züge in die Tabelle? Ich habe jetzt die Tabelle schon entsprechend erweitert weiß nur leider nicht wie ich die Zeit abfrage.