360Radar.co.uk is a browser-based ADS-B and MLAT aircraft tracking system.
I knocked together an initscript for Linux users which should work with most Debian-based Linux distros (inc. Raspbian on the Raspberry Pi).
This assumes you are running as a user with root-level permissions (if not, sudo is your friend), a level of familiarity with the Linux command line, permissions, etc.
Install mono
Follow the Install Mono instructions in the official 360Radar installation instructions:
http://radar.lowflyingwales.co.uk/360radar-adsb-uploader-instructions-raspberry-pi/
Create a new user to run the ADS-B uploader
Rather than run the uploader as an existing user (e.g. pi), we’ll create a new user to run it away from our normal login user.
I’m creating a new user called (rather unimaginatively) adsbfilter, with a home directory of /opt/adsbfilter.
useradd -m -g nogroup -d /opt/adsbfilter adsbfilter
Change to the new user and download the uploader
su – adsbfilter
Now we’re in the new user environment, we need to download the uploader. Back to the official installation instructions:
wget http://radar.lowflyingwales.co.uk/files/adsb/rpi/AdsbFilter-1.0.17.tgz
Extract the compressed tarball you download:
tar xzf AdsbFilter-1.0.17.tgz
This’ll create a new directory AdsbFilter containing the ADS-B uploader.
Create a wrapper script
We’ll use a wrapper script to restart the ADS-B uploader unless it’s stopped cleanly and deliberately. This will automatically restart it in the event of a segfault, which seems to happen from time to time with the nightly mono builds.
Create adsbfilter.sh in /opt/adsbfilter/AdsbFilter (or modify with your chosen path):
nano -w /opt/adsbfilter/AdsbFilter/adsbfilter.sh
#!/bin/bash
while :; do
/usr/bin/mono AdsbFilter.exe "$@"
result=$?
if [ $result -eq 58 ]; then
echo "adsbfilter terminated normally"
break
else
echo "adsbfilter terminated with return code: $result"
fi
sleep 5
echo "restarting adsbfilter..."
done
Set the executable bit on the wrapper and the program itself:
cd /opt/adsbfilter/AdsbFilter
chmod +x adsbfilter.sh AdsbFilter.exe
Now come out of our adsbfilter user environment:
exit
Create the initscript
We’ll create a standard Debian initscript in /etc/init.d/adsbfilter:
#!/bin/bash
### BEGIN INIT INFO
# Provides: adsbfilter
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: ADSB Filter
# Description: Sends ADS-B messages to 360radar.co.uk
### END INIT INFO
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="adsbfilter"
NAME=adsbfilter
DAEMON=/opt/adsbfilter/AdsbFilter/adsbfilter.sh
ARGS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# work out daemon args
# sanitize missing settings
badconfig=""
[ -z "$START_CLIENT" ] && START_CLIENT=no
[ -z "$RUN_AS_USER" ] && badconfig="$badconfig RUN_AS_USER"
[ -z "$INPUT_HOST" ] && INPUT_HOST=localhost
[ -z "$INPUT_TYPE" ] && INPUT_TYPE=dump1090
[ -z "$LAT" ] && badconfig="$badconfig LAT"
[ -z "$LON" ] && badconfig="$badconfig LON"
[ -z "$EMAIL" ] && badconfig="$badconfig EMAIL"
[ -z "$LIGHTWEIGHT" ] && LIGHTWEIGHT=no
ARGS="--input-host $INPUT_HOST --input-type $INPUT_TYPE --lat $LAT --lon $LON --email $EMAIL"
if [ "$LIGHTWEIGHT" == "yes" ]; then
ARGS="$ARGS --lightweight"
fi
ARGS="$ARGS $EXTRA_ARGS"
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
if [ "x$START_CLIENT" != "xyes" ]; then
log_warning_msg "Not starting $NAME daemon, disabled via /etc/default/$NAME"
return 2
fi
if [ -n "$badconfig" ]; then
log_warning_msg "Not starting $NAME daemon, missing configuration options ($badconfig)"
return 2
fi
start-stop-daemon --start --quiet --pidfile $PIDFILE --user "$RUN_AS_USER" --startas $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --nicelevel 5 --quiet --pidfile $PIDFILE --user "$RUN_AS_USER" --chuid "$RUN_AS_USER" --make-pidfile --background --no-close --startas $DAEMON -- \
$ARGS >>$LOGFILE 2>&1 \
|| return 2
sleep 1
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --retry=TERM/30/KILL/5 --pidfile $PIDFILE --user "$RUN_AS_USER"
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
sleep 1
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:
If you decided to use a different username or path, change the following line accordingly:
DAEMON=/opt/adsbfilter/AdsbFilter/adsbfilter.sh
Make it executable:
chmod +x /etc/init.d/adsbfilter
Create the settings file
Create the following in /etc/default/adsbfilter:
# Start the client? START_CLIENT="yes" # System user to run as. RUN_AS_USER="adsbfilter" # Logfile to log to LOGFILE="/var/log/adsbfilter.log" # Input receiver type (dump1090, sbs) INPUT_TYPE="dump1090" # Input host INPUT_HOST="localhost" # Latitude of the receiver, in decimal degrees LAT="<your latitude>" # Longitude of the receiver, in decimal degrees LON="<your longitude>" # Email address for login EMAIL="<your email>" # Ignores some ADSB messges to trade off CPU # usage in return for performance LIGHTWEIGHT="yes" # Other arguments to pass to adsbfilter EXTRA_ARGS=""
Modify the various parameters as required. At the very least, you’ll need latitude, longitude and email.
Finalising the install
We now need to tell the system about the new script:
systemctl daemon-reload
And add it to the autostart runlevels:
update-rc.d adsbfilter defaults
And finally, start it manually for the first time:
service adsbfilter start
Check to make sure things started properly by viewing /var/log/adsbfilter.log
Optional: add a logrotate snippet
The ADS-B uploader logs its activity every second, so the adsbfilter.log file can quickly become large. We can use logrotate to trim it periodically and archive off a few days of historical data.
Create /etc/logrotate.d/adsbfilter:
/var/log/adsbfilter.log {
rotate 7
daily
delaycompress
compress
copytruncate
}
And that’s it!