1
0
Fork 0
mirror of https://github.com/sdr-enthusiasts/docker-adsb-ultrafeeder.git synced 2024-11-21 13:20:11 +00:00

initial commit

This commit is contained in:
kx1t 2023-03-21 20:56:02 +01:00
parent 3ab9b41ff7
commit ad94959060
13 changed files with 1315 additions and 2 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

12
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,12 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "docker" # See documentation for possible values
directory: "/" # Location of package manifests
target-branch: "main"
schedule:
interval: "daily"

21
.github/workflows/cancel_dupes.yml vendored Normal file
View file

@ -0,0 +1,21 @@
name: Cancelling Duplicates
on:
workflow_run:
workflows:
- 'Deploy to Docker Hub'
- 'Check Linting'
- 'Tests'
types: ['requested']
jobs:
cancel-duplicate-workflow-runs:
name: "Cancel duplicate workflow runs"
runs-on: ubuntu-18.04
steps:
- uses: potiuk/cancel-workflow-runs@master
name: "Cancel duplicate workflow runs"
with:
cancelMode: allDuplicates
token: ${{ secrets.GITHUB_TOKEN }}
sourceRunId: ${{ github.event.workflow_run.id }}

111
.github/workflows/deploy.yml vendored Normal file
View file

@ -0,0 +1,111 @@
---
name: Deploy Main
on:
workflow_dispatch:
inputs:
reason:
required: false
description: 'Reason for running this workflow'
push:
branches:
- main
# Don't trigger if it's just a documentation update
paths-ignore:
- '**.md'
- '**.MD'
- '**.yml'
- 'LICENSE'
- '.gitattributes'
- '.gitignore'
- '.dockerignore'
# Set workflow-wide environment variables
# - REPO: repo name on dockerhub
# - IMAGE: image name on dockerhub
env:
# DOCKERHUB_REPO: sdr-enthusiasts
# DOCKERHUB_IMAGE: vrs
GHCR_IMAGE: sdr-enthusiasts/docker-adsb-all-in-one
GHCR_REGISTRY: ghcr.io
GH_LABEL: main
GHCR_TAG: latest
jobs:
workflow-dispatch:
name: Triggered via Workflow Dispatch?
# only run this step if workflow dispatch triggered
# log the reason the workflow dispatch was triggered
if: |
github.event_name == 'workflow_dispatch' &&
github.event.inputs.reason != ''
runs-on: ubuntu-latest
steps:
- name: Log dispatch reason
env:
INPUTS_REASON: ${{ github.event.inputs.reason }}
run: |
echo "Workflow dispatch reason: $INPUTS_REASON"
hadolint:
name: Run hadolint against docker files
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Pull hadolint/hadolint:latest Image
run: docker pull hadolint/hadolint:latest
- name: Run hadolint against Dockerfiles
run: docker run --rm -i -v "$PWD":/workdir --workdir /workdir --entrypoint hadolint hadolint/hadolint --ignore DL3015 --ignore DL3003 --ignore DL3006 --ignore DL3010 --ignore DL4001 --ignore DL3007 --ignore DL3008 --ignore SC2068 --ignore DL3007 --ignore SC1091 --ignore DL3013 --ignore DL3010 $(find . -type f -iname "Dockerfile*")
deploy_ghcr_multiarch:
name: Deploy ghcr.io (Multi-Arch)
needs: [hadolint]
runs-on: ubuntu-latest
permissions:
packages: write
steps:
# Check out our code
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ env.GH_LABEL }}
# Log into ghcr (so we can push images)
- name: Login to ghcr.io
uses: docker/login-action@v2
with:
registry: ${{ env.GHCR_REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# Get metadata from repo
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }}
# Set up QEMU for multi-arch builds
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
# Set up buildx for multi platform builds
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: image=moby/buildkit:v0.10.6
# Build "latest"
- name: Build & Push - latest
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
no-cache: true
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/i386
push: true
tags: ghcr.io/${{ env.GHCR_IMAGE }}:${{ env.GHCR_TAG }}
labels: ${{ steps.meta.outputs.labels }}

5
.hadolint.yaml Normal file
View file

@ -0,0 +1,5 @@
ignored:
- DL3003
- DL3008
- SC3054
- SC3044

66
Dockerfile Normal file
View file

