Skip to content

Commit 76bc419

Browse files
wiedehopfThom-x
andauthored
feat: asdbexchange support (#80)
Co-authored-by: Thomas MAUGIN <maugin.thomas@gmail.com>
1 parent 3c9dcf7 commit 76bc419

File tree

28 files changed

+230
-1
lines changed

28 files changed

+230
-1
lines changed

Dockerfile

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,74 @@ RUN ./sensible-build.sh ${DEBIAN_VERSION} && \
6868
cd package-${DEBIAN_VERSION} && \
6969
dpkg-buildpackage -b
7070

71+
#ADSBEXCHANGE
72+
# pinned commits, feel free to update to most recent commit, no major versions usually
73+
74+
FROM debian:buster as adsbexchange_packages
75+
76+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
77+
WORKDIR /tmp
78+
RUN set -x && \
79+
apt-get update && \
80+
apt-get install -y --no-install-suggests --no-install-recommends \
81+
jq \
82+
uuid-runtime \
83+
wget \
84+
make \
85+
gcc \
86+
ncurses-dev \
87+
ncurses-bin \
88+
zlib1g-dev \
89+
zlib1g \
90+
python3-venv \
91+
python3-dev
92+
93+
FROM adsbexchange_packages as adsbexchange
94+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
95+
WORKDIR /tmp
96+
RUN set -x && \
97+
mkdir -p /usr/local/share/adsbexchange/ && \
98+
SRCTMP=/srctmp && \
99+
# readsb as a feed client
100+
URL=https://github.com/adsbxchange/readsb && \
101+
COMMIT=da57fe341a2485fbeb645147f3738c565c38c312 && \
102+
mkdir -p $SRCTMP && wget -O ${SRCTMP}.tar.gz ${URL}/archive/${COMMIT}.tar.gz && tar xf ${SRCTMP}.tar.gz -C ${SRCTMP} --strip-components=1 && \
103+
pushd ${SRCTMP} && \
104+
echo "$COMMIT" > READSB_VERSION && \
105+
cat READSB_VERSION && \
106+
make -j "$(nproc)" AIRCRAFT_HASH_BITS=12 && \
107+
cp -v -T readsb /usr/local/share/adsbexchange/readsb && \
108+
popd && \
109+
rm -rf ${SRCTMP} ${SRCTMP}.tar.gz && \
110+
# mlat-client
111+
URL=https://github.com/adsbxchange/mlat-client &&\
112+
COMMIT=8d8b5a784727526620d5608c6d581fe3082deb79 && \
113+
mkdir -p $SRCTMP && wget -O ${SRCTMP}.tar.gz ${URL}/archive/${COMMIT}.tar.gz && tar xf ${SRCTMP}.tar.gz -C ${SRCTMP} --strip-components=1 && \
114+
pushd ${SRCTMP} && \
115+
VENV="/usr/local/share/adsbexchange/venv" && \
116+
python3 -m venv "${VENV}" && \
117+
source "${VENV}/bin/activate" && \
118+
./setup.py build && \
119+
./setup.py install && \
120+
deactivate && \
121+
popd && \
122+
ldconfig && \
123+
rm -rf ${SRCTMP} ${SRCTMP}.tar.gz && \
124+
# adsbexchange-stats
125+
URL=https://github.com/adsbxchange/adsbexchange-stats && \
126+
COMMIT=6b9fe07ba728de5e732fe87fa3ae0afdbb390709 && \
127+
mkdir -p $SRCTMP && wget -O ${SRCTMP}.tar.gz ${URL}/archive/${COMMIT}.tar.gz && tar xf ${SRCTMP}.tar.gz -C ${SRCTMP} --strip-components=1 && \
128+
cp -v -T ${SRCTMP}/json-status /usr/local/share/adsbexchange/json-status && \
129+
rm -rf ${SRCTMP} ${SRCTMP}.tar.gz && \
130+
# Clean-up
131+
apt-get remove -y ${TEMP_PACKAGES[@]} && \
132+
apt-get autoremove -y && \
133+
rm -rf /tmp/* /var/lib/apt/lists/* && \
134+
# readsb: simple tests
135+
/usr/local/share/adsbexchange/readsb --version && \
136+
# mlat-client: simple test
137+
/usr/local/share/adsbexchange/venv/bin/python3 -c 'import mlat.client'
138+
71139
# THTTPD
72140
FROM alpine:3.13.2 AS thttpd
73141

@@ -101,6 +169,7 @@ FROM debian:buster-slim as copyall
101169
COPY --from=dump1090 /tmp/dump1090/dump1090 /copy_root/usr/lib/fr24/
102170
COPY --from=dump1090 /tmp/dump1090/public_html_merged /copy_root/usr/lib/fr24/public_html
103171
COPY --from=piaware /tmp/piaware_builder /copy_root/piaware_builder
172+
COPY --from=adsbexchange /usr/local/share/adsbexchange /copy_root/usr/local/share/adsbexchange
104173
RUN mv /copy_root/piaware_builder/piaware_*_*.deb /copy_root/piaware.deb && \
105174
rm -rf /copy_root/piaware_builder
106175
COPY --from=thttpd /thttpd/thttpd /copy_root/
@@ -149,7 +218,15 @@ RUN apt-get update && \
149218
librtlsdr-dev \
150219
pkg-config \
151220
libncurses5-dev \
152-
libbladerf-dev && \
221+
libbladerf-dev \
222+
# adsbexchange
223+
jq \
224+
ncurses-bin \
225+
zlib1g \
226+
python3-venv \
227+
curl \
228+
gzip \
229+
&& \
153230
# RTL-SDR
154231
cd /tmp && \
155232
mkdir -p /etc/modprobe.d && \

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ docker run -d -p 8080:8080 -p 8754:8754 \
3636
-e "HTML_SITE_NAME=MY_SITE_NAME" \
3737
-e "PANORAMA_ID=MY_PANORAMA_ID" \
3838
-e "LAYERS_OWM_API_KEY=MY_OWM_API_KEY" \
39+
-e "SERVICE_ENABLE_ADSBEXCHANGE=true" \
40+
-e "ADSBEXCHANGE_UUID=MY_UUID" \
41+
-e "ADSBEXCHANGE_STATION_NAME=MY_STATION_NAME" \
42+
-e "MLAT_EXACT_LAT=MY_EXACT_SITE_LAT" \
43+
-e "MLAT_EXACT_LON=MY_EXACT_SITE_LON" \
44+
-e "MLAT_ALTITUDE_MSL_METERS=MY_SITE_ALT_MSL_METERS" \
3945
thomx/fr24feed-piaware
4046
```
4147

@@ -58,6 +64,7 @@ To disable starting a service you can add an environement variable :
5864
| `SERVICE_ENABLE_FR24FEED` | `false` | Disable fr24feed service |
5965
| `SERVICE_ENABLE_HTTP` | `false` | Disable http service |
6066
| `SERVICE_ENABLE_IMPORT_OVER_NETCAT` | `false` | Disable import over netcat|
67+
| `SERVICE_ENABLE_ADSBEXCHANGE` | `false` | Disable adsbexchange feed |
6168

6269

6370
Ex : `-e "SERVICE_ENABLE_HTTP=false"`
@@ -73,6 +80,7 @@ docker run -it --rm \
7380
-e "SERVICE_ENABLE_DUMP1090=false" \
7481
-e "SERVICE_ENABLE_HTTP=false" \
7582
-e "SERVICE_ENABLE_FR24FEED=false" \
83+
-e "SERVICE_ENABLE_ADSBEXCHANGE=false" \
7684
thomx/fr24feed-piaware /bin/bash
7785
```
7886
When the container starts you should see the feeder id, note it. Wait 5 minutes and you should see a new receiver at https://fr.flightaware.com/adsb/piaware/claim (use the same IP as your docker host), claim it and exit the container.
@@ -98,6 +106,7 @@ docker run -it --rm \
98106
-e "SERVICE_ENABLE_HTTP=false" \
99107
-e "SERVICE_ENABLE_PIAWARE=false" \
100108
-e "SERVICE_ENABLE_FR24FEED=false" \
109+
-e "SERVICE_ENABLE_ADSBEXCHANGE=false" \
101110
thomx/fr24feed-piaware /bin/bash
102111
```
103112

@@ -122,6 +131,45 @@ Add the environment variable `FR24FEED_FR24KEY` with your sharing key.
122131

123132
Ex : `-e "FR24FEED_FR24KEY=0123456789"`
124133

134+
## ADS-B Exchange
135+
136+
137+
Add the environment variable `ADSBEXCHANGE_UUID` with a UUID generated by <https://www.adsbexchange.com/myip/gen-uuid/>.
138+
In case of multiple receivers, please use a different UUID for each receiver.
139+
140+
Add the environment variable `SERVICE_ENABLE_ADSBEXCHANGE` and set it to `true`.
141+
142+
143+
| Environment Variable | Configuration property | Default value |
144+
|---------------------------------------|--------------------------|-------------------|
145+
| `SERVICE_ENABLE_ADSBEXCHANGE` | `enable this feed client`| `false` |
146+
| `ADSBEXCHANGE_UUID` | `uuid (required)` | `none` |
147+
| `ADSBEXCHANGE_STATION_NAME` | `station name` | `none` |
148+
| `ADSBEXCHANGE_MLAT` | `mlat` | `true` |
149+
150+
Configure the MLAT coordinates so that adsbexchange MLAT can work. (see its own section below)
151+
If you don't want to supply your exact coordinates, please set the `ADSBEXCHANGE_MLAT` environment variable to `false`. (you won't get MLAT results and won't contribute to MLAT)
152+
153+
Add the environment variable `ADSBEXCHANGE_STATION_NAME`, it will be used for the mlat map / sync status.
154+
You can check that your MLAT is working correctly by searching for your station name here: <https://map.adsbexchange.com/mlat-map/>
155+
(MLAT map marker is snapped to a 5 mile grid and then offset randomly to avoid stacking markers, the precise lat / lon for MLAT are not publicly accessible at adsbexchange)
156+
157+
The ADS-B Exchange Anywhere map will be available at: <https://www.adsbexchange.com/api/feeders/?feed=MY_UUID>
158+
159+
## Exact coordinates for MLAT
160+
161+
Get your exact coordinates and altitude above sealevel in meters from one these websites:
162+
- <https://www.freemaptools.com/elevation-finder.htm>
163+
- <https://www.mapcoordinates.net/en>
164+
165+
It's important for MLAT accuracy that these aren't off by more than about 10 m / 30 ft.
166+
167+
| Environment Variable | Configuration property | Default value |
168+
|---------------------------------------|--------------------------|-------------------|
169+
| `MLAT_EXACT_LAT` | `decimal latitude` | `none` |
170+
| `MLAT_EXACT_LON` | `decimal longitude` | `none` |
171+
| `MLAT_ALTITUDE_MSL_METERS` | `altitude above MSL in m`| `none` |
172+
125173
## Add custom properties
126174

127175
**Note** : you can add any property to either fr24feed or piaware configuration file by adding an environment variable starting with `PIAWARE_...` or `FR24FEED_...`.

docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ services:
2727
logging:
2828
options:
2929
max-size: "30m"
30+
tmpfs:
31+
- /run:exec,size=32M
32+
- /usr/lib/fr24/public_html/data:size=32M

root/etc/s6-overlay/s6-rc.d/adsbexchange-bundle/contents.d/adsbexchange-feed

Whitespace-only changes.

root/etc/s6-overlay/s6-rc.d/adsbexchange-bundle/contents.d/adsbexchange-mlat

Whitespace-only changes.

root/etc/s6-overlay/s6-rc.d/adsbexchange-bundle/contents.d/adsbexchange-stats

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bundle

root/etc/s6-overlay/s6-rc.d/adsbexchange-feed/dependencies.d/conf-adsbexchange

Whitespace-only changes.

root/etc/s6-overlay/s6-rc.d/adsbexchange-feed/dependencies.d/dump1090

Whitespace-only changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/command/with-contenv bash
2+
3+
# exit container stop s6
4+
kill 1
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/command/with-contenv bash
2+
3+
set -eo pipefail
4+
5+
/usr/local/share/adsbexchange/readsb --net-only --debug=n --quiet \
6+
--net-beast-reduce-interval 0.5 --net-connector feed.adsbexchange.com,30004,beast_reduce_out,feed.adsbexchange.com,64004 \
7+
--write-json /run/adsbexchange-feed \
8+
--write-json-every 1 \
9+
--write-prom /run/adsbexchange-feed/stats.prom \
10+
--net-heartbeat 60 --net-ro-size 1280 --net-ro-interval 0.2 \
11+
--net-bi-port 30154 \
12+
--net-connector 127.0.0.1,30005,beast_in \
13+
--lat "${HTML_SITE_LAT}" --lon "${HTML_SITE_LON}" \
14+
2>&1 | mawk -W interactive '{printf "%c[32m[adsbexchange-feed]%c[0m %s\n", 27, 27, $0}'
15+
16+
# awk -W interactive ... (prefix log messages with color and "[adsbexchange-feed]")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
longrun

root/etc/s6-overlay/s6-rc.d/adsbexchange-mlat/dependencies.d/adsbexchange-feed

Whitespace-only changes.

root/etc/s6-overlay/s6-rc.d/adsbexchange-mlat/dependencies.d/conf-adsbexchange

Whitespace-only changes.

root/etc/s6-overlay/s6-rc.d/adsbexchange-mlat/dependencies.d/dump1090

Whitespace-only changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/command/with-contenv bash
2+
3+
# exit container stop s6
4+
kill 1
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/command/with-contenv bash
2+
3+
if [ "$ADSBEXCHANGE_MLAT" == "no" ] || [ "$ADSBEXCHANGE_MLAT" == "false" ]; then
4+
tail -f /dev/null
5+
exit 0
6+
fi
7+
8+
set -eo pipefail
9+
10+
MLAT_ALTITUDE_MSL_METERS="$( echo "${MLAT_ALTITUDE_MSL_METERS}" | tr --delete ' m')"
11+
12+
if [ -z "$MLAT_EXACT_LAT" ] || [ -z "$MLAT_EXACT_LON" ] || [ -z "$MLAT_ALTITUDE_MSL_METERS" ] || [ -z "$ADSBEXCHANGE_STATION_NAME" ]; then
13+
for i in {1..5}; do
14+
echo "FATAL: MLAT_EXACT_LAT or MLAT_EXACT_LON or MLAT_ALTITUDE_MSL_METERS or ADSBEXCHANGE_STATION_NAME not set!" | mawk -W interactive '{printf "%c[32m[adsbexchange-conf]%c31m %s\n", 27, 27, $0}'
15+
done
16+
kill 1
17+
exit 1
18+
fi
19+
# pushes MLAT results into dump1090 via port 30104
20+
# listens on 31003 to provide MLAT results as SBS / basestation
21+
# listens on 30157 to provide MLAT results as beast
22+
# pushes MLAT results into adsbexchange-feed so adsbexchange-stats can push a json with MLAT results for the anywhere map
23+
/usr/local/share/adsbexchange/venv/bin/mlat-client \
24+
--input-type dump1090 --no-udp \
25+
--input-connect 127.0.0.1:30005 \
26+
--server feed.adsbexchange.com:31090 \
27+
--lat "${MLAT_EXACT_LAT}" --lon "${MLAT_EXACT_LON}" \
28+
--alt "${MLAT_ALTITUDE_MSL_METERS}" \
29+
--user "${ADSBEXCHANGE_STATION_NAME}" \
30+
--results beast,connect,127.0.0.1:30104 \
31+
--results basestation,listen,31003 \
32+
--results beast,listen,30157 \
33+
--results beast,connect,127.0.0.1:30154 \
34+
2>&1 | mawk -W interactive '{printf "%c[32m[adsbexchange-mlat]%c[0m %s\n", 27, 27, $0}'
35+
36+
# awk -W interactive ... (prefix log messages with color and "[adsbexchange-mlat]")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
longrun

root/etc/s6-overlay/s6-rc.d/adsbexchange-stats/dependencies.d/adsbexchange-feed

Whitespace-only changes.

root/etc/s6-overlay/s6-rc.d/adsbexchange-stats/dependencies.d/conf-adsbexchange

Whitespace-only changes.

root/etc/s6-overlay/s6-rc.d/adsbexchange-stats/dependencies.d/dump1090

Whitespace-only changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/command/with-contenv bash
2+
3+
# exit container stop s6
4+
kill 1
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/command/with-contenv bash
2+
3+
set -eo pipefail
4+
5+
/usr/local/share/adsbexchange/json-status 2>&1 | mawk -W interactive '{printf "%c[32m[adsbexchange-stats]%c[0m %s\n", 27, 27, $0}'
6+
7+
# awk -W interactive ... (prefix log messages with color and "[adsbexchange-stats]")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
longrun
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/command/with-contenv bash
2+
3+
SERVICE_ENABLE_ADSBEXCHANGE=${SERVICE_ENABLE_ADSBEXCHANGE:-false}
4+
5+
if [ "$SERVICE_ENABLE_ADSBEXCHANGE" == "false" ]; then
6+
exit 1
7+
fi
8+
9+
if (( ${#ADSBEXCHANGE_UUID} == 36 )); then
10+
set -eo pipefail
11+
12+
echo "${ADSBEXCHANGE_UUID}" > /usr/local/share/adsbexchange/adsbx-uuid
13+
mkdir -p /run/adsbexchange-stats
14+
mkdir -p /run/adsbexchange-feed
15+
16+
# delay other adsbexchange services a little bit to produce less error messages on startup
17+
sleep 1.5
18+
else
19+
for i in {1..5}; do
20+
echo "FATAL: ADSB_EXCHANGE_UUID not set or invalid!" | mawk -W interactive '{printf "%c[32m[adsbexchange-conf]%c[31m %s\n", 27, 27, $0}'
21+
done
22+
kill 1
23+
exit 1
24+
fi
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
oneshot
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/etc/s6-overlay/s6-rc.d/conf-adsbexchange/script

root/etc/s6-overlay/s6-rc.d/user/contents.d/adsbexchange-bundle

Whitespace-only changes.

0 commit comments

Comments
 (0)