From 31a957461ec8f7218899c674b2cf0ae780f0b5cd Mon Sep 17 00:00:00 2001 From: localhorst Date: Sun, 24 Mar 2024 21:12:47 +0100 Subject: [PATCH] added payload formatter --- payload_formatter.js | 238 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 payload_formatter.js diff --git a/payload_formatter.js b/payload_formatter.js new file mode 100644 index 0000000..0cd0263 --- /dev/null +++ b/payload_formatter.js @@ -0,0 +1,238 @@ +/* +JS payload formatter for decoding VEGAPULS Air TTN payload +change the following line to run the script with 'node payload_formatter.js' for debugging +*/ +const debug = false + +if (debug) { + function main() { + const decoded_payload = [0x08, 0x42, 0x28, 0xF5, 0xC3, 0x01, 0x02, 0x00, 0x2A, 0x03, 0x04]; + var decoded = Decoder(decoded_payload, 0x01); + console.log(decoded); + } + + if (require.main === module) { + main(); + } +} + +function Decoder(frm_payload, f_port) { + if (debug) { + console.log(frm_payload); + } + + function bytesToFloat(bytesToDecode) { + // JavaScript bitwise operators yield a 32 bits integer, not a float. + // Assume LSB (least significant byte first). + var bits = bytesToDecode[0] << 24 | bytesToDecode[1] << 16 | bytesToDecode[2] << 8 | bytesToDecode[3]; + var sign = (bits >>> 31 === 0) ? 1.0 : -1.0; + var e = bits >>> 23 & 0xff; + var m = (e === 0) ? (bits & 0x7fffff) << 1 : (bits & 0x7fffff) | 0x800000; + var f = sign * m * Math.pow(2, e - 150); + return f; + } + + function bytesToInt16(bytesToDecode) { + var tmpInt16 = (bytesToDecode[0] << 24 >> 16) | bytesToDecode[1]; + return tmpInt16; + } + + function bytesToUInt32(bytesToDecode) { + var tmpUInt32 = bytesToDecode[0] * 256 * 256 * 256 + bytesToDecode[1] * 256 * 256 + bytesToDecode[2] * 256 + bytesToDecode[3]; + return tmpUInt32; + } + + if (frm_payload.length < 1) { + if (debug) { + console.log("Invalid payload length"); + } + return null; + } + + var decoded = {}; + decoded.raw_frm_payload = frm_payload; + decoded.PacketIdentifier = frm_payload[0]; + + switch (decoded.PacketIdentifier) { + case 8: // OKAY + decoded.Distance = bytesToFloat(frm_payload.slice(1, 5)); + decoded.Unit = frm_payload[5]; + decoded.RemainingPower = frm_payload[6]; + decoded.Temperature = bytesToInt16(frm_payload.slice(7, 9)); + decoded.UnitTemperature = frm_payload[9]; + decoded.Inclination_degree = frm_payload[10]; + break; + case 9: // OKAY AND GPS + decoded.Distance = bytesToFloat(frm_payload.slice(1, 5)); + decoded.Unit = frm_payload[5]; + decoded.RemainingPower = frm_payload[6]; + decoded.GNSSLatitude = bytesToFloat(frm_payload.slice(7, 11)); + decoded.GNSSLongitude = bytesToFloat(frm_payload.slice(11, 15)); + decoded.Temperature = bytesToInt16(frm_payload.slice(15, 17)); + decoded.UnitTemperature = frm_payload[17]; + decoded.Inclination_degree = frm_payload[18]; + break; + case 10: // ERROR + decoded.NamurState = frm_payload[1]; + decoded.Distance = bytesToFloat(frm_payload.slice(2, 6)); + decoded.Unit = frm_payload[6]; + decoded.RemainingPower = frm_payload[7]; + decoded.DetailState = bytesToUInt32(frm_payload.slice(8, 12)); + decoded.Temperature = bytesToInt16(frm_payload.slice(12, 14)); + decoded.UnitTemperature = frm_payload[14]; + decoded.Inclination_degree = frm_payload[15]; + break; + case 11: // ERROR AND GPS + decoded.NamurState = frm_payload[1]; + decoded.Distance = bytesToFloat(frm_payload.slice(2, 6)); + decoded.Unit = frm_payload[6]; + decoded.RemainingPower = frm_payload[7]; + decoded.GNSSLatitude = bytesToFloat(frm_payload.slice(8, 12)); + decoded.GNSSLongitude = bytesToFloat(frm_payload.slice(12, 16)); + decoded.DetailState = bytesToUInt32(frm_payload.slice(16, 20)); + decoded.Temperature = bytesToInt16(frm_payload.slice(20, 22)); + decoded.UnitTemperature = frm_payload[22]; + decoded.Inclination_degree = frm_payload[23]; + break; + case 12: // MEASUREMENT OKAY + decoded.Distance = bytesToFloat(frm_payload.slice(1, 5)); + decoded.Unit = frm_payload[5]; + decoded.MvProcent = bytesToInt16(frm_payload.slice(6, 8)); + decoded.MvLinProcent = bytesToInt16(frm_payload.slice(8, 10)); + decoded.MvScaled = bytesToFloat(frm_payload.slice(10, 14)); + decoded.MvScaledUnit = frm_payload[14]; + decoded.RemainingPower = frm_payload[15]; + decoded.Temperature = bytesToInt16(frm_payload.slice(16, 18)); + decoded.UnitTemperature = frm_payload[18]; + decoded.Inclination_degree = frm_payload[19]; + break; + case 13: // MEASUREMENT OKAY AND GPS + decoded.Distance = bytesToFloat(frm_payload.slice(1, 5)); + decoded.Unit = frm_payload[5]; + decoded.MvProcent = bytesToInt16(frm_payload.slice(6, 8)); + decoded.MvLinProcent = bytesToInt16(frm_payload.slice(8, 10)); + decoded.MvScaled = bytesToFloat(frm_payload.slice(10, 14)); + decoded.MvScaledUnit = frm_payload[14]; + decoded.RemainingPower = frm_payload[15]; + decoded.GNSSLatitude = bytesToFloat(frm_payload.slice(16, 20)); + decoded.GNSSLongitude = bytesToFloat(frm_payload.slice(20, 24)); + decoded.Temperature = bytesToInt16(frm_payload.slice(24, 26)); + decoded.UnitTemperature = frm_payload[26]; + decoded.Inclination_degree = frm_payload[27]; + break; + case 14: // MEASUREMENT ERROR + decoded.NamurState = frm_payload[1]; + decoded.Distance = bytesToFloat(frm_payload.slice(2, 6)); + decoded.Unit = frm_payload[6]; + decoded.MvProcent = bytesToInt16(frm_payload.slice(7, 9)); + decoded.MvLinProcent = bytesToInt16(frm_payload.slice(9, 11)); + decoded.MvScaled = bytesToFloat(frm_payload.slice(11, 15)); + decoded.MvScaledUnit = frm_payload[15]; + decoded.RemainingPower = frm_payload[16]; + decoded.DetailState = bytesToUInt32(frm_payload.slice(17, 21)); + decoded.Temperature = bytesToInt16(frm_payload.slice(21, 23)); + decoded.UnitTemperature = frm_payload[23]; + decoded.Inclination_degree = frm_payload[24]; + break; + case 15: // MEASUREMENT ERROR AND GPS + decoded.NamurState = frm_payload[1]; + decoded.Distance = bytesToFloat(frm_payload.slice(2, 6)); + decoded.Unit = frm_payload[6]; + decoded.MvProcent = bytesToInt16(frm_payload.slice(7, 9)); + decoded.MvLinProcent = bytesToInt16(frm_payload.slice(9, 11)); + decoded.MvScaled = bytesToFloat(frm_payload.slice(11, 15)); + decoded.MvScaledUnit = frm_payload[15]; + decoded.RemainingPower = frm_payload[16]; + decoded.GNSSLatitude = bytesToFloat(frm_payload.slice(17, 21)); + decoded.GNSSLongitude = bytesToFloat(frm_payload.slice(21, 25)); + decoded.DetailState = bytesToUInt32(frm_payload.slice(25, 29)); + decoded.Temperature = bytesToInt16(frm_payload.slice(29, 31)); + decoded.UnitTemperature = frm_payload[31]; + decoded.Inclination_degree = frm_payload[32]; + break; + case 16: // INFORMATION PACKAGES 1 + decoded.Information = frm_payload[1]; + decoded.DtmID = bytesToUInt32(frm_payload.slice(2, 6)); + decoded.ManufacturerID = bytesToUInt32(frm_payload.slice(6, 10)); + decoded.DeviceType = bytesToUInt32(frm_payload.slice(10, 14)); + decoded.SoverSystem = frm_payload[14]; + decoded.SoverFunction = frm_payload[15]; + decoded.SoverError = frm_payload[16]; + decoded.SoverCustomer = frm_payload[17]; + decoded.MeasureAndSendIntervall = bytesToUInt32(frm_payload.slice(18, 22)) | bytesToInt16(frm_payload.slice(22, 24)) | frm_payload[24]; + decoded.ChangeCounter = bytesToInt16(frm_payload.slice(25, 27)); + decoded.MvScaledMin = bytesToFloat(frm_payload.slice(27, 31)); + decoded.MvScaledMax = bytesToFloat(frm_payload.slice(31, 35)); + break; + case 17: + decoded.DeviceName = bytesToUInt32(frm_payload.slice(1, 5)) | bytesToUInt32(frm_payload.slice(5, 9)) | bytesToUInt32(frm_payload.slice(9, 13)) | + bytesToUInt32(frm_payload.slice(13, 17)) | bytesToInt16(frm_payload.slice(17, 19)) | frm_payload[19]; + decoded.DeviceTag = bytesToUInt32(frm_payload.slice(20, 24)) | bytesToUInt32(frm_payload.slice(24, 29)) | bytesToUInt32(frm_payload.slice(29, 33)) | + bytesToUInt32(frm_payload.slice(33, 37)) | bytesToInt16(frm_payload.slice(37, 39)) | frm_payload[39]; + break; + case 18: // US SF10 OKAY + decoded.Distance = bytesToFloat(frm_payload.slice(1, 5)); + decoded.Unit = frm_payload[5]; + decoded.RemainingPower = frm_payload[6]; + decoded.Temperature = bytesToInt16(frm_payload.slice(7, 9)); + decoded.UnitTemperature = frm_payload[9]; + decoded.Inclination_degree = frm_payload[10]; + break; + case 19: // US SF10 ERROR 1 + decoded.NamurState = frm_payload[1]; + decoded.Distance = bytesToFloat(frm_payload.slice(2, 6)); + decoded.Unit = frm_payload[6]; + decoded.RemainingPower = frm_payload[7]; + decoded.Inclination_degree = frm_payload[8]; + break; + case 20: // US SF10 ERROR 2 + decoded.NamurState = frm_payload[1]; + decoded.DetailState = bytesToUInt32(frm_payload.slice(8, 12)); + decoded.Temperature = bytesToInt16(frm_payload.slice(12, 14)); + decoded.UnitTemperature = frm_payload[14]; + break; + case 21: // US SF10 GPS  + decoded.NamurState = frm_payload[1]; + decoded.GNSSLatitude = bytesToFloat(frm_payload.slice(2, 6)); + decoded.GNSSLongitude = bytesToFloat(frm_payload.slice(6, 10)); + break; + case 22: // US SF10 MEASUREMENT + decoded.NamurState = frm_payload[1]; + decoded.MvProcent = bytesToInt16(frm_payload.slice(2, 4)); + decoded.MvLinProcent = bytesToInt16(frm_payload.slice(4, 6)); + decoded.MvScaled = bytesToFloat(frm_payload.slice(6, 10)); + decoded.MvScaledUnit = frm_payload[10]; + break; + case 23: // US SF10 INFO1 + decoded.NamurState = frm_payload[1]; + decoded.Information = frm_payload[2]; + decoded.DtmID = bytesToUInt32(frm_payload.slice(3, 6)); + decoded.ManufacturerID = bytesToUInt32(frm_payload.slice(6, 10)); + break; + case 24: // US SF10 INFO2 + decoded.NamurState = frm_payload[1]; + decoded.DeviceType = bytesToUInt32(frm_payload.slice(2, 6)); + decoded.SoverSystem = frm_payload[6]; + decoded.SoverFunction = frm_payload[7]; + decoded.SoverError = frm_payload[8]; + decoded.SoverCustomer = frm_payload[9]; + break; + case 25: // US SF10 INFO3 + decoded.NamurState = frm_payload[1]; + decoded.MeasureAndSendIntervall = bytesToUInt32(frm_payload.slice(2, 6)) | bytesToInt16(frm_payload.slice(6, 8)) | frm_payload[8]; + decoded.ChangeCounter = bytesToInt16(frm_payload.slice(9, 11)); + break; + case 26: // US SF10 INFO4 + decoded.NamurState = frm_payload[1]; + decoded.MvScaledMin = bytesToFloat(frm_payload.slice(2, 6)); + decoded.MvScaledMax = bytesToFloat(frm_payload.slice(6, 10)); + break; + default: + if (debug) { + console.log("Invalid PacketIdentifier type: " + String(decoded.PacketIdentifier)); + } + decoded = null; + break; + } + return decoded; +} \ No newline at end of file