Read data from U-Blox GPS devices and distribute to multiple projects via ZMQ pub/sub
Project description
gps-mouse ๐ฐ๏ธ
A lightweight Python library for reading data from U-Blox GPS devices and distributing it to multiple projects via ZMQ, REST API, MQTT, or file logging.
Features
- Read NMEA sentences (GGA, RMC, VTG) from any serial GPS device
- Auto-reconnect when device is unplugged and re-plugged
- ZMQ pub/sub โ distribute to multiple projects simultaneously
- REST API + Live map dashboard โ browser-based Leaflet.js map
- MQTT โ publish to any MQTT broker (Home Assistant, Node-RED, etc.)
- CSV + GPX logging โ record tracks for later analysis
- gpsd support โ use the standard Linux GPS daemon
- CLI tools โ
gps-server,gps-read,gps-log,gps-api - Docker โ single-command deployment
- Sync and async support
Tested Device
| Device | Interface | Default Port |
|---|---|---|
| U-Blox 7 (USB) | /dev/ttyACM0 |
9600 baud |
Works with any NMEA-compatible GPS device.
Installation
# Core library
pip install gps-mouse
# With REST API + dashboard
pip install "gps-mouse[api]"
# With MQTT support
pip install "gps-mouse[mqtt]"
# With YAML config support
pip install "gps-mouse[yaml]"
# Everything
pip install "gps-mouse[all]"
System permission (Linux)
sudo usermod -aG dialout $USER
newgrp dialout
Quick Start
CLI
# Read and print GPS data
gps-read
# Start server with ZMQ + live map
gps-server --api
# Log to CSV + GPX
gps-log --csv track.csv --gpx track.gpx
# REST API + dashboard only
gps-api
Python โ read data
import time
from gps_mouse import GPSReader
def on_data(data):
if data.has_fix:
print(f"lat={data.latitude:.6f} lon={data.longitude:.6f} alt={data.altitude}m")
with GPSReader() as reader:
reader.add_callback(on_data)
time.sleep(60)
Python โ ZMQ broadcast + subscribe
# Server (reads GPS, broadcasts)
from gps_mouse import GPSReader, GPSPublisher
reader = GPSReader()
pub = GPSPublisher()
pub.attach(reader)
reader.start()
# Client (any other project)
from gps_mouse import GPSSubscriber
for data in GPSSubscriber().iter_fixes():
print(data.latitude, data.longitude)
Python โ REST API + live map
from gps_mouse import GPSReader
from gps_mouse.api import GPSApi
reader = GPSReader()
reader.start()
GPSApi(reader, port=8080).serve()
# Open http://localhost:8080 in browser
Python โ MQTT
from gps_mouse import GPSReader
from gps_mouse.mqtt import GPSMQTTPublisher
reader = GPSReader()
mqtt = GPSMQTTPublisher(broker="localhost", topic="gps/data")
mqtt.attach(reader)
reader.start()
Python โ CSV + GPX logging
import time
from gps_mouse import GPSReader
from gps_mouse.logger import GPSLogger
with GPSLogger(csv_path="track.csv", gpx_path="track.gpx") as log:
with GPSReader() as reader:
reader.add_callback(log.record)
time.sleep(3600)
Config file
cp config.example.yml config.yml
# Edit config.yml
gps-server --config config.yml
Docker
# Start with docker-compose
docker compose up -d
# Open dashboard
open http://localhost:8080
systemd Service
sudo cp systemd/gps-mouse.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now gps-mouse
sudo journalctl -u gps-mouse -f
Architecture
GPS Device (/dev/ttyACM0 or gpsd)
โ
GPSReader โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโบ GPSPublisher (ZMQ PUB :5557)
โ โโโบ Project A, B, C (GPSSubscriber)
โ
โโโโบ GPSMQTTPublisher โ MQTT Broker
โ โโโบ Home Assistant, Node-RED, โฆ
โ
โโโโบ GPSApi (FastAPI :8080)
โ โโโบ GET /gps (latest fix JSON)
โ โโโบ GET /gps/stream (SSE stream)
โ โโโบ WS /gps/ws (WebSocket)
โ โโโบ GET / (live map)
โ
โโโโบ GPSLogger โ CSV / GPX files
GPSData Fields
| Field | Type | Description |
|---|---|---|
latitude |
float | None |
Decimal degrees (negative = South) |
longitude |
float | None |
Decimal degrees (negative = West) |
altitude |
float | None |
Metres above mean sea level |
speed |
float | None |
Speed in m/s |
speed_kmh |
float | None |
Speed in km/h (property) |
heading |
float | None |
True North heading in degrees |
fix_quality |
FixQuality |
GPS fix type (NO_FIX, GPS, DGPS, RTKโฆ) |
num_satellites |
int |
Number of satellites in use |
hdop |
float | None |
Horizontal dilution of precision |
timestamp |
datetime |
UTC timestamp from device |
has_fix |
bool |
True if a valid position fix exists |
Examples
| File | Description |
|---|---|
examples/01_basic_read.py |
Print GPS values to terminal |
examples/02_zmq_server.py |
Read GPS and broadcast over ZMQ |
examples/03_zmq_client.py |
Subscribe from another project |
examples/04_async_stream.py |
Async producer/consumer |
examples/05_wait_for_fix.py |
Block until first fix |
Requirements
- Python 3.10+
- pyserial, pynmea2, pyzmq (core)
- fastapi, uvicorn (optional โ
[api]) - paho-mqtt (optional โ
[mqtt]) - pyyaml (optional โ
[yaml])
Contributing
See CONTRIBUTING.md.
Changelog
See CHANGELOG.md.
License
MIT ยฉ 2026 erelbi
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gps_mouse-0.1.3.tar.gz.
File metadata
- Download URL: gps_mouse-0.1.3.tar.gz
- Upload date:
- Size: 25.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a108adce11c09a6343e8aac8e205ee23942deee04d3663eacf698ad579314c91
|
|
| MD5 |
3c27a663539a6a22398b98c37f5fec46
|
|
| BLAKE2b-256 |
51e5875b9a574aa7868bb8f4a6e9af305fa6acc5452a669c38328800fa99c232
|
File details
Details for the file gps_mouse-0.1.3-py3-none-any.whl.
File metadata
- Download URL: gps_mouse-0.1.3-py3-none-any.whl
- Upload date:
- Size: 24.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c808f65a85942196b0a7eda22910896fcc26f768ac8e0e8aa935542f1877c29
|
|
| MD5 |
14d9d8a1214a7237f9200904a7f81ebe
|
|
| BLAKE2b-256 |
73172b643a6008dc9e7977d6b02c191cb230343df60145133ee7afccb820be8b
|