@oliverio
Bei mir läuft die node Version 18.17.0
Der aktuelle Code sieht so aus:
/* Meteohub
Skript holt Daten aus Meteohub XML Datei, bereitet sie auf und stellt einige Datenpunkte zur Verfügung
erstellt: 2020 Wolfgang Berger
{1}
V 0.1 Initiale Version. Hartcodierte Zuordnung. Wird nicht funktionieren sobald der Windmesser online ist.
V 0.2 jetzt Sensoren in Liste
V 0.3 kosmetische Aufbereitung. Altlasten entfernt.
*/
// Settings ################################################################
const mh_URL = 'http://192.168.75.9/meteograph.cgi?text=allxml';
const axios = require('axios') // das an den Anfang des Skripts
// End of settings ###########################################################
// Includes ################################################################
const request = require('request');
var parser = require('xml2json');
const util = require('util'); // for debugging. Use log(util.inspect(obj));
// Type definitions ################################################################
var state_temp = { type: 'number', unit: '°C', read: true, write: false,role: 'value.temperature' };
var state_json = { read: true, write: false,role: 'mh.json' };
var state_humidity = { type: 'number', unit: '%rH', read: true, write: false,role: 'value.humidity' };
var state_speed = { type: 'number', unit: 'km/h', read: true, write: false,role: 'value.speed' };
var state_direction = { type: 'number', unit: '°', read: true, write: false,role: 'value.direction' };
var state_pressure = { type: 'number', unit: 'mbar', read: true, write: false,role: 'value.pressure' };
var state_rainrate = { type: 'number', unit: 'mm/h', read: true, write: false,role: 'value.precipitation.hour' };
var state_rain = { type: 'number', unit: 'mm', read: true, write: false,role: 'value.precipitation.today' };
// Now build State Tree ################################################################
function parseXML(xmldata,do_init) {
log(xmldata)
var mh_json = parser.toJson(xmldata); // convert XML to JSON
var mh_data = JSON.parse(mh_json); // parse JSON into JS object
let data = mh_data.meteohub.data; // only use the data section of the object. We ignore the config section for now.
// Loop through data sections. each data[i] contains data for a given timeframe like actual, like 1h, 1day, etc.
for(let i = 0; i < data.length; i++) {
let folder = 'meteohub.' + data[i].timeframe + '.'; // timeframe is can be "actual", "alltime" and much more. Each datasection only contains one timeframe value
let item = data[i].item;
// log(util.inspect(data[i]));
// Now we have selected one timeframe and loop through all items
// instead of building a state tree with hundreds of values, we pick only the ones that are interesting.
for(let j = 0; j < item.length; j++) {
let id = folder + item[j].sensor + '.' + item[j].cat;
// Temperature Value in degrees Celsius
if( (item[j].cat == 'temp') && (item[j].unit == 'c')) {
if (do_init==true) { createState(id,parseFloat(item[j].$t),state_temp); }
else { setState(id,parseFloat(item[j].$t)); }
}
// Humidity as relative humidity
if( (item[j].cat == 'hum') && (item[j].unit == 'rel')) {
if (do_init==true) { createState(id,parseFloat(item[j].$t),state_humidity); }
else { setState(id,parseFloat(item[j].$t)); }
}
// Air pressure refered to sealevel
if( (item[j].cat == 'sealevel') && (item[j].unit == 'hpa')) {
if (do_init==true) { createState(id,parseFloat(item[j].$t),state_pressure); }
else { setState(id,parseFloat(item[j].$t)); }
}
// rain values in mm
if( (item[j].sensor == 'rain0') && (item[j].unit == 'mm')) {
if (do_init==true) { createState(id,parseFloat(item[j].$t),state_rain); }
else { setState(id,parseFloat(item[j].$t)); }
}
// for windsensor currently we tend to catch nearly all, because the whitelist could be long. For example windspeed is interesting in different units.
// Therefore instead of whitelisting the values we do the oposit and use a blacklist for the ones we don't like.
if( (item[j].sensor == 'wind0') ) {
if ((item[j].unit == 'time')) {
let dat = item[j].$t;
let d = new Date(dat.substring(0,4) + '-' + dat.substring(4,6) + '-' + dat.substring(6,8) + 'T' + dat.substring(8,10) +':' + dat.substring(10,12) + ':'+ dat.substring(12,14) );
if (do_init==true) { createState(id+'.'+item[j].unit, d); }
else { setState(id+'.'+item[j].unit, d); }
}
else {
// first catch values in degrees celsius. Because there we can set the unit. Leave the others without unit.
if (item[j].unit == 'c') {
if (do_init==true) { createState(id+'.'+item[j].unit, parseFloat(item[j].$t),state_temp); }
else { setState(id+'.'+item[j].unit, parseFloat(item[j].$t)); }
}
else {
// Blacklisting for values we don't like
if (!(item[j].unit == 'f' || item[j].unit == 'en' || item[j].unit == 'nl' || item[j].unit == 'mph')) {
if (do_init==true) { createState(id+'.'+item[j].unit, parseFloat(item[j].$t)); }
else { setState(id+'.'+item[j].unit, parseFloat(item[j].$t)); }
}
}
}
}
}
}
} // end parseXML()
async function getXML(do_init) {
// loads full meteohub xml file from the mh_URL and calls the parse function.
// on very first execution do_init is true and all states are created. Each successive call only sets the state values.
log('meteohub query data from '+mh_URL); // Debug output
let result = null
try {
result = await execAsync('curl '+mh_URL)
log(result) // kann weg wenns geht, ansonsten das hier posten
} catch(e) {log(e)}
if (result) {
var start = new Date();
parseXML(result, do_init);
var time = new Date() - start;
log('Meteohub XML2JSON Durchlaufzeit: '+time);
} else {
log('Keine Daten','warn')
};
}
// On first script execution, create the states
let do_init=true;
getXML(do_init);
function execAsync(f) {
return new Promise((resolve, reject) => {
exec(f, function (error, stdout, stderr) {
resolve();
});
})
}
// Regular Update
schedule('*/1 * * * *', function () {
let do_init=false;
getXML(do_init); // regelmäßiger Update
});
Ursprünglich war es der Code aus dem Post und die Zeile für den Datenabruf:
const mh_URL = 'http://192.168.75.9/meteograph.cgi?text=allxml';
musste angepasst werden. Danach hatte ich das Problem, dass er wegen folgenden Fehler hatte:
20.7.2023, 21:05:08.838 [error]: javascript.0 (2129892) script.js.common.WetterdatenEinlesen: Fehler beim Herunterladen Meteohub XML: Error: Parse Error: Invalid header value char
@Homoran , @paul53 und @ticaki haben sich dann an vielen Dingen versucht, aber bisher ohne Erfolg