Um die Luftqualität zu messen gibt es verschiedene Sensoren. Mit denen kann man sich eine Luftgütestation selber bauen. Eine Messtation selber bauen ist nicht das Ziel. Ich wollte mittels einer Schnittstelle (API) Daten von Messstationen weltweit auslesen können und diese in ioBroker integrieren. Datenpunkte erstellen, befüllen und in Lovelace visuell darstellen.[md_icon style=“filled“ icon=“md-ac_unit“]
Ich habe mich nach ausgiebigen Recherchen für das World Air Quality Index Project entschieden. Dieses Projekt startete 2007 und hat mittlerweile 30000 Stationen in über 130 Ländern verfügbar und das in Echtzeit. Nicht jede kleine Stadt hat eine registrierte Messtation. In der Nähe befindet sich auf jeden Fall eine Station. Auf der Website gibt es eine Suchfunktion.
Der Air Quality Index (AQI) ist ein zusammengefasster Wert von unterschiedlichen Sensoren. Die Werte werden von
0-500 definiert. 0 = Gut / 500 = Schlecht (sehr gesundheitsschädlich).
Wir brauchen einen Token (für den API-Zugriff) den man mittels einfacher Mail-Registrierung erhält.
Danach wird euch eine Bestätigungsmail gesendet. Den Link/Button bestätigen und schon landet ihr auf einer Seite auf der euch der Token mit einem Beispiel angezeigt wird.

