Cross-platform TUI for NMEA 2000 with canboat decoding and pluggable drivers
Project description
pgntui
Cross-platform TUI for NMEA 2000 with canboat decoding.
Read live N2K frames through pluggable drivers, decode them with the
canboat PGN database, and route values into JSON-defined dashboards. Record
sessions to .pgnlog and replay them later — no boat required.
Expand any signal ([+]) to reveal its sparkline; set the sparkline height
from the Settings menu, and browse/play recordings from File → Open recording.
| Settings menu | Open recording |
|---|---|
Install
The easiest path is pipx:
pipx install pgntui
Don't have pipx? Install it with pip, then make sure it is on PATH:
python -m pip install --user pipx
python -m pipx ensurepath
Open a new terminal afterwards so the PATH change takes effect. On
Debian/Ubuntu you can use sudo apt install pipx instead, and on macOS
brew install pipx.
If your system Python is older than 3.11, point pipx at a newer interpreter:
pipx install --python python3.12 pgntui
Or run in a project venv:
python3 -m venv .venv && . .venv/bin/activate
pip install pgntui
Standalone single-file binaries for macOS (arm64, x86_64), Linux (x86_64) and Windows (x86_64) are attached to each GitHub release.
Quickstart
Scaffold the example workspace and launch:
pgntui --example # writes the example workspace at the OS default location
pgntui # opens the TUI; no driver yet, debug tab will be empty
Replay a recording:
pgntui replay path/to/session.pgnlog
Run with a real driver — pgntui picks the driver named in config.toml:
pgntui # uses driver.name from <workspace>/config.toml
Workspace layout
pgntui reads everything from a workspace directory. By default the location
follows platformdirs.user_config_dir("pgntui"):
| OS | Default workspace |
|---|---|
| Linux | ~/.config/pgntui |
| macOS | ~/Library/Application Support/pgntui |
| Windows | %LOCALAPPDATA%\pgntui\pgntui |
(On Windows platformdirs nests <appauthor>\<appname>, so the path segment
pgntui appears twice — e.g. C:\Users\you\AppData\Local\pgntui\pgntui.)
Override with --workspace <path> on the command line.
Layout:
<workspace>/
config.toml # driver + theme + paths
signals/*.json # signal definitions (PGN -> field -> widget)
containers/*.json # dashboard layouts (tab -> grid of signals)
recordings/ # .pgnlog files written by the R hotkey
logs/ # CSV exports
Run pgntui --example to drop a working sample inside this directory.
JSON library
library/ in the repo ships ready-made signal + container sets
for one tab per NMEA Simulator page — GPS, Environmental, Boat, Batteries,
Engine (main / status / transmission), Tanks, Binary, DC and Charge, AC,
Windlass, Thruster. Copy the pages you want into your workspace:
cp library/gps/signals/*.json <workspace>/signals/
cp library/gps/containers/*.json <workspace>/containers/
See library/README.md for the page list and unit
conventions.
Drivers
Built-in driver entry points (pgntui.drivers):
actisense-ngt1— Actisense NGT-1 USB serial gateway (pyserial)file-replay— replay an Actisense.pgnlogcapture
Pick one in config.toml:
[driver]
name = "actisense-ngt1"
port = "/dev/tty.usbserial-XXXX" # macOS / Linux
# port = "COM4" # Windows
baud = 115200
Third-party drivers can register additional entry points under the
pgntui.drivers group.
Actisense NGT-1
The NGT-1 is a USB↔NMEA 2000 gateway. The easiest path is the in-app
Connection menu — run pgntui, press C (or click Connection in the
title bar), pick the port and speed, and press Test to confirm it's
receiving. Save writes the choice to config.toml; Connect goes live
without a restart.
Prefer the command line? Find the port and test it there:
pgntui --list-ports # list serial ports
pgntui probe --port COM4 # 2-second connection test + verdict
Then set driver.name = "actisense-ngt1" and driver.port in config.toml
(COM4 on Windows, /dev/ttyUSB0 on Linux, /dev/tty.usbserial-XXXX on
macOS) and run pgntui — incoming PGNs scroll on the Debug tab and feed the
dashboards. The driver speaks the Actisense BST serial protocol
(DLE STX…DLE ETX framing, 0x93 receive / 0x94 send). Writes
(analog_out/digital_out) additionally need --enable-write and
app.write_enabled = true.
Signal types
Signal JSON files declare how each PGN field renders:
analog_in— gauge / numeric readout (RPM, speed, depth, temperature)digital_in— boolean lamp (alarm, anchor light, bilge pump state)analog_out— write-back analog control (sends an outbound frame)digital_out— write-back toggle (sends an outbound frame)
analog_out and digital_out need --enable-write on the CLI and
app.write_enabled = true in config.toml; otherwise they render as
read-only.
Themes
Six builtins ship in the wheel:
dark(default)lightamber-crtgreen-phosphormono-asciirainbow-disco
Custom themes are JSON files referenced from config.toml:
[app]
theme = "dark"
Replay
Replay an Actisense-format .pgnlog:
pgntui replay capture.pgnlog
The replay driver respects the original frame spacing. Press the R hotkey
inside the TUI to start/stop recording the live stream to a new
.pgnlog file under <workspace>/recordings/.
Hotkeys
Tab / Shift+Tab next / previous container tab
D jump to Debug tab
R start / stop recording
C open the Connection menu (NGT-1 port / speed / test)
A show the About dialog
Q / Ctrl+Q quit immediately
? show help line in status bar
Layout sketch
+---------------------------------------------------+
| pgntui |
+---------------------------------------------------+
| [Main] [Engine] [Nav] [Debug] |
+---------------------------------------------------+
| RPM 1450 Speed 6.8 kn Depth 12.3 m |
| +----+ +----+ +----+ |
| |####| |## | |# | |
| +----+ +----+ +----+ |
| |
| Bilge OFF Anchor Light ON |
+---------------------------------------------------+
| [Tab] Next [D] Debug [R] Rec [Q] Quit |
| status: idle |
+---------------------------------------------------+
Status
Early days — expect rough edges. Solid enough to use for real on a boat whose NMEA 2000 network you already trust, or on a test-bench setup.
- Works: TUI shell, canboat decoder, signal routing, file replay, Actisense NGT-1 driver (read), recording.
- Partial: NGT-1 write-back is wired but field-tested only against a tiny PGN subset.
- Not yet: TwoCAN / Yacht Devices native drivers, more layout primitives, per-signal alarm thresholds in the UI.
Bug reports and patches welcome — file an issue at https://github.com/phobicdotno/pgntui/issues.
License
MIT. See LICENSE.
Links
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 pgntui-0.6.38.tar.gz.
File metadata
- Download URL: pgntui-0.6.38.tar.gz
- Upload date:
- Size: 558.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa57dbca03d52e14c5fa7d991458e866b6975921d8f722cf7a055bdfcff15666
|
|
| MD5 |
f43d60d4c1ca814a3b834fb921bb96ab
|
|
| BLAKE2b-256 |
39ad84987ca00bf91854867f5c0ef05ad440daeb41a1d78e6e783acab5d652bd
|
Provenance
The following attestation bundles were made for pgntui-0.6.38.tar.gz:
Publisher:
release.yml on phobicdotno/pgntui
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pgntui-0.6.38.tar.gz -
Subject digest:
aa57dbca03d52e14c5fa7d991458e866b6975921d8f722cf7a055bdfcff15666 - Sigstore transparency entry: 1790305958
- Sigstore integration time:
-
Permalink:
phobicdotno/pgntui@ea9f65fd1a71084e5f20772b74ec0c4ace765d35 -
Branch / Tag:
refs/tags/v0.6.38 - Owner: https://github.com/phobicdotno
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ea9f65fd1a71084e5f20772b74ec0c4ace765d35 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pgntui-0.6.38-py3-none-any.whl.
File metadata
- Download URL: pgntui-0.6.38-py3-none-any.whl
- Upload date:
- Size: 233.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
743eaeee29cab3a40b3851451dde9848fa9a87ad5c7c3a897cf79e35d55b18c5
|
|
| MD5 |
d8ca1930df47b2d7d424fd6c2d9f79e2
|
|
| BLAKE2b-256 |
e080b450fd19acd7d85d17dfe863343e1cbac9fe2a0531825553915ece84844a
|
Provenance
The following attestation bundles were made for pgntui-0.6.38-py3-none-any.whl:
Publisher:
release.yml on phobicdotno/pgntui
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pgntui-0.6.38-py3-none-any.whl -
Subject digest:
743eaeee29cab3a40b3851451dde9848fa9a87ad5c7c3a897cf79e35d55b18c5 - Sigstore transparency entry: 1790306043
- Sigstore integration time:
-
Permalink:
phobicdotno/pgntui@ea9f65fd1a71084e5f20772b74ec0c4ace765d35 -
Branch / Tag:
refs/tags/v0.6.38 - Owner: https://github.com/phobicdotno
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ea9f65fd1a71084e5f20772b74ec0c4ace765d35 -
Trigger Event:
push
-
Statement type: