Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions INSTALLATION.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# PyGPSClient Installation

[Basics](#basics) |
Expand Down Expand Up @@ -92,25 +91,43 @@ brew install python-tk@3.13 libspatialite

Note also that the Homebrew formulae for python-tk>=3.12 include the latest tkinter 9.0 (rather than 8.6). There are known compatibility issues between tkinter 9.0 and other Python packages (*e.g. ImageTk*) on some platform configurations, which may result in PyGPSClient being unable to load. If you encounter these issues, consider using `brew install python-tk@3.11` or an official [Python.org](https://www.python.org/downloads/macos) installation package instead.

Note that on MacOS, serial ports may appear as `/dev/tty*` *or* `/dev/cu*`. To understand the differences between the two, see [here](https://www.codegenes.net/blog/what-s-the-difference-between-dev-tty-and-dev-cu-on-macos/).

### Linux (including Raspberry Pi OS)

Some Linux distributions may not include the necessary pip, tkinter, Pillow or spatialite libraries by default. They may need to be installed separately, e.g.:
Some Linux distributions may not include the necessary pip, venv, tkinter, Pillow or spatialite libraries by default. They may need to be installed separately, e.g. for Debian-based distibutions, a combination of some or all of the following:

```shell
sudo apt install python3-pip python3-tk python3-pil python3-venv python3-pil.imagetk libjpeg-dev zlib1g-dev tk-dev libspatialite
```

For Arch-based distributions:

```shell
sudo apt install python3-pip python3-tk python3-pil python3-pil.imagetk libjpeg-dev zlib1g-dev tk-dev libspatialite
sudo pacman -S tk libspatialite
```

⁴ Support for the sqlite3 `mod_spatialite` extension may require a custom version of Python to be [compiled from source](https://github.com/semuconsulting/PyGPSClient/blob/master/examples/python_compile.sh) if a suitable version is not available from any of the distribution's repos.

## <a name="userpriv">User Privileges</a>

To access the serial port on most Linux platforms, you will need to be a member of the
`tty` and/or `dialout` groups. Other than this, no special privileges are required.
To access the serial port (`/dev/tty*`) on most Linux platforms, you will need to be a member of whichever group or "`Gid`" the `/dev/tty*` device belongs to. Failure to do this will typically result in an error `[Errno 13] could not open port /dev/ttyACM0 [Errno 13] permission denied /dev/ttyACM0`

To check and set the necessary group permissions:

```shell
stat /dev/ttyACM0 | grep Gid
```
`Access: (0660/crw-rw----) Uid: ( 0/ root) Gid: ( 20/ dialout)` <-- group in this case is `dialout`; add user to this group using usermod (*you may have to log out and in again for this to take effect*):

```shell
usermod -a -G tty myuser
sudo usermod -a -G dialout myuser
```

For Debian-based platforms, the group is normally `dialout`; on Arch-based platforms it may be `uucp` or `tty`.

Other than this, no special privileges are required.

## <a name="pip">Install using pip</a>

The recommended way to install the latest version of `PyGPSClient` is with [pip](http://pypi.python.org/pypi/pip/):
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ PyGPSClient is a free, open-source, multi-platform graphical GNSS/GPS testing, d
* Supports NMEA, UBX, SBF, QGC, RTCM3, NTRIP, SPARTN, MQTT and TTY (ASCII) protocols¹.
* Capable of reading from a variety of GNSS data streams: Serial (USB / UART), Socket (TCP / UDP), binary data stream (terminal or file capture) and binary recording (e.g. u-center \*.ubx).
* Provides [NTRIP](#ntripconfig) client facilities.
* Can serve as an [NTRIP base station](#basestation) with an RTK-compatible receiver (e.g. u-blox ZED-F9P/ZED-X20P, Quectel LG290P/LG580P/LC29H and Septentrio Mosaic G5/X5).
* Supports GNSS (*and related*) device configuration via proprietary UBX, NMEA and ASCII TTY protocols, including most u-blox, Quectel, Septentrio and Feyman GNSS devices.
* Can serve as an [NTRIP base station](#basestation) with an RTK-compatible receiver (e.g. u-blox ZED-F9P/ZED-X20P, Quectel LG290P/LG580P/LC29H, Septentrio Mosaic G5/X5 or Unicore UM98n).
* Supports GNSS (*and related*) device configuration via proprietary UBX, NMEA and ASCII TTY protocols, including most u-blox, Quectel, Septentrio, Unicore and Feyman GNSS devices.
* Can be installed using the standard `pip` Python package manager - see [installation instructions](#installation) below.

This is an independent project and we have no affiliation whatsoever with any GNSS manufacturer or distributor.
Expand Down Expand Up @@ -104,6 +104,8 @@ For more comprehensive installation instructions, please refer to [INSTALLATION.
1. By default, the Settings panel is displayed to the right of the main application window. It can be hidden or shown via Menu..View..Hide/Show Settings. The panel can also be 'undocked' from the main application window via Menu..View..Undock Settings and - if [non-transient](#transient) (`transient_dialog_b: 0`) - minimized independently of the main window. Exiting the undocked dialog, or selecting Menu..View..Dock Settings, will 'dock' the panel.
1. To connect to a GNSS receiver via USB or UART port, select the device from the listbox, set the appropriate serial connection parameters and click
![connect icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/usbport-1-24.png?raw=true). The application will endeavour to pre-select a recognised GNSS/GPS device but this is platform and device dependent. Press the ![refresh](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-refresh-6-16.png?raw=true) button to refresh the list of connected devices at any point. `Rate bps` (baud rate) is typically the only setting that might need adjusting, but tweaking the `timeout` setting may improve performance on certain platforms. The `Msg Mode` parameter defaults to `GET` i.e., periodic or poll response messages *from* a receiver. If you wish to parse streams of command or poll messages being sent *to* a receiver, set the `Msg Mode` to `SET` or `POLL`. An optional serial or socket stream inactivity timeout can also be set (in seconds; 0 = no timeout).

If you get a permissions error on attempting to connect to a serial port e.g. `[Errno 13] permission denied /dev/ttyACM0`, refer to the [Installation Guidelines - User Privileges](https://github.com/semuconsulting/PyGPSClient/blob/master/INSTALLATION.md#user-privileges).
1. A custom user-defined serial port can also be passed via the json configuration file setting `"userport_s":`, via environment variable `PYGPSCLIENT_USERPORT` or as a command line argument `--userport`. A special userport value of "ubxsimulator" invokes the experimental [`pyubxutils.UBXSimulator`](https://github.com/semuconsulting/pyubxutils/blob/main/src/pyubxutils/ubxsimulator.py) utility to emulate a GNSS NMEA/UBX serial stream.
1. To connect to a TCP or UDP socket, enter the server URL and port, select the protocol (defaults to TCP) and click
![connect socket icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/ethernet-1-24.png?raw=true). For encrypted TLS connections, tick the 'TLS' checkbox. Tick the 'Self Sign' checkbox to accommodate self-signed TLS certification (*typically for test or demonstration services*).
Expand Down Expand Up @@ -353,7 +355,7 @@ By default, the server/caster binds to the host address '0.0.0.0' (IPv4) or '::'
1. Select NTRIP CASTER mode and (if necessary) enter the host IP address and port.
1. Select 'TLS' to enable an encrypted TLS (HTTPS) connection.
1. An additional expandable panel is made available to allow the user to configure a connected RTK-compatible receiver to operate in either `FIXED` or `SURVEY-IN` Base Station mode (*NB: parameters can only be amended while the caster is stopped*).
1. Select the receiver type (currently u-blox ZED-F9*, u-blox ZED-X20*, Quectel LG290P, Quectel LC29HBA and Septentrio Mosaic X5 receivers are supported) and click the Send button to send the appropriate configuration commands to the receiver.
1. Select the receiver type and click the Send button to send the appropriate configuration commands to the receiver.
1. **NB** Septentrio Mosaic X5: These receivers are configured via ASCII TTY commands - to monitor the command responses, set the console protocol to "TTY" (*remember to set it back to RTCM when monitoring the RTCM3 output*). Note also that the input (ASCII command) UART port may be different to the output (RTCM3) UART port - make sure to select the appropriate port(s) when configuring the device and monitoring the RTCM3 output.
1. NMEA messages can be suppressed by checking 'Disable NMEA'.
1. NTRIP client login credentials are set via the user and password fields.
Expand Down
6 changes: 6 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# PyGPSClient Release Notes

### RELEASE 1.6.2

1. Add support for Unicore Secondary Antenna and Attitude (IMU) NMEA sentences e.g. UM98n "GGAH", "HPD" (requires pynmeagps>=1.1.0).
1. Minor cosmetic UI enhancements to improve rendering on some Linux window managers (e.g. xfce).
1. `Waiting for XXX data` alerts added to user-selectable widgets to clarify which type of GNSS data each widget is waiting for. Widgets are not 'initialised' (underlying grids & labels drawn) until this data arrives. As in previous versions, widgets which depend on protocol-specific data (e.g. UBX) will display a `Receiver does not appear to support XXX data` alert if requisite data isn't received after 10 navigation solutions.

### RELEASE 1.6.1

1. Updates to main application window geometry (size and position) handling. Current window geometry is now saved to json configuration file as `screengeom_s` (e.g. `"1373x798+71+44"`), and will be restored on restart. Default startup geometry is centered at 75% of screen resolution.
Expand Down
8 changes: 8 additions & 0 deletions docs/pygpsclient.rst
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,14 @@ pygpsclient.ubx\_solrate\_frame module
:undoc-members:
:show-inheritance:

pygpsclient.uni\_handler module
-------------------------------

.. automodule:: pygpsclient.uni_handler
:members:
:undoc-members:
:show-inheritance:

pygpsclient.widget\_state module
--------------------------------

Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ disable = """

[tool.pytest.ini_options]
minversion = "7.0"
addopts = "--cov --cov-report html --cov-fail-under 16"
addopts = "--cov --cov-report html --cov-fail-under 17"
pythonpath = ["src"]
testpaths = ["tests"]

Expand All @@ -145,7 +145,7 @@ source = ["src"]
source = ["src"]

[tool.coverage.report]
fail_under = 16
fail_under = 17

[tool.coverage.html]
directory = "htmlcov"
2 changes: 0 additions & 2 deletions src/pygpsclient/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
:license: BSD 3-Clause
"""

import sys
from argparse import SUPPRESS, ArgumentDefaultsHelpFormatter, ArgumentParser
from logging import getLogger
from tkinter import Tk
Expand Down Expand Up @@ -151,7 +150,6 @@ def main():
root = Tk()
App(root, **kwargs)
root.mainloop()
sys.exit()


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion src/pygpsclient/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
:license: BSD 3-Clause
"""

__version__ = "1.6.1"
__version__ = "1.6.2"
2 changes: 1 addition & 1 deletion src/pygpsclient/about_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def _body(self):
self._btn_checkupdate = Button(
self._frm_body,
text="",
width=14,
width=16,
cursor="hand2",
)
self._chk_checkupdate = Checkbutton(
Expand Down
Loading