Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Skript Luftdaten

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Skript Luftdaten

    This topic has been deleted. Only users with topic management privileges can see it.
    • Ro75
      Ro75 last edited by Ro75

      Hallo. Heute stelle ich euch einmal mein Skript "Luftdaten" vor. Dieses Skript liest Daten einer Websiteaus. Es ermittelt wie auch andere Skripts (z.B. Wetter, Biowetter, AlleStörungen, usw.) Daten und schreibt diese zur Weiterverarbeitung in einzelne Datenpunkte.

      Ausgelesen werden Daten für Ozon, NO2, PM10 und PM25. Damit lassen sich einfache, individuelle Visualisierungen erstellen. Dies ist vielleicht ein weiteres Skript für Nutzer vom ioBroker.

      VORARBEITEN für SKRIPT - Anleitung um meinen Ort und damit die URL zu finden

      1. Adresse https://www.accuweather.com/ öffnen und im Suchfeld dein Ort eingeben und auswählen - Hinweis: Funktioniert mit Orten aus DE, AT, CH
        2d7aaaf9-e7ec-412d-aadf-6d492926ff1c-image.png

      2. Auf der neuen Seite, unterhalb des Suchfeldes auf den Link "LUFTQUALITÄT" klicken
        5284ee36-d54b-4b21-aa31-718b89226b41-image.png

      3. In der ersten Karte (LUFTQUALITÄT HEUTE) unten rechts auf den Link "plume labs" klicken
        65a95d62-4dc4-4dd5-a510-ff9274d4f03d-image.png

      4. Adresse im Browser kopieren und die Konstante sURL anpassen - sollte etwa so aussehen: https://air.plumelabs.com/air-quality-in-XXXXXX-aw-YYYYYYYY?utm_source=accuweather&utm_medium=current_aq_widget&utm_campaign=#ae16

      VORARBEITEN für Visualisierung (VIS) - ICON

      Nachfolgende Bilder müssen in den Ordner "luftdaten". Dieser ist ein Unterordner von "vis.0". Ergebnis: "/vis.0/luftdaten". Hinweis. Sollte eine andere Visualisierung genutzt werden, müssen ggfs. individuelle Anpassungen vorgenommen werden.

      aqip6.png
      aqip5.png
      aqip4.png
      aqip3.png
      aqip2.png
      aqip1.png
      luftdaten-images.zip

      //Version 1.0.0
      //23.09.2024
      //Ersteller Ro75.
      
      //Voraussetzungen (Version 1.0.0 getestet mit)
      //NodeJS: 20.x
      //Javascript-Adapter: 8.7.6
      //Admin-Adapter: 7.0.23
      //JS-Controller: 6.0.11
      
      //Vorarbeiten abarbeiten
      
      const sMainPath     = '0_userdata.0.Luftdaten.';
      //URL zum Auslesen - bitte anpassen - Anleitung beachten!!
      const sURL          = 'https://air.plumelabs.com/air-quality-in-bautzen-aw-171290?utm_source=accuweather&utm_medium=current_aq_widget&utm_campaign=#ae16'; // Ermittlung Schritt 1 - 4
      //nicht ändern!!!
      const airBasis      = 'O3,PM10,PM25,NO2';
      const airDetails    = 'hervorragend,angemessen,schlecht,ungesund,sehr ungesund,gefährlich';
      
      function Initalisierung(){
          let sAIR = airBasis.split(',');
          for (let i = 0; i <= sAIR.length-1; i++) {
              createState(sMainPath+sAIR[i]+'.value', 0, {name: 'Wert',type: 'number', read: true, write: true, unit: 'µg/m³'});
              createState(sMainPath+sAIR[i]+'.index', 0, {name: 'Index',type: 'number', read: true, write: true});
              createState(sMainPath+sAIR[i]+'.desc', '', {name: 'Beschreibung',type: 'string', read: true, write: true});
              createState(sMainPath+sAIR[i]+'.image', '', {name: 'VIS',type: 'string', read: true, write: true});
          }
          createState(sMainPath+'data_json', '', {name: 'JSON',type: 'string', def: '[]', read: true, write: true, desc: 'JSON Widget'});
          createState(sMainPath+'Gesamt.index', '', {name: 'Index',type: 'number', read: true, write: true});
          createState(sMainPath+'Gesamt.value', '', {name: 'Wert',type: 'number', read: true, write: true});
          createState(sMainPath+'Gesamt.desc', '', {name: 'Beschreibung',type: 'string', read: true, write: true});
          createState(sMainPath+'Gesamt.image', '', {name: 'VIS',type: 'string', read: true, write: true});
          //erster Datenabruf
          LuftMessDaten();
      }
      //START
      Initalisierung();
      
      //automatischer Abruf aller 15 Minuten - weniger nicht empfohlen
      schedule('*/15 * * * *', LuftMessDaten);
      
      
      function NormZahl(wert) {
          if(isNaN(wert)) {
              wert = 0;
          }
          return wert;
      }
      
      function LuftMessDaten() {
          httpGet(sURL, { timeout: 30000, "headers":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0"}}, (error, response) => {
              if (!error && response.statusCode == 200) {
                  let info = response.data;
                  let sAIR = airBasis.split(',');
                  for (let i = 0; i <= sAIR.length-1; i++) {
                      AuswertungLuftMessDaten(info,sAIR[i]);
                  }
                  AuswertungLuftMessDatenEx();
                  CreateJSON();
                  info = '';
              } else {
                  if (response.statusCode != 502) {
                      console.error('LuftMessDaten: ' + response.statusCode);
                  }
              }    
          })
      }
      
      
      function CreateJSON() {
          let JSON_List   = [];
          let sAIR = airBasis.split(',');
          for (let i = 0; i <= sAIR.length-1; i++) {
              JSON_List.push({"air": sAIR[i], "index": getState(sMainPath+sAIR[i]+'.index').val, "value": getState(sMainPath+sAIR[i]+'.value').val, "desc": getState(sMainPath+sAIR[i]+'.desc').val, "image": getState(sMainPath+sAIR[i]+'.image').val});
          }
          setState(sMainPath+'data_json', JSON.stringify(JSON_List), true);
          JSON_List = [];
      }
      
      function AuswertungLuftMessDaten(sData='', sIndex=''){
          var info = sData;
          var Position = info.indexOf('window.current_data');
          var dummy = info.substr(Position, 1000);
          var Position = dummy.indexOf('"'+sIndex+'"');
          var dummy = dummy.substr(Position, 100);
      
          var Position = dummy.indexOf('"pi":');
          var dummy = dummy.substr(Position+6, 7);
          setState(sMainPath+sIndex+'.index', parseInt(dummy), true);
          var lIndex = LuftIndex(parseInt(dummy));
          setState(sMainPath+sIndex+'.desc', airDetails.split(',')[lIndex-1], true);
          setState(sMainPath+sIndex+'.image', '/vis.0/luftdaten/aqip'+lIndex+'.png', true);
      
          var Position = info.indexOf('window.current_data');
          var dummy = info.substr(Position, 1000);
          var Position = dummy.indexOf('"'+sIndex+'"');
          var dummy = dummy.substr(Position, 100);
      
          var Position = dummy.indexOf('"value_upm":');
          var dummy = dummy.substr(Position+13, 7);
          setState(sMainPath+sIndex+'.value', parseFloat(dummy), true);
      }
      
      function AuswertungLuftMessDatenEx(){
          let sAIR = airBasis.split(',');
          var aqi = Math.max(NormZahl(getState(sMainPath+sAIR[0]+'.index').val), NormZahl(getState(sMainPath+sAIR[1]+'.index').val), NormZahl(getState(sMainPath+sAIR[2]+'.index').val), NormZahl(getState(sMainPath+sAIR[3]+'.index').val));
          var lIndex = LuftIndex(aqi);
      
          setState(sMainPath+'Gesamt.value', aqi, true);
          setState(sMainPath+'Gesamt.index', lIndex, true);
          setState(sMainPath+'Gesamt.desc', airDetails.split(',')[lIndex-1], true);
          setState(sMainPath+'Gesamt.image', '/vis.0/luftdaten/aqip'+lIndex+'.png', true);
      }
      
      function LuftIndex(aqi){
          if (aqi <= 20) {
              return 1;
          } else if (aqi <= 50) {
              return 2;
          } else if (aqi <= 100) {
              return 3;
          } else if (aqi <= 150) {
              return 4;
          } else if (aqi <= 250) {
              return 5;
          } else {
              return 6;
          }
      }
      

      Im Grunde sollte alles selbsterklärend sein. Die hinzugefügten Kommentare geben Info und Einstellmöglichkeiten. Für Anregungen bin ich offen, auch wenn es ggfs. nicht gleich umgesetzt werden kann (die gute Zeit).

      99be4083-ed00-4301-a5a4-94396ed1ac1f-image.png

      Ich wünsche euch viel Spaß.

      Ro75.

      S sigi234 2 Replies Last reply Reply Quote 4
      • S
        spike2 @Ro75 last edited by spike2

        @ro75 Dankeschön für das Script, funktioniert ohne Probleme 👍 😊

        Anbei ein Beispiel in VIS:

        1b693b42-90d5-4e6f-9e96-56e38c26b31d-grafik.png

        Grüße Spike

        1 Reply Last reply Reply Quote 1
        • sigi234
          sigi234 Forum Testing Most Active @Ro75 last edited by

          @ro75

          Super aber /vis.0/luftdaten/aqip0.png gibt es nicht?

          D 1 Reply Last reply Reply Quote 0
          • D
            Dischro @sigi234 last edited by

            @sigi234
            ich hab sie umbenannt, von 0-5

            Ro75 1 Reply Last reply Reply Quote 0
            • Ro75
              Ro75 @Dischro last edited by

              @dischro sollte so nicht sein. Passe das Skript an, hatte es etwas abgeändert.

              Ro75

              bahnuhr 1 Reply Last reply Reply Quote 1
              • bahnuhr
                bahnuhr Forum Testing Most Active @Ro75 last edited by

                @ro75
                Auch ne Anmerkung von mir.

                Aufruf "Start" geht ins Leere -> diese Funktion gibt es nicht.
                (gilt auch für dein anderes Script -> Pollenflug)

                'info.substr' is deprecated.
                ersetze es durch substring

                769213d3-ee61-4bc0-9e2f-5cba8a599ddb-image.png
                Kann man auch die Texte rausholen ?

                Ansonsten top -> sofort umgesetzt
                Danke.

                Ro75 1 Reply Last reply Reply Quote 0
                • Ro75
                  Ro75 @bahnuhr last edited by

                  @bahnuhr START ist ein Kommentar. Das andere schaue ich mir an

                  Ro75

                  bahnuhr 1 Reply Last reply Reply Quote 0
                  • bahnuhr
                    bahnuhr Forum Testing Most Active @Ro75 last edited by

                    @ro75 sagte in Skript Luftdaten:

                    @bahnuhr START ist ein Kommentar. Das andere schaue ich mir an

                    Ro75

                    Hast recht.
                    zu schnell gekuckt und noch schneller geschrieben.
                    mfg

                    1 Reply Last reply Reply Quote 0
                    • M
                      MCU last edited by MCU

                      @Ro75 Ist eine Raute in der URL gibt es einen Fehler.

                      httpGet(url=https://air.plumelabs.com/air-quality-in-hamburg-cdmq?utm_source=accuweather&utm_medium=current_aq_widget&utm_campaign=#ae16, error=timeout of 30000ms exceeded)
                      

                      Man muss # durch %23 ersetzen, dann geht es.

                      bahnuhr 1 Reply Last reply Reply Quote 0
                      • bahnuhr
                        bahnuhr Forum Testing Most Active @MCU last edited by

                        @Ro75

                        Zeile 92: setState(sMainPath+sIndex+'.image', '/vis.0/main/img/Luftdaten/aqip'+(lIndex-1)+'.png', true);
                        Zeile 112: setState(sMainPath+'Gesamt.image', '/vis.0/main/img/Luftdaten/aqip'+(lIndex-1)+'.png', true);

                        Bei beiden Zeilen habe ich den Pfad geändert.

                        In den Objekten steht aber trotzdem der alte Pfad:
                        d81ab6be-d487-481f-adf4-02b433982944-image.png

                        Was übersehe ich?
                        Finde den Gedankenfehler nicht.

                        bahnuhr 1 Reply Last reply Reply Quote 0
                        • bahnuhr
                          bahnuhr Forum Testing Most Active @bahnuhr last edited by

                          @bahnuhr

                          Hat sich erledigt.
                          Cache gelöscht. Dann stand es richtig drin.

                          mfg

                          S 1 Reply Last reply Reply Quote 0
                          • S
                            stenmic @bahnuhr last edited by stenmic

                            script ist gut, aber… wie zufrieden seid ihr mit den Werten?
                            Ich hole mir den Index über iqair. die haben auch ne offene api (mit free token). Leider aber nur für die jeweiligen Messstationen.
                            zum Glück hab ich gleich eine vom Wetterdienst in der Nachbarstadt.

                            Hier mal zum Vergleich
                            iqair AQI 60
                            IMG_0765.jpeg

                            accuweather AQI 33
                            IMG_0764.jpeg

                            was stimmt denn jetzt 🤒

                            S 1 Reply Last reply Reply Quote 0
                            • S
                              spike2 @stenmic last edited by

                              @stenmic Das habe ich auch schon festgestellt, aber man muss auch mal prüfen wo genau die Messstationen der jeweiligen Anbieter sind 😉

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post

                              Support us

                              ioBroker
                              Community Adapters
                              Donate

                              817
                              Online

                              31.7k
                              Users

                              79.9k
                              Topics

                              1.3m
                              Posts

                              7
                              13
                              838
                              Loading More Posts
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes
                              Reply
                              • Reply as topic
                              Log in to reply
                              Community
                              Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                              The ioBroker Community 2014-2023
                              logo