From ca46b9c906440f57f7b3cbe20841cad4ba91ab6d Mon Sep 17 00:00:00 2001 From: kx1t Date: Sat, 18 May 2024 16:39:49 -0400 Subject: [PATCH 01/20] partial mlat-gps feature commit --- Dockerfile | 12 +++++ .../gpsd_mlat_restart/dependencies.d/startup | 0 .../s6-overlay/s6-rc.d/gpsd_mlat_restart/run | 2 + .../s6-overlay/s6-rc.d/gpsd_mlat_restart/type | 1 + .../s6-rc.d/user/contents.d/gpsd_mlat_restart | 0 .../etc/s6-overlay/scripts/gpsd_mlat_restart | 50 +++++++++++++++++++ rootfs/etc/s6-overlay/scripts/mlat-client | 12 ++--- 7 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/dependencies.d/startup create mode 100755 rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/run create mode 100644 rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/type create mode 100644 rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/gpsd_mlat_restart create mode 100755 rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart diff --git a/Dockerfile b/Dockerfile index e2802ef..c0413b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,14 @@ +FROM ghcr.io/sdr-enthusiasts/docker-baseimage:base AS build + +RUN set -x && \ + apt-get update -y && \ + apt-get install -q -o Dpkg::Options::="--force-confnew" -y \ + git gcc && \ + cd / && \ + git clone --depth=1 --single-branch https://github.com/sdr-enthusiasts/docker-vesselalert.git && \ + cd /docker-vesselalert/src && \ + gcc -static distance.c -o distance -lm -Ofast + FROM ghcr.io/sdr-enthusiasts/docker-tar1090:latest LABEL org.opencontainers.image.source = "https://github.com/sdr-enthusiasts/docker-adsb-ultrafeeder" @@ -58,6 +69,7 @@ RUN TEMP_PACKAGES=() && \ echo "alias nano=\"nano -l\"" >> /root/.bashrc COPY rootfs/ / +COPY --from=build /docker-vesselalert/src/distance /usr/local/bin/distance # Add Container Version RUN set -x && \ diff --git a/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/dependencies.d/startup b/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/dependencies.d/startup new file mode 100644 index 0000000..e69de29 diff --git a/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/run b/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/run new file mode 100755 index 0000000..8fefd29 --- /dev/null +++ b/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/run @@ -0,0 +1,2 @@ +#!/bin/sh +exec /etc/s6-overlay/scripts/gpsd_mlat_restart diff --git a/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/type b/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/type @@ -0,0 +1 @@ +longrun diff --git a/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/gpsd_mlat_restart b/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/gpsd_mlat_restart new file mode 100644 index 0000000..e69de29 diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart new file mode 100755 index 0000000..787256e --- /dev/null +++ b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart @@ -0,0 +1,50 @@ +#!/command/with-contenv bash +# shellcheck shell=bash disable=SC2015,SC2016,SC1091,SC2001,SC2154 + +#--------------------------------------------------------------------------------------------- +# Copyright (C) 2023-2024, Ramon F. Kolb (kx1t) and contributors +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with this program. +# If not, see . +#--------------------------------------------------------------------------------------------- + +source /scripts/common + +# Check if GPSD_IN has been enabled +if ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_CONFIG" && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then + "${s6wrap[@]}" echo "GPSD not enabled - no need to check receiver location" + exec sleep infinity +fi + +# Now wait a bit to allow GPS to establish itself +sleep "${GPSD_INITIAL_WAIT:-300}" + +# Make sure that receiver.json exists; if it doesn't we need to wait for it +while ! [[ -f /run/readsb/receiver.json ]]; do + sleep 1 & wait $! +done + +# Get initial lat/lon/alt +lat="$(jq -r .lat /run/readsb/receiver.json)" +lon="$(jq -r .lon /run/readsb/receiver.json)" + +while :; do + sleep "${GPSD_CHECK_INTERVAL:30}" & wait $! + new_lat="$(jq -r .lat /run/readsb/receiver.json)" + new_lon="$(jq -r .lon /run/readsb/receiver.json)" + new_alt="$(jq -r .alt_m_amsl /run/readsb/receiver.json)" + distance="$(nice -n 20 distance "$lat" "$lon" "$new_lat" "$new_lon")" + if (( ${distance%%.*} > ${GPSD_MIN_DISTANCE} )); then + "${s6wrap[@]}" echo "Receiver moved ${distance%%.*} meters - restarting all mlat-clients" + pkill -f "/usr/bin/python3 /usr/bin/mlat-client" >/dev/null 2>&1 + fi +done \ No newline at end of file diff --git a/rootfs/etc/s6-overlay/scripts/mlat-client b/rootfs/etc/s6-overlay/scripts/mlat-client index 16ed88c..68075e5 100755 --- a/rootfs/etc/s6-overlay/scripts/mlat-client +++ b/rootfs/etc/s6-overlay/scripts/mlat-client @@ -51,17 +51,17 @@ then exec sleep infinity fi -if [[ -z "$LAT$READSB_LAT" ]]; then - "${s6wrap[@]}" --args echo "ERROR: READSB_LAT or LAT must be defined - MLAT will be disabled." +if [[ -z "$LAT$READSB_LAT" ]] && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_CONFIG" && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then + "${s6wrap[@]}" --args echo "ERROR: READSB_LAT or LAT must be defined or GPSD must be enabled - MLAT will be disabled." exec sleep infinity fi -if [[ -z "$LONG$READSB_LON" ]]; then - "${s6wrap[@]}" --args echo "ERROR: READSB_LON or LONG must be defined - MLAT will be disabled." +if [[ -z "$LONG$READSB_LON" ]] && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_CONFIG" && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then + "${s6wrap[@]}" --args echo "ERROR: READSB_LON or LONG must be defined or GPSD must be enabled - MLAT will be disabled." exec sleep infinity fi -if [[ -z "$ALT$READSB_ALT" ]]; then - "${s6wrap[@]}" --args echo "ERROR: READSB_ALT or ALT must be defined - MLAT will be disabled." +if [[ -z "$ALT$READSB_ALT" ]] && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_CONFIG" && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then + "${s6wrap[@]}" --args echo "ERROR: READSB_ALT or ALT must be defined or GPSD must be enabled - MLAT will be disabled." exec sleep infinity fi From 46b072763df04690dd402df46edfe0e9a42474ed Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 17:46:21 -0400 Subject: [PATCH 02/20] further updates to make GPSD work --- .../etc/s6-overlay/scripts/gpsd_mlat_restart | 39 ++++++++------- rootfs/etc/s6-overlay/scripts/mlat-client | 50 ++++++++++++++++--- 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart index 787256e..ba7ae9c 100755 --- a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart +++ b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart @@ -19,32 +19,35 @@ source /scripts/common -# Check if GPSD_IN has been enabled -if ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_CONFIG" && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then - "${s6wrap[@]}" echo "GPSD not enabled - no need to check receiver location" - exec sleep infinity +# Check every 60 secs if GPSD has been enabled +if [[ ! -f /run/readsb/gpsd.json ]] || [[ "$(jq -r .lat /run/readsb/gpsd.json)" == "null" ]]; then + sleep 60 & wait $! fi -# Now wait a bit to allow GPS to establish itself -sleep "${GPSD_INITIAL_WAIT:-300}" - -# Make sure that receiver.json exists; if it doesn't we need to wait for it -while ! [[ -f /run/readsb/receiver.json ]]; do - sleep 1 & wait $! +# Then wait until all mlat-client instances have started +while [[ ! -f /run/.all_mlatclient_instances_have_started ]]; do + sleep 5 & wait $! done +rm -f /run/.all_mlatclient_instances_have_started + +# Now wait a bit to allow GPS to establish itself +sleep "${GPSD_INITIAL_WAIT:-60}" + # Get initial lat/lon/alt -lat="$(jq -r .lat /run/readsb/receiver.json)" -lon="$(jq -r .lon /run/readsb/receiver.json)" +lat="${LAT:-${READSB_LAT:-$(jq -r .lat /run/readsb/gpsd.json)}}" +lon="${LONG:-${READSB_LON:-$(jq -r .lon /run/readsb/gpsd.json)}}" while :; do - sleep "${GPSD_CHECK_INTERVAL:30}" & wait $! - new_lat="$(jq -r .lat /run/readsb/receiver.json)" - new_lon="$(jq -r .lon /run/readsb/receiver.json)" - new_alt="$(jq -r .alt_m_amsl /run/readsb/receiver.json)" + new_lat="$(jq -r .lat /run/readsb/gpsd.json)" + new_lon="$(jq -r .lon /run/readsb/gpsd.json)" distance="$(nice -n 20 distance "$lat" "$lon" "$new_lat" "$new_lon")" - if (( ${distance%%.*} > ${GPSD_MIN_DISTANCE} )); then + if (( ${distance%%.*} > GPSD_MIN_DISTANCE )); then "${s6wrap[@]}" echo "Receiver moved ${distance%%.*} meters - restarting all mlat-clients" - pkill -f "/usr/bin/python3 /usr/bin/mlat-client" >/dev/null 2>&1 + # flag to the mlat-client script that it should try to use GPS coords instead of the predefined LAT/LON + touch /run/.gpsd_is_active + # kill the mlat-client instances so they get restarted with the new GPS coords + pkill -f "/usr/bin/python3 /usr/bin/mlat-client" >/dev/null 2>&1 fi + sleep "${GPSD_CHECK_INTERVAL:30}" & wait $! done \ No newline at end of file diff --git a/rootfs/etc/s6-overlay/scripts/mlat-client b/rootfs/etc/s6-overlay/scripts/mlat-client index 68075e5..5763e20 100755 --- a/rootfs/etc/s6-overlay/scripts/mlat-client +++ b/rootfs/etc/s6-overlay/scripts/mlat-client @@ -1,5 +1,5 @@ #!/command/with-contenv bash -# shellcheck shell=bash disable=SC1091,SC2015,SC2016 +# shellcheck shell=bash disable=SC1091,SC2015,SC2016,SC2001 #--------------------------------------------------------------------------------------------- # Copyright (C) 2023-2024, Ramon F. Kolb (kx1t) and contributors @@ -176,24 +176,39 @@ do fi # add LAT/LON/ALT to instance: - if [[ -n "${lat_arg}" ]]; then - MLAT_PARAM+=(--lat "${lat_arg}") + # see if we need to use GPS coords: + unset new_lat + unset new_lon + unset new_alt + if [[ -f /run/.gpsd_is_active && -f /run/readsb/receiver.json ]]; then + new_lat="$(jq -r .lat /run/readsb/receiver.json)" + new_lon="$(jq -r .lon /run/readsb/receiver.json)" + new_alt="$(jq -r .alt_m_amsl /run/readsb/receiver.json)" + if [[ "$new_lat" == "null" ]] || [[ "$new_lon" == "null" ]] || [[ "$new_alt" == "null" ]]; then + unset new_lat + unset new_lon + unset new_alt + fi + fi + + if [[ -n "${new_lat:-$lat_arg}" ]]; then + MLAT_PARAM+=(--lat "${new_lat:-$lat_arg}") elif [[ -n "${LAT}" ]]; then MLAT_PARAM+=(--lat "${LAT}") elif [[ -n "${READSB_LAT}" ]]; then MLAT_PARAM+=(--lat "${READSB_LAT}") fi - if [[ -n "${lon_arg}" ]]; then - MLAT_PARAM+=(--lon "${lon_arg}") + if [[ -n "${new_lon:-$lon_arg}" ]]; then + MLAT_PARAM+=(--lon "${new_lon:-$lon_arg}") elif [[ -n "${LONG}" ]]; then MLAT_PARAM+=(--lon "${LONG}") elif [[ -n "${READSB_LON}" ]]; then MLAT_PARAM+=(--lon "${READSB_LON}") fi - if [[ -n "${alt_arg}" ]]; then - MLAT_PARAM+=(--alt "${alt_arg}") + if [[ -n "${new_alt:-$alt_arg}" ]]; then + MLAT_PARAM+=(--alt "${new_alt:-$alt_arg}") elif [[ -n "${ALT}" ]]; then MLAT_PARAM+=(--alt "${ALT}") elif [[ -n "${READSB_ALT}" ]]; then @@ -240,6 +255,7 @@ do done sleep 5 & wait $! +touch /run/.all_mlatclient_instances_have_started # Now iterate over all MLAT-client instances and check if they are still running: while true @@ -257,6 +273,18 @@ do # shellcheck disable=SC2086 execstring="$(echo ${MLAT_CMD} ${pid_array[$mlat_pid]} | xargs)" + # If GPSD is active, then replace the lat/lon/alt params with the ones from GPSD + if [[ -f /run/readsb/gpsd.json ]] && [[ "$(jq -r .lat /run/readsb/gpsd.json)" != "null" ]]; then + new_lat="$(jq -r .lat /run/readsb/gpsd.json)" + new_lon="$(jq -r .lon /run/readsb/gpsd.json)" + new_alt="$(jq -r .altMSL /run/readsb/gpsd.json)" + if [[ "$new_lat" != "null" ]] && [[ "$new_lon" != "null" ]] && [[ "$new_alt" != "null" ]]; then + execstring="$(sed "s/^\(.*\s\+--lat\s\+\)[0-9.-]\+\(.*\)$/\1${new_lat}\2/g" <<< "$execstring")" + execstring="$(sed "s/^\(.*\s\+--lon\s\+\)[0-9.-]\+\(.*\)$/\1${new_lon}\2/g" <<< "$execstring")" + execstring="$(sed "s/^\(.*\s\+--alt\s\+\)[mft0-9.-]\+\(.*\)$/\1${new_alt}m\2/g" <<< "$execstring")" + fi + fi + #shellcheck disable=SC2069,SC2086 if [[ "${LOGLEVEL}" == "verbose" ]]; then "${s6wrap[@]}" --prepend="$(basename "$0")][${servername}" --args ${execstring} & @@ -270,5 +298,11 @@ do unset "pid_array[${mlat_pid}]" fi done - sleep 10 & wait $! + + # If GPSD is running, do more frequent checks than if it's not running + if [[ -f /run/readsb/gpsd.json ]] && [[ "$(jq -r .lat /run/readsb/gpsd.json)" != "null" ]]; then + sleep 1 & wait $! + else + sleep 10 & wait $! + fi done From 04207020703173e7dc3ba3760ab4e480a3c63bd5 Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 17:47:57 -0400 Subject: [PATCH 03/20] minor addition --- rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart index ba7ae9c..872ddc3 100755 --- a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart +++ b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart @@ -42,7 +42,7 @@ while :; do new_lat="$(jq -r .lat /run/readsb/gpsd.json)" new_lon="$(jq -r .lon /run/readsb/gpsd.json)" distance="$(nice -n 20 distance "$lat" "$lon" "$new_lat" "$new_lon")" - if (( ${distance%%.*} > GPSD_MIN_DISTANCE )); then + if (( ${distance%%.*} > ${GPSD_MIN_DISTANCE:-20} )); then "${s6wrap[@]}" echo "Receiver moved ${distance%%.*} meters - restarting all mlat-clients" # flag to the mlat-client script that it should try to use GPS coords instead of the predefined LAT/LON touch /run/.gpsd_is_active From 02e63838e38c8c3e965d4a057a114cb18b5eeeeb Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 17:58:07 -0400 Subject: [PATCH 04/20] bug fix --- rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart index 872ddc3..ab32d8a 100755 --- a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart +++ b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart @@ -49,5 +49,5 @@ while :; do # kill the mlat-client instances so they get restarted with the new GPS coords pkill -f "/usr/bin/python3 /usr/bin/mlat-client" >/dev/null 2>&1 fi - sleep "${GPSD_CHECK_INTERVAL:30}" & wait $! + sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! done \ No newline at end of file From 2b8ac0b40b6a18dd23c776858da23509760fd03a Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 18:00:47 -0400 Subject: [PATCH 05/20] add log verbosity --- rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart index ab32d8a..5ab325b 100755 --- a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart +++ b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart @@ -38,6 +38,8 @@ sleep "${GPSD_INITIAL_WAIT:-60}" lat="${LAT:-${READSB_LAT:-$(jq -r .lat /run/readsb/gpsd.json)}}" lon="${LONG:-${READSB_LON:-$(jq -r .lon /run/readsb/gpsd.json)}}" +"${s6wrap[@]}" echo "GPSD is active. Your mlat-client will restart with new coordinates if you move more than ${GPSD_MIN_DISTANCE:-20} meters" + while :; do new_lat="$(jq -r .lat /run/readsb/gpsd.json)" new_lon="$(jq -r .lon /run/readsb/gpsd.json)" From 5006f66b68ed5d15bdfc9424dbe20d374a04cb13 Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 18:03:48 -0400 Subject: [PATCH 06/20] typo --- rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart index 5ab325b..055a7cd 100755 --- a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart +++ b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart @@ -38,7 +38,7 @@ sleep "${GPSD_INITIAL_WAIT:-60}" lat="${LAT:-${READSB_LAT:-$(jq -r .lat /run/readsb/gpsd.json)}}" lon="${LONG:-${READSB_LON:-$(jq -r .lon /run/readsb/gpsd.json)}}" -"${s6wrap[@]}" echo "GPSD is active. Your mlat-client will restart with new coordinates if you move more than ${GPSD_MIN_DISTANCE:-20} meters" +"${s6wrap[@]}" echo "GPSD is active. Your mlat-client(s) will restart with new coordinates if you move more than ${GPSD_MIN_DISTANCE:-20} meters" while :; do new_lat="$(jq -r .lat /run/readsb/gpsd.json)" From 67e548907d206a1e3d76790ecfa13d8e7843566d Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 18:05:29 -0400 Subject: [PATCH 07/20] updates --- rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart index 055a7cd..bd815ef 100755 --- a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart +++ b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart @@ -46,10 +46,10 @@ while :; do distance="$(nice -n 20 distance "$lat" "$lon" "$new_lat" "$new_lon")" if (( ${distance%%.*} > ${GPSD_MIN_DISTANCE:-20} )); then "${s6wrap[@]}" echo "Receiver moved ${distance%%.*} meters - restarting all mlat-clients" - # flag to the mlat-client script that it should try to use GPS coords instead of the predefined LAT/LON - touch /run/.gpsd_is_active # kill the mlat-client instances so they get restarted with the new GPS coords pkill -f "/usr/bin/python3 /usr/bin/mlat-client" >/dev/null 2>&1 + lat="$new_lat" + lon="$new_lon" fi sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! done \ No newline at end of file From 4ac8c1aa2fbb0e95a3ceafbda55f239bc020ff32 Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 18:14:28 -0400 Subject: [PATCH 08/20] fix distance so the output in in meters instead of nm --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c0413b1..beb9c3d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,13 @@ FROM ghcr.io/sdr-enthusiasts/docker-baseimage:base AS build RUN set -x && \ apt-get update -y && \ - apt-get install -q -o Dpkg::Options::="--force-confnew" -y \ + apt-get install -q -o Dpkg::Options::="--force-confnew" -y --no-install-recommends \ git gcc && \ cd / && \ git clone --depth=1 --single-branch https://github.com/sdr-enthusiasts/docker-vesselalert.git && \ cd /docker-vesselalert/src && \ + # make the output in meters instead of nautical miles: + sed -i 's|/ 1852.0||g' distance.c && \ gcc -static distance.c -o distance -lm -Ofast FROM ghcr.io/sdr-enthusiasts/docker-tar1090:latest From 9a99ca9118277903b84e036507e28ddcdc7dfd6f Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 18:21:21 -0400 Subject: [PATCH 09/20] add local version of distance.c --- Dockerfile | 7 ++--- downloads/distance.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 downloads/distance.c diff --git a/Dockerfile b/Dockerfile index beb9c3d..cb65887 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,13 +2,10 @@ FROM ghcr.io/sdr-enthusiasts/docker-baseimage:base AS build RUN set -x && \ apt-get update -y && \ - apt-get install -q -o Dpkg::Options::="--force-confnew" -y --no-install-recommends \ + apt-get install -q -o Dpkg::Options::="--force-confnew" -y \ git gcc && \ cd / && \ - git clone --depth=1 --single-branch https://github.com/sdr-enthusiasts/docker-vesselalert.git && \ - cd /docker-vesselalert/src && \ - # make the output in meters instead of nautical miles: - sed -i 's|/ 1852.0||g' distance.c && \ + curl -sSL https://raw.githubusercontent.com/sdr-enthusiasts/docker-adsb-ultrafeeder/main/downloads/distance.c -o /distance.c && \ gcc -static distance.c -o distance -lm -Ofast FROM ghcr.io/sdr-enthusiasts/docker-tar1090:latest diff --git a/downloads/distance.c b/downloads/distance.c new file mode 100644 index 0000000..d87c2da --- /dev/null +++ b/downloads/distance.c @@ -0,0 +1,69 @@ +/* +--------------------------------------------------------------------------------------------- +Copyright (C) 2002-2022, Chris Veness +Adaptations Copyright (C) 2023, John Norrbin (JohnEx) +Adaptations (C) 2023, Ramon F. Kolb (kx1t) + +MIT License: + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------------------------------------------------------------------- +*/ +#include +#include +#include + +#define PI 3.14159265 + +// https://www.movable-type.co.uk/scripts/latlong.html +double distance(double lat_a, double lon_a, double lat_b, double lon_b) +{ + + double lat_a_scaled = lat_a * (double)PI / 180.0; + double lat_b_scaled = lat_b * (double)PI / 180.0; + double lat_delta = (lat_b - lat_a) * (double)PI / 180.0; + double lon_delta = (lon_b - lon_a) * (double)PI / 180.0; + + double a = sin(lat_delta / 2.0) * sin(lat_delta / 2.0) + cos(lat_a_scaled) * cos(lat_b_scaled) * sin(lon_delta / 2.0) * sin(lon_delta / 2.0); + double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a)); + + return 6372797.56085 * c; +} + + +int main(int argc, char *argv[]) +{ + if (argc != 5) + { + printf("Usage: distance lat1 lon1 lat2 lon2\n"); + return 1; + } + + double lat1 = atof(argv[1]); + double lon1 = atof(argv[2]); + double lat2 = atof(argv[3]); + double lon2 = atof(argv[4]); + + double d = distance(lat1, lon1, lat2, lon2); + printf("%f\n", d); + return 0; +} From 91cef40cb8876b1a5f9b90d5af7f9f8c8b7221d7 Mon Sep 17 00:00:00 2001 From: kx1t Date: Thu, 23 May 2024 18:28:10 -0400 Subject: [PATCH 10/20] build fix --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index cb65887..0f4fdcd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM ghcr.io/sdr-enthusiasts/docker-baseimage:base AS build RUN set -x && \ apt-get update -y && \ apt-get install -q -o Dpkg::Options::="--force-confnew" -y \ - git gcc && \ + gcc && \ cd / && \ curl -sSL https://raw.githubusercontent.com/sdr-enthusiasts/docker-adsb-ultrafeeder/main/downloads/distance.c -o /distance.c && \ gcc -static distance.c -o distance -lm -Ofast @@ -68,7 +68,7 @@ RUN TEMP_PACKAGES=() && \ echo "alias nano=\"nano -l\"" >> /root/.bashrc COPY rootfs/ / -COPY --from=build /docker-vesselalert/src/distance /usr/local/bin/distance +COPY --from=build /distance /usr/local/bin/distance # Add Container Version RUN set -x && \ From b0fadb8682ef8ce7be3b49df14aae88722c96fb5 Mon Sep 17 00:00:00 2001 From: kx1t Date: Fri, 24 May 2024 09:29:36 -0400 Subject: [PATCH 11/20] fix issue --- rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart index bd815ef..2e8888f 100755 --- a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart +++ b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart @@ -19,18 +19,17 @@ source /scripts/common -# Check every 60 secs if GPSD has been enabled -if [[ ! -f /run/readsb/gpsd.json ]] || [[ "$(jq -r .lat /run/readsb/gpsd.json)" == "null" ]]; then - sleep 60 & wait $! -fi - -# Then wait until all mlat-client instances have started +# Wait until all mlat-client instances have started while [[ ! -f /run/.all_mlatclient_instances_have_started ]]; do sleep 5 & wait $! done - rm -f /run/.all_mlatclient_instances_have_started +# Check every 60 secs if GPSD has been enabled +while [[ ! -f /run/readsb/gpsd.json ]] || [[ "$(jq -r .lat /run/readsb/gpsd.json)" == "null" ]]; do + sleep 60 & wait $! +done + # Now wait a bit to allow GPS to establish itself sleep "${GPSD_INITIAL_WAIT:-60}" From a0360d933bf5f2ed1a600e5f9b3f836a3516dbbb Mon Sep 17 00:00:00 2001 From: kx1t Date: Fri, 24 May 2024 09:35:54 -0400 Subject: [PATCH 12/20] updates --- .hadolint.yaml | 1 + Dockerfile | 4 +-- downloads/distance.c | 69 -------------------------------------------- 3 files changed, 3 insertions(+), 71 deletions(-) delete mode 100644 downloads/distance.c diff --git a/.hadolint.yaml b/.hadolint.yaml index 0306774..5bdcc7b 100644 --- a/.hadolint.yaml +++ b/.hadolint.yaml @@ -4,3 +4,4 @@ ignored: - DL3008 - SC3054 - SC3044 + - DL3015 diff --git a/Dockerfile b/Dockerfile index 0f4fdcd..52cc723 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,8 +5,8 @@ RUN set -x && \ apt-get install -q -o Dpkg::Options::="--force-confnew" -y \ gcc && \ cd / && \ - curl -sSL https://raw.githubusercontent.com/sdr-enthusiasts/docker-adsb-ultrafeeder/main/downloads/distance.c -o /distance.c && \ - gcc -static distance.c -o distance -lm -Ofast + curl -sSL https://raw.githubusercontent.com/sdr-enthusiasts/docker-adsb-ultrafeeder/main/downloads/distance-in-meters.c -o /distance-in-meters.c && \ + gcc -static distance-in-meters.c -o distance -lm -Ofast FROM ghcr.io/sdr-enthusiasts/docker-tar1090:latest diff --git a/downloads/distance.c b/downloads/distance.c deleted file mode 100644 index d87c2da..0000000 --- a/downloads/distance.c +++ /dev/null @@ -1,69 +0,0 @@ -/* ---------------------------------------------------------------------------------------------- -Copyright (C) 2002-2022, Chris Veness -Adaptations Copyright (C) 2023, John Norrbin (JohnEx) -Adaptations (C) 2023, Ramon F. Kolb (kx1t) - -MIT License: - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------------------------- -*/ -#include -#include -#include - -#define PI 3.14159265 - -// https://www.movable-type.co.uk/scripts/latlong.html -double distance(double lat_a, double lon_a, double lat_b, double lon_b) -{ - - double lat_a_scaled = lat_a * (double)PI / 180.0; - double lat_b_scaled = lat_b * (double)PI / 180.0; - double lat_delta = (lat_b - lat_a) * (double)PI / 180.0; - double lon_delta = (lon_b - lon_a) * (double)PI / 180.0; - - double a = sin(lat_delta / 2.0) * sin(lat_delta / 2.0) + cos(lat_a_scaled) * cos(lat_b_scaled) * sin(lon_delta / 2.0) * sin(lon_delta / 2.0); - double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a)); - - return 6372797.56085 * c; -} - - -int main(int argc, char *argv[]) -{ - if (argc != 5) - { - printf("Usage: distance lat1 lon1 lat2 lon2\n"); - return 1; - } - - double lat1 = atof(argv[1]); - double lon1 = atof(argv[2]); - double lat2 = atof(argv[3]); - double lon2 = atof(argv[4]); - - double d = distance(lat1, lon1, lat2, lon2); - printf("%f\n", d); - return 0; -} From c03cbdd73b5326d245c605f1c9dc24e196e8fac6 Mon Sep 17 00:00:00 2001 From: kx1t Date: Fri, 24 May 2024 10:59:03 -0400 Subject: [PATCH 13/20] add `gpsd` directive to the `ULTRAFEEDER-CONFIG` param; update documentation --- README.md | 61 +++++++++++++++++++++ rootfs/scripts/interpret_ultrafeeder_config | 9 +++ 2 files changed, 70 insertions(+) diff --git a/README.md b/README.md index bfc00f8..a53c174 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,9 @@ - [Configuring the Core Temperature graphs](#configuring-the-core-temperature-graphs) - [Reducing Disk IO for Graphs1090](#reducing-disk-io-for-graphs1090) - [`timelapse1090` Configuration](#timelapse1090-configuration) + - [Updating your location with GPSD](#updating-your-location-with-gpsd) + - [Basic Installation and Configuration of your GPS hardware and `gpsd` drivers](#basic-installation-and-configuration-of-your-gps-hardware-and-gpsd-drivers) + - [Optional parameters regulating the restart of `mlat-client` when the location changes](#optional-parameters-regulating-the-restart-of-mlat-client-when-the-location-changes) - [Web Pages](#web-pages) - [Paths](#paths) - [Display of Metrix with Grafana and Prometheus/InfluxDB](#display-of-metrix-with-grafana-and-prometheusinfluxdb) @@ -728,6 +731,64 @@ Legacy: **We recommend AGAINST enabling this feature** as it has been replaced w | `TIMELAPSE1090_INTERVAL` | Snapshot interval in seconds | `10` | | `TIMELAPSE1090_HISTORY` | Time saved in hours | `24` | +## Updating your location with GPSD + +This feature enables you to deploy Ultrafeeder while you are moving around. It will read your current longitude/latitude/altitude from a GPS unit that is connected to `gpsd` on your host system, and ensure that the map will show your current location. It will also restart any `mlat-client` instances once it detects that you moved from your previous location. + +### Basic Installation and Configuration of your GPS hardware and `gpsd` drivers + +The simplest way of getting this to work is to acquire a ["VK163" USB GPS "Mouse"](https://a.co/d/0D7Tj0n), similar to the one in the link. You can connect this mouse to any USB port on your machine. + +For this to work, you should install and configure GPSD to work on your host machine. The `DEVICES` parameter is probably correct as shown below, but you may want to double-check that data is received on that device (`cat /dev/ttyACM0`) and adjust it if needed: + +```bash +sudo apt update && sudo apt install -y gpsd +cat < EOM | sudo tee /etc/default/gpsd +# Devices gpsd should collect to at boot time. +# They need to be read/writeable, either by user gpsd or the group dialout. +DEVICES="/dev/ttyACM0" +# Other options you want to pass to gpsd +GPSD_OPTIONS="-G" +# Automatically hot add/remove USB GPS devices via gpsdctl +USBAUTO="true" +EOM +sudo systemctl restart gpsd +``` + +Then, you can add the following values to `ultrafeeder` service settings in `docker-compose.yml`: + +```yaml +services: +... + ultrafeeder: + ... + extra_hosts: + - "host.docker.internal:host-gateway" + ... + environment: + ULTRAFEEDER-CONFIG= + gpsd,host.docker.internal,2947; + ... +``` + +Finally, restart the container with `docker compose up -d` + +This will: + +- install and configure `gpsd` (`/etc/default/gpsd`) so it makes GPS data available on the default TCP port 2947 of your host system +- configure the ultrafeeder docker container to read GPSD data +- configure the ultrafeeder container so the hostname `host.docker.internal` always resolves to the IP address of the underlying machine (where `gpsd` is running) + +### Optional parameters regulating the restart of `mlat-client` when the location changes + +The following parameters are all optional. You don't need to set them unless you want to change the default behavior: + +| Environment Variable | Purpose | Default | +| -------------------- | ------- | ------- | +| `GPSD_INITIAL_WAIT` | The initial wait period (in seconds) for the GPS data to stabilize once the container detects that GPS data is being provided | `60` (seconds) | +| `GPSD_MIN_DISTANCE` | Distance (in meters) that your station must move before the `mlat-client`(s) are restarted with the new latitude/longitude/altitude | `20` (meters) | +| `GPSD_CHECK_INTERVAL` | How often the container checks for updated location information. Please don't make this shorter than 30 seconds to avoid race conditions, which may cause mlat-client to stop feeding some of the aggregators | `30` (seconds) | + ## Web Pages If you have configured the container as described above, you should be able to browse to the following web pages: diff --git a/rootfs/scripts/interpret_ultrafeeder_config b/rootfs/scripts/interpret_ultrafeeder_config index 811783d..ce70123 100755 --- a/rootfs/scripts/interpret_ultrafeeder_config +++ b/rootfs/scripts/interpret_ultrafeeder_config @@ -123,6 +123,15 @@ do MLATHUB_CONF_ARR+=("--net-connector=${mlathub_str}") ;; + gpsd) + # add gpsd_in parameter to $READSB_CONF_ARR + readsb_str="${param[1]},${param[2]}" + if [[ -n "${param[3]}" ]] && [[ -n "${param[4]}" ]]; then + readsb_str="$readsb_str,${param[3]},${param[4]}" + fi + READSB_CONF_ARR+=("--net-connector=${readsb_str},gpsd_in") + ;; + *) # Check if there's anything in ${ULTRAFEEDER_NET_CONNECTOR} -- if not, it's a bad config element. If yes, add it as if it were ADSB if [[ -z "${ULTRAFEEDER_NET_CONNECTOR}" ]]; then From 04e7707600b12257ed22802f1c6ea213304467d3 Mon Sep 17 00:00:00 2001 From: kx1t Date: Fri, 24 May 2024 11:14:33 -0400 Subject: [PATCH 14/20] make GPS-related restarts faster --- rootfs/etc/s6-overlay/scripts/mlat-client | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rootfs/etc/s6-overlay/scripts/mlat-client b/rootfs/etc/s6-overlay/scripts/mlat-client index 5763e20..1b4b478 100755 --- a/rootfs/etc/s6-overlay/scripts/mlat-client +++ b/rootfs/etc/s6-overlay/scripts/mlat-client @@ -265,7 +265,10 @@ do if ! kill -0 "${mlat_pid}" >/dev/null 2>&1 then # it exited - let's restart: - sleep "${RESTARTTIMER}" & wait $! + if [[ ! -f /run/readsb/gpsd.json ]] || [[ "$(jq -r .lat /run/readsb/gpsd.json)" == "null" ]]; then + # only sleep for a bit if the restarts aren't caused by GPS movement: + sleep "${RESTARTTIMER}" & wait $! + fi servername="$(awk '{print $4}' <<< "${pid_array[$mlat_pid]}")" servername="${servername%%:*}" @@ -287,6 +290,7 @@ do #shellcheck disable=SC2069,SC2086 if [[ "${LOGLEVEL}" == "verbose" ]]; then + "${s6wrap[@]}" --prepend="$(basename "$0")][${servername}" --args echo "Restarting: ${execstring}" "${s6wrap[@]}" --prepend="$(basename "$0")][${servername}" --args ${execstring} & elif [[ "${LOGLEVEL}" == "error" ]]; then "${s6wrap[@]}" --ignore=stdout --prepend="$(basename "$0")][${servername}" --args ${execstring} & From e1280accdd5d4b47674eb20213005b1c325fec16 Mon Sep 17 00:00:00 2001 From: Matthias Wirth Date: Sun, 26 May 2024 20:40:46 +0200 Subject: [PATCH 15/20] move gpsd_mlat_restart into mlat-client scripting add some wait time for receiver to be stationary --- .../gpsd_mlat_restart/dependencies.d/startup | 0 .../s6-overlay/s6-rc.d/gpsd_mlat_restart/run | 2 - .../s6-overlay/s6-rc.d/gpsd_mlat_restart/type | 1 - .../s6-rc.d/user/contents.d/gpsd_mlat_restart | 0 .../etc/s6-overlay/scripts/gpsd_mlat_restart | 54 ------- rootfs/etc/s6-overlay/scripts/mlat-client | 139 ++++++++++++------ rootfs/etc/s6-overlay/scripts/readsb | 8 + 7 files changed, 106 insertions(+), 98 deletions(-) delete mode 100644 rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/dependencies.d/startup delete mode 100755 rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/run delete mode 100644 rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/type delete mode 100644 rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/gpsd_mlat_restart delete mode 100755 rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart diff --git a/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/dependencies.d/startup b/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/dependencies.d/startup deleted file mode 100644 index e69de29..0000000 diff --git a/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/run b/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/run deleted file mode 100755 index 8fefd29..0000000 --- a/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/run +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec /etc/s6-overlay/scripts/gpsd_mlat_restart diff --git a/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/type b/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/type deleted file mode 100644 index 5883cff..0000000 --- a/rootfs/etc/s6-overlay/s6-rc.d/gpsd_mlat_restart/type +++ /dev/null @@ -1 +0,0 @@ -longrun diff --git a/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/gpsd_mlat_restart b/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/gpsd_mlat_restart deleted file mode 100644 index e69de29..0000000 diff --git a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart b/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart deleted file mode 100755 index 2e8888f..0000000 --- a/rootfs/etc/s6-overlay/scripts/gpsd_mlat_restart +++ /dev/null @@ -1,54 +0,0 @@ -#!/command/with-contenv bash -# shellcheck shell=bash disable=SC2015,SC2016,SC1091,SC2001,SC2154 - -#--------------------------------------------------------------------------------------------- -# Copyright (C) 2023-2024, Ramon F. Kolb (kx1t) and contributors -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along with this program. -# If not, see . -#--------------------------------------------------------------------------------------------- - -source /scripts/common - -# Wait until all mlat-client instances have started -while [[ ! -f /run/.all_mlatclient_instances_have_started ]]; do - sleep 5 & wait $! -done -rm -f /run/.all_mlatclient_instances_have_started - -# Check every 60 secs if GPSD has been enabled -while [[ ! -f /run/readsb/gpsd.json ]] || [[ "$(jq -r .lat /run/readsb/gpsd.json)" == "null" ]]; do - sleep 60 & wait $! -done - -# Now wait a bit to allow GPS to establish itself -sleep "${GPSD_INITIAL_WAIT:-60}" - -# Get initial lat/lon/alt -lat="${LAT:-${READSB_LAT:-$(jq -r .lat /run/readsb/gpsd.json)}}" -lon="${LONG:-${READSB_LON:-$(jq -r .lon /run/readsb/gpsd.json)}}" - -"${s6wrap[@]}" echo "GPSD is active. Your mlat-client(s) will restart with new coordinates if you move more than ${GPSD_MIN_DISTANCE:-20} meters" - -while :; do - new_lat="$(jq -r .lat /run/readsb/gpsd.json)" - new_lon="$(jq -r .lon /run/readsb/gpsd.json)" - distance="$(nice -n 20 distance "$lat" "$lon" "$new_lat" "$new_lon")" - if (( ${distance%%.*} > ${GPSD_MIN_DISTANCE:-20} )); then - "${s6wrap[@]}" echo "Receiver moved ${distance%%.*} meters - restarting all mlat-clients" - # kill the mlat-client instances so they get restarted with the new GPS coords - pkill -f "/usr/bin/python3 /usr/bin/mlat-client" >/dev/null 2>&1 - lat="$new_lat" - lon="$new_lon" - fi - sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! -done \ No newline at end of file diff --git a/rootfs/etc/s6-overlay/scripts/mlat-client b/rootfs/etc/s6-overlay/scripts/mlat-client index 1b4b478..c5788bc 100755 --- a/rootfs/etc/s6-overlay/scripts/mlat-client +++ b/rootfs/etc/s6-overlay/scripts/mlat-client @@ -51,18 +51,67 @@ then exec sleep infinity fi -if [[ -z "$LAT$READSB_LAT" ]] && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_CONFIG" && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then - "${s6wrap[@]}" --args echo "ERROR: READSB_LAT or LAT must be defined or GPSD must be enabled - MLAT will be disabled." - exec sleep infinity -fi +function check_gpsd() { + if [[ -z "$GPSD" ]] || ! [[ -f /run/readsb/gpsd.json ]]; then + return 1 + fi + if new_lat="$(jq -r .lat /run/readsb/gpsd.json)" \ + && [[ "$new_lat" != "null" ]] \ + && new_lon="$(jq -r .lon /run/readsb/gpsd.json)" \ + && [[ "$new_lon" != "null" ]] \ + && new_alt="$(jq -r .altMSL /run/readsb/gpsd.json)" \ + && [[ "$new_alt" != "null" ]] \ -if [[ -z "$LONG$READSB_LON" ]] && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_CONFIG" && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then - "${s6wrap[@]}" --args echo "ERROR: READSB_LON or LONG must be defined or GPSD must be enabled - MLAT will be disabled." - exec sleep infinity -fi -if [[ -z "$ALT$READSB_ALT" ]] && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_CONFIG" && ! grep -qi "gpsd_in" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then - "${s6wrap[@]}" --args echo "ERROR: READSB_ALT or ALT must be defined or GPSD must be enabled - MLAT will be disabled." - exec sleep infinity + then + # yay, vars are set and not null + if ! [[ -f "$LOCATION_PERSIST" ]]; then + echo "$new_lat" "$new_lon" "$new_alt" > "$LOCATION_PERSIST" + fi + return 0 + else + new_lat="" + new_lon="" + new_alt="" + return 1 + fi +} + +if grep -qs "gpsd" <<< "$ULTRAFEEDER_CONFIG" || grep -qs "gpsd" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then + GPSD=1 + LOCATION_PERSIST=/var/globe_history/gpsd_last_location + if [[ -f "$LOCATION_PERSIST" ]] && { grep -qs "gpsd" <<< "$ULTRAFEEDER_CONFIG" || grep -qs "gpsd" <<< "$ULTRAFEEDER_NET_CONNECTOR"; }; then + read new_lat new_lon new_alt < "$LOCATION_PERSIST" + "${s6wrap[@]}" --args echo "Using last known GPSD location for startup: $new_lat,$new_lon (alt: $new_alt)" + else + # wait for gpsd to continue with startup + "${s6wrap[@]}" --args echo "GPSD configured, no location set, no persistent location found, waiting for gpsd to provide location data" + while ! check_gpsd; do + sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! + done + "${s6wrap[@]}" --args echo "GPSD has provided location data, starting mlat-clients" + fi + # initialize "old" location for gpsd movement detection + old_lat="$new_lat" + old_lon="$new_lon" + + # in seconds + no_movement_required=19 + # set no_movement to a number higher than the required time of no movement + # this way on startup there is no bogus message printed about starting mlat-clients with a new location + no_movement=$(( 2 * no_movement_required )) +else + if [[ -z "$LAT$READSB_LAT" ]]; then + "${s6wrap[@]}" --args echo "ERROR: READSB_LAT or LAT must be defined or GPSD must be enabled - MLAT will be disabled." + exec sleep infinity + fi + if [[ -z "$LONG$READSB_LON" ]]; then + "${s6wrap[@]}" --args echo "ERROR: READSB_LON or LONG must be defined or GPSD must be enabled - MLAT will be disabled." + exec sleep infinity + fi + if [[ -z "$ALT$READSB_ALT" ]]; then + "${s6wrap[@]}" --args echo "ERROR: READSB_ALT or ALT must be defined or GPSD must be enabled - MLAT will be disabled." + exec sleep infinity + fi fi # MLAT_CONFIG has the following format: @@ -176,20 +225,6 @@ do fi # add LAT/LON/ALT to instance: - # see if we need to use GPS coords: - unset new_lat - unset new_lon - unset new_alt - if [[ -f /run/.gpsd_is_active && -f /run/readsb/receiver.json ]]; then - new_lat="$(jq -r .lat /run/readsb/receiver.json)" - new_lon="$(jq -r .lon /run/readsb/receiver.json)" - new_alt="$(jq -r .alt_m_amsl /run/readsb/receiver.json)" - if [[ "$new_lat" == "null" ]] || [[ "$new_lon" == "null" ]] || [[ "$new_alt" == "null" ]]; then - unset new_lat - unset new_lon - unset new_alt - fi - fi if [[ -n "${new_lat:-$lat_arg}" ]]; then MLAT_PARAM+=(--lat "${new_lat:-$lat_arg}") @@ -255,11 +290,43 @@ do done sleep 5 & wait $! -touch /run/.all_mlatclient_instances_have_started # Now iterate over all MLAT-client instances and check if they are still running: while true do + if check_gpsd; then + distance="$(distance "$old_lat" "$old_lon" "$new_lat" "$new_lon")" + if (( ${distance%%.*} > ${GPSD_MIN_DISTANCE:-20} )); then + + # kill the mlat-client instances so they get restarted with the new GPS coords + if pkill -f "/usr/bin/python3 /usr/bin/mlat-client" >/dev/null 2>&1; then + "${s6wrap[@]}" --args echo "Receiver moved ${distance%%.*} meters - Stopping all mlat-clients" + else + "${s6wrap[@]}" --args echo "Receiver moved ${distance%%.*} meters" + fi + + old_lat="$new_lat" + old_lon="$new_lon" + + # new location means the receiver has moved, sleep a bit and then check again + no_movement=0 + sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! + # as the recevier has moved, mlat-clients are not restarted until there has been no movement for some time + # thus we continue skipping the mlat-client restart section of the loop + continue + else + # no movement during the checking interval, allow mlat-clients to be restarted + (( no_movement += ${GPSD_CHECK_INTERVAL:-30} )) || true + if (( no_movement < no_movement_required )); then + sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! + continue + elif (( no_movement / ${GPSD_CHECK_INTERVAL:-30} == no_movement_required / ${GPSD_CHECK_INTERVAL:-30} )); then + "${s6wrap[@]}" --args echo "Receiver stationary - starting all mlat-clients with new location" + echo "$new_lat" "$new_lon" "$new_alt" > "$LOCATION_PERSIST" + fi + fi + fi + for mlat_pid in "${!pid_array[@]}" do if ! kill -0 "${mlat_pid}" >/dev/null 2>&1 @@ -277,15 +344,10 @@ do execstring="$(echo ${MLAT_CMD} ${pid_array[$mlat_pid]} | xargs)" # If GPSD is active, then replace the lat/lon/alt params with the ones from GPSD - if [[ -f /run/readsb/gpsd.json ]] && [[ "$(jq -r .lat /run/readsb/gpsd.json)" != "null" ]]; then - new_lat="$(jq -r .lat /run/readsb/gpsd.json)" - new_lon="$(jq -r .lon /run/readsb/gpsd.json)" - new_alt="$(jq -r .altMSL /run/readsb/gpsd.json)" - if [[ "$new_lat" != "null" ]] && [[ "$new_lon" != "null" ]] && [[ "$new_alt" != "null" ]]; then - execstring="$(sed "s/^\(.*\s\+--lat\s\+\)[0-9.-]\+\(.*\)$/\1${new_lat}\2/g" <<< "$execstring")" - execstring="$(sed "s/^\(.*\s\+--lon\s\+\)[0-9.-]\+\(.*\)$/\1${new_lon}\2/g" <<< "$execstring")" - execstring="$(sed "s/^\(.*\s\+--alt\s\+\)[mft0-9.-]\+\(.*\)$/\1${new_alt}m\2/g" <<< "$execstring")" - fi + if [[ -n new_lat ]];then + execstring="$(sed "s/^\(.*\s\+--lat\s\+\)[0-9.-]\+\(.*\)$/\1${new_lat}\2/g" <<< "$execstring")" + execstring="$(sed "s/^\(.*\s\+--lon\s\+\)[0-9.-]\+\(.*\)$/\1${new_lon}\2/g" <<< "$execstring")" + execstring="$(sed "s/^\(.*\s\+--alt\s\+\)[mft0-9.-]\+\(.*\)$/\1${new_alt}m\2/g" <<< "$execstring")" fi #shellcheck disable=SC2069,SC2086 @@ -303,10 +365,5 @@ do fi done - # If GPSD is running, do more frequent checks than if it's not running - if [[ -f /run/readsb/gpsd.json ]] && [[ "$(jq -r .lat /run/readsb/gpsd.json)" != "null" ]]; then - sleep 1 & wait $! - else - sleep 10 & wait $! - fi + sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! done diff --git a/rootfs/etc/s6-overlay/scripts/readsb b/rootfs/etc/s6-overlay/scripts/readsb index 5c1841c..8536ea6 100755 --- a/rootfs/etc/s6-overlay/scripts/readsb +++ b/rootfs/etc/s6-overlay/scripts/readsb @@ -31,6 +31,14 @@ if ! [[ "$LOGLEVEL" =~ ^(verbose|error|none)$ ]]; then LOGLEVEL="verbose" fi +LOCATION_PERSIST=/var/globe_history/gpsd_last_location +if [[ -f "$LOCATION_PERSIST" ]] && { grep -qs "gpsd" <<< "$ULTRAFEEDER_CONFIG" || grep -qs "gpsd" <<< "$ULTRAFEEDER_NET_CONNECTOR"; }; then + read LAT LON ALT < "$LOCATION_PERSIST" + READSB_LAT="" + READSB_LON="" + READSB_ALT="" +fi + # Build the readsb command line based on options READSB_BIN="/usr/local/bin/readsb" From 342d3fcd75c8b9bb87f6a8510330643447d49dbc Mon Sep 17 00:00:00 2001 From: Matthias Wirth Date: Sun, 26 May 2024 23:26:12 +0200 Subject: [PATCH 16/20] no_movement_required default / ensure > check interval --- rootfs/etc/s6-overlay/scripts/mlat-client | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rootfs/etc/s6-overlay/scripts/mlat-client b/rootfs/etc/s6-overlay/scripts/mlat-client index c5788bc..b299078 100755 --- a/rootfs/etc/s6-overlay/scripts/mlat-client +++ b/rootfs/etc/s6-overlay/scripts/mlat-client @@ -95,7 +95,10 @@ if grep -qs "gpsd" <<< "$ULTRAFEEDER_CONFIG" || grep -qs "gpsd" <<< "$ULTRAFEEDE old_lon="$new_lon" # in seconds - no_movement_required=19 + no_movement_required=90 + if (( no_movement_required < "${GPSD_CHECK_INTERVAL:-30}" )); then + no_movement_required="${GPSD_CHECK_INTERVAL:-30}" + fi # set no_movement to a number higher than the required time of no movement # this way on startup there is no bogus message printed about starting mlat-clients with a new location no_movement=$(( 2 * no_movement_required )) From 04a95b7c5ea5fa2c8328e082f9c2c173499e9b3a Mon Sep 17 00:00:00 2001 From: Matthias Wirth Date: Fri, 7 Jun 2024 16:00:27 +0200 Subject: [PATCH 17/20] Dockerfile: move where distance binary is built --- Dockerfile | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 52cc723..4a3aa6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,3 @@ -FROM ghcr.io/sdr-enthusiasts/docker-baseimage:base AS build - -RUN set -x && \ - apt-get update -y && \ - apt-get install -q -o Dpkg::Options::="--force-confnew" -y \ - gcc && \ - cd / && \ - curl -sSL https://raw.githubusercontent.com/sdr-enthusiasts/docker-adsb-ultrafeeder/main/downloads/distance-in-meters.c -o /distance-in-meters.c && \ - gcc -static distance-in-meters.c -o distance -lm -Ofast - FROM ghcr.io/sdr-enthusiasts/docker-tar1090:latest LABEL org.opencontainers.image.source = "https://github.com/sdr-enthusiasts/docker-adsb-ultrafeeder" @@ -53,6 +43,10 @@ RUN TEMP_PACKAGES=() && \ ln -s /usr/local/bin/mlat-client /usr/bin/mlat-client && \ popd && \ rm -rf /git && \ + # Compile distance binary + curl -sSL https://raw.githubusercontent.com/sdr-enthusiasts/docker-adsb-ultrafeeder/main/downloads/distance-in-meters.c -o /distance-in-meters.c && \ + gcc -static /distance-in-meters.c -o /usr/local/bin/distance -lm -Ofast && \ + rm -f /distance-in-meters.c && \ # # Clean up and install POST_PACKAGES: apt-get remove -q -y "${TEMP_PACKAGES[@]}" && \ @@ -68,7 +62,6 @@ RUN TEMP_PACKAGES=() && \ echo "alias nano=\"nano -l\"" >> /root/.bashrc COPY rootfs/ / -COPY --from=build /distance /usr/local/bin/distance # Add Container Version RUN set -x && \ From 6378d30318d3af2c498ceff70560e880687dc1b5 Mon Sep 17 00:00:00 2001 From: Matthias Wirth Date: Fri, 7 Jun 2024 18:16:19 +0200 Subject: [PATCH 18/20] update readme for gpsd mlat related vars enforce limits for gpsd mlat related vars add readme to change gpsd.socket --- README.md | 25 +++++++++++++---- rootfs/etc/s6-overlay/scripts/mlat-client | 33 +++++++++++++++++------ 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a53c174..5273cfc 100644 --- a/README.md +++ b/README.md @@ -752,7 +752,22 @@ GPSD_OPTIONS="-G" # Automatically hot add/remove USB GPS devices via gpsdctl USBAUTO="true" EOM -sudo systemctl restart gpsd +cat < EOM | sudo tee /lib/systemd/system/gpsd.socket +[Unit] +Description=GPS (Global Positioning System) Daemon Sockets + +[Socket] +ListenStream=/run/gpsd.sock +ListenStream=[::]:2947 +ListenStream=0.0.0.0:2947 +SocketMode=0600 +BindIPv6Only=yes + +[Install] +WantedBy=sockets.target +EOM +sudo systemctl daemon-reload +sudo systemctl restart gpsd gpsd.socket ``` Then, you can add the following values to `ultrafeeder` service settings in `docker-compose.yml`: @@ -781,13 +796,13 @@ This will: ### Optional parameters regulating the restart of `mlat-client` when the location changes -The following parameters are all optional. You don't need to set them unless you want to change the default behavior: +The following parameters are all optional and are subject to change. You don't need to set them unless you want to change the default behavior: | Environment Variable | Purpose | Default | | -------------------- | ------- | ------- | -| `GPSD_INITIAL_WAIT` | The initial wait period (in seconds) for the GPS data to stabilize once the container detects that GPS data is being provided | `60` (seconds) | -| `GPSD_MIN_DISTANCE` | Distance (in meters) that your station must move before the `mlat-client`(s) are restarted with the new latitude/longitude/altitude | `20` (meters) | -| `GPSD_CHECK_INTERVAL` | How often the container checks for updated location information. Please don't make this shorter than 30 seconds to avoid race conditions, which may cause mlat-client to stop feeding some of the aggregators | `30` (seconds) | +| `GPSD_MIN_DISTANCE` | Distance (in meters) that your station must move before it's considered moving (maximum 40 meters) | `20` (meters) | +| `GPSD_MLAT_WAIT` | The wait period (in seconds) your station must be stationary before mlat is started (minimum 90 seconds) | `90` (seconds) | +| `GPSD_CHECK_INTERVAL` | How often the container checks for updated location information. (minimum 5 seconds) | `30` (seconds) | ## Web Pages diff --git a/rootfs/etc/s6-overlay/scripts/mlat-client b/rootfs/etc/s6-overlay/scripts/mlat-client index b299078..9ec731f 100755 --- a/rootfs/etc/s6-overlay/scripts/mlat-client +++ b/rootfs/etc/s6-overlay/scripts/mlat-client @@ -52,7 +52,7 @@ then fi function check_gpsd() { - if [[ -z "$GPSD" ]] || ! [[ -f /run/readsb/gpsd.json ]]; then + if (( GPSD == 0 )) || ! [[ -f /run/readsb/gpsd.json ]]; then return 1 fi if new_lat="$(jq -r .lat /run/readsb/gpsd.json)" \ @@ -64,9 +64,6 @@ function check_gpsd() { then # yay, vars are set and not null - if ! [[ -f "$LOCATION_PERSIST" ]]; then - echo "$new_lat" "$new_lon" "$new_alt" > "$LOCATION_PERSIST" - fi return 0 else new_lat="" @@ -76,6 +73,7 @@ function check_gpsd() { fi } +GPSD=0 if grep -qs "gpsd" <<< "$ULTRAFEEDER_CONFIG" || grep -qs "gpsd" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then GPSD=1 LOCATION_PERSIST=/var/globe_history/gpsd_last_location @@ -88,16 +86,32 @@ if grep -qs "gpsd" <<< "$ULTRAFEEDER_CONFIG" || grep -qs "gpsd" <<< "$ULTRAFEEDE while ! check_gpsd; do sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! done - "${s6wrap[@]}" --args echo "GPSD has provided location data, starting mlat-clients" + "${s6wrap[@]}" --args echo "GPSD has provided location data" fi # initialize "old" location for gpsd movement detection old_lat="$new_lat" old_lon="$new_lon" + GPSD_MIN_DISTANCE="${GPSD_MIN_DISTANCE:-20}" + # enforce gpsd min distance is no larger than 40m + if (( GPSD_MIN_DISTANCE > 40 )); then + GPSD_MIN_DISTANCE=40 + fi + + GPSD_CHECK_INTERVAL="${GPSD_CHECK_INTERVAL:-30}" + if (( GPSD_CHECK_INTERVAL < 5 )); then + GPSD_CHECK_INTERVAL=5 + fi + # in seconds - no_movement_required=90 - if (( no_movement_required < "${GPSD_CHECK_INTERVAL:-30}" )); then - no_movement_required="${GPSD_CHECK_INTERVAL:-30}" + no_movement_required=${GPSD_MLAT_WAIT:-90} + # enforce it to be longer than the checking interval for implementation reasons + if (( no_movement_required < GPSD_CHECK_INTERVAL )); then + no_movement_required="${GPSD_CHECK_INTERVAL}" + fi + # enforce 90 second minimum + if (( no_movement_required < 90 )); then + no_movement_required=90 fi # set no_movement to a number higher than the required time of no movement # this way on startup there is no bogus message printed about starting mlat-clients with a new location @@ -299,6 +313,9 @@ while true do if check_gpsd; then distance="$(distance "$old_lat" "$old_lon" "$new_lat" "$new_lon")" + if ! [[ -f "$LOCATION_PERSIST" ]]; then + echo "$new_lat" "$new_lon" "$new_alt" > "$LOCATION_PERSIST" + fi if (( ${distance%%.*} > ${GPSD_MIN_DISTANCE:-20} )); then # kill the mlat-client instances so they get restarted with the new GPS coords From 372600dfb5a1e92fa5e586562fdef39a0b29552f Mon Sep 17 00:00:00 2001 From: Matthias Wirth Date: Fri, 7 Jun 2024 18:30:25 +0200 Subject: [PATCH 19/20] fix mlat-client auto restart when gpsd inactive --- rootfs/etc/s6-overlay/scripts/mlat-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootfs/etc/s6-overlay/scripts/mlat-client b/rootfs/etc/s6-overlay/scripts/mlat-client index 9ec731f..b13fc82 100755 --- a/rootfs/etc/s6-overlay/scripts/mlat-client +++ b/rootfs/etc/s6-overlay/scripts/mlat-client @@ -364,7 +364,7 @@ do execstring="$(echo ${MLAT_CMD} ${pid_array[$mlat_pid]} | xargs)" # If GPSD is active, then replace the lat/lon/alt params with the ones from GPSD - if [[ -n new_lat ]];then + if (( GPSD == 1 )); then execstring="$(sed "s/^\(.*\s\+--lat\s\+\)[0-9.-]\+\(.*\)$/\1${new_lat}\2/g" <<< "$execstring")" execstring="$(sed "s/^\(.*\s\+--lon\s\+\)[0-9.-]\+\(.*\)$/\1${new_lon}\2/g" <<< "$execstring")" execstring="$(sed "s/^\(.*\s\+--alt\s\+\)[mft0-9.-]\+\(.*\)$/\1${new_alt}m\2/g" <<< "$execstring")" From 0b10463093b12e590652612003ccf1cceea1d694 Mon Sep 17 00:00:00 2001 From: Matthias Wirth Date: Fri, 7 Jun 2024 19:28:16 +0200 Subject: [PATCH 20/20] don't immediately start mlat clients when GPSD is configured --- rootfs/etc/s6-overlay/scripts/mlat-client | 46 +++++++++++++++-------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/rootfs/etc/s6-overlay/scripts/mlat-client b/rootfs/etc/s6-overlay/scripts/mlat-client index b13fc82..09eb8ae 100755 --- a/rootfs/etc/s6-overlay/scripts/mlat-client +++ b/rootfs/etc/s6-overlay/scripts/mlat-client @@ -77,20 +77,20 @@ GPSD=0 if grep -qs "gpsd" <<< "$ULTRAFEEDER_CONFIG" || grep -qs "gpsd" <<< "$ULTRAFEEDER_NET_CONNECTOR"; then GPSD=1 LOCATION_PERSIST=/var/globe_history/gpsd_last_location - if [[ -f "$LOCATION_PERSIST" ]] && { grep -qs "gpsd" <<< "$ULTRAFEEDER_CONFIG" || grep -qs "gpsd" <<< "$ULTRAFEEDER_NET_CONNECTOR"; }; then + if [[ -f "$LOCATION_PERSIST" ]]; then read new_lat new_lon new_alt < "$LOCATION_PERSIST" - "${s6wrap[@]}" --args echo "Using last known GPSD location for startup: $new_lat,$new_lon (alt: $new_alt)" - else - # wait for gpsd to continue with startup - "${s6wrap[@]}" --args echo "GPSD configured, no location set, no persistent location found, waiting for gpsd to provide location data" - while ! check_gpsd; do - sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! - done - "${s6wrap[@]}" --args echo "GPSD has provided location data" fi # initialize "old" location for gpsd movement detection - old_lat="$new_lat" - old_lon="$new_lon" + # use zero island as starting point if location persist does not exit + old_lat=${new_lat:-0} + old_lon=${new_lon:-0} + + # wait for gpsd to continue with startup + "${s6wrap[@]}" --args echo "GPSD configured, waiting for gpsd to provide location data" + while ! check_gpsd; do + sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! + done + "${s6wrap[@]}" --args echo "GPSD has provided location data" GPSD_MIN_DISTANCE="${GPSD_MIN_DISTANCE:-20}" # enforce gpsd min distance is no larger than 40m @@ -284,6 +284,12 @@ do # shellcheck disable=SC2048,SC2086 execstring="$(echo ${MLAT_CMD} ${MLAT_PARAM[*]} | xargs)" + if (( GPSD == 1 )); then + # when GPSD is active, just write the pid array, mlat-client will be started by the gpsd checking logic later + # use a long random PID so that it's detected as "not running" + pid_array["${RANDOM}${RANDOM}${RANDOM}"]="${MLAT_PARAM[*]}" + continue + fi # stagger by 15 second so they don't all start at the same time sleep "${MLAT_STARTUP_STAGGER:-15}" & wait $! @@ -311,20 +317,28 @@ sleep 5 & wait $! # Now iterate over all MLAT-client instances and check if they are still running: while true do - if check_gpsd; then + if (( GPSD == 1 )); then + if ! check_gpsd; then + # don't do mlat client restarts if GPSD is configured but not providing a position + sleep "${GPSD_CHECK_INTERVAL}" & wait $! + continue + fi + distance="$(distance "$old_lat" "$old_lon" "$new_lat" "$new_lon")" if ! [[ -f "$LOCATION_PERSIST" ]]; then echo "$new_lat" "$new_lon" "$new_alt" > "$LOCATION_PERSIST" fi if (( ${distance%%.*} > ${GPSD_MIN_DISTANCE:-20} )); then + msg="Receiver moved ${distance%%.*} meters" + # kill the mlat-client instances so they get restarted with the new GPS coords if pkill -f "/usr/bin/python3 /usr/bin/mlat-client" >/dev/null 2>&1; then - "${s6wrap[@]}" --args echo "Receiver moved ${distance%%.*} meters - Stopping all mlat-clients" - else - "${s6wrap[@]}" --args echo "Receiver moved ${distance%%.*} meters" + msg+=" - Stopping all mlat-clients" fi + "${s6wrap[@]}" --args echo "${msg}" + old_lat="$new_lat" old_lon="$new_lon" @@ -338,6 +352,8 @@ do # no movement during the checking interval, allow mlat-clients to be restarted (( no_movement += ${GPSD_CHECK_INTERVAL:-30} )) || true if (( no_movement < no_movement_required )); then + msg="Receiver moved less than ${GPSD_MIN_DISTANCE} meters, $(( no_movement_required - no_movement )) seconds remaining before starting mlat-clients" + "${s6wrap[@]}" --args echo "${msg}" sleep "${GPSD_CHECK_INTERVAL:-30}" & wait $! continue elif (( no_movement / ${GPSD_CHECK_INTERVAL:-30} == no_movement_required / ${GPSD_CHECK_INTERVAL:-30} )); then