NEWS
Skript Luftdaten
-
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
-
Adresse https://www.accuweather.com/ öffnen und im Suchfeld dein Ort eingeben und auswählen - Hinweis: Funktioniert mit Orten aus DE, AT, CH
-
Auf der neuen Seite, unterhalb des Suchfeldes auf den Link "LUFTQUALITÄT" klicken
-
In der ersten Karte (LUFTQUALITÄT HEUTE) unten rechts auf den Link "plume labs" klicken
-
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.
//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).
Ich wünsche euch viel Spaß.
Ro75.
-
-
-
Super aber /vis.0/luftdaten/aqip0.png gibt es nicht?
-
@sigi234
ich hab sie umbenannt, von 0-5 -
@dischro sollte so nicht sein. Passe das Skript an, hatte es etwas abgeändert.
Ro75
-
@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
Kann man auch die Texte rausholen ?Ansonsten top -> sofort umgesetzt
Danke. -
@bahnuhr START ist ein Kommentar. Das andere schaue ich mir an
Ro75
-
@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 -
@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. -
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:
Was übersehe ich?
Finde den Gedankenfehler nicht. -
-
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
accuweather AQI 33
was stimmt denn jetzt
-
@stenmic Das habe ich auch schon festgestellt, aber man muss auch mal prüfen wo genau die Messstationen der jeweiligen Anbieter sind