Skip to main content

gps-mouse 🛰️

PyPI version Python Tests License: MIT

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 toolsgps-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

Release files for gps-mouse 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gps-mouse 0.1.3
File Size Uploaded
gps_mouse-0.1.3.tar.gz 25.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gps-mouse 0.1.3
File Interpreter ABI Platform
gps_mouse-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 50.4 kB

Release files / gps_mouse-0.1.3.tar.gz

Download URL gps_mouse-0.1.3.tar.gz
Size 25.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a108adce11c09a6343e8aac8e205ee23942deee04d3663eacf698ad579314c91
BLAKE2b-256 checksum
How to use checksums
51e5875b9a574aa7868bb8f4a6e9af305fa6acc5452a669c38328800fa99c232
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / gps_mouse-0.1.3-py3-none-any.whl

Download URL gps_mouse-0.1.3-py3-none-any.whl
Size 24.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c808f65a85942196b0a7eda22910896fcc26f768ac8e0e8aa935542f1877c29
BLAKE2b-256 checksum
How to use checksums
73172b643a6008dc9e7977d6b02c191cb230343df60145133ee7afccb820be8b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page