Reference Guide
Complete documentation of terminology, data formats, conversion rules, and protocol specifications.
Quick Navigation
1 Timestamps
Device Timestamp (Recorded At)
The exact time when the GPS device captured/recorded the location data.
0x26 = 26
Server Timestamp (Received At)
The time when the server received and stored the data packet.
Transmission Delay
The time difference between when data was recorded and when it was received.
- Realtime data: Few seconds (network latency only)
- Historical data: Minutes to hours (stored during network outage)
- Negative values: Indicates clock sync issue between device and server
2 Data Types (Realtime vs Historical)
Data transmitted immediately after GPS capture when network is available.
Data stored locally on device during network outage, transmitted when connectivity restored.
When the device loses network connectivity, it continues recording GPS data locally. Once connectivity is restored, all stored records are transmitted as a batch (0x0210) with their original device timestamps preserved.
3 Location Data
| Field | Bytes | Raw Format | Conversion | Unit |
|---|---|---|---|---|
| Latitude | 8-11 | uint32 BE | raw / 1,000,000 | Degrees |
| Longitude | 12-15 | uint32 BE | raw / 1,000,000 | Degrees |
| Altitude | 16-17 | uint16 BE | raw (no conversion) | Meters |
| Speed | 18-19 | uint16 BE | raw / 10 | km/h |
| Direction | 20-21 | uint16 BE | raw (no conversion) | Degrees (0-359) |
| Timestamp | 22-27 | BCD[6] | YY-MM-DD-HH-MM-SS | UTC+0 |
Direction to Compass Mapping
Hemisphere Correction
Latitude and longitude signs are determined by status flag bits:
4 Status Flags (32-bit)
Status is a 32-bit integer from packet bytes 4-7. Each bit represents a different status.
| Bit | Name | 0 = Off | 1 = On | Check Formula |
|---|---|---|---|---|
| 0 | ACC | OFF | ON | status & (1 << 0) |
| 1 | GPS Valid | Invalid | Valid | status & (1 << 1) |
| 2 | Latitude South | North (+) | South (-) | status & (1 << 2) |
| 3 | Longitude West | East (+) | West (-) | status & (1 << 3) |
| 6 | Motion | Moving | Static | status & (1 << 6) |
| 14 | Sealed | Unsealed | Sealed | status & (1 << 14) |
| 15 | Shackle | Open | Closed | status & (1 << 15) |
| 16-17 | Charge Status |
0: None
1: Charging
2: Full
|
(status >> 16) & 0x03 | |
| 18-19 | Network Type |
0: Default
1: 2G
2: 3G
3: 4G
|
(status >> 18) & 0x03 | |
0x00050003
5 Alarm Flags (32-bit)
Alarm is a 32-bit integer from packet bytes 0-3. Each bit represents a different alarm condition.
| Bit | Name | Severity | Description | Check Formula |
|---|---|---|---|---|
| 0 | Shackle Damaged | Critical | Lock mechanism physically damaged | alarm & (1 << 0) |
| 1 | Shell Tampered | Critical | Device enclosure opened/tampered | alarm & (1 << 1) |
| 2 | Low Battery | Warning | Battery level below threshold | alarm & (1 << 2) |
| 3 | MCU Error | Warning | Microcontroller error detected | alarm & (1 << 3) |
| 4 | Wire Rope Cut | Critical | Security wire/rope has been cut | alarm & (1 << 4) |
| 9 | Overspeed | Warning | Vehicle exceeded speed limit | alarm & (1 << 9) |
| 10 | Timeout Parking | Warning | Vehicle parked beyond allowed time | alarm & (1 << 10) |
| 12 | Main Power Failure | Critical | External power disconnected | alarm & (1 << 12) |
Critical Alarms
Require immediate attention. Indicate security breach or device tampering.
Warning Alarms
Should be monitored. Indicate operational issues or policy violations.
6 Additional Information Fields
Optional TLV (Type-Length-Value) fields appended after the main location data (starting at byte 28).
| ID (Hex) | Name | Length | Conversion | Range/Unit |
|---|---|---|---|---|
| 0x68 | Battery Percent | 1 byte | raw (no conversion) | 0-100% |
| 0x69 | Battery Voltage | 2 bytes | raw × 0.01 | Volts (e.g., 3.70V) |
| 0x6A | Signal CSQ | 1 byte | raw (no conversion) | 0-31 (higher = better) |
| 0x6B | Satellite Count | 1 byte | raw (no conversion) | 0-12+ satellites |
68 01 4B = Battery at 75% (0x4B = 75)
Signal CSQ Quality Guide
7 Protocol Structure (JT808/IMZ)
Frame Structure
Header Structure (12 bytes)
| Offset | Length | Field | Description |
|---|---|---|---|
| 0-1 | 2 | Message ID | Command/response type (e.g., 0x0200) |
| 2-3 | 2 | Body Properties | Length, encryption, subpacket flags |
| 4-9 | 6 | Terminal ID | Device identifier (BCD encoded) |
| 10-11 | 2 | Serial Number | Message sequence number |
Common Message IDs
Escape Sequences
To avoid confusion with frame delimiters, special bytes are escaped:
8 Conversion Formulas & Code Examples
BCD Timestamp Decoding
def decode_bcd_timestamp(bcd: bytes) -> datetime:
def bcd_to_int(b):
return ((b >> 4) * 10) + (b & 0x0F)
return datetime(
2000 + bcd_to_int(bcd[0]), # Year (00-99 → 2000-2099)
bcd_to_int(bcd[1]), # Month (01-12)
bcd_to_int(bcd[2]), # Day (01-31)
bcd_to_int(bcd[3]), # Hour (00-23)
bcd_to_int(bcd[4]), # Minute (00-59)
bcd_to_int(bcd[5]), # Second (00-59)
tzinfo=timezone.utc
)
Coordinate Conversion
# Read raw values (Big Endian unsigned 32-bit)
lat_raw = struct.unpack(">I", body[8:12])[0]
lon_raw = struct.unpack(">I", body[12:16])[0]
# Convert to degrees
latitude = lat_raw / 1_000_000
longitude = lon_raw / 1_000_000
# Apply hemisphere correction from status flags
if status & (1 << 2): # Bit 2: South
latitude = -latitude
if status & (1 << 3): # Bit 3: West
longitude = -longitude
Status Flag Extraction
# Read 32-bit status (Big Endian)
status = struct.unpack(">I", body[4:8])[0]
# Extract individual flags
acc_on = bool(status & (1 << 0))
gps_valid = bool(status & (1 << 1))
motion_static = bool(status & (1 << 6))
sealed = bool(status & (1 << 14))
shackle_closed = bool(status & (1 << 15))
# Extract multi-bit values
charge_status = (status >> 16) & 0x03 # Bits 16-17
network_type = (status >> 18) & 0x03 # Bits 18-19
Checksum Calculation (XOR)
def calculate_checksum(data: bytes) -> int:
checksum = 0
for byte in data:
checksum ^= byte
return checksum
# Verify: calculated checksum should match last byte before 0x7E
JavaScript UTC to IST Conversion
// Parse timestamp (handles both ISO and SQLite formats)
function parseTimestamp(timestamp) {
let ts = timestamp;
// If no timezone marker, assume UTC
if (!ts.includes('Z') && !/[+-]\d{2}:\d{2}$/.test(ts)) {
ts = ts.replace(' ', 'T') + 'Z';
}
return new Date(ts);
}
// Convert to IST (UTC+5:30)
const istOffset = 5.5 * 60 * 60 * 1000;
const istDate = new Date(utcDate.getTime() + istOffset);
Data Flow Overview
- Device: Records UTC timestamp in BCD format (bytes 22-27)
- Server: Adds server receive timestamp (CURRENT_TIMESTAMP in UTC)
- UI: Converts both timestamps to IST for display