Das Beispiel gibt als Resultat einen JSON zurück. Damit brauchen die Werte lediglich mit einem Skript in ioBroker eingelesen und verarbeitet werden. Das fertige Skript stelle ich euch am Ende des Artikels zur Verfügung.
// Datenpunkte anlegen (einmalig) createState("0_userdata.0.Luftqualität.aqi-data", "", {name: 'AQI-Data', type: 'string'}); createState("0_userdata.0.Luftqualität.status", "", {name: 'Status', role: 'indicator.connected', type: 'string'}); createState("0_userdata.0.Luftqualität.aqi", "", {name: 'AQI', type: 'string'}); createState("0_userdata.0.Luftqualität.url", "", {name: 'URL', type: 'string'}); createState("0_userdata.0.Luftqualität.url-name", "", {name: 'URL-Name', type: 'string'}); createState("0_userdata.0.Luftqualität.url-quelle", "", {name: 'URL-Quelle', type: 'string'}); createState("0_userdata.0.Luftqualität.url-quelle-name", "", {name: 'URL-Quelle-Name', type: 'string'}); createState("0_userdata.0.Luftqualität.city-geo-latitude", "", {name: 'City-Geo-Latitude', type: 'number'}); createState("0_userdata.0.Luftqualität.city-geo-longitude", "", {name: 'City-Geo-Longitude', type: 'number'}); createState("0_userdata.0.Luftqualität.city-name", "", {name: 'City-Name', type: 'string'}); createState("0_userdata.0.Luftqualität.city-url", "", {name: 'City-URL', type: 'string'}); createState("0_userdata.0.Luftqualität.dominentpol", "", {name: 'Dominentpol', type: 'string'}); createState("0_userdata.0.Luftqualität.iaqi-humidity", "", {name: 'Humidity', type: 'number'}); createState("0_userdata.0.Luftqualität.iaqi-no2", "", {name: 'Nitrogen-Dioxide', type: 'number'}); createState("0_userdata.0.Luftqualität.iaqi-o3", "", {name: 'Ozone', type: 'number'}); createState("0_userdata.0.Luftqualität.iaqi-p", "", {name: 'Pressure', type: 'number'}); createState("0_userdata.0.Luftqualität.iaqi-pm10", "", {name: 'Particulates-PM10', type: 'number'}); createState("0_userdata.0.Luftqualität.iaqi-t", "", {name: 'Temperature', type: 'number'}); createState("0_userdata.0.Luftqualität.iaqi-w", "", {name: 'Wind', type: 'number'}); createState("0_userdata.0.Luftqualität.iaqi-wg", "", {name: 'Wind-Speed', type: 'number'}); createState("0_userdata.0.Luftqualität.iaqi-time", "", {name: 'Timestamp', type: 'string'}); createState("0_userdata.0.Luftqualität.debug-sync", "", {name: 'Debug-Sync', type: 'string'}); var result; var Status, obj; var AQI; var URL; var URLName, URLQuelle, URLQuelleName, CityGeoLatitude, CityGeoLongitude, CityName, CityURL; var Dominentpol, iaqiHumidity, iaqiNo2, iaqiO3, iaqiP, iaqiPm10, iaqiT, iaqiW, iaqiWg, dTime; var resultIAQ; var debugSync; schedule("*/5 * * * *", async function () { try { require("request")('https://api.waqi.info/feed/@6215/?token=2ba0b7ea3fd0735c288d13916a4f199a5ed81d83', async function (error, response, result) { setState("0_userdata.0.Luftqualität.aqi-data", result, true); console.log(result); }).on("error", function (e) {console.error(e);}); } catch (e) { console.error(e); } getAqiData(); }); function getAqiData() { //Verarbeiten des JSON-Arrays setTimeout(function() { // Code, der erst nach 2 Sekunden ausgeführt wird resultIAQ = getState("0_userdata.0.Luftqualität.aqi-data").val; //Der try ist wichtig damit der Adapter nicht abschmiert bei einem Fehler - hiermit parsen wir die JSON in ein Object try {obj = JSON.parse(resultIAQ); } catch (e) { console.error('Cannot parse:'); return; } // Objektvariablen Status = obj.status; AQI = obj.data.aqi; URL = obj.data.attributions[0].url; URLName = obj.data.attributions[0].name; URLQuelle = obj.data.attributions[1].url; URLQuelleName = obj.data.attributions[1].name; CityGeoLatitude = obj.data.city.geo[0]; CityGeoLongitude= obj.data.city.geo[1]; CityName = obj.data.city.name; CityURL = obj.data.city.url; Dominentpol = obj.data.dominentpol; iaqiHumidity = obj.data.iaqi.h.v; iaqiNo2 = obj.data.iaqi.no2.v; iaqiO3 = obj.data.iaqi.o3.v; iaqiP = obj.data.iaqi.p.v; iaqiPm10 = obj.data.iaqi.pm10.v; iaqiT = obj.data.iaqi.t.v; iaqiW = obj.data.iaqi.w.v; iaqiWg = obj.data.iaqi.wg.v; dTime = obj.data.time.s; debugSync = obj.data.debug.sync; // Temporäre Variablen AQI = parseFloat(AQI); AQI = AQI.toFixed(0); // Datenpunkte werden mit Inhalt gefüllt setState('0_userdata.0.Luftqualität.status', (Status)); setState('0_userdata.0.Luftqualität.aqi', (AQI)); setState('0_userdata.0.Luftqualität.url', (URL)); setState('0_userdata.0.Luftqualität.url-name', (URLName)); setState('0_userdata.0.Luftqualität.url-quelle', (URLQuelle)); setState('0_userdata.0.Luftqualität.url-quelle-name', (URLQuelleName)); setState('0_userdata.0.Luftqualität.city-geo-latitude', (CityGeoLatitude)); setState('0_userdata.0.Luftqualität.city-geo-longitude', (CityGeoLongitude)); setState('0_userdata.0.Luftqualität.city-name', (CityName)); setState('0_userdata.0.Luftqualität.city-url', (CityURL)); setState('0_userdata.0.Luftqualität.dominentpol', (Dominentpol)); setState('0_userdata.0.Luftqualität.iaqi-humidity', (iaqiHumidity)); setState('0_userdata.0.Luftqualität.iaqi-no2', (iaqiNo2)); setState('0_userdata.0.Luftqualität.iaqi-o3', (iaqiO3)); setState('0_userdata.0.Luftqualität.iaqi-p', (iaqiP)); setState('0_userdata.0.Luftqualität.iaqi-pm10', (iaqiPm10)); setState('0_userdata.0.Luftqualität.iaqi-t', (iaqiT)); setState('0_userdata.0.Luftqualität.iaqi-w', (iaqiW)); setState('0_userdata.0.Luftqualität.iaqi-wg', (iaqiWg)); setState('0_userdata.0.Luftqualität.iaqi-time', (dTime)); setState('0_userdata.0.Luftqualität.debug-sync', (debugSync)); }, 2000); };
N’Abend !
Ich habe das Script bei mir installiert. Die Daten von der Internetseite werden als JSON eingelesen. Ab dann hapert es leider. Eine Idee ?
javascript.0
2022-01-16 19:55:02.019 error at processTimers (internal/timers.js:500:7)
javascript.0
2022-01-16 19:55:02.019 error at listOnTimeout (internal/timers.js:557:17)
javascript.0
2022-01-16 19:55:02.019 error at Timeout._onTimeout (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:2117:34)
javascript.0
2022-01-16 19:55:02.018 error at Object. (script.js.common.Luftqualität:80:44)
javascript.0
2022-01-16 19:55:02.018 error Error in callback: TypeError: Cannot read property ‚v‘ of undefined
javascript.0
2022-01-16 19:55:00.816 info script.js.common.Luftqualität: {„status“:“ok“,“data“:{„aqi“:76,“idx“:1451,“attributions“:[{„url“:“http://www.bjmemc.com.cn/“,“name“:“Beijing Environmental Protection Monitoring Center (北京市环境保护监测中心)“},{„url“:“https://waqi.info/“,“name“:“World Air Quality Index Project“}],“city“:{„geo“:[39.954592,116.468117],“name“:“Beijing (北京)“,“url“:“https://aqicn.org/city/beijing“},“dominentpol“:“pm25″,“iaqi“:{„co“:{„v“:6.4},“h“:{„v“:66},“no2″:{„v“:29.3},“o3″:{„v“:0.5},“p“:{„v“:1030},“pm10″:{„v“:47},“pm25″:{„v“:76},“so2″:{„v“:1.6},“t“:{„v“:-11},“w“:{„v“:1.5}},“time“:{„s“:“2022-01-17 02:00:00″,“tz“:“+08:00″,“v“:1642384800,“iso“:“2022-01-17T02:00:00+08:00″},“forecast“:{„daily“:{„o3“:[{„avg“:7,“day“:“2022-01-15″,“max“:15,“min“:1},{„avg“:2,“day“:“2022-01-16″,“max“:9,“min“:1},{„avg“:2,“day“:“2022-01-17″,“max“:10,“min“:1},{„avg“:1,“day“:“2022-01-18″,“max“:4,“min“:1},{„avg“:1,“day“:“2022-01-19″,“max“:8,“min“:1},{„avg“:1,“day“:“2022-01-20″,“max“:4,“min“:1},{„avg“:1,“day“:“2022-01-21″,“max“:1,“min“:1}],“pm10″:[{„avg“:44,“day“:“2022-01-15″,“max“:73,“min“:15},{„avg“:49,“day“:“2022-01-16″,“max“:58,“min“:33},{„avg“:50,“day“:“2022-01-17″,“max“:72,“min“:19},{„avg“:61,“day“:“2022-01-18″,“max“:73,“min“:44},{„avg“:29,“day“:“2022-01-19″,“max“:45,“min“:19},{„avg“:58,“day“:“2022-01-20″,“max“:72,“min“:28},{„avg“:72,“day“:“2022-01-21″,“max“:115,“min“:46},{„avg“:103,“day“:“2022-01-22″,“max“:123,“min“:62}],“pm25″:[{„avg“:122,“day“:“2022-01-15″,“max“:174,“min“:58},{„avg“:142,“day“:“2022-01-16″,“max“:158,“min“:100},{„avg“:144,“day“:“2022-01-17″,“max“:173,“min“:68},{„avg“:160,“day“:“2022-01-18″,“max“:174,“min“:132},{„avg“:93,“day“:“2022-01-19″,“max“:134,“min“:68},{„avg“:154,“day“:“2022-01-20″,“max“:173,“min“:89},{„avg“:167,“day“:“2022-01-21″,“max“:189,“min“:134},{„avg“:219,“day“:“2022-01-22″,“max“:252,“min“:162}],“uvi“:[{„avg“:0,“day“:“2022-01-16″,“max“:1,“min“:0},{„avg“:0,“day“:“2022-01-17″,“max“:2,“min“:0},{„avg“:0,“day“:“2022-01-18″,“max“:1,“min“:0},{„avg“:0,“day“:“2022-01-19″,“max“:1,“min“:0},{„avg“:0,“day“:“2022-01-20″,“max“:1,“min“:0},{„avg“:0,“day“:“2022-01-21″,“max“:0,“min“:0}]}},“debug“:{„sync“:“2022-01-17T03:54:27+09:00″}}}
Hallo Mascho,
mit welcher JavaScript-Adapter Version arbeitest du im ioBroker?
Hast du deinen eigenen API-Key eingefügt?
Gruß, Jan