From 056cedc107483c26fec6202fc6e0a94da36c8bfb Mon Sep 17 00:00:00 2001 From: Astro Date: Sat, 30 Oct 2021 22:52:01 +0200 Subject: [PATCH] radiobert: switch from dump1090 to readsb --- hosts/containers/sdrweb/adsb.html | 2 +- hosts/radiobert/dump1090.nix | 21 +++++++++- hosts/radiobert/sbs2json.rb | 67 +++++++++++++++++++++++++++++++ hosts/radiobert/soapysdr.nix | 2 + overlay/default.nix | 2 + overlay/readsb.nix | 37 +++++++++++++++++ 6 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 hosts/radiobert/sbs2json.rb create mode 100644 overlay/readsb.nix diff --git a/hosts/containers/sdrweb/adsb.html b/hosts/containers/sdrweb/adsb.html index 73cecdaa..87bee301 100644 --- a/hosts/containers/sdrweb/adsb.html +++ b/hosts/containers/sdrweb/adsb.html @@ -136,7 +136,7 @@ myplane.flight = plane.flight; if (myplane.hex == Selected) refreshSelectedInfo(); - } else { + } else if (plane.lat && plane.lon) { var icon = getIconForPlane(plane); var marker = L.marker([plane.lat, plane.lon], {icon: icon}).addTo(Map); var hex = plane.hex; diff --git a/hosts/radiobert/dump1090.nix b/hosts/radiobert/dump1090.nix index a76022d6..733b98d7 100644 --- a/hosts/radiobert/dump1090.nix +++ b/hosts/radiobert/dump1090.nix @@ -16,13 +16,29 @@ systemd.services.dump1090 = { wantedBy = [ "multi-user.target" ]; serviceConfig = { - ExecStart = "${pkgs.dump1090_sdrplus}/bin/dump1090 --aggressive --net"; + ExecStart = "${pkgs.readsb}/bin/readsb --modeac --aggressive --net --net-sbs-port=30003"; User = "dump1090"; Group = "dump1090"; ProtectSystem = "full"; ProtectHome = true; WorkingDirectory = "/tmp/dump1090"; WritablePaths = "/tmp/dump1090"; + Restart = "always"; + RestartSec = "10s"; + }; + }; + # SHIM because readsb has no web server like dump1090 + systemd.services.sbs2json = { + wantedBy = [ "multi-user.target" ]; + requires = [ "dump1090.service" ]; + serviceConfig = { + ExecStart = "${pkgs.ruby}/bin/ruby ${./sbs2json.rb}"; + User = "dump1090"; + Group = "dump1090"; + ProtectSystem = "full"; + ProtectHome = true; + Restart = "always"; + RestartSec = "10s"; }; }; @@ -32,7 +48,7 @@ }; systemd.services.dump1090-influxdb = { wantedBy = [ "multi-user.target" ]; - requires = [ "dump1090.services" ]; + requires = [ "dump1090.service" ]; serviceConfig = { ExecStart = "${pkgs.dump1090-influxdb}/bin/dump1090-influxdb"; User = "dump1090-influxdb"; @@ -46,5 +62,6 @@ environment.systemPackages = with pkgs; [ dump1090_sdrplus + readsb ]; } diff --git a/hosts/radiobert/sbs2json.rb b/hosts/radiobert/sbs2json.rb new file mode 100644 index 00000000..d61d7c0b --- /dev/null +++ b/hosts/radiobert/sbs2json.rb @@ -0,0 +1,67 @@ +#!/usr/bin/env ruby + +require 'socket' +require 'webrick' +require 'json' + +TIMEOUT = 60 +data = {} + +Thread.new do + server = WEBrick::HTTPServer.new :Port => 8080 + server.mount_proc "/data.json" do |req, res| + res.status = 200 + res['Content-Type'] = 'application/json' + res.body = data.values.to_json + end + server.start +end + +sock = TCPSocket.new "radiobert.serv.zentralwerk.org", 30003 +while line = sock.gets + begin + fields = line.chomp.split(/,/) + msg_type = fields[1].to_i + values = { + :hex => fields[4].downcase, + :last => Time.now.to_i + } + + case msg_type + when 1 + values[:flight] = fields[10] + + when 3 + unless fields[14].empty? or fields[15].empty? + values[:lat] = fields[14].to_f + values[:lon] = fields[15].to_f + end + unless fields[11].empty? + values[:altitude] = fields[11].to_i + end + + when 4 + unless fields[12].empty? + values[:speed] = fields[12].to_i + end + unless fields[13].empty? + values[:track] = fields[13].to_i + end + end + + old_value = data[values[:hex]] + if old_value + old_value.merge! values + else + data[values[:hex]] = values + end + + data.delete_if { |hex, values| + Time.now.to_i >= values[:last] + TIMEOUT + } + + rescue + STDERR.puts $! + end +end + diff --git a/hosts/radiobert/soapysdr.nix b/hosts/radiobert/soapysdr.nix index 727edc40..ba0a354d 100644 --- a/hosts/radiobert/soapysdr.nix +++ b/hosts/radiobert/soapysdr.nix @@ -19,6 +19,8 @@ Group = "soapysdr"; ProtectSystem = "full"; ProtectHome = true; + Restart = "always"; + RestartSec = "60s"; }; }; } diff --git a/overlay/default.nix b/overlay/default.nix index 7096ae6b..2a1c3352 100644 --- a/overlay/default.nix +++ b/overlay/default.nix @@ -14,4 +14,6 @@ final: prev: hackrf = import ./hackrf.nix prev; dump1090-influxdb = import ./dump1090-influxdb { pkgs = prev; }; + + readsb = prev.callPackage ./readsb.nix { }; } diff --git a/overlay/readsb.nix b/overlay/readsb.nix new file mode 100644 index 00000000..6c8b9973 --- /dev/null +++ b/overlay/readsb.nix @@ -0,0 +1,37 @@ +{ stdenv, fetchFromGitHub +, pkg-config, protobufc +, ncurses, rrdtool, libusb1 +, libbladeRF, librtlsdr +# , libad9361, libiio +}: +stdenv.mkDerivation rec { + name = "readsb-protobuf"; + + src = fetchFromGitHub { + owner = "Mictronics"; + repo = name; + rev = "dev"; + sha256 = "03hq9bjg9p6wysys7p0l3hzlfwzbp74k50yjd2n9lg3v1yc4vccl"; + }; + + nativeBuildInputs = [ + pkg-config protobufc + ]; + buildInputs = [ + ncurses rrdtool libusb1 + libbladeRF librtlsdr + # libad9361 libiio + ]; + # enableParallelBuilding = true; + makeFlags = [ + "BLADERF=yes" + "RTLSDR=yes" + # "PLUTOSDR=yes" + ]; + + installPhase = '' + find . -type f + mkdir -p $out/bin + cp -a readsb viewadsb $out/bin/ + ''; +}