/* 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; }