Telemetry Packet: Difference between revisions
No edit summary |
No edit summary |
||
| Line 201: | Line 201: | ||
button { | button { | ||
padding: 10px 20px; | padding: 10px 20px; | ||
<html> | |||
<div id="packet-parser"> | |||
<h3>Telemetry Packet Parser</h3> | |||
</ | |||
<textarea id="hexInput" placeholder="Paste HEX packet here..." style="width:100%;height:100px;"></textarea><br> | |||
<textarea id="hexInput" placeholder="Paste HEX packet here..."></textarea><br> | <button onclick="parseTelemetry()" style="margin-top:10px; padding:8px 16px; background-color:#680022; color:white; font-weight:bold; border:none; cursor:pointer;">Parse Packet</button> | ||
<button onclick="parseTelemetry()">Parse Packet</button> | |||
< | <h4>Parsed Output:</h4> | ||
<table id="resultTable"> | <table id="resultTable" class="wikitable" style="margin-top:10px;"> | ||
<thead><tr><th>Field</th><th>Value</th></tr></thead> | <thead><tr><th>Field</th><th>Value</th></tr></thead> | ||
<tbody></tbody> | <tbody></tbody> | ||
</table> | </table> | ||
</div> | |||
<script> | <script> | ||
function hexToBits(hex) { | function hexToBits(hex) { | ||
return hex.match(/.{1,2}/g).map( | return hex.match(/.{1,2}/g).map(b=>parseInt(b,16).toString(2).padStart(8,'0')).join(''); | ||
} | } | ||
function bitsToInt(bits) { return parseInt(bits, 2); } | |||
function bitsToSignedInt(bits) { let v=parseInt(bits,2),m=2**bits.length; return v>=m/2?v-m:v; } | |||
function bigIntFromBits(bits) { return BigInt('0b'+bits).toString(); } | |||
function parseTelemetry() { | function parseTelemetry() { | ||
const hex = document.getElementById("hexInput").value.trim().toLowerCase(); | const hex = document.getElementById("hexInput").value.trim().toLowerCase(); | ||
const | const table = document.querySelector("#resultTable tbody"); | ||
table.innerHTML = ""; | |||
if (!hex.startsWith("24")) { alert("Invalid packet"); return; } | |||
if ( | |||
const bits = hexToBits(hex); | const bits = hexToBits(hex); | ||
const output = ( | const output = (k,v) => table.innerHTML += `<tr><td>${k}</td><td>${v}</td></tr>`; | ||
const fields = [ | const fields = [ | ||
["Start Byte", 0, 8], ["Data Length", 8, 20], ["No. of Packets", 20, 25], | ["Start Byte", 0, 8], ["Data Length", 8, 20], ["No. of Packets", 20, 25], ["IMEI", 25, 75], ["Packet Type", 75, 80], | ||
["Packet Status", 80, 81], ["Frame Number", 81, 97], ["Alert ID", 97, 102], ["Operator", 102, 106], ["Signal Strength", 106, 111], | |||
["MCC", 111, 121], ["MNC", 121, 131], ["Cell ID", 131, 147], ["LAC", 147, 163], ["Fix Status", 163, 164], | |||
["Latitude", 164, 193], ["NS Indication", 193, 194], ["Longitude", 194, 223], ["EW Indication", 223, 224], | |||
["HDOP", 224, 234], ["PDOP", 234, 244], ["Speed", 244, 259], ["Altitude", 259, 274], | |||
["Latitude", 164, 193], ["NS Indication", 193, 194], ["Longitude", 194, 223], | ["Power Status", 274, 275], ["Ignition Status", 275, 276], ["Immobilizer Status", 276, 277], ["Tamper", 277, 278], | ||
["Supply Voltage", 278, 288], ["Internal Battery Voltage", 288, 294], | |||
["Fuel Sensor Status 1", 294, 295], ["Fuel Percentage 1", 295, 305], ["Fuel Sensor Value 1", 305, 321], | |||
["Fuel Sensor Status 2", 321, 322], ["Fuel Percentage 2", 322, 332], ["Fuel Sensor Value 2", 332, 348], | |||
["Fuel Sensor Status 3", 348, 349], ["Fuel Percentage 3", 349, 359], ["Fuel Sensor Value 3", 359, 375], | |||
["Fuel Sensor Status 1", 294, 295], ["Fuel Percentage 1", 295, 305], | ["Analog Input 1", 375, 385], ["Analog Input 2", 385, 395], | ||
["Digital Input 1", 395, 396], ["Digital Input 2", 396, 397], | |||
["Digital Output 1", 397, 398], ["Digital Output 2", 398, 399], | |||
["Fuel Sensor Status 3", 348, 349], ["Fuel Percentage 3", 349, 359], | ["Temperature Sensor Status 1", 399, 400], ["Temperature 1", 400, 412], | ||
["Temperature Sensor Status 2", 412, 413], ["Temperature 2", 413, 425], | |||
["Temperature Sensor Status 3", 425, 426], ["Temperature 3", 426, 438], | |||
["Humidity", 438, 445], ["Odometer", 445, 480], | |||
["DateTime UTC", 480, 512], ["TimeZone", 512, 520] | ["DateTime UTC", 480, 512], ["TimeZone", 512, 520] | ||
]; | ]; | ||
let | let dt = 0; | ||
for (const [label, start, end] of fields) { | for (const [label, start, end] of fields) { | ||
const val = bits.slice(start, end); | const val = bits.slice(start, end); | ||
switch (label) { | switch (label) { | ||
case "IMEI": | case "IMEI": output(label, bigIntFromBits(val)); break; | ||
case "Latitude": | case "Latitude": | ||
case "Longitude": | case "Longitude": output(label, bitsToInt(val) / 1e6); break; | ||
case "HDOP": | case "HDOP": | ||
case "PDOP": | case "PDOP": output(label, bitsToInt(val) / 100); break; | ||
case "Speed": output(label, bitsToInt(val) / 100); break; | |||
case "Speed": | |||
case "Altitude": | case "Altitude": | ||
case "Supply Voltage": | case "Supply Voltage": | ||
| Line 317: | Line 270: | ||
case "Analog Input 1": | case "Analog Input 1": | ||
case "Analog Input 2": | case "Analog Input 2": | ||
output(label, bitsToInt(val) / 10); | output(label, bitsToInt(val) / 10); break; | ||
case "Temperature 1": | case "Temperature 1": | ||
case "Temperature 2": | case "Temperature 2": | ||
case "Temperature 3": | case "Temperature 3": | ||
output(label, bitsToSignedInt(val) / 10); | output(label, bitsToSignedInt(val) / 10); break; | ||
case "DateTime UTC": | case "DateTime UTC": | ||
dt = bitsToInt(val); | |||
output("DateTime (UTC)", new Date(dt * 1000).toISOString()); | |||
output("DateTime (UTC)", | |||
break; | break; | ||
case "TimeZone": | case "TimeZone": | ||
const tz = bitsToSignedInt(val); | const tz = bitsToSignedInt(val); | ||
const | const offset = tz * 15; | ||
const h = Math.floor(Math.abs(offset) / 60); | |||
const h = Math.floor(Math.abs( | const m = Math.abs(offset % 60); | ||
const m = Math.abs( | output("TimeZone", `${offset} mins = UTC${offset >= 0 ? '+' : '-'}${h}:${m.toString().padStart(2, '0')}`); | ||
output("TimeZone", `${ | const local = new Date((dt + offset * 60) * 1000); | ||
const | output("DateTime (Local Time)", local.toISOString().replace("T", " ").replace(".000Z", "")); | ||
break; | break; | ||
default: | default: output(label, bitsToInt(val)); | ||
} | } | ||
} | } | ||
} | } | ||
</script> | </script> | ||
</html> | </html> | ||
Revision as of 07:28, 16 July 2025
| Field | Size (bits) | Bit Range | Description | Breakdown |
|---|---|---|---|---|
| Header (10 bytes) | ||||
| Start byte | 8 | 0–7 | Starting character $ (ASCII value 36) | $ |
| Data length | 12 | 08–19 | 2-byte length of the data following the header | |
| Num of data packets | 5 | 20–24 | Number of packets (0–32) | 0–32 |
| IMEI | 50 | 25–74 | Unique device identifier | e.g., 887744556677882 |
| packet type | 5 | 75–79 | Integer type:
| |
| Data (= 55 bytes × number of packets) | ||||
| Packet Status | 1 | — | Type of packet | |
| Frame Number | 16 | — | Frame number | |
| AlertID | 8 | — | Alert identifier | |
| Operator | 4 | — | Network operator | 00-Airtel, 01-BSNL, 02-VI, 04-JIO |
| Signal Strength | 5 | — | Signal strength | Integer (0–31) |
| MCC | 10 | — | Mobile country code | Integer |
| MNC | 6 | — | Mobile network code | Integer |
| Cell Id | 16 | — | Cell tower ID | Integer |
| Location Area Code | 16 | — | Location area code | Integer |
| Fix_status | 1 | — | GPS fix status | 0: No fix, 1: Valid Fix |
| Start byte | 1 | — | Latitude coordinate | Divide by 1,000,000 for float value |
| NS_Indication | 1 | — | N or S | 0: N, 1: S |
| Longitude | 29 | — | Longitude coordinate | Divide by 1,000,000 for float value |
| EW_Indication | 1 | — | East/West Indication | 0: E, 1: W |
| HDOP | 10 | — | Horizontal dilution | Divide by 10 for float value |
| PDOP | 10 | — | Position dilution | Divide by 10 for float value |
| Speed | 10 | — | Speed in km/h | Divide by 10 for float value |
| Altitude | 15 | — | Altitude in meters | Divide by 10 for float value |
| Power Status | 1 | — | Power connection status | 0: Power disconnected, 1: Power connected |
| Ignition Status | 1 | — | Ignition status | 0: OFF, 1: ON |
| Immobilizer Status | 1 | — | Immobilizer status | 0: OFF, 1: ON |
| Tamper | 1 | — | Wire Tamper detection | 0: Tamper clear, 1: Tamper alert ON |
| Supply Voltage | 6 | — | External battery voltage | Divide by 10 for float value |
| Internal Battery Voltage | 6 | — | Internal battery voltage | Divide by 10 for float value |
| Fuel SensorValue 1 | 16 | — | Fuel sensor value | Divide by 10 if float |
| Fuel Percentage 1 | 16 | — | Fuel level percentage | Divide by 10 for float value |
| Fuel SensorValue 2 | 16 | — | Fuel sensor value | Divide by 10 if float |
| Fuel Percentage 2 | 16 | — | Fuel level percentage | Divide by 10 for float value |
| Fuel SensorValue 3 | 16 | — | Fuel sensor value | Divide by 10 if float |
| Fuel Percentage 3 | 16 | — | Fuel level percentage | Divide by 10 for float value |
| Analog Input | 10 | — | Analog input | Divide by 10 for float value |
| Analog Input 1 | 10 | — | Analog input 1 | Divide by 10 for float value |
| Digital Input 1 | 1 | — | Digital input 1 | 0 or 1 |
| Digital Input 2 | 1 | — | Digital input 2 | 0 or 1 |
| Digital Output 1 | 1 | — | Digital output 1 | 0 or 1 |
| Digital Output 2 | 1 | — | Digital output 2 | 0 or 1 |
| Temperature sensor status 1 | 1 | — | Status of temperature sensor 1 | 1 if connected, 0 if not connected |
| Temperature 1 | 12 | — | Temperature in °C | Signed, divide by 10 |
| Temperature sensor status 2 | 1 | — | Status of temperature sensor 2 | 1 if connected, 0 if not connected |
| Temperature 2 | 12 | — | Temperature in °C | Signed, divide by 10 |
| Temperature sensor status 3 | 1 | — | Status of temperature sensor 3 | 1 if connected, 0 if not connected |
| Temperature 3 | 12 | — | Temperature in °C | Signed, divide by 10 |
| Humidity | 8 | — | Humidity percentage | |
| Odometer | 35 | — | Odometer value in meters | |
| DateTime UTC | 32 | — | Timestamp | UTC time in seconds |
| TimeZone | 8 | — |
Timezone in quarter-hours (e.g., 22 = +5:30). Each unit = 15 mins. Value 22 = 22 × 15 mins = 330 mins = +5:30 Range: -48 to 56, 2's complement || | |
| Tail | ||||
| End Character | 8 | 0–7 | Starting character * (ASCII value 42) | * |
| CRC | 8 | 8–15 | 8-bit XOR CRC of data starting from $ to * (excluding $ and *) | |
Sample Packet
HEX "240370e2400e60e3ad81801b0cfaca0be02541c2000000000000000000000000000000009800000000000000000000000000000000000000000000006875e9e5162a05"
{
"imei": 864218069278060,
"packet_type": 1,
"no_packets": 1,
"packet_status": 1,
"frame_number": 54,
"alert_id": 3,
"operator": 3,
"signal_strength": 29,
"mcc": 404, "mnc": 95,
"cell_id": 298,
"lac": 3600,
"fix_status": 0,
"latitude": 0.0,
"latitude_dir": 0,
"longitude": 0.0,
"longitude_dir": 0,
"hdop": 0.0,
"pdop": 0.0,
"speed": 0.0,
"altitude": 0.0,
"power": 0,
"ignition": 0,
"immobilizer": 0,
"tamper": 0,
"supply_volatge": 0.0,
"internal_battery_volatge": 3.8,
"fuel_sensor_status_1": 0,
"fuel_percentage_1": 0.0,
"fuel_value_sensor_1": 0,
"fuel_sensor_status_2": 0,
"fuel_percentage_2": 0.0,
"fuel_value_sensor_2": 0,
"fuel_sensor_status_3": 0,
"fuel_percentage_3": 0.0,
"fuel_value_sensor_3": 0,
"analog_input1": 0.0,
"analog_input2": 0.0,
"digital_input1": 0,
"digital_input2": 0,
"digital_output1": 0,
"digital_output2": 0,
"temp_sensor_status_1": 0,
"temperature_1": 0.0,
"temp_sensor_status_2": 0,
"temperature_2": 0.0,
"temp_sensor_status_3": 0,
"temperature_3": 0.0,
"humidity": 0,
"odometer": 0,
"dateTime": 1752558053,
"timezone": 22,
"dateTime_tz": "2025-07-15 11:10:53",
"error_code": 0
}