NEWS
Geparste Werte von String zu Number konvertieren
-
Liebe Community,
Leider bin ich mit JavaScript noch nicht so geübt.
Wie kann ich geparste Werte von String in number konvertieren?
Ich wäre gerne die Fehler im Log wieder los.const soilup = "mqtt.1.v3.030374@ttn.devices.eui-70b3d57ed005e017.up"; const path = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017'; const idBat = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Batterie'; const idMoist = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Feuchtigkeit'; const idAir = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Luftfeuchtigkeit'; const idTemp = '0_userdata.0.Bewässerung.eui-70b3d57ed005e017.Temperatur'; on(soilup, function(dp) { let obj = JSON.parse(dp.state.val).uplink_message.decoded_payload; setState(idBat, obj.Batterie, true); setState(idMoist, obj.Feuchtigkeit, true); setState(idAir, obj.Luftfeuchtigkeit, true); setState(idTemp, obj.Temperatur, true); });
Herzlichen Dank für die Unterstützung!
-
@bloop sagte: von String in number konvertieren?
Beispiel:
setState(idBat, parseFloat(obj.Batterie), true);
Es ist allerdings ungewöhnlich, dass sie nicht im JSON als Zahl gespeichert sind.
-
@paul53
Super Danke hat Funktioniert!
Der JSON kommt von TTN dieser wird per MQTT an iobroker gesendet. Auf TTN wird in erster Instanz der vom Sensor geschickte Werte erst von einem Payload Formater Script verarbeitet. Ich habe dieses lediglich kopiert und eingefügt, da ich mich damit noch weniger auskenne.// TTNV3 Payload Formatter Uplink V0.1 function decodeUplink(input) { if ((input.fPort > 0) && (input.fPort < 223)) { var decodedTemp = 0; var decodedHumi = 0; var decodedBatt = 0; // seperate raw data from payload var rawSoil = input.bytes[0] + input.bytes[1] * 256; var rawTemp = input.bytes[2] + input.bytes[3] * 256; var rawHumi = input.bytes[4] + input.bytes[5] * 256; var rawBatt = input.bytes[6] + input.bytes[7] * 256; // decode raw data to values decodedTemp = sflt162f(rawTemp) * 100; // value calculated to range -1..x..+1 by dividing /100 decodedHumi = sflt162f(rawHumi) * 100; // value calculated to range -1..x..+1 by dividing /100 if (rawBatt !== 0) decodedBatt = rawBatt / 1000; // batterie voltage ist transmitted in mV, recalculate in V // definition of the decimal places decodedTemp = decodedTemp.toFixed(2); decodedHumi = decodedHumi.toFixed(2); decodedBatt = decodedBatt.toFixed(2); // return values return { data: { Feuchtigkeit: rawSoil, Temperatur: decodedTemp, Luftfeuchtigkeit: decodedHumi, Batterie: decodedBatt }, warnings: [], errors: [] }; } else { return { data: {}, warnings: [], errors: ["Invalid data received"] }; } } function sflt162f(rawSflt16) { // rawSflt16 is the 2-byte number decoded from wherever; // it's in range 0..0xFFFF // bit 15 is the sign bit // bits 14..11 are the exponent // bits 10..0 are the the mantissa. Unlike IEEE format, // the msb is transmitted; this means that numbers // might not be normalized, but makes coding for // underflow easier. // As with IEEE format, negative zero is possible, so // we special-case that in hopes that JavaScript will // also cooperate. // // The result is a number in the open interval (-1.0, 1.0); // // throw away high bits for repeatability. rawSflt16 &= 0xFFFF; // special case minus zero: if (rawSflt16 == 0x8000) return -0.0; // extract the sign. var sSign = ((rawSflt16 & 0x8000) !== 0) ? -1 : 1; // extract the exponent var exp1 = (rawSflt16 >> 11) & 0xF; // extract the "mantissa" (the fractional part) var mant1 = (rawSflt16 & 0x7FF) / 2048.0; // convert back to a floating point number. We hope // that Math.pow(2, k) is handled efficiently by // the JS interpreter! If this is time critical code, // you can replace by a suitable shift and divide. var f_unscaled = sSign * mant1 * Math.pow(2, exp1 - 15); return f_unscaled; }
-
@bloop
Zeilen 22 bis 24: toFixed(2) macht aus den Zahlenwerten Strings. -
Hallo,
Leider erhalte ich seit der Änderung im Script nun folgende Fehlermeldung:javascript.0 2023-06-02 21:59:22.190 error at processImmediate (node:internal/timers:471:21) javascript.0 2023-06-02 21:59:22.190 error at Immediate._onImmediate (/opt/iobroker/node_modules/@iobroker/js-controller-adapter/src/lib/adapter/adapter.js:5916:56) javascript.0 2023-06-02 21:59:22.189 error at Object.stateChange(/opt/iobroker/node_modules/iobroker.javascript/main.js:593:29) javascript.0 2023-06-02 21:59:22.189 error at Object.callback (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1244:38) javascript.0 2023-06-02 21:59:22.189 error at Object.<anonymous> (script.js.common.Bewässerung.Json_to_DP:49:37) javascript.0 2023-06-02 21:59:22.189 error Error in callback: TypeError: Cannot read properties of undefined (reading 'Batterie')
Es scheint so, als würden die Werte nicht bei jeder Übertragung von TTN mitgeschickt zu werden.
Könnte mir eventuell wieder jemand weiterhelfen?Herzlichen Dank!
-
@bloop
Die Zeilenangabe in der Fehlermeldung passt nicht zu den beiden SkriptsEs sieht jedoch so aus als wenn der Fehler in Zeile 4 auftritt deshalb Zeile 3 einfügen. Da Batterie auch 0 sein kann auf undefined testen.
Wenn .Batterie da ist, müsste auch der Rest da sein.on(soilup, function(dp) { let obj = JSON.parse(dp.state.val).uplink_message.decoded_payload; if (!obj || obj.Batterie == undefined) return setState(idBat, obj.Batterie, true); setState(idMoist, obj.Feuchtigkeit, true); setState(idAir, obj.Luftfeuchtigkeit, true); setState(idTemp, obj.Temperatur, true); });
-
@ticaki
Super Danke!
Glaube jetzt hab ich`s gecheckt.