@ -0,0 +1,66 @@
FROM ghcr.io/sdr-enthusiasts/docker-baseimage:wreadsb
LABEL org.opencontainers.image.source = "https://github.com/sdr-enthusiasts/docker-multifeeder"
ENV URL_MLAT_CLIENT_REPO="https://github.com/adsbxchange/mlat-client.git" \
PRIVATE_MLAT="false" \
MLAT_INPUT_TYPE="auto"
RUN set -x && \
# define packages needed for installation and general management of the container:
TEMP_PACKAGES=() && \
KEPT_PACKAGES=() && \
KEPT_PACKAGES+=(procps nano aptitude) && \
KEPT_PACKAGES+=(psmisc) && \
# Git and net-tools are needed to install and run @Mikenye's HealthCheck framework
KEPT_PACKAGES+=(git) && \
#
# Needed to run the mlat_client:
KEPT_PACKAGES+=(python3) && \
KEPT_PACKAGES+=(python3-pip) && \
KEPT_PACKAGES+=(python3-setuptools) && \
KEPT_PACKAGES+=(python3-wheel) && \
#
# These are needed to compile and install the mlat_client:
TEMP_PACKAGES+=(build-essential) && \
TEMP_PACKAGES+=(debhelper) && \
TEMP_PACKAGES+=(python3-dev) && \
TEMP_PACKAGES+=(python3-distutils-extra) && \
#
# Install all these packages:
apt-get update -q -y && \
apt-get install -o Dpkg::Options::="--force-confnew" --force-yes -y --no-install-recommends -q \
${KEPT_PACKAGES[@]} \
${TEMP_PACKAGES[@]} && \
#
# Compile and Install the mlat_client
mkdir -p /git && \
pushd /git && \
git clone --depth 1 $URL_MLAT_CLIENT_REPO && \
cd mlat-client && \
./setup.py install && \
ln -s /usr/local/bin/mlat-client /usr/bin/mlat-client && \
popd && \
rm -rf /git && \
#
# Clean up
apt-get remove -q -y ${TEMP_PACKAGES[@]} && \
apt-get autoremove -q -o APT::Autoremove::RecommendsImportant=0 -o APT::Autoremove::SuggestsImportant=0 -y && \
apt-get clean -q -y && \
rm -rf /src /tmp/* /var/lib/apt/lists/* /git && \
#
# Do some stuff for kx1t's convenience:
echo "alias dir=\"ls -alsv\"" >> /root/.bashrc && \
echo "alias nano=\"nano -l\"" >> /root/.bashrc
COPY rootfs/ /
# Add Container Version
RUN set -x && \
branch="##BRANCH##" && \
[[ "${branch:0:1}" == "#" ]] && branch="main" || true && \
git clone --depth=1 -b $branch https://github.com/sdr-enthusiasts/docker-multifeeder.git /tmp/clone && \
pushd /tmp/clone && \
echo "$(TZ=UTC date +%Y%m%d-%H%M%S)_$(git rev-parse --short HEAD)_$(git branch --show-current)" > /.CONTAINER_VERSION && \
popd && \
rm -rf /tmp/*

519
README.md
View file

@ -1,2 +1,517 @@
# docker-adsb-all-in-one
# sdr-enthusiasts/docker-adsb-all-in-one
`adsb-all-in-one` is a ADS-B data collector container that can be used to:
* retrieve ADS-B data from your SDR or other device
* display it on a local map, including options to show tracks, heatmaps, and system performance graphs
* forward the data to one or more aggregators using BEAST/BEAST-REDUCE/BEAST-REDUCE-PLUS format
* send MLAT data to these aggregators
* receive and optionally consolidate MLAT results data (built-in `mlatuhb`)
* Interface with external visualization tools such as Grafana using statistics data available in InfluxDB and Prometheus format
In order to accomplish this, the container makes use of the following underlying technologies:
* SDR-Enthusiasts [Docker Base-Image](https://github.com/sdr-enthusiasts/docker-baseimage)
* [Wiedehopf's branch of `readsb`](https://github.com/wiedehopf/readsb)
* Wiedehopf's [tar1090](https://github.com/wiedehopf/tar1090) graphical interface
* Wiedehopf's [graphs1090](https://github.com/wiedehopf/graphs1090)
* [MLAT Client](https://github.com/adsbxchange/mlat-client.git)
It builds and runs on `linux/amd64`, `linux/arm/v7 (linux/armhf)` and `linux/arm64` architectures.
## Up-and-Running with `docker run`
```bash
docker run -d \
--name=tar1090 \
-p 8078:80 \
-e TZ=<TIMEZONE> \
-e BEASTHOST=<BEASTHOST> \
-e MLATHOST=<MLATHOST> \
-e LAT=xx.xxxxx \
-e LONG=xx.xxxxx \
-v /opt/adsb/tar1090/graphs1090:/var/lib/collectd \
--tmpfs=/run:exec,size=64M \
--tmpfs=/var/log \
ghcr.io/sdr-enthusiasts/docker-tar1090:latest
```
Replacing `TIMEZONE` with your timezone, `BEASTHOST` with the IP address of a host that can provide Beast data, and `MLATHOST` with the IP address of a host that can provide MLAT data.
For example:
```bash
docker run -d \
--name=tar1090 \
-p 8078:80 \
-e TZ=Australia/Perth \
-e BEASTHOST=readsb \
-e MLATHOST=adsbx \
-e LAT=-33.33333 \
-e LONG=111.11111 \
-v /opt/adsb/tar1090/graphs1090:/var/lib/collectd \
--tmpfs=/run:exec,size=64M \
--tmpfs=/var/log \
ghcr.io/sdr-enthusiasts/docker-tar1090:latest
```
You should now be able to browse to:
* <http://dockerhost:8078/> to access the tar1090 web interface
* <http://dockerhost:8078/?replay> to see a replay of past data
* <http://dockerhost:8078/?heatmap> to see the heatmap for the past 24 hours.
* <http://dockerhost:8078/?heatmap&realHeat> to see a different heatmap for the past 24 hours.
* <http://dockerhost:8078/graphs1090/> to see performance graphs
## Up-and-Running with `docker-compose`
An example `docker-compose.xml` file is below:
```yaml
version: '3.8'
services:
tar1090:
image: ghcr.io/sdr-enthusiasts/docker-adsb-all-in-one:latest
tty: true
container_name: adsb-all-in-one
restart: always
environment:
- TZ=Australia/Perth
- BEASTHOST=readsb
- MLATHOST=adsbx
- LAT=-33.33333
- LONG=111.11111
volumes:
- /opt/adsb/tar1090/globe_history:/var/globe_history
- /opt/adsb/tar1090/timelapse1090:/var/timelapse1090
- /opt/adsb/tar1090/graphs1090:/var/lib/collectd
- /proc/diskstats:/proc/diskstats:ro
# - /run/airspy_adsb:/run/airspy_adsb
ports:
- 8078:80
tmpfs:
- /run:exec,size=64M
- /var/log
```
You should now be able to browse to:
* <http://dockerhost:8078/> to access the tar1090 web interface.
* <http://dockerhost:8078/?replay> to see a replay of past data
* <http://dockerhost:8078/?heatmap> to see the heatmap for the past 24 hours.
* <http://dockerhost:8078/?heatmap&realHeat> to see a different heatmap for the past 24 hours.
* <http://dockerhost:8078/graphs1090/> to see performance graphs
*Note*: the example above excludes `MLATHOST` as `readsb` alone cannot provide MLAT data. You'll need a feeder container for this.
## Ports
Some common ports are as follows (which may or may not be in use depending on your configuration):
| Port | Details |
|------|---------|
| `30001/tcp` | Raw protocol input |
| `30002/tcp` | Raw protocol output |
| `30003/tcp` | SBS/Basestation protocol output |
| `32006/tcp` | SBS/Basestation protocol input |
| `30004/tcp` | Beast protocol input |
| `30005/tcp` | Beast protocol output |
| `30006/tcp` | Beast reduce protocol output |
| `30047/tcp` | Json position output |
Json position output:
* outputs an aircraft object for every new position received for an aircraft if the --json-trace-interval has elapsed for that aircraft
* to make it output every received position, set READSB_JSON_TRACE_INTERVAL to 0.1
* each json object will be on a new line
* <https://github.com/wiedehopf/readsb/blob/dev/README-json.md>
Aircraft.json:
* <https://github.com/wiedehopf/readsb/blob/dev/README-json.md>
* available on the same port as the web interface, example: `http://192.168.x.yy:8087/data/aircraft.json`
### Outgoing
This container will try to connect to the `BEASTHOST` on TCP port `30005` by default. This can be changed by setting the `BEASTPORT` environment variable.
If `MLATHOST` is set, this container will try to connecto the `MLATHOST` on TCP port `30105` by default. This can be changed to setting the `MLATPORT` environment variable.
### Incoming
This container accepts HTTP connections on TCP port `80` by default. You can change this with the container's port mapping. In the examples above, this has been changed to `8078`.
## Runtime Environment Variables
### Container Configuration
| Environment Variable | Purpose | Default |
|----------------------|---------|---------|
| `BEASTHOST` | Required. IP/Hostname of a Mode-S/Beast provider (`dump1090`/`readsb`) | |
| `BEASTPORT` | Optional. TCP port number of Mode-S/Beast provider (`dump1090`/`readsb`) | `30005` |
| `LAT` | Optional. The latitude of your antenna | |
| `LONG` | Optional. The longitude of your antenna | |
| `MLATHOST` | Optional. IP/Hostname of an MLAT provider (`mlat-client`) | |
| `MLATPORT` | Optional. TCP port number of an MLAT provider (`mlat-client`) | 30105 |
| `TZ` | Optional. Your local timezone in [TZ-database-name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) format | |
| `HEYWHATSTHAT_PANORAMA_ID` | Optional. Your `heywhatsthat.com` panorama ID. See <https://github.com/wiedehopf/tar1090#heywhatsthatcom-range-outline>. | |
| `HEYWHATSTHAT_ALTS` | Optional. Comma separated altitudes for multiple outlines. Use no units or `ft` for feet, `m` for meters, or `km` for kilometers. Only integer numbers are accepted, no decimals please | `12192m` (=40000 ft) |
| `HTTP_ACCESS_LOG` | Optional. Set to `true` to display HTTP server access logs. | `false` |
| `HTTP_ERROR_LOG` | Optional. Set to `false` to hide HTTP server error logs. | `true` |
| `READSB_MAX_RANGE` | Optional. Maximum range (in nautical miles). | `300` |
| `ENABLE_TIMELAPSE1090` | Optional / Legacy. Set to any value to enable timelapse1090. Once enabled, can be accessed via <http://dockerhost:port/timelapse/>. | Unset |
| `READSB_EXTRA_ARGS` | Optional, allows to specify extra parameters for readsb | Unset |
| `READSB_DEBUG` | Optional, used to set debug mode. `n`: network, `P`: CPR, `S`: speed check | Unset |
| `S6_SERVICES_GRACETIME` | Optional, set to 30000 when saving traces / globe_history | `3000` |
| `ENABLE_AIRSPY` | Optional, set to any non-empty value if you want to enable the special AirSpy graphs. See below for additional configuration requirements | Unset |
READSB_EXTRA_ARGS just passes arguments to the commandline, you can check this file for more options for wiedehofps readsb fork: <https://github.com/wiedehopf/readsb/blob/dev/help.h>
If you want to save historic data with tar1090, see a modified mode of operation at the end of the readme
### `tar1090` Configuration
All of the variables below are optional.
#### `tar1090` Core Configuration
| Environment Variable | Purpose | Default |
|----------------------|---------|---------|
| `READSB_JSON_INTERVAL` | Update data update interval for the webinterface in seconds | `1.0` |
| `UPDATE_TAR1090` | At startup update tar1090 and tar1090db to the latest versions | `true` |
| `INTERVAL` | Interval at which the track history is saved | `8` |
| `HISTORY_SIZE` | How many points in time are stored in the track history | `450` |
| `ENABLE_978` | Change to yes to enable UAT/978 display in `tar1090`. This will also enable UAT-specific graphs in graphs1090 | `no` |
| `URL_978` | The URL needs to point at where you would normally find the skyview978 webinterface | `http://127.0.0.1/skyaware978` |
| `GZIP_LVL` | `1`-`9` are valid, lower lvl: less CPU usage, higher level: less network bandwidth used when loading the page | `3` |
| `PTRACKS` | Shows the last `$PTRACKS` hours of traces you have seen at the `?pTracks` URL | `8` |
| `TAR1090_FLIGHTAWARELINKS` | Set to any value to enable FlightAware links in the web interface | `null` |
| `TAR1090_ENABLE_AC_DB` | Set to `true` to enable extra information, such as aircraft type and registration, to be included in in `aircraft.json` output. Will use more memory; use caution on older Pis or similiar devices. | `false` |
* For documentation on the aircraft.json format see this page: <https://github.com/wiedehopf/readsb/blob/dev/README-json.md>
* TAR1090_ENABLE_AC_DB causes readsb to load the tar1090 database as a csv file from this repository: <https://github.com/wiedehopf/tar1090-db/tree/csv>
#### `tar1090` `config.js` Configuration - Title
| Environment Variable | Purpose | Default |
|----------------------|---------|---------|
| `TAR1090_PAGETITLE` | Set the tar1090 web page title | `tar1090` |
| `TAR1090_PLANECOUNTINTITLE` | Show number of aircraft in the page title | `false` |
| `TAR1090_MESSAGERATEINTITLE` | Show number of messages per second in the page title | `false` |
#### `tar1090` `config.js` Configuration - Output
| Environment Variable | Purpose | Default |
|----------------------|---------|---------|
| `TAR1090_DISPLAYUNITS` | The DisplayUnits setting controls whether nautical (ft, NM, knots), metric (m, km, km/h) or imperial (ft, mi, mph) units are used in the plane table and in the detailed plane info. Valid values are "`nautical`", "`metric`", or "`imperial`". | `nautical` |
#### `tar1090` `config.js` Configuration - Map Settings
| Environment Variable | Purpose | Default |
|----------------------|---------|---------|
| `TAR1090_BINGMAPSAPIKEY` | Provide a Bing Maps API key to enable the Bing imagery layer. You can obtain a free key (with usage limits) at <https://www.bingmapsportal.com/> (you need a "basic key"). | `null` |
| `TAR1090_DEFAULTCENTERLAT` | Default center (latitude) of the map. This setting is overridden by any position information provided by dump1090/readsb. All positions are in decimal degrees. | `45.0` |
| `TAR1090_DEFAULTCENTERLON` | Default center (longitude) of the map. This setting is overridden by any position information provided by dump1090/readsb. All positions are in decimal degrees. | `9.0` |
| `TAR1090_DEFAULTZOOMLVL` | The google maps zoom level, `0` - `16`, lower is further out. | `7` |
| `TAR1090_SITESHOW` | Center marker. If dump1090 provides a receiver location, that location is used and these settings are ignored. Set to `true` to show a center marker. | `false` |
| `TAR1090_SITELAT` | Center marker. If dump1090 provides a receiver location, that location is used and these settings are ignored. Position of the marker (latitude). | `45.0` |
| `TAR1090_SITELON` | Center marker. If dump1090 provides a receiver location, that location is used and these settings are ignored. Position of the marker (longitude). | `9.0` |
| `TAR1090_SITENAME` | The tooltip of the center marker. | `My Radar Site` |
| `TAR1090_RANGE_OUTLINE_COLOR` | Colour for the range outline. | `#0000DD` |
| `TAR1090_RANGE_OUTLINE_WIDTH` | Width for the range outline. | `1.7` |
| `TAR1090_RANGE_OUTLINE_COLORED_BY_ALTITUDE` | Range outline is coloured by altitude. | `false` |
| `TAR1090_RANGE_OUTLINE_DASH` | Range outline dashing. Syntax `[L, S]` where `L` is the pixel length of the line, and `S` is the pixel length of the space. | Unset |
| `TAR1090_ACTUAL_RANGE_OUTLINE_COLOR` | Colour for the actual range outline | `#00596b` |
| `TAR1090_ACTUAL_RANGE_OUTLINE_WIDTH` | Width of the actual range outline | `1.7` |
| `TAR1090_ACTUAL_RANGE_OUTLINE_DASH` | Dashed style for the actual range outline. Unset for solid line. `[5,5]` for a dashed line with 5 pixel lines and spaces in between | Unset |
| `TAR1090_MAPTYPE_TAR1090` | Which map is displayed to new visitors. Valid values for this setting are `osm`, `esri`, `carto_light_all`, `carto_light_nolabels`, `carto_dark_all`, `carto_dark_nolabels`, `gibs`, `osm_adsbx`, `chartbundle_sec`, `chartbundle_tac`, `chartbundle_hel`, `chartbundle_enrl`, `chartbundle_enra`, `chartbundle_enrh`, and only with bing key `bing_aerial`, `bing_roads`. | `carto_light_all` |
| `TAR1090_MAPDIM` | Default map dim state, true or false. | `true` |
| `TAR1090_MAPDIMPERCENTAGE` | The percentage amount of dimming used if the map is dimmed, `0`-`1` | `0.45` |
| `TAR1090_MAPCONTRASTPERCENTAGE` | The percentage amount of contrast used if the map is dimmed, `0`-`1` | `0` |
| `TAR1090_DWDLAYERS` | Various map layers provided by the DWD geoserver can be added here. [Preview and available layers](https://maps.dwd.de/geoserver/web/wicket/bookmarkable/org.geoserver.web.demo.MapPreviewPage?1&filter=false). Multiple layers are also possible. Syntax: `dwd:layer1,dwd:layer2,dwd:layer3` | `dwd:RX-Produkt` |
| `TAR1090_LABELZOOM` | Displays aircraft labels only until this zoom level, `1`-`15` (values >`15` don't really make sense)| |
| `TAR1090_LABELZOOMGROUND` | Displays ground traffic labels only until this zoom level, `1`-`15` (values >`15` don't really make sense) | |
#### `tar1090` `config.js` Configuration - Range Rings
| Environment Variable | Purpose | Default |
|----------------------|---------|---------|
| `TAR1090_RANGERINGS` | `false` to hide range rings | `true` |
| `TAR1090_RANGERINGSDISTANCES` | Distances to display range rings, in miles, nautical miles, or km (depending settings value '`TAR1090_DISPLAYUNITS`'). Accepts a comma separated list of numbers (no spaces, no quotes). | `100,150,200,250` |
| `TAR1090_RANGERINGSCOLORS` | Colours for each of the range rings specified in `TAR1090_RANGERINGSDISTANCES`. Accepts a comma separated list of hex colour values, each enclosed in single quotes (eg `TAR1090_RANGERINGSCOLORS='#FFFFF','#00000'`). No spaces. | Blank |
### `timelapse1090` Configuration
Legacy: consider using <http://dockerhost:port/?replay> instead
| Environment Variable | Purpose | Default |
|----------------------|---------|---------|
| `TIMELAPSE1090_INTERVAL` | Snapshot interval in seconds | `10` |
| `TIMELAPSE1090_HISTORY` | Time saved in hours | `24` |
## Paths
No paths need to be mapped through to persistent storage. However, if you don't want to lose your range outline and aircraft tracks/history and heatmap / replay data on container restart, you can optionally map these paths:
| Path | Purpose |
|------|---------|
| `/var/globe_history` | Holds range outline data, heatmap / replay data and traces if enabled.
*Note: this data won't be automatically deleted, you will need to delete it eventually if you map this path.* |
| `/var/timelapse1090` | Holds timelapse1090 data if enabled |
| `/var/lib/collectd` | Holds graphs1090 & performance data |
### `readsb` Network Options
This container uses the readsb fork by wiedehopf as a backend to tar1090: <https://github.com/wiedehopf/readsb>
Where the default value is "Unset", `readsb`'s default will be used.
| Variable | Description | Controls which `readsb` option | Default |
|----------|-------------|--------------------------------|---------|
| `READSB_NET_CONNECTOR` | See "`READSB_NET_CONNECTOR` syntax" below. | `--net-connector=<ip,port,protocol>` | Unset |
| `READSB_NET_API_PORT` | <https://github.com/wiedehopf/readsb/blob/dev/README-json.md#--net-api-port-query-formats> | `--net-api-port=<ports>` | `30152` |
| `READSB_NET_BEAST_REDUCE_INTERVAL` | BeastReduce position update interval, longer means less data (valid range: `0.000` - `14.999`) | `--net-beast-reduce-interval=<seconds>` | `0.125` |
| `READSB_NET_BEAST_REDUCE_FILTER_DIST` | Restrict beast-reduce output to aircraft in a radius of X nmi | `--net-beast-reduce-filter-dist=<nmi>` | Unset |
| `READSB_NET_BEAST_REDUCE_FILTER_ALT` | Restrict beast-reduce output to aircraft below X ft | `--net-beast-reduce-filter-alt=<ft>` | Unset |
| `READSB_NET_BEAST_REDUCE_OUT_PORT` | TCP BeastReduce output listen ports (comma separated) | `--net-beast-reduce-out-port=<ports>` | Unset |
| `READSB_NET_BEAST_INPUT_PORT`| TCP Beast input listen ports | `--net-bi-port=<ports>` | `30004,30104` |
| `READSB_NET_BEAST_OUTPUT_PORT` | TCP Beast output listen ports | `--net-bo-port=<ports>` | `30005` |
| `READSB_NET_BUFFER` | TCP buffer size 64Kb * (2^n) | `--net-buffer=<n>` | `2` (256Kb) |
| `READSB_NET_RAW_OUTPUT_INTERVAL` | TCP output flush interval in seconds (maximum interval between two network writes of accumulated data). | `--net-ro-interval=<rate>` | `0.05` |
| `READSB_NET_RAW_OUTPUT_SIZE` | TCP output flush size (maximum amount of internally buffered data before writing to network). | `--net-ro-size=<size>` | `1200` |
| `READSB_NET_CONNECTOR_DELAY` | Outbound re-connection delay. | `--net-connector-delay=<seconds>` | `30` |
| `READSB_NET_HEARTBEAT` | TCP heartbeat rate in seconds (0 to disable). | `--net-heartbeat=<rate>` | `60` |
| `READSB_NET_RAW_INPUT_PORT` | TCP raw input listen ports. | `--net-ri-port=<ports>` | `30001` |
| `READSB_NET_RAW_OUTPUT_PORT` | TCP raw output listen ports. | `--net-ro-port=<ports>` | `30002` |
| `READSB_NET_SBS_INPUT_PORT` | TCP BaseStation input listen ports. | `--net-sbs-in-port=<ports>` | Unset |
| `READSB_NET_SBS_OUTPUT_PORT` | TCP BaseStation output listen ports. | `--net-sbs-port=<ports>` | `30003` |
| `REASSB_NET_VERBATIM` | Set this to any value to forward messages unchanged. | `--net-verbatim` | Unset |
| `READSB_NET_VRS_PORT` | TCP VRS JSON output listen ports. | `--net-vrs-port=<ports>` | Unset |
| `READSB_WRITE_STATE_ONLY_ON_EXIT` | if set to anything, it will only write the status range outlines, etc. upon termination of `readsb` | `--write-state-only-on-exit` | Unset |
#### `READSB_NET_CONNECTOR` syntax
This variable allows you to configure outgoing connections. The variable takes a semicolon (`;`) separated list of `ip,port,protocol`, where:
* `ip` is an IP address. Specify an IP/hostname/containername for outgoing connections.
* `port` is a TCP port number
* `protocol` can be one of the following:
* `beast_out`: Beast-format output
* `beast_in`: Beast-format input
* `raw_out`: Raw output
* `raw_in`: Raw input
* `sbs_out`: SBS-format output
* `vrs_out`: SBS-format output
For example, to pull in MLAT results (so the performance graphs in the web interface show MLAT numbers), you could do the following:
```yaml
environment:
...
- READSB_NET_CONNECTOR=piaware,30105,beast_in;adsbx,30105,beast_in;rbfeeder,30105,beast_in
...
```
### `readsb` General Options
Where the default value is "Unset", `readsb`'s default will be used.
| Variable | Description | Controls which `readsb` option | Default |
|----------|-------------|--------------------------------|---------|
| `READSB_ENABLE_BIASTEE` | Set to any value to enable bias tee on supporting interfaces | | Unset |
| `READSB_RX_LOCATION_ACCURACY` | Accuracy of receiver location in metadata: 0=no location, 1=approximate, 2=exact | `--rx-location-accuracy=<n>` | `2` |
| `READSB_JSON_INTERVAL` | Update interval for the webinterface in seconds / interval between aircraft.json writes | `--write-json-every=<sec>` | `1.0` |
| `READSB_JSON_TRACE_INTERVAL` | Per plane interval for json position output and trace interval for globe history | `--json-trace-interval=<sec>` | `15` |
| `READSB_HEATMAP_INTERVAL` | Per plane interval for heatmap and replay (if you want to lower this, also lower json-trace-interval to this or a lower value) | `--heatmap=<sec>` | `15` |
| `READSB_MAX_RANGE` | Absolute maximum range for position decoding (in nm) | `--max-range=<dist>` | `300` |
| `READSB_MLAT` | Set this to add timestamps to AVR / RAW output | `--mlat` | Unset |
| `READSB_STATS_EVERY` | Number of seconds between showing and resetting stats. | `--stats-every=<sec>` | Unset |
| `READSB_STATS_RANGE` | Set this to any value to collect range statistics for polar plot. | `--stats-range` | Unset |
| `READSB_RANGE_OUTLINE_HOURS` | Change which past timeframe the range outline is based on | `--range-outline-hours` | `24` |
## Message decoding introspection
You can look at individual messages and what information they contain, either for all or for an individual aircraft by hex:
```shell
# only for hex 3D3ED0
docker exec -it tar1090 /usr/local/bin/viewadsb --show-only 3D3ED0
# for all aircraft
docker exec -it tar1090 /usr/local/bin/viewadsb --no-interactive
# show position / CPR debugging for hex 3D3ED0
docker exec -it tar1090 /usr/local/bin/viewadsb --cpr-focus 3D3ED0
```
## Configuring `graphs1090`
### `graphs1090` Environment Parameters
| Variable | Description | Default |
|----------|-------------|---------|
| `GRAPHS1090_DARKMODE` | If set to any value, `graphs1090` will be rendered in "dark mode". | Unset |
| `GRAPHS1090_RRD_STEP` | Interval in seconds to feed data into RRD files. | `60` |
| `GRAPHS1090_SIZE` | Set graph size, possible values: `small`, `default`, `large`, `huge`, `custom`. | `default` |
| `GRAPHS1090_ALL_LARGE` | Make the small graphs as large as the big ones by setting to `yes`. | `no` |
| `GRAPHS1090_FONT_SIZE` | Font size (relative to graph size). | `10.0` |
| `GRAPHS1090_MAX_MESSAGES_LINE` | Set to any value to draw a reference line at the maximum message rate. | Unset |
| `GRAPHS1090_LARGE_WIDTH` | Defines the width of the larger graphs. | `1096` |
| `GRAPHS1090_LARGE_HEIGHT` | Defines the height of the larger graphs. | `235` |
| `GRAPHS1090_SMALL_WIDTH` | Defines the width of the smaller graphs. | `619` |
| `GRAPHS1090_SMALL_HEIGHT` | Defines the height of the smaller graphs. | `324` |
| `GRAPHS1090_DISK_DEVICE` | Defines which disk device (`mmc0`, `sda`, `sdc`, etc) is shown. Leave empty for default device | Unset |
| `GRAPHS1090_ETHERNET_DEVICE` | Defines which (wired) ethernet device (`eth0`, `enp0s`, etc) is shown. Leave empty for default device | Unset |
| `GRAPHS1090_WIFI_DEVICE` | Defines which (wireless) WiFi device (`wlan0`, `wlp3s0`, etc) is shown. Leave empty for default device | Unset |
| `GRAPHS1090_DISABLE` | Set to any value to disable the GRAPHS1090 web page | Unset |
### Enabling UAT data
ADS-B over UAT data is transmitted in the 978 MHz band, and this is used in the USA only. To display the corresponding graphs, you should:
1. Set the following environment parameters:
```yaml
- ENABLE_978=yes
- URL_978=http://dump978/skyaware978
```
2. Install the [`docker-dump978` container](https://github.com/sdr-enthusiasts/docker-dump978). Note - only containers downloaded/deployed on/after Feb 8, 2023 will work.
Note that you **must** configure `URL_978` to point at a working skyaware978 website with `aircraft.json` data feed. This means that the URL `http://dump978/skyaware978/data/aircraft.json` must return valid JSON data to this `tar1090` container.
### Enabling AirSpy graphs
Users of AirSpy devices can enable extra `graphs1090` graphs by configuring the following:
* Set the following environment parameter:
```yaml
- ENABLE_AIRSPY=yes
```
* To provide the container access to the AirSpy statistics, map a volume in your `docker-compose.yml` file as follows:
```yaml
volumes:
- /run/airspy_adsb:/run/airspy_adsb
...
```
### Enabling Disk IO and IOPS data
To allow the container access to the Disk IO data, you should map the following volume:
```yaml
volumes:
- /proc/diskstats:/proc/diskstats:ro
...
```
### Configuring the Core Temperature graphs
By default, the system will use the temperature available at Thermal Zone 0. This generally works well on Raspberry Pi devices, and no additional changes are needed.
On different devices, the Core Temperature is mapped to a different Thermal Zone. To ensure the Core Temperature graph works, follow these steps
First check out which Thermal Zone contains the temperature you want to monitor. On your host system, do this:
```bash
for i in /sys/class/thermal/thermal_zone* ; do echo "$i - $(cat ${i}/type) - $(cat ${i}/temp 2>/dev/null)"; done
```
Something similar to this will be show:
```bash
/sys/class/thermal/thermal_zone0 - acpitz - 25000
/sys/class/thermal/thermal_zone1 - INT3400 Thermal - 20000
/sys/class/thermal/thermal_zone2 - TSKN - 43050
/sys/class/thermal/thermal_zone3 - NGFF - 32050
/sys/class/thermal/thermal_zone4 - TMEM - 39050
/sys/class/thermal/thermal_zone5 - pch_skylake - 40500
/sys/class/thermal/thermal_zone6 - B0D4 - 54050
/sys/class/thermal/thermal_zone7 - iwlwifi_1 -
/sys/class/thermal/thermal_zone8 - x86_pkg_temp - 57000
```
Repeat this a few times to ensure that the temperature varies and isn't hardcoded to a value. In our case, either Thermal Zone 5 (`pch_skylake` is the Intel Core name) or Thermal Zone 8 (the temp of the entire SOC package) can be used. Once you have determined which Thermal Zone number you want to use, map it to a volume like this. Make sure that the part to the left of the first `:` reflects your Thermal Zone directory; the part to the right of the first `:` should always be `/sys/class/thermal/thermal_zone0:ro`.
Note that you will have to add `- privileged: true` capabilities to the container. This is less than ideal as it will give the container access to all of your system devices and processes. Make sure you feel comfortable with this before you do this.
```yaml
privileged: true
volumes:
- /sys/class/thermal/thermal_zone8:/sys/class/thermal/thermal_zone0:ro
...
```
Note - on some systems (DietPi comes to mind), `/sys/class/thermal/` may not be available.
## Logging
All logs are to the container's stdout and can be viewed with `docker logs -t [-f] container`.
## Getting help
Please feel free to [open an issue on the project's GitHub](https://github.com/sdr-enthusiasts/docker-tar1090/issues).
We also have a [Discord channel](https://discord.gg/sTf9uYF), feel free to [join](https://discord.gg/sTf9uYF) and converse.
## Using tar1090 with an SDR
| Variable | Description | Controls which `readsb` option | Default |
|----------|-------------|--------------------------------|---------|
| `READSB_GAIN` | Set gain (in dB). Use `autogain` to have the container determine an appropriate gain, more on this below. | `--gain=<db>` | Max gain |
| `READSB_DEVICE_TYPE` | If using an SDR, set this to `rtlsdr`, `modesbeast`, `gnshulc` depending on the model of your SDR. If not using an SDR, leave un-set. | `--device-type=<type>` | Unset |
| `READSB_RTLSDR_DEVICE` | Select device by serial number. | `--device=<serial>` | Unset |
| `READSB_RTLSDR_PPM` | Set oscillator frequency correction in PPM. See section [Estimating PPM](https://github.com/docker-readsb/README.MD#estimating-ppm) below | `--ppm=<correction>` | Unset |
| `READSB_BEAST_SERIAL` | only when type `modesbeast` or `gnshulc` is used: Path to Beast serial device. | `--beast-serial=<path>` | `/dev/ttyUSB0` |
Example (devices: section is mandatory)
```yaml
version: '3.8'
services:
tar1090:
image: ghcr.io/sdr-enthusiasts/docker-tar1090:latest
tty: true
container_name: tar1090
hostname: tar1090
restart: always
environment:
- TZ=Australia/Perth
- LAT=-33.33333
- LONG=111.11111
- READSB_DEVICE_TYPE=rtlsdr
- READSB_GAIN=43.9
- READSB_RTLSDR_DEVICE=0
ports:
- 8078:80
tmpfs:
- /run:exec,size=64M
- /var/log
devices:
- /dev/bus/usb:/dev/bus/usb
```
## globe-history or sometimes ironically called destroy-sd-card
See also: <https://github.com/wiedehopf/tar1090#0800-destroy-sd-card>
```yaml
environment:
...
- READSB_EXTRA_ARGS=--write-json-globe-index --write-globe-history /var/globe_history
...
volumes:
- /hostpath/to/your/globe_history:/var/globe_history
```
The first part of the mount before the : is the path on the docker host, don't change the 2nd part.
Using this volume gives you persistence for the history / heatmap / range outline
Note that this mode will make T not work as before for displaying all tracks as tracks are only loaded when you click them.

37
buildnow.sh Executable file
View file

@ -0,0 +1,37 @@
#!/bin/bash
# shellcheck disable=SC2086,SC2162
[[ "$1" != "" ]] && BRANCH="$1" || BRANCH="$(git branch --show-current)"
[[ "$BRANCH" == "main" ]] && TAG="latest" || TAG="$BRANCH"
[[ "$ARCHS" == "" ]] && ARCHS="linux/armhf,linux/arm64,linux/amd64"
BASETARGET1=ghcr.io/sdr-enthusiasts
BASETARGET2=kx1t
IMAGE1="$BASETARGET1/$(pwd | sed -n 's|.*/\(docker-.*\)|\1|p'):$TAG"
IMAGE2="$BASETARGET2/$(pwd | sed -n 's|.*/docker-\(.*\)|\1|p'):$TAG"
echo "press enter to start building $IMAGE1 and $IMAGE2 from $BRANCH"
read
git checkout $BRANCH
starttime="$(date +%s)"
# rebuild the container
set -x
# git pull -a
cp -f Dockerfile Dockerfile.tmp-backup
if [[ "$(uname -s)" == "Darwin" ]]
then
sed -i '' 's/##BRANCH##/'"$BRANCH"'/g' Dockerfile
else
sed -i 's/##BRANCH##/'"$BRANCH"'/g' Dockerfile
fi
docker buildx build -f Dockerfile --compress --push $2 --platform $ARCHS --tag "$IMAGE1" .
[[ $? ]] && docker buildx build --compress --push $2 --platform $ARCHS --tag $IMAGE2 .
mv -f Dockerfile.tmp-backup Dockerfile
echo "Total build time: $(( $(date +%s) - starttime )) seconds"

