Skip to main content

Read data from U-Blox GPS devices and distribute to multiple projects via ZMQ pub/sub

Project description

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gps_mouse-0.1.3.tar.gz (25.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gps_mouse-0.1.3-py3-none-any.whl (24.5 kB view details)

Uploaded Python 3

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

Hashes for gps_mouse-0.1.3.tar.gz
Algorithm Hash digest
SHA256 a108adce11c09a6343e8aac8e205ee23942deee04d3663eacf698ad579314c91
MD5 3c27a663539a6a22398b98c37f5fec46
BLAKE2b-256 51e5875b9a574aa7868bb8f4a6e9af305fa6acc5452a669c38328800fa99c232

See more details on using hashes here.

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

Hashes for gps_mouse-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 2c808f65a85942196b0a7eda22910896fcc26f768ac8e0e8aa935542f1877c29
MD5 14d9d8a1214a7237f9200904a7f81ebe
BLAKE2b-256 73172b643a6008dc9e7977d6b02c191cb230343df60145133ee7afccb820be8b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page