No description
- Fix packet length calculation for Topin variant - Try multiple length interpretations, prefer ones with valid stop bits - Validate coordinates are within valid ranges (-90/90 lat, -180/180 lon) - Set invalid coordinates to 0,0 and mark GPS as invalid |
||
|---|---|---|
| .claude | ||
| docs/plans | ||
| src/gps_tracker | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| gps_dashboard.py | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
GPS Tracker Server
A multi-protocol Python server for receiving and visualizing location data from GPS tracking devices. Supports MQTT publishing in OwnTracks format.
Supported Devices
| Protocol | Devices | Default Port |
|---|---|---|
| GT06/Topin 365GPS | G68, ZX303, ZX612, and similar | 5023 |
| H02/SinoTrack | ST-904L, ST-901, and similar | 5014 |
Features
- 📡 Multi-protocol support (GT06, H02) in a single process
- 🔓 Decodes binary and ASCII GPS protocols
- 💾 Stores locations in JSON Lines format
- 📤 MQTT publishing in OwnTracks format
- 🔋 Battery status tracking
- 🐳 Single Docker container for all protocols
Quick Start
Using Docker (recommended)
# Clone and start
docker compose up -d --build
# View logs
docker compose logs -f
Using UV (development)
# Install dependencies
uv sync
# Run server (default: GT06 on port 5023)
uv run gps-tracker
# Run with multiple protocols
uv run gps-tracker -p gt06:5023 -p h02:5014
# Run with debug logging
uv run gps-tracker -p gt06 -p h02 --debug
Server Options
gps-tracker --help
Options:
-p, --protocol NAME[:PORT] Protocol to enable (repeatable)
Examples: gt06, h02:5014, gt06:5023
Default: gt06 on port 5023
--host HOST Host to bind to (default: 0.0.0.0)
--data-dir DIR Directory for location data (default: .)
--debug Enable debug logging
MQTT options:
--mqtt-host HOST MQTT broker host
--mqtt-port PORT MQTT broker port (default: 1883, 8883 with TLS)
--mqtt-user USER MQTT username
--mqtt-password PASS MQTT password
--mqtt-topic-prefix PREFIX Topic prefix (default: owntracks)
--mqtt-client-user USER User name for topic (default: gps)
--mqtt-tls Enable TLS for MQTT connection
--mqtt-ca-cert PATH Path to CA certificate
Device Configuration
GT06/Topin Devices
Send these SMS commands to your tracker's SIM card:
APN,your_apn_name,,#
SERVER#your_server_ip#5023#
SinoTrack Devices (H02)
Send these SMS commands (default password: 0000):
8030000 your.apn.name # Set APN
8040000 your.server.ip 5014 # Set server IP and port
8960000 0 # Set timezone to UTC
RCONF # Check current configuration
MQTT / OwnTracks Integration
Enable MQTT to publish locations in OwnTracks format:
# Via environment variables
cp .env.example .env
# Edit .env with your MQTT broker settings
docker compose up -d --build
# Via command line
uv run gps-tracker -p gt06 -p h02 --mqtt-host mqtt.example.com
Locations are published to {MQTT_TOPIC_PREFIX}/{MQTT_CLIENT_USER}/{imei}:
{
"_type": "location",
"lat": 47.389770,
"lon": 8.424429,
"tst": 1736583387,
"tid": "06",
"batt": 45
}
Environment Variables
| Variable | Default | Description |
|---|---|---|
MQTT_HOST |
- | MQTT broker hostname (required for MQTT) |
MQTT_PORT |
1883 (8883 with TLS) | MQTT broker port |
MQTT_USER |
- | MQTT username |
MQTT_PASSWORD |
- | MQTT password |
MQTT_TOPIC_PREFIX |
owntracks | Topic prefix |
MQTT_CLIENT_USER |
gps | User in topic path |
MQTT_TLS |
false | Enable TLS (set to true/1/yes) |
MQTT_CA_CERT |
- | Path to CA certificate |
Data Storage
Locations are saved to locations_<IMEI>.jsonl:
{"imei": "861261021043506", "timestamp": "2026-01-11T07:22:02", "latitude": 47.38977, "longitude": 8.424429, "speed": 1, "course": 102, "satellites": 15, "gps_valid": true, "battery": 45}
Architecture
src/gps_tracker/
├── cli.py # Unified CLI entry point
├── models.py # GPSLocation dataclass
├── protocols/
│ ├── base.py # BaseDecoder ABC
│ ├── gt06/ # GT06/Topin protocol
│ └── h02/ # H02/SinoTrack protocol
├── server/
│ ├── base.py # Server, ProtocolListener, BaseConnection
│ ├── gt06.py # GT06 connection handler
│ └── h02.py # H02 connection handler
└── output/
├── base.py # OutputHandler ABC
├── file.py # FileWriter (JSONL)
└── mqtt.py # MQTTPublisher (OwnTracks)
Adding a New Protocol
- Create
protocols/newproto/decoder.pyextendingBaseDecoder - Create
server/newproto.pywith connection handler extendingBaseConnection - Register in
protocols/__init__.py:register("newproto", 5025, NewProtoDecoder, NewProtoConnection)
Troubleshooting
Tracker not connecting?
- Check APN - Verify with your SIM provider
- Check firewall - Ports must be open for TCP (5023 for GT06, 5014 for H02)
- Try IP - Some trackers don't resolve DNS well
- Debug mode - Run with
--debugto see raw packets
No GPS coordinates?
- The tracker may be indoors without GPS signal
- Check
gps_validfield - if false, GPS not locked - Some devices only report when moving
SMS Commands Reference
GT06/Topin Devices
| Command | Description |
|---|---|
IMEI# |
Query device IMEI |
TIMER,X,Y# |
Set upload interval (X=moving, Y=idle, in seconds) |
APN,X,Y,Z# |
Set APN (X=name, Y=username, Z=password) |
SERVER#ip#port# |
Set server address |
REST# |
Reboot device |
SinoTrack Devices (H02)
| Command | Description |
|---|---|
IMEI# |
Query device IMEI |
8030000 apn |
Set APN |
8040000 ip port |
Set server address |
8960000 offset |
Set timezone offset |
RCONF |
Query current configuration |
License
MIT - Use freely for personal and commercial projects.