View file

@ -0,0 +1,21 @@
#!/usr/bin/with-contenv bash
#shellcheck shell=bash disable=SC2015
# Print container version
#---------------------------------------------------------------------------------------------
# Copyright (C) 2023, Ramon F. Kolb (kx1t)
#
# 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 <https://www.gnu.org/licenses/>.
#---------------------------------------------------------------------------------------------
[[ -f /.CONTAINER_VERSION ]] && echo "[$(date)][INIT] Container Version: $(cat /.CONTAINER_VERSION), build date $(stat -c '%y' /.CONTAINER_VERSION |sed 's|\(.*\)\.[0-9]* \(.*\)|\1 \2|g')" || true

View file

@ -0,0 +1,26 @@
#!/usr/bin/with-contenv bash
#shellcheck shell=bash disable=SC2015
# Write UUID to file
#---------------------------------------------------------------------------------------------
# Copyright (C) 2023, Ramon F. Kolb (kx1t)
#
# 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 <https://www.gnu.org/licenses/>.
#---------------------------------------------------------------------------------------------
if [[ -n "${UUID}" ]]
then
echo "$UUID" > /run/uuid
fi
exit 0

View file

@ -0,0 +1,103 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash disable=SC2015,SC2016
#---------------------------------------------------------------------------------------------
# Copyright (C) 2023, Ramon F. Kolb (kx1t)
#
# 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 <https://www.gnu.org/licenses/>.
#---------------------------------------------------------------------------------------------
APPNAME="mlat-client"
echo "[$(date)][${APPNAME}] Started as an s6 service"
MLAT_CMD="/usr/bin/mlat-client"
RESTARTTIMER=15
declare -A pid_array
if [[ -z "${MLAT_CONFIG}" ]]
then
echo "[$(date)][${APPNAME}] Warning: MLAT_CONFIG not defined - MLAT will be disabled."
sleep infinity
fi
if [[ -z "${MLAT_USER}" ]] && [[ -z "${UUID}" ]]
then
echo "[$(date)][${APPNAME}] ERROR: either UUID or MLAT_USER must be defined - MLAT will be disabled."
sleep infinity
fi
# MLAT_CONFIG has the following format:
# MLAT_CONFIG=mlatserver_1,mlatserver_port_1[,results_port_1[,extra_params_1]];mlatserver_2,mlatserver_port_2[,results_port_2[,extra_params_2]] etc
# parse MLAT_CONFIG string into mlat_configs array
readarray -td ";" mlat_configs < <(printf '%s' "${MLAT_CONFIG// /}")
# Now loop through the MLAT_CONFIG items and start up an Mlat_client for each of them:
for instance in "${mlat_configs[@]}"
do
[[ -z "${instance}" ]] && continue || true
# put individual params into the $params array:
readarray -td "," params < <(printf '%s' "${instance}")
# Check if the params array has values for the mandatory elements:
if [[ -z "${params[0]}" ]] || [[ -z "${params[1]}" ]]
then
echo "[$(date)][${APPNAME}] ERROR -- MLAT_CONFIG is malformed: \"${instance}\". Stopping MLAT execution."
# shellcheck disable=SC2046
kill $(ps -s $$ -o pid=)
sleep infinity
fi
# Build the MLAT parameter string:
MLAT_PARAM=(--input-type "${MLAT_INPUT_TYPE}")
MLAT_PARAM+=(--input-connect localhost:30005)
MLAT_PARAM+=(--server "${params[0]}:${params[1]}")
MLAT_PARAM+=(--lat "${READSB_LAT}")
MLAT_PARAM+=(--lon "${READSB_LON}")
MLAT_PARAM+=(--alt "${READSB_ALT}")
# [[ -n "${UUID}" ]] && MLAT_PARAM+=(--user "${UUID}") || MLAT_PARAM+=(--user "${MLAT_USER}")
[[ -n "${MLAT_USER}" ]] && MLAT_PARAM+=(--user "${MLAT_USER}") || MLAT_PARAM+=(--user "${UUID}")
[[ -n "${params[2]}" ]] && MLAT_PARAM+=("--results beast,listen,${params[2]}") || true
[[ -n "${params[3]}" ]] && MLAT_PARAM+=("${params[3]}") || true
# shellcheck disable=SC2048,SC2086
execstring="$(echo ${MLAT_CMD} ${MLAT_PARAM[*]} | xargs)"
# run this Mlat_client instance in the background:
echo "[$(date)][${APPNAME}] starting: ${MLAT_CMD} ${MLAT_PARAM[*]}"
{ exec ${execstring} 2>&1 1>/dev/null | stdbuf -o0 awk -v app="${APPNAME}" -v inst="${params[0]}" '{print "[" strftime("%Y/%m/%d %H:%M:%S", systime()) "][" app "][" inst "] " $0}'; } &
pid_array[$!]="${MLAT_PARAM[*]}"
sleep 5
done
# Now iterate over all MLAT-client instances and check if they are still running:
while true
do
for mlat_pid in "${!pid_array[@]}"
do
if ! kill -0 "${mlat_pid}" >/dev/null 2>&1
then
# it exited - let's restart:
sleep "${RESTARTTIMER}"
echo "[$(date)][${APPNAME}] MLAT_Client $(awk '{print $6}' <<< "${pid_array[$mlat_pid]}") exited. Attempting to restart."
# shellcheck disable=SC2086
execstring="$(echo ${MLAT_CMD} ${pid_array[$mlat_pid]} | xargs)"
{ exec ${execstring} 2>&1 1>/dev/null | stdbuf -o0 awk -v app="${APPNAME}" -v inst="$(awk '{split($6,x,":"); print x[1]}' <<< "${pid_array[$mlat_pid]}")" '{print "[" strftime("%Y/%m/%d %H:%M:%S", systime()) "][" app "][" inst "] " $0}'; } &
pid_array[$!]="${pid_array[${mlat_pid}]}"
unset "pid_array[${mlat_pid}]"
fi
done
sleep 10
done

