Metadata-Version: 2.5
Name: ntrip-rtcm3-to-rtcm2p3
Version: 0.1.0.post39
Summary: NTRIP receiver + LAN rebroadcaster that converts an RTCM 3.x reference stream into RTCM 2.3 DGPS corrections for legacy receivers
Project-URL: Homepage, https://github.com/mithro/ntrip-rtcm3-to-rtcm2p3
Project-URL: Documentation, https://ntrip-rtcm3-to-rtcm2p3.readthedocs.io/
Project-URL: Repository, https://github.com/mithro/ntrip-rtcm3-to-rtcm2p3
Project-URL: Issues, https://github.com/mithro/ntrip-rtcm3-to-rtcm2p3/issues
Author-email: Tim 'mithro' Ansell <me@mith.ro>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: dgps,gnss,gps,ntrip,rtcm
Requires-Python: >=3.11
Requires-Dist: pyrtcm>=1.2
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: docs
Requires-Dist: furo>=2024.1; extra == 'docs'
Requires-Dist: myst-parser>=3; extra == 'docs'
Requires-Dist: sphinx>=7; extra == 'docs'
Requires-Dist: sphinxcontrib-mermaid>=1.0; extra == 'docs'
Description-Content-Type: text/markdown

# ntrip-rtcm3-to-rtcm2p3

An [NTRIP](https://software.rtcm-ntrip.org/) **receiver + LAN rebroadcaster** that
also **converts** an [RTCM](https://www.rtcm.org/publications) 3.x reference stream
into **RTCM 2.3** DGPS corrections, so that legacy single-band receivers that only
understand RTCM 2.3 (e.g. the [u-blox 7](https://www.u-blox.com/en/product/neo-7-series))
can benefit from a modern RTCM3-only correction network.

> Built incrementally with a full test suite; every conversion stage is
> cross-checked against independent implementations (see the Validation docs).

📖 **[Documentation](https://ntrip-rtcm3-to-rtcm2p3.readthedocs.io/)** (Read the Docs)

## Why

Modern correction networks (e.g. Geoscience Australia's
[AUSCORS](https://gnss.ga.gov.au/)) broadcast **RTCM 3.x** only. A u-blox 7 / NEO-7
accepts **RTCM 2.3** DGPS corrections but has no RTCM3 decoder. No off-the-shelf
tool converts RTCM3 → RTCM 2.3 ([RTKLIB](https://github.com/tomojitakasu/RTKLIB)'s
`str2str` can only *emit* RTCM3; the
[BKG NTRIP Client (BNC)](https://igs.bkg.bund.de/ntrip/bnc) only *decodes* RTCM2).
RTCM 2.3 Type 1 messages are
*derived* pseudorange corrections, not a reformat — they must be computed from the
base station's observations, its known position, and satellite positions from
broadcast ephemeris.

## Pipeline

```
        obs + base position                 broadcast ephemeris
   (RTCM3 MSM7 1077, 1006)                 (RTCM3 1019, separate mount)
             │                                       │
             ▼                                       ▼
      decode pseudoranges  ───────────────►  satellite position + clock
             │                                       │
             └───────────────┬───────────────────────┘
                             ▼
                   per-SV PRC / RRC  (DGPS reference-station math)
                             ▼
                   encode RTCM 2.3 Type 1 / 3 (parity, IOD, scaling)
                             ▼
              serve as a local NTRIP mount alongside the raw RTCM3
```

## Install

The packages are published as a signed apt repository per Debian suite:
trixie, forky and sid. They are `Architecture: all`, so the one build serves
every architecture. Put your suite's name in place of `trixie` below.

```sh
sudo install -d -m0755 /etc/apt/keyrings
curl -fsSL https://mith.ro/ntrip-rtcm3-to-rtcm2p3/ntrip-rtcm3-to-rtcm2p3.gpg | sudo tee /etc/apt/keyrings/ntrip-rtcm3-to-rtcm2p3.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/ntrip-rtcm3-to-rtcm2p3.gpg] https://mith.ro/ntrip-rtcm3-to-rtcm2p3/trixie/ ./" \
  | sudo tee /etc/apt/sources.list.d/ntrip-rtcm3-to-rtcm2p3.list
sudo apt update
sudo apt install ntrip-rtcm3-to-rtcm2p3
```

The repository is signed with the key
`36E5 D845 2935 9CFE 8874  F1F1 44EA 5E20 5EE9 F42E`
(`gpg --show-keys /etc/apt/keyrings/ntrip-rtcm3-to-rtcm2p3.gpg` shows it).
It also carries the dependencies a suite's Debian archive doesn't have, so apt
finds every one: `python3-pyrtcm` in every suite, and `python3-pynmeagps` in
trixie (forky and sid have Debian's own).

`ntrip-rtcm3-to-rtcm2p3` is the systemd service; `python3-ntrip-rtcm3-to-rtcm2p3`
alone is the library and the command. Set the upstream caster, credentials and
bind addresses in `/etc/ntrip-rtcm3-to-rtcm2p3/env`, then
`sudo systemctl restart ntrip-rtcm3-to-rtcm2p3`. See the
[usage documentation](https://ntrip-rtcm3-to-rtcm2p3.readthedocs.io/usage.html).

## Development

```bash
uv run --extra dev pytest        # test suite
uv run --extra dev ruff check .  # lint
```

The `Debian packages` workflow runs the tests in each suite's container, then
builds the packages with
[mithro/apt-repo-action](https://github.com/mithro/apt-repo-action)'s shared
`build-deb` action, install-tests them (`packaging/install-test.sh`) and, from
`main`, publishes them. The version comes from `git describe` plus the suite's
`~deb<R>` (`0.1.0.post25~deb13`; nothing for sid). There is no committed
`debian/changelog`: the build writes one with just its own entry, and git
ignores it.

The same workflow builds `python3-pyrtcm` and `python3-pynmeagps` from their
PyPI sdists (`packaging/build-pypi-deb.sh`), but only for a suite whose Debian
archive doesn't have the package: the script asks the suite's own apt, so our
build never shadows Debian's. Their version is
`<upstream>-0+welland<M>[~deb<R>]`, with PyPI's version as `<upstream>` and
nothing for sid, as above. `<M>` counts the commits that changed the script,
and the `-0` sorts below Debian's own `-1`, so on an upgrade to a suite that
has the package, Debian's replaces ours. Neither part follows this
repository's own commits, so the two packages are republished at the same
version until the script or the release on PyPI changes.

## License

Apache-2.0. See [LICENSE](LICENSE).
