CLI tool
semuconsulting/PyGPSClient avatar
semuconsulting/PyGPSClient

PyGPSClient: a tkinter workbench for testing and configuring GNSS receivers

Python Graphical GPS Client Application supporting NMEA, UBX, SBF, UNI, QGC, RTCM3, NTRIP & SPARTN Protocols

855 stars140 forksPythonBSD-3-Clause

At a glance

What is it?
PyGPSClient is a free multi-platform graphical GNSS testing, diagnostic and configuration tool written in Python and tkinter, covering NMEA, UBX, SBF, UNI, QGC, RTCM3, SPARTN and NTRIP, whose value is the breadth of receiver configuration it exposes rather than any polished interface.
Who is it for?
PyGPSClient fits an engineer who needs to see what a GNSS receiver is actually saying, configure a u-blox, Quectel, Septentrio or Unicore device from a desktop, or run an NTRIP client or caster without installing vendor software, and it fits a Raspberry Pi on a bench.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A bench tool built on Python and tkinter

PyGPSClient is a free, open-source, multi-platform graphical GNSS and GPS testing, diagnostic and configuration application, written entirely by volunteers in Python and tkinter.

The toolkit choice says a lot about the intent. tkinter is the desktop GUI that ships with Python, which means the application runs anywhere a Python 3 interpreter with tkinter 8.6 or later is available. The README lists Windows, MacOS and Linux, and also names popular single-board computers like Raspberry Pi, BeagleBoard and Jetson. A hardware GNSS engineer working on a bench with a Pi and a USB receiver is exactly the person this constraint set serves.

The packaging metadata matches. The project requires Python 3.10 or later, and the classifiers list Python 3.10 through 3.15, with the development status marked as Production/Stable and the intended audience covering developers, science and research, and end users on the desktop. The runtime dependencies are deliberately small: requests, Pillow and pygnssutils, the last of which is the protocol parsing library that does much of the heavy lifting.

The README is careful about one point: this is an independent project with no affiliation whatsoever with any GNSS manufacturer or distributor. For a tool whose value is reading vendor protocols, that independence is what makes it usable with equipment from several vendors without licence or support restrictions.

Nine protocols, and the caveat attached to them

The protocol list is the substance of the application. The README states support for NMEA, UBX which is the u-blox binary format, SBF for Septentrio binary, UNI for Unicore binary, QGC for Quectel binary, RTCM3, SPARTN, NTRIP and TTY for ASCII text.

There is a footnote, and it matters. Specific message support is subject to the underlying parser implementation and open-source permissions. In other words, the protocol is supported to the extent that the parser library and any licensing on the message definitions allow, which is a real constraint when a vendor specification is not freely redistributable.

Data sources are equally broad. The application can read from serial connections over USB or UART, from sockets over TCP or UDP, from a binary data stream in a terminal or captured file, and from binary recordings such as u-center .ubx files. The last of these is the most useful for a post mortem: a capture taken in the field can be replayed and inspected without the receiver being present.

The result is a tool that covers the whole path from the antenna cable to the correction stream, which is what a diagnostic application needs to be useful across different setups rather than only with the receiver the author owns.

NTRIP client and NTRIP base station in the same application

Two capabilities make PyGPSClient more than a serial terminal.

The NTRIP client facilities cover both RTCM3 and SPARTN NTRIP services, so the app can pull correction data from a caster and feed it to a receiver, which is the normal way to turn a normal GNSS receiver into an RTK setup.

The other side is that PyGPSClient can serve as an NTRIP base station with an RTK-compatible receiver. The README names the supported hardware families: u-blox ZED-F9P and ZED-X20P, the Quectel LG and LC series, the Septentrio Mosaic series and the Unicore UM9 series. That is a differentiator, because a base station normally needs vendor software or a second machine, and here the same application that configures the receiver also publishes the corrections.

Alongside that, the application supports configuration of GNSS and related devices through proprietary UBX, NMEA and ASCII TTY protocols, covering most u-blox, Quectel, Septentrio, Unicore and Feyman devices. Device configuration is the tedious part of bringing up a receiver, and doing it from a GUI is what separates this from a protocol viewer.

The screenshot in the README shows a mixed protocol stream from a u-blox ZED-F9P receiver using the NTRIP client with a base station 26 km to the west, to achieve better than 2 cm accuracy. That figure is the author's own scenario description rather than an independent measurement.

Installing with pip, and why the venv route exists

Installation is a pip operation, and the README is precise about the prerequisites: an official Python 3.10 or later with tkinter 8.6 or later installed, and the project binaries folder in your PATH.

The quick version is one command and one command to run it:

shell
python3 -m pip install --upgrade pygpsclient
shell
pygpsclient

The console entry point comes from the project scripts table, where pygpsclient maps to pygpsclient.__main__:mai, so the launcher name is the package name.

A virtual environment is recommended, and the README explains why in a parenthetical that is easy to miss: it may be necessary if you have an externally-managed-environment, which is the marker modern Linux distributions place on the system Python to stop packages installing into it globally.

shell
python3 -m venv pygpsclient
source pygpsclient/bin/activate # (or .\pygpsclient\Scripts\activate on Windows)
python3 -m pip install --upgrade pygpsclient
pygpsclient
deactivate # to deactivate virtual environment when finished

For anything more involved, the repository carries INSTALLATION.md with comprehensive instructions, and the examples directory holds quick installation shell scripts for Linux and MacOS platforms, named pygpsclient_arch_install.sh, pygpsclient_debian_install.sh and pygpsclient_macos_install.sh.

The examples folder is the real integration guide

The top level of the repository is conventional for a Python application, with src/, tests/, docs/, images/ and examples/ alongside pyproject.toml, MANIFEST.in, CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, RELEASE_NOTES.md, CITATION.cff and APPLAUNCH.md.

The examples directory is where the interesting detail sits, because its file names describe the tasks people actually want to do. There is a script to convert UBX presets, one to convert text to UBX, one to retrieve data, one to serve a socket, plus TCP client and threaded TCP server examples, a georeferencing example, a presets example, and a u-center configuration JSON file for a dummy device.

The dummy device configuration matters more than it looks. A file named device-dummy123-1234-1234-1234-abcdefghijkl-ucenter-config.json implies you can exercise the configuration UI against a simulated device, which is the difference between learning the application without hardware and needing a receiver on the desk.

The README also documents features beyond the device work: a GPX track viewer, experimental RINEX conversion of raw observation, navigation and meteorology data, an NTRIP caster and socket server, a Mapquest API key section, user-defined presets, and CLI utilities. The RINEX conversion is labelled experimental in the README, which is the honest signal that it may not handle every case.

Maintenance, licence and an explicit policy on generated contributions

The project is not archived and the last push was on 2026-10-14, the same day as the v1.7.8 release. Before that come v1.7.7 on 2026-09-30 and v1.7.6 on 2026-09-17, which is a cadence of frequent patch releases, consistent with the breadth of device support that has to track vendor firmware changes.

The licence is BSD-3-Clause, with the terms in the LICENSE file, and the package metadata declares it directly with a license-files entry pointing at that file. BSD-3-Clause is permissive and places no copyleft requirement on software that links against it, which suits an application that people run locally on their own equipment.

The contribution policy is the most distinctive thing in the README. It states that contributions from human beings are welcome, and the repository carries an image labelled No Copilot under that line, alongside a CONTRIBUTING.md and a CODE_OF_CONDUCT.md. The intent is clear: the project is asking for human authored work, and the reference to the no Copilot image is a signal about how contributions should be produced.

Support follows the same split. Bug reports should use the provided template in the GitHub issue templates directory, while feature requests, general queries and advice should go to the GitHub Discussions channels first, where the project asks people to post before opening an issue.

Editorial conclusion

PyGPSClient fits an engineer who needs to see what a GNSS receiver is actually saying, configure a u-blox, Quectel, Septentrio or Unicore device from a desktop, or run an NTRIP client or caster without installing vendor software, and it fits a Raspberry Pi on a bench. It is the wrong choice for a fleet monitoring deployment, for a headless server, or for a project that needs a supported commercial toolchain, since the project is written and maintained by volunteers with no affiliation to any GNSS manufacturer or distributor. Before adopting it, confirm the receiver model and protocol you need are covered, since specific message support is subject to the underlying parser implementation and open-source permissions, and pin a version, with v1.7.8 published on 2026-10-14.

Frequently asked questions

How do I install and start PyGPSClient?

With Python 3.10 or later and tkinter 8.6 or later installed, run python3 -m pip install --upgrade pygpsclient and then start it with pygpsclient. The README also documents installing into a virtual environment, which may be needed on a system with an externally-managed-environment Python.

Which GNSS protocols does PyGPSClient support?

The README lists NMEA, UBX for u-blox binary, SBF for Septentrio binary, UNI for Unicore binary, QGC for Quectel binary, RTCM3, SPARTN, NTRIP and TTY for ASCII text. It notes that specific message support is subject to the underlying parser implementation and open-source permissions.

Can PyGPSClient act as an NTRIP base station?

Yes. The README states it can serve as an NTRIP base station with an RTK-compatible receiver, naming u-blox ZED-F9P and ZED-X20P, Quectel LG and LC series, Septentrio Mosaic series and Unicore UM9 series receivers. It also provides NTRIP client facilities for both RTCM3 and SPARTN services.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. README
  4. Releases
  5. semuconsulting/PyGPSClient on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/semuconsulting-pygpsclient.svg)](https://hysenlabs.com/projects/semuconsulting-pygpsclient)

Was this useful?