virtueller HTTP Eingang Befehl dynamische befehlserkennung

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • toubee
    Dumb Home'r
    • 05.04.2019
    • 19

    #1

    virtueller HTTP Eingang Befehl dynamische befehlserkennung

    Hallo Zusammen

    Ich versuche die Wetterdaten für die Schweiz von Meteoschweiz in den Miniserver zu erhalten. Die Daten sind als JSON für einen Ort abrufbar, bspw. unter diesem Link: https://app-prod-ws.meteoswiss-app.c...ail?plz=800100, wobei die plz die Postleitzahl ist, im Beispiel Zürich.

    Die Daten kann ich per virtuellem http Eingang einlesen und per Befehlserkennung (Command Recognition) auslesen.

    Das Ziel ist, die Daten irgendwann in als Wetterdaten in den Miniserver zu erhalten, dazu werde ich den Loxone Grabber ausprobieren, danke für den Hinweis Christian.

    Allerdings muss ich zuvor noch einen (für mich) kniffligen Zwischenschritt lösen:
    Die Niederschlagsmenge kommt bei Meteoschweiz in zwei verschiedenen Auflösungen daher: 10-Minuten-Auflösung (graph_precipitation10m) und 1h-Auflösung (graph_precipitation1h). Für beide Auflösungen habe ich einen Startzeitpunkt:
    • 1h-Vorhersage beginnt Zeitpunkt T+5h mit T=aktuelle Stunde (graph_startLowResolution)
    • 10m-Vorhersage beginnt (vermutlich immer) um Mitternacht des aktuellen Tages (graph_start)
    Mein Problem:
    Mich interessieren nur die 30 Datenpunkte, welche unmittelbar in der Zukunft liegen, da diese nicht durch die 1h-Vorhersage abgedeckt sind.
    Weil die 10m-Vorhersage aber um Mitternacht beginnt, muss ich sämtliche Datenpunkte berücksichtigen und je nach Uhrzeit auswählen.

    Sämtliche Datenpunkte als HTTP-Eingänge in die Config einzufügen (bis zu 144) scheint mir unrealistisch, zumal dann noch eine Logik für die Selektion der relevanten Datenpunkte benötigt wird. (36 Multiplexer...)

    Ich habe das Thema virtueller http Eingang mit dynamischer URL gelesen, was nah dran an meiner Problematik ist, jedoch bräuchte ich ein virtueller http Eingang mit dynamischer Befehlserkennung, so dass ich je nach Zeitpunkt einen anderen Wert auslesen könnte.
    Die Befehlserkennung lautet:
    Code:
    precipitation10m":[\sXX\v
    wobei XX ein vielfaches von 4 ist und den auszulesenden Wert festlegt (0 = 1. Wert, 4 = 2. Wert, 8 = 3. Wert usw.)

    Kennt jemand eine Möglichkeit dazu?

    Falls nicht, gibt es vielleicht ein Plugin für den Loxberry, mit welchem das möglichst elegant umsetzbar ist?

    Vielen Dank für eure Ideen und Grüsse aus der Schweiz

    toubee
  • EdiB
    Extension Master
    • 30.12.2015
    • 135

    #2
    Ich habe dir keine fertige Lösung, aber schon mal daran gedacht, das mit LoxberryXL (PHP) zu machen? Ich hole mit damit lediglich die Wetterwarnungen von der MeteoSwiss. Brauchst dazu natürlich ein bisschen PHP Kenntnis.

    Hier mein PHP Script. Vielleicht kannst du was ableiten.

    PHP-Code:
    #!/usr/bin/env php
    <?php
    require_once "loxberry_XL.php";
    /*
    LOXBERRY XL
    EXtended Logic
    
    Meteo Swiss API Wetter Warnungen an MQTT Plugin > Miniserver
    */
    
    // In some cases, servers will disallow requests that contain unidentified user agents
    // ini_set('user_agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36');
    
    // Postleitzahl für die Abfrage (XXXX00)
    $PLZ = "953300";
    
    //set URL
    $url = "https://app-prod-ws.meteoswiss-app.ch/v1/plzDetail?plz=$PLZ";
    
    // HTTP Header Optionen
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $headers = array(
    "User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
    "Accept-Language: de",
    );
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    $resp = curl_exec($curl);
    curl_close($curl);
    // var_dump($resp);
    
    // JSON auslesen
    $json_decoded = json_decode($resp);
    // print_r($json_decoded);
    
    if(array_key_exists('warnType', $json_decoded->warnings[0])) { // prüfen ob eine erste Warnung vorhanden ist
    $wN = 0;
    if(array_key_exists('warnType', $json_decoded->warnings[1])) { // prüfen ob eine weitere Warnung vorhanden ist und entsprechend priorität festlegen
    $warn0Type = $json_decoded->warnings[0]->warnType;
    $warn1Type = $json_decoded->warnings[1]->warnType;
    $warnType0Prio = SetWarnTypPrio ($warn0Type); // Übergaben an Funktion zum setzen der Priorität je nach Typ
    $warnType1Prio = SetWarnTypPrio ($warn1Type); // Übergaben an Funktion zum setzen der Priorität je nach Typ
    if($warnType0Prio > $warnType1Prio) { // prüfen welche Warnung höher priorisiert ist und entsprechend die Warung zur Auswertung festlegen
    $wN = 0; // set warningNumber to 0
    } else {
    $wN = 1; // set warningNumber to 1
    }
    }
    $warnType = $json_decoded->warnings[$wN]->warnType;
    $warnLevel = $json_decoded->warnings[$wN]->warnLevel;
    if(array_key_exists('text', $json_decoded->warnings[$wN])) { // bei Lawinenwarung z.B. gibt es diesen Pfad nicht
    $warnText = $json_decoded->warnings[$wN]->text;
    } else {
    $warnText = "-";
    }
    $validFrom = date('d.m.Y H:i', substr($json_decoded->warnings[$wN]->validFrom, 0, 10));
    $validTo = date('d.m.Y H:i', substr($json_decoded->warnings[$wN]->validTo, 0, 10));
    $warnTypeName = Warning_TypeName ($warnType, $warnLevel, $warnText);
    } else {
    $warnType = 99;
    $warnLevel = 0;
    $warnText = "-";
    $validFrom = date('d.m.Y H:i');
    $validTo = date('d.m.Y H:i', strtotime("+5 minutes")); // 5min ist das Abrage Intervall für die Warnmeldungen
    $warnTypeName = "keine Gefahren";
    }
    
    echo '<br>' . '<br>';
    echo $warnType . "_" . $warnTypeName . '<br>';
    echo $warnLevel . '<br>';
    echo $warnText . '<br>';
    echo $validFrom . '<br>';
    echo $validTo . '<br>';
    
    // Publish to local MQTT broker
    $mqtt->retain("LoxBerryXL/WeatherForecast/Warning/warnType", $warnType);
    $mqtt->retain("LoxBerryXL/WeatherForecast/Warning/warnTypeName", $warnTypeName);
    $mqtt->retain("LoxBerryXL/WeatherForecast/Warning/warnLevel", $warnLevel);
    $mqtt->retain("LoxBerryXL/WeatherForecast/Warning/validFrom", $validFrom);
    $mqtt->retain("LoxBerryXL/WeatherForecast/Warning/validTo", $validTo);
    
    function Warning_TypeName ($warnType, $warnLevel, $warnText) {
    if ($warnType == 0) { // Wind
    switch ($warnLevel) { // Es werden nur Windwarnungen der Stufe 2 bis 5 ausgegeben
    case 2: $warnTypeName = "Wind (Stufe " . $warnLevel . ") 70-90km/h"; break;
    case 3: $warnTypeName = "Sturm (Stufe " . $warnLevel . ") 90-110km/h"; break;
    case 4: $warnTypeName = "Sturm (Stufe " . $warnLevel . ") 110-140km/h"; break;
    case 5: $warnTypeName = "Orkan (Stufe " . $warnLevel . ") >140km/h"; break;
    }
    } elseif ($warnType == 1) { // Gewitter
    $warnTypeName = "Gewitter (Stufe " . $warnLevel . ") " . $warnText;
    } elseif ($warnType == 2) { // Regen
    $warnTypeName = "Regen (Stufe " . $warnLevel . ") " . $warnText;
    } elseif ($warnType == 3) {
    $warnTypeName = "nicht definiert";
    } elseif ($warnType == 8) { // Lawine
    $warnTypeName = "Lawinen(Stufe " . $warnLevel . ") " . $warnText;
    } elseif ($warnType == 9) { // Erdbeben
    $warnTypeName = "Erdbeben (Stufe " . $warnLevel . ") " . $warnText;
    } elseif ($warnType == 10) { // Waldbrand
    $warnTypeName = "Waldbrand (Stufe " . $warnLevel . ") " . $warnText;
    } elseif ($warnType == 11) { // Hochwasser
    $warnTypeName = "Hochwasser (Stufe " . $warnLevel . ") " . $warnText;
    } else {
    $warnTypeName = $warnType . "-nicht definiert (Stufe " . $warnLevel . ") " . $warnText;
    }
    return $warnTypeName;
    }
    
    function SetWarnTypPrio ($warnType) {
    switch ($warnType) { // Prioritäten für verschiedene Warnungen festlegen
    case 1: $warnTypePrio = 10; break; // Gewitter
    case 0: $warnTypePrio = 9; break; // Wind
    case 9: $warnTypePrio = 8; break; // Erdbeben
    case 11: $warnTypePrio = 7; break; // Hochwasser
    case 2: $warnTypePrio = 6; break; // Regen
    case 10: $warnTypePrio = 4; break; // Waldbrand
    case 8: $warnTypePrio = 1; break; // Lawine
    }
    return $warnTypePrio;
    }
    
    /*
    Script mit Zeitplan verlinken
    ln -s /opt/loxberry/webfrontend/html/XL/user/meteo_swiss.php /opt/loxberry/system/cron/cron.05min/meteo_swiss
    
    Dem Script und dem Job noch die richtigen Permissions geben, sonst wird es von Cron nicht ausgeführt:
    chmod 755 /opt/loxberry/webfrontend/html/XL/user/meteo_swiss.php
    chmod 755 /opt/loxberry/system/cron/cron.05min/meteo_swiss
    
    Script vom Zeitplan löschen (falls der nicht mehr benötigt werden sollte)
    unlink /opt/loxberry/system/cron/cron.05min/meteo_swiss
    */
    Zuletzt geändert von EdiB; 02.10.2021, 13:12.

    Kommentar


    • toubee
      toubee kommentierte
      Kommentar bearbeiten
      Hi EdiB.
      Besten Dank für Deinen Hinweis und für dein Script. Ich werde mich demnächst mit der Funktionalität von Loxberry XL auseinandersetzen. PHP muss ich mich zuerst einlesen, aber dein Beispiel ist schonmal ein Anfang
  • toubee
    Dumb Home'r
    • 05.04.2019
    • 19

    #3
    Dank der Hilfestellung von EdiB (danke!) konnte Ich mein Vorhaben wie gewünscht umsetzen.

    Hier meine Lösung, falls diese jemand anders nützlich sein sollte:

    --edit 2023-11-27: in der Datei hatte es einen Fehler, welcher interessanterweise erst jetzt ersichtlich wurde. Ich habe die Datei angepasst und unten hineinkopiert--

    PHP-Code:
    #!/usr/bin/env php
    <?php
    require_once "loxberry_XL.php";
    /*
    LOXBERRY XL
    EXtended Logic
    
    Meteo Swiss API 10m Niederschlag an MQTT Plugin > Miniserver
    
    durch den Aufruf der auf dem Loxberry gehosteten Datei (http://loxberry/XL/user/meteoschweizNiederschlag.php) werden die Werte in den Miniserver geschrieben, siehe anleitung auf Loxforum:
    
    */
    
    // In some cases, servers will disallow requests that contain unidentified user agents
    // ini_set('user_agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36');
    
    // Postleitzahl für die Abfrage (XXXX00)
    $PLZ = "857200";
    
    echo '<br><br>PLZ=' . $PLZ . '<br><br>';
    
    //set URL
    $url = "https://app-prod-ws.meteoswiss-app.ch/v1/plzDetail?plz=$PLZ";
    
    // HTTP Header Optionen
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $headers = array(
    "User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
    "Accept-Language: de",
    );
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    $resp = curl_exec($curl);
    curl_close($curl);
    // var_dump($resp);
    
    // JSON auslesen
    $json_decoded = json_decode($resp);
    //print_r($json_decoded);
    
    //berechne aktuellen Zeitblock: ( aktuelle stunde * 60 + aktuelle Minute ) / 10
    $aktuellerBlock = ( date('H') * 60 + date('i') ) / 10;
    //print_r($aktuellerBlock);
    
    //schneide die nachkommastellen ab
    $aktuellerBlock = (int)$aktuellerBlock;
    echo '<br>' . $aktuellerBlock . '<br>';
    
    //erstelle für jede Stunde eine Regenvorhersage indem für jede Stunde die Regenmenge aufsummiert wird
    //iteration durch die stunden
    for ($i = 0; $i <= 4; $i++) {
        //iteration durch die Minuten
        for ($j = 0; $j <= 5; $j++) {
            //schrittberechnung war fehlerhaft
            $step = $j * 1 + $i * 6;
            //$precipitationHour muss ein Array sein, da sonst die Werte über alle Stunden aufsummiert werden (1 Wert)
            $precipitationHour[$i] = $precipitationHour[$i] + $json_decoded->graph->precipitation10m[$aktuellerBlock + $step];
            echo $i . '/' . $j . '(' . ($aktuellerBlock + $step) . ')' . ':' . $precipitationHour[$i] . '<br>';
        }
        echo $precipitationHour[$i] . '<br>';
        //$precipitation[$i] = $precipitationHour;
        //echo $precipitationHour[$i] . '<br>';
    }
    
    print_r($precipitationHour);
    
    // Publish to local MQTT broker
    $mqtt->retain("LoxBerryXL/WeatherForecast/precipitation0", $precipitationHour[0]);
    $mqtt->retain("LoxBerryXL/WeatherForecast/precipitation1", $precipitationHour[1]);
    $mqtt->retain("LoxBerryXL/WeatherForecast/precipitation2", $precipitationHour[2]);
    $mqtt->retain("LoxBerryXL/WeatherForecast/precipitation3", $precipitationHour[3]);
    $mqtt->retain("LoxBerryXL/WeatherForecast/precipitation4", $precipitationHour[4]);
    
    
    /*
    Script mit Zeitplan verlinken
    ln -s /opt/loxberry/webfrontend/html/XL/user/meteo_swiss.php /opt/loxberry/system/cron/cron.05min/meteo_swiss
    
    Dem Script und dem Job noch die richtigen Permissions geben, sonst wird es von Cron nicht ausgeführt:
    chmod 755 /opt/loxberry/webfrontend/html/XL/user/meteo_swiss.php
    chmod 755 /opt/loxberry/system/cron/cron.05min/meteo_swiss
    
    Script vom Zeitplan löschen (falls der nicht mehr benötigt werden sollte)
    unlink /opt/loxberry/system/cron/cron.05min/meteo_swiss
    */
    Zuletzt geändert von toubee; 27.11.2023, 22:45.

    Kommentar

    Lädt...