Analyses NTRIP RTCM 3.x streams from GNSS base stations, and answers whether a station is fit to serve RTK.
The project has one configuration format. Every program in it — the CLI, the Windows GUI, the monitoring daemon and the Android app — reads and writes the same file, so a configuration written anywhere is usable everywhere.
The filename is yours to choose.
config.jsonis only what the CLI looks for when you do not tell it otherwise:-ctakes any path, the GUI opens whatever you point it at, and the daemon takes--config. Name files after the stations they describe —rfsee.json,kadaster-apel.json— and a directory of them stays readable. Nothing in any program requires the word “config”.
{
"output_dir": "/var/lib/ntrip-monitor",
"interval_s": 10,
"mountpoints": [
{
"name": "my station",
"caster": "ntrip.kadaster.nl",
"port": 2101,
"mountpoint": "APEL00NLD0",
"username": "ntrip-analyser",
"password": "password",
"tls": false,
"send_gga": false,
"latitude": 52.230481,
"longitude": 5.942016,
"eph_caster": "ntrip.kadaster.nl",
"eph_port": 2101,
"eph_mountpoint": "BCEP00KAD0",
"eph_username": "ntrip-analyser",
"eph_password": "password",
"eph_tls": false
}
]
}
The file is a list, even when it holds one connection. That single decision is what lets a set configured on a phone in the field be dropped onto a server, and a server’s configuration be opened on a phone.
Caster passwords in this file are plain text. There is no encryption, no obfuscation and no key derivation. A copy in a Downloads folder, attached to a support e-mail, committed to a repository or synced to a cloud drive hands over every credential it contains.
That is unavoidable in an exchange format — the file has to be readable by a text editor, by four programs on three platforms, and by whoever is diagnosing a problem — but it means the file must be handled like a password file, because it is one:
*.json outright, allowing back only the two placeholder examples
(bin/exampleConfig.json and service/monitord.example.json), so a
real configuration cannot be committed here by accident. Any other
repository you copy one into has no such protection.xxx first. Nobody diagnosing a stream needs it./etc/ntrip-monitord/
owned by root with mode 0600, not in a home directory.Casters issue per-user registrations, so a leaked password is one account’s problem rather than a network’s — but it is still an account someone signed up for, sometimes a paid one.
| Key | Type | Meaning |
|---|---|---|
mountpoints |
array | The connections. Required; everything else is optional |
output_dir |
string | Where ntrip-monitord writes its snapshots. Must match the Munin plugin’s env.statedir. Ignored by the other programs |
interval_s |
number | Seconds between the daemon’s snapshot writes. Ignored by the other programs |
mountpoints| Key | Type | Meaning |
|---|---|---|
caster |
string | Caster hostname |
port |
number | Caster port, usually 2101 |
mountpoint |
string | Mountpoint to open |
username, password |
string | Caster credentials, in the clear |
tls |
boolean | Speak TLS to the caster. An explicit choice, never inferred from the port; absent means plain text, so an older file keeps meaning what it meant. The certificate is always verified — there is no connect-anyway mode |
send_gga |
boolean | Send the periodic GGA uplink. Network (VRS) mountpoints require it; a single base ignores it |
latitude, longitude |
number | Position for that uplink, degrees |
name |
string | A label for people. Optional, and ignored by every parser that does not need it |
eph_caster, eph_port, eph_mountpoint, eph_username, eph_password, eph_tls |
string / number / boolean | Optional. A second connection carrying broadcast ephemerides (RTCM 1019/1020/1041/1042/1044/1045/1046), which the sky plot needs to place satellites and the self-position solve needs to place the station — in the GUI and in the monitoring daemon, which shares one connection among every entry naming the same source. Only for stations that do not broadcast them on the observation stream — those are decoded from it directly. Leave the block out to disable it |
A missing key leaves its field empty rather than terminating the program — one typo used to take a whole run down. The cost is that a silently empty caster is possible, so validate a file before trusting it:
ntrip-analyser --check-config
which applies the command-line and environment overrides, resolves the caster by DNS, prints what it would use, and exits.
| Program | Reads | Writes |
|---|---|---|
CLI (ntrip-analyser) |
the first entry; says so when there are more | -g writes a template of one |
| Windows GUI | the first entry; the log names how many were ignored | Save Configuration writes the one it is driving |
ntrip-monitord |
every entry, monitored simultaneously | — |
| Android, pro edition | every entry, merged into its saved connections | Save configuration writes them all |
| Android, free edition | the first entry — it saves one connection | — |
The analysers examine one stream at a time, so they take the first entry and say so:
[CONFIG] fromphone.json lists 2 connections; using the first (HANESE) and ignoring the other 1.
A user who exported five connections and sees one is otherwise entitled to think the file was truncated.
The Android pro edition merges rather than replacing: an entry naming a caster, port and mountpoint it already has updates that connection, and anything else is added while there is room. Loading a colleague’s file gains you a connection instead of costing you five.
Every release before this format wrote a flat object with upper-case keys:
{
"NTRIP_CASTER": "ntrip.kadaster.nl",
"NTRIP_PORT": 2101,
"TLS": false,
"MOUNTPOINT": "APEL00NLD0",
"USERNAME": "ntrip-analyser",
"PASSWORD": "password",
"LATITUDE": 52.230481,
"LONGITUDE": 5.942016,
"EPH_CASTER": "ntrip.kadaster.nl",
"EPH_PORT": 2101,
"EPH_MOUNTPOINT": "BCEP00KAD0",
"EPH_USERNAME": "ntrip-analyser",
"EPH_PASSWORD": "password",
"EPH_TLS": false
}
Those files still work. The CLI, the GUI and the Android app read them as a single connection — they exist on disks, in support e-mails and in released assets, and they still say exactly what they meant. Nothing writes this layout any more; saving a configuration from any program produces the list format above, which is how a file migrates.
| I want to… | Do |
|---|---|
| Analyse one stream now, interactively | Any file; the first entry is used |
Run --check on a station for sign-off |
Any file |
| Move a setup between desktop and phone | Save from either; both read it |
| Watch several stations continuously and graph them | Put several entries in mountpoints, point ntrip-monitord at it |
| Take a set of connections from the field to a server | Save from the Android pro edition; copy to /etc/ntrip-monitord/ |
A ready-to-edit example ships as
bin/exampleConfig.json, targeting the
Dutch Kadaster open caster with its ephemeris stream. Its username
and password are empty on purpose: those streams are served
anonymously, so the file works unedited. Fill them in for a caster that
requires an account — obtaining one is the user’s business, not the
application’s.
ntrip-monitord, Munin, and deployment