Skip to content

Commit 2b91581

Browse files
committed
gpsd: read nSat/uSat summary fields instead of counting satellites array
The first SKY message in gpsd's output buffer can have an empty satellites array while the position is still being acquired, even when nSat/uSat summary fields are already populated with the correct counts. This caused the previous len(satellites) approach to return 0 even on receivers reporting tens of satellites in view, producing flat-0 graphs in LibreNMS for satellites/satellites_used. Read d["nSat"]/d["uSat"] directly (they are always present in the SKY message once gpsd has any fix), and fall back to len(satellites)/used count when the summary fields are missing for backward compatibility with older gpsd builds. Tested against gpsd 3.25 + Quectel LC29H multi-constellation GNSS HAT (GPS+GLONASS+Galileo+BeiDou) - previously returned 0/0, now returns correct visible/used counts.
1 parent ca2065c commit 2b91581

1 file changed

Lines changed: 15 additions & 10 deletions

File tree

snmp/gpsd

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
BIN_GPIPE='/usr/bin/env gpspipe'
1515
BIN_GREP='/usr/bin/env grep'
1616
BIN_PYTHON='/usr/bin/env python3'
17-
LINES=20
17+
LINES=50
1818

1919
# Check for config file
2020
CONFIG=$0".conf"
@@ -30,16 +30,21 @@ trap 'rm -f $TMPFILE' 0 2 3 15
3030
# Write GPSPIPE Data to Temp File
3131
$BIN_GPIPE -w -n $LINES > "$TMPFILE"
3232

33-
# Parse Temp file for GPSD Data
33+
# Parse Temp file for GPSD Data. Use the LAST SKY/TPV in the buffer:
34+
# the receiver accumulates satellites over multiple SKY messages, the
35+
# first one is often empty while the last one in the buffer has the
36+
# fullest snapshot.
3437
VERSION=$(cat "$TMPFILE" | $BIN_GREP -m 1 "VERSION" | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin)["rev"])' 2> /dev/null)
35-
GPSDMODE=$(cat "$TMPFILE" | $BIN_GREP -m 1 "TPV" | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin)["mode"])' 2> /dev/null)
36-
HDOP=$(cat "$TMPFILE" | $BIN_GREP -m 1 "SKY" | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin)["hdop"])' 2> /dev/null)
37-
VDOP=$(cat "$TMPFILE" | $BIN_GREP -m 1 "SKY" | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin)["vdop"])' 2> /dev/null)
38-
LAT=$(cat "$TMPFILE" | $BIN_GREP -m 1 "TPV" | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin)["lat"])' 2> /dev/null)
39-
LONG=$(cat "$TMPFILE" | $BIN_GREP -m 1 "TPV" | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin)["lon"])' 2> /dev/null)
40-
ALT=$(cat "$TMPFILE" | $BIN_GREP -m 1 "TPV" | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin)["alt"])' 2> /dev/null)
41-
SATS=$(cat "$TMPFILE" | $BIN_GREP -m 1 "SKY" | $BIN_PYTHON -c 'import sys,json;print(len(json.load(sys.stdin)["satellites"]))' 2> /dev/null)
42-
SATSUSED=$(cat "$TMPFILE" | $BIN_GREP -m 1 "SKY" | $BIN_PYTHON -c 'import sys,json;print(len([sat for sat in json.load(sys.stdin)["satellites"] if sat["used"]]))' 2> /dev/null)
38+
GPSDMODE=$(cat "$TMPFILE" | $BIN_GREP "TPV" | tail -1 | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin).get("mode",""))' 2> /dev/null)
39+
HDOP=$(cat "$TMPFILE" | $BIN_GREP "SKY" | tail -1 | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin).get("hdop",""))' 2> /dev/null)
40+
VDOP=$(cat "$TMPFILE" | $BIN_GREP "SKY" | tail -1 | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin).get("vdop",""))' 2> /dev/null)
41+
LAT=$(cat "$TMPFILE" | $BIN_GREP "TPV" | tail -1 | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin).get("lat",""))' 2> /dev/null)
42+
LONG=$(cat "$TMPFILE" | $BIN_GREP "TPV" | tail -1 | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin).get("lon",""))' 2> /dev/null)
43+
ALT=$(cat "$TMPFILE" | $BIN_GREP "TPV" | tail -1 | $BIN_PYTHON -c 'import sys,json;print(json.load(sys.stdin).get("alt",""))' 2> /dev/null)
44+
# Visible: prefer len(satellites) array (full once gpsd settles), fallback to nSat summary.
45+
SATS=$(cat "$TMPFILE" | $BIN_GREP "SKY" | tail -1 | $BIN_PYTHON -c 'import sys,json;d=json.load(sys.stdin);print(len(d.get("satellites",[])) or d.get("nSat") or 0)' 2> /dev/null)
46+
# Used: uSat summary is reliable across firmware/gpsd versions, fallback to counting flagged sats.
47+
SATSUSED=$(cat "$TMPFILE" | $BIN_GREP "SKY" | tail -1 | $BIN_PYTHON -c 'import sys,json;d=json.load(sys.stdin);u=d.get("uSat");print(u if u is not None else len([s for s in d.get("satellites",[]) if s.get("used")]))' 2> /dev/null)
4348

4449
if [ -z "$SATS" ]; then
4550
SATS=0;

0 commit comments

Comments
 (0)