View file

@ -0,0 +1,99 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash disable=SC2016
# /usr/local/bin/readsb --net-bind-address=0.0.0.0 --quiet --write-output=/run/readsb --forward-mlat --gain=-10 --net --net-bo-port=30105 --net-connector=tar1090,30003,beast_in --net-connector=piaware,30105,beast_in --net-connector=rbfeeder,30105,beast_in --net-connector=radarvirtuel,30105,beast_in --net-connector=multifeeder,39000,beast_in --net-connector=multifeeder,39001,beast_in --net-connector=multifeeder,39002,beast_in --net-connector=multifeeder,39003,beast_in --net-connector=multifeeder,39004,beast_in --net-only --net-ro-port=30002 --net-sbs-port=30003
if [[ -z "${MLAT_CONFIG}" ]]
then
echo "[$(date)][mlathub] No MLAT servers have been defined in MLAT_CONFIG - no need to start MLATHUB"
sleep infinity
fi
if [[ -n "${MLATHUB_DISABLED}" ]]
then
echo "[$(date)][mlathub] MLATHUB is disabled."
sleep infinity
fi
# Build the readsb command line based on options
MLATHUB_BIN="/usr/local/bin/readsb"
MLATHUB_CMD=("--net")
MLATHUB_CMD+=("--quiet")
MLATHUB_CMD+=("--net-only")
MLATHUB_CMD+=("--mlat")
MLATHUB_CMD+=("--forward-mlat")
MLATHUB_CMD+=("--net-bo-port=${MLATHUB_BEAST_OUT_PORT:-39105}")
MLATHUB_CMD+=("--net-sbs-port=${MLATHUB_SBS_OUTPUT_PORT:-39003}")
# We need to get the mlat results ports from the parameters:
# parse MLAT_CONFIG string into mlat_configs array
readarray -td ";" mlat_configs < <(printf '%s' "${MLAT_CONFIG// /}")
# Now loop through the MLAT_CONFIG items and start up an Mlat_client for each of them:
mlat_result_sources=0
for instance in "${mlat_configs[@]}"
do
[[ -z "${instance}" ]] && continue || true
# put individual params into the $params array:
readarray -td "," params < <(printf '%s' "${instance}")
if [[ -n "${params[2]}" ]]
then
MLATHUB_CMD+=("--net-connector=localhost,${params[2]},beast_in")
(( mlat_result_sources++ ))
fi
done
if ((mlat_result_sources == 0 ))
then
echo "[$(date)][mlathub] No MLAT servers have been defined in MLAT_CONFIG - no need to start MLATHUB"
sleep infinity
fi
# Add any additional net_connectors:
if [[ -n "$MLATHUB_NET_CONNECTOR" ]]; then
IFS=';' read -r -a MLATHUB_NET_CONNECTOR_ARRAY <<< "$MLATHUB_NET_CONNECTOR"
for NET_CONNECTOR_ELEMENT in "${MLATHUB_NET_CONNECTOR_ARRAY[@]}"
do
MLATHUB_CMD+=("--net-connector=${NET_CONNECTOR_ELEMENT// /}")
done
fi
if [ -n "${READSB_DEBUG}" ]; then
MLATHUB_CMD+=("--debug=$READSB_DEBUG")
fi
if [ -n "${LAT}" ]; then
MLATHUB_CMD+=(--lat "${LAT}")
elif [ -n "${READSB_LAT}" ]; then
MLATHUB_CMD+=(--lat "${READSB_LAT}")
fi
if [ -n "${LONG}" ]; then
MLATHUB_CMD+=(--lon "${LONG}")
elif [ -n "${READSB_LON}" ]; then
MLATHUB_CMD+=(--lon "${READSB_LON}")
fi
# Handle "--max-range=<dist>"
if [[ -n "$READSB_MAX_RANGE" ]]; then
MLATHUB_CMD+=("--max-range=$READSB_MAX_RANGE")
fi
# Handle "--net-connector-delay=<seconds>"
if [[ -n "$READSB_NET_CONNECTOR_DELAY" ]]; then
MLATHUB_CMD+=("--net-connector-delay=$READSB_NET_CONNECTOR_DELAY")
fi
# Handle "--net-heartbeat=<rate>"
if [[ -n "$READSB_NET_HEARTBEAT" ]]; then
MLATHUB_CMD+=("--net-heartbeat=$READSB_NET_HEARTBEAT")
fi
echo "[$(date)][mlathub] Starting MLATHUB with this command line: ${MLATHUB_BIN} ${MLATHUB_CMD[*]} $MLATHUB_EXTRA_ARGS"
# shellcheck disable=SC2086
"${MLATHUB_BIN}" "${MLATHUB_CMD[@]}" $MLATHUB_EXTRA_ARGS 2>&1 | \
mawk -W Interactive '{print "[" strftime("%Y/%m/%d %H:%M:%S", systime()) "][mlathub] " $0}'

View file

@ -0,0 +1,297 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash disable=SC2016
#all-in-one
mkdir -p /run/readsb
# Build the readsb command line based on options
READSB_BIN="/usr/local/bin/readsb"
READSB_CMD=("--net")
READSB_CMD+=("--quiet")
if [ -n "${READSB_NET_ONLY}" ]; then
READSB_CMD+=("--net-only")
fi
if [ -n "${LAT}" ]; then
READSB_CMD+=(--lat "${LAT}")
elif [ -n "${READSB_LAT}" ]; then
READSB_CMD+=(--lat "${READSB_LAT}")
fi
if [ -n "${LONG}" ]; then
READSB_CMD+=(--lon "${LONG}")
elif [ -n "${READSB_LON}" ]; then
READSB_CMD+=(--lon "${READSB_LON}")
fi
if [ -n "${MLATHOST}" ]; then
READSB_CMD+=("--net-connector=${MLATHOST},${MLATPORT},beast_in")
fi
if [ -n "${BEASTHOST}" ]; then
READSB_CMD+=("--net-connector=${BEASTHOST},${BEASTPORT},beast_in")
fi
if [ -n "${UUID}" ]; then
READSB_CMD+=("--uuid-file=/run/uuid")
fi
READSB_CMD+=("--write-json=/run/readsb")
READSB_CMD+=("--heatmap-dir=/var/globe_history")
READSB_CMD+=("--heatmap=15")
READSB_CMD+=("--write-state=/var/globe_history")
READSB_CMD+=("--json-trace-interval=15")
READSB_CMD+=("--json-reliable=1")
READSB_CMD+=("--net-ri-port=30001")
READSB_CMD+=("--net-ro-port=30002")
READSB_CMD+=("--net-sbs-port=30003")
READSB_CMD+=("--net-bi-port=30004,30104")
READSB_CMD+=("--net-bo-port=30005")
READSB_CMD+=("--net-beast-reduce-out-port=30006")
READSB_CMD+=("--net-json-port=30047")
READSB_CMD+=(--net-api-port=30152)
# READSB_CMD+=(--forward-mlat)
READSB_CMD+=(--net-sbs-in-port=32006)
if [[ -n "${READSB_FORWARD_MLAT}" ]]; then
READSB_CMD+=("--forward-mlat")
fi
if [[ -n "$READSB_RX_LOCATION_ACCURACY" ]]; then
READSB_CMD+=("--json-location-accuracy=$READSB_RX_LOCATION_ACCURACY")
fi
if [[ -n "$READSB_JSON_INTERVAL" ]]; then
READSB_CMD+=("--write-json-every=$READSB_JSON_INTERVAL")
fi
if [ -n "${READSB_DEBUG}" ]; then
READSB_CMD+=("--debug=$READSB_DEBUG")
fi
# Handle --write-state-only-on-exit
if [ -n "${READSB_WRITE_STATE_ONLY_ON_EXIT}" ]; then
READSB_CMD+=("--write-state-only-on-exit")
fi
# Handle "--max-range=<dist>"
if [[ -n "$READSB_MAX_RANGE" ]]; then
READSB_CMD+=("--max-range=$READSB_MAX_RANGE")
fi
# Handle "--mlat"
if [[ -n "$READSB_MLAT" ]]; then
READSB_CMD+=("--mlat")
fi
# Handle "--modeac"
if [[ -n "$READSB_MODEAC" ]]; then
READSB_CMD+=("--modeac")
fi
# Handle "--stats-every=<sec>"
if [[ -n "$READSB_STATS_EVERY" ]]; then
READSB_CMD+=("--stats-every=$READSB_STATS_EVERY")
fi
# Handle "--stats-range"
if [[ -n "$READSB_STATS_RANGE" ]]; then
READSB_CMD+=("--stats-range")
fi
if [[ -n "$READSB_RANGE_OUTLINE_HOURS" ]]; then
READSB_CMD+=("--range-outline-hours=$READSB_RANGE_OUTLINE_HOURS")
fi
##### NETWORK OPTIONS #####
#
READSB_CMD+=("--net-api-port=${READSB_NET_API_PORT:-30152")
# Handle "--net-beast-reduce-interval=<seconds>"
if [[ -n "$READSB_NET_BEAST_REDUCE_INTERVAL" ]]; then
READSB_CMD+=("--net-beast-reduce-interval=$READSB_NET_BEAST_REDUCE_INTERVAL")
fi
# Handle "--net-beast-reduce-out-port=<ports>"
if [[ -n "$READSB_NET_BEAST_REDUCE_OUT_PORT" ]]; then
READSB_CMD+=("--net-beast-reduce-out-port=$READSB_NET_BEAST_REDUCE_OUT_PORT")
fi
if [[ -n "$READSB_NET_SBS_REDUCE" ]]; then
READSB_CMD+=("--net-sbs-reduce")
fi
if [[ -n "$READSB_NET_BEAST_REDUCE_FILTER_DIST" ]]; then
READSB_CMD+=("--net-beast-reduce-filter-dist=$READSB_NET_BEAST_REDUCE_FILTER_DIST")
fi
if [[ -n "$READSB_JSON_TRACE_INTERVAL" ]]; then
READSB_CMD+=("--json-trace-interval=$READSB_JSON_TRACE_INTERVAL")
fi
if [[ -n "$READSB_HEATMAP_INTERVAL" ]]; then
READSB_CMD+=("--heatmap=$READSB_HEATMAP_INTERVAL")
fi
if [[ -n "$READSB_NET_BEAST_REDUCE_FILTER_ALT" ]]; then
READSB_CMD+=("--net-beast-reduce-filter-alt=$READSB_NET_BEAST_REDUCE_FILTER_ALT")
fi
# Handle "--net-bi-port=<ports>"
if [[ -n "$READSB_NET_BEAST_INPUT_PORT" ]]; then
READSB_CMD+=("--net-bi-port=$READSB_NET_BEAST_INPUT_PORT")
fi
# Handle "--net-bo-port=<ports>"
if [[ -n "$READSB_NET_BEAST_OUTPUT_PORT" ]]; then
READSB_CMD+=("--net-bo-port=$READSB_NET_BEAST_OUTPUT_PORT")
fi
# Handle "--net-buffer=<n>"
if [[ -n "$READSB_NET_BUFFER" ]]; then
READSB_CMD+=("--net-buffer=$READSB_NET_BUFFER")
fi
# Handle "--net-connector=<ip,port,protocol>"
if [[ -n "$READSB_NET_CONNECTOR" ]]; then
IFS=';' read -r -a READSB_NET_CONNECTOR_ARRAY <<< "$READSB_NET_CONNECTOR"
for NET_CONNECTOR_ELEMENT in "${READSB_NET_CONNECTOR_ARRAY[@]}"
do
READSB_CMD+=("--net-connector=${NET_CONNECTOR_ELEMENT// /}")
done
fi
# Handle "--net-connector-delay=<seconds>"
if [[ -n "$READSB_NET_CONNECTOR_DELAY" ]]; then
READSB_CMD+=("--net-connector-delay=$READSB_NET_CONNECTOR_DELAY")
fi
# Handle "--net-heartbeat=<rate>"
if [[ -n "$READSB_NET_HEARTBEAT" ]]; then
READSB_CMD+=("--net-heartbeat=$READSB_NET_HEARTBEAT")
fi
# Handle "--net-ri-port=<ports>"
if [[ -n "$READSB_NET_RAW_INPUT_PORT" ]]; then
READSB_CMD+=("--net-ri-port=$READSB_NET_RAW_INPUT_PORT")
fi
# Handle "--net-ro-interval=<rate>"
if [[ -n "$READSB_NET_RAW_OUTPUT_INTERVAL" ]]; then
READSB_CMD+=("--net-ro-interval=$READSB_NET_RAW_OUTPUT_INTERVAL")
fi
# Handle "--net-ri-port=<ports>"
if [[ -n "$READSB_NET_RAW_OUTPUT_PORT" ]]; then
READSB_CMD+=("--net-ro-port=$READSB_NET_RAW_OUTPUT_PORT")
fi
# Handle "--net-ro-size=<size>"
if [[ -n "$READSB_NET_RAW_OUTPUT_SIZE" ]]; then
READSB_CMD+=("--net-ro-size=$READSB_NET_RAW_OUTPUT_SIZE")
fi
# Handle "--net-sbs-in-port=<ports>"
if [[ -n "$READSB_NET_SBS_INPUT_PORT" ]]; then
READSB_CMD+=("--net-sbs-in-port=$READSB_NET_SBS_INPUT_PORT")
fi
# Handle "--net-sbs-port=<ports>"
if [[ -n "$READSB_NET_SBS_OUTPUT_PORT" ]]; then
READSB_CMD+=("--net-sbs-port=$READSB_NET_SBS_OUTPUT_PORT")
fi
# Handle "--net-verbatim"
if [[ -n "$REASSB_NET_VERBATIM" ]]; then
READSB_CMD+=("--net-verbatim")
fi
# Handle "--net-vrs-port=<ports>"
if [[ -n "$READSB_NET_VRS_PORT" ]]; then
READSB_CMD+=("--net-vrs-port=$READSB_NET_VRS_PORT")
fi
# make sure the db file exists, and if it does, use it
if [[ -e $TAR1090_INSTALL_DIR/aircraft.csv.gz ]]; then
if [[ "$TAR1090_ENABLE_AC_DB" == "true" ]]; then
READSB_CMD+=("--db-file=$TAR1090_INSTALL_DIR/aircraft.csv.gz")
fi
fi
# Handle "--device-type"
if [[ -n "$READSB_DEVICE_TYPE" ]]; then
READSB_CMD+=("--device-type=$READSB_DEVICE_TYPE")
fi
if [[ -n "$READSB_GAIN" ]]; then
READSB_CMD+=("--gain=$READSB_GAIN")
fi
##### RTL-SDR OPTIONS #####
# Handle "--device=<index|serial>"
if [[ -n "$READSB_RTLSDR_DEVICE" ]]; then
READSB_CMD+=("--device=$READSB_RTLSDR_DEVICE")
fi
# Handle "--enable-agc"
if [[ -n "$READSB_RTLSDR_ENABLE_AGC" ]]; then
READSB_CMD+=("--enable-agc")
fi
# Handle "--ppm=<correction>"
if [[ -n "$READSB_RTLSDR_PPM" ]]; then
READSB_CMD+=("--ppm=$READSB_RTLSDR_PPM")
fi
##### MODE-S BEAST OPTIONS #####
# Handle "--beast-crc-off"
if [[ -n "$READSB_BEAST_CRC_OFF" ]]; then
READSB_CMD+=("--beast-crc-off")
fi
# Handle "--beast-df045-on"
if [[ -n "$READSB_BEAST_DF045_ON" ]]; then
READSB_CMD+=("--beast-df045-on")
fi
# Handle "--beast-df1117-on"
if [[ -n "$READSB_BEAST_DF1117_ON" ]]; then
READSB_CMD+=("--beast-df1117-on")
fi
# Handle "--beast-fec-off"
if [[ -n "$READSB_BEAST_FEC_OFF" ]]; then
READSB_CMD+=("--beast-fec-off")
fi
# Handle "--beast-mlat-off"
if [[ -n "$READSB_BEAST_MLAT_OFF" ]]; then
READSB_CMD+=("--beast-mlat-off")
fi
# Handle "--beast-modeac"
if [[ -n "$READSB_BEAST_MODEAC" ]]; then
READSB_CMD+=("--beast-modeac")
fi
# Handle "--beast-serial=<path>"
if [[ -n "$READSB_BEAST_SERIAL" ]]; then
READSB_CMD+=("--beast-serial=$READSB_BEAST_SERIAL")
fi
if [[ -n "$READSB_BEAST_BAUDRATE" ]]; then
READSB_CMD+=("--beast-baudrate=$READSB_BEAST_BAUDRATE")
fi
# shellcheck disable=SC2086
"${READSB_BIN}" "${READSB_CMD[@]}" $READSB_EXTRA_ARGS 2>&1 | \
mawk -W Interactive '{print "[" strftime("%Y/%m/%d %H:%M:%S", systime()) "][readsb] " $0}'