heliwatch: switch from json to beast
This commit is contained in:
parent
afca212069
commit
873f0b639f
|
@ -147,12 +147,6 @@ dependencies = [
|
||||||
"safemem",
|
"safemem",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bumpalo"
|
|
||||||
version = "3.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.4.3"
|
version = "1.4.3"
|
||||||
|
@ -278,15 +272,6 @@ dependencies = [
|
||||||
"generic-array 0.14.4",
|
"generic-array 0.14.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "encoding_rs"
|
|
||||||
version = "0.8.29"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enum-as-inner"
|
name = "enum-as-inner"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -608,10 +593,11 @@ dependencies = [
|
||||||
name = "heliwatch"
|
name = "heliwatch"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"adsb",
|
||||||
|
"beast",
|
||||||
"csv",
|
"csv",
|
||||||
"futures",
|
"futures",
|
||||||
"geo",
|
"geo",
|
||||||
"reqwest",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -719,19 +705,6 @@ dependencies = [
|
||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hyper-tls"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"hyper",
|
|
||||||
"native-tls",
|
|
||||||
"tokio",
|
|
||||||
"tokio-native-tls",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -780,7 +753,7 @@ dependencies = [
|
||||||
"socket2 0.3.19",
|
"socket2 0.3.19",
|
||||||
"widestring",
|
"widestring",
|
||||||
"winapi",
|
"winapi",
|
||||||
"winreg 0.6.2",
|
"winreg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -804,15 +777,6 @@ dependencies = [
|
||||||
"minidom",
|
"minidom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "js-sys"
|
|
||||||
version = "0.3.55"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
|
||||||
dependencies = [
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "keccak"
|
name = "keccak"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1500,41 +1464,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "reqwest"
|
|
||||||
version = "0.11.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280"
|
|
||||||
dependencies = [
|
|
||||||
"base64",
|
|
||||||
"bytes",
|
|
||||||
"encoding_rs",
|
|
||||||
"futures-core",
|
|
||||||
"futures-util",
|
|
||||||
"http",
|
|
||||||
"http-body",
|
|
||||||
"hyper",
|
|
||||||
"hyper-tls",
|
|
||||||
"ipnet",
|
|
||||||
"js-sys",
|
|
||||||
"lazy_static",
|
|
||||||
"log",
|
|
||||||
"mime",
|
|
||||||
"native-tls",
|
|
||||||
"percent-encoding",
|
|
||||||
"pin-project-lite",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"serde_urlencoded",
|
|
||||||
"tokio",
|
|
||||||
"tokio-native-tls",
|
|
||||||
"url",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"web-sys",
|
|
||||||
"winreg 0.7.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "resolv-conf"
|
name = "resolv-conf"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -2270,82 +2199,6 @@ version = "0.10.2+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen"
|
|
||||||
version = "0.2.78"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"wasm-bindgen-macro",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-backend"
|
|
||||||
version = "0.2.78"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
|
||||||
dependencies = [
|
|
||||||
"bumpalo",
|
|
||||||
"lazy_static",
|
|
||||||
"log",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-futures"
|
|
||||||
version = "0.4.28"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-macro"
|
|
||||||
version = "0.2.78"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"wasm-bindgen-macro-support",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-macro-support"
|
|
||||||
version = "0.2.78"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"wasm-bindgen-backend",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-shared"
|
|
||||||
version = "0.2.78"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "web-sys"
|
|
||||||
version = "0.3.55"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
|
||||||
dependencies = [
|
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "widestring"
|
name = "widestring"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -2383,15 +2236,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winreg"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wyz"
|
name = "wyz"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl Entry {
|
||||||
self.last_update = Some(Instant::now());
|
self.last_update = Some(Instant::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn location(&self) -> Option<adsb::Position> {
|
pub fn position(&self) -> Option<adsb::Position> {
|
||||||
match (&self.cpr1, &self.cpr2) {
|
match (&self.cpr1, &self.cpr2) {
|
||||||
(Some(cpr1), Some(cpr2)) => {
|
(Some(cpr1), Some(cpr2)) => {
|
||||||
let pos = adsb::cpr::get_position((cpr1, cpr2))?;
|
let pos = adsb::cpr::get_position((cpr1, cpr2))?;
|
||||||
|
@ -70,6 +70,17 @@ impl Entry {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn flight(&self) -> Option<&str> {
|
||||||
|
self.callsign.as_ref().map(|callsign| {
|
||||||
|
callsign.split(char::is_whitespace)
|
||||||
|
.next().unwrap()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn altitude_m(&self) -> Option<f64> {
|
||||||
|
self.altitude.map(|altitude| altitude as f64 * 0.3048)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
|
@ -57,7 +57,7 @@ async fn main() {
|
||||||
update_min(&entry.ground_speed, &mut min_speed);
|
update_min(&entry.ground_speed, &mut min_speed);
|
||||||
update_max(&entry.ground_speed, &mut max_speed);
|
update_max(&entry.ground_speed, &mut max_speed);
|
||||||
|
|
||||||
if let Some(pos) = entry.location() {
|
if let Some(pos) = entry.position() {
|
||||||
let altitude_m = entry.altitude.unwrap_or(0) as f64 * 0.3048;
|
let altitude_m = entry.altitude.unwrap_or(0) as f64 * 0.3048;
|
||||||
let distance_km = WGS84::from_degrees_and_meters(pos.latitude, pos.longitude, altitude_m)
|
let distance_km = WGS84::from_degrees_and_meters(pos.latitude, pos.longitude, altitude_m)
|
||||||
.distance(&home) / 1000.0;
|
.distance(&home) / 1000.0;
|
||||||
|
|
|
@ -6,10 +6,11 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
reqwest = { version = "0.11", features = ["json"] }
|
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
geo = "0.18"
|
geo = "0.18"
|
||||||
csv = "1.1"
|
csv = "1.1"
|
||||||
tokio-xmpp = "3"
|
tokio-xmpp = "3"
|
||||||
xmpp-parsers = "0.18"
|
xmpp-parsers = "0.18"
|
||||||
|
adsb = "0.3"
|
||||||
|
beast = { path = "../beast" }
|
||||||
|
|
|
@ -1,59 +1,15 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use serde::Deserialize;
|
|
||||||
use tokio::sync::mpsc::{channel, Receiver};
|
use tokio::sync::mpsc::{channel, Receiver};
|
||||||
|
|
||||||
use super::location::Locations;
|
use super::location::Locations;
|
||||||
|
|
||||||
/// ft
|
/// ft
|
||||||
const MAX_ALTITUDE: u32 = 5000;
|
const MAX_ALTITUDE: u16 = 5000;
|
||||||
/// s
|
/// s
|
||||||
const STATE_TIMEOUT: u64 = 180;
|
const STATE_TIMEOUT: u64 = 180;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
|
||||||
pub struct Info {
|
|
||||||
hex: String,
|
|
||||||
flight: String,
|
|
||||||
lat: f64,
|
|
||||||
lon: f64,
|
|
||||||
/// ft
|
|
||||||
altitude: u32,
|
|
||||||
track: u32,
|
|
||||||
/// kts
|
|
||||||
speed: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Info {
|
|
||||||
pub fn get_hex(&self) -> &str {
|
|
||||||
let mut hex = &self.hex[..];
|
|
||||||
while hex.len() > 0 && hex.chars().last().unwrap().is_whitespace() {
|
|
||||||
hex = &hex[..hex.len() - 1];
|
|
||||||
}
|
|
||||||
hex
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_flight(&self) -> Option<String> {
|
|
||||||
let mut i = self.flight.len();
|
|
||||||
while i > 0 && self.flight.chars().nth(i - 1).unwrap().is_whitespace() {
|
|
||||||
i -= 1;
|
|
||||||
}
|
|
||||||
if i > 0 {
|
|
||||||
Some(self.flight[0..i].to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_altitude_m(&self) -> f64 {
|
|
||||||
self.altitude as f64 * 0.3048
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn get_speed_kph(&self) -> f64 {
|
|
||||||
// self.speed as f64 * 1.852
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Event {
|
pub struct Event {
|
||||||
pub action: Action,
|
pub action: Action,
|
||||||
|
@ -69,41 +25,63 @@ pub enum Action {
|
||||||
Ignored,
|
Ignored,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Info {
|
||||||
|
pub hex: String,
|
||||||
|
pub flight: Option<String>,
|
||||||
|
pub altitude_m: Option<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
info: Option<Info>,
|
info: Info,
|
||||||
|
position: Option<adsb::Position>,
|
||||||
location: Option<Arc<String>>,
|
location: Option<Arc<String>>,
|
||||||
last: Instant,
|
last: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn new() -> Self {
|
pub fn new(hex: String) -> Self {
|
||||||
State {
|
State {
|
||||||
info: None,
|
info: Info {
|
||||||
|
hex,
|
||||||
|
flight: None,
|
||||||
|
altitude_m: None,
|
||||||
|
},
|
||||||
|
position: None,
|
||||||
location: None,
|
location: None,
|
||||||
last: Instant::now(),
|
last: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, info: Info, locations: &Locations) -> Option<Event> {
|
pub fn update(&mut self, entry: &beast::aircrafts::Entry, locations: &Locations) -> Option<Event> {
|
||||||
self.last = Instant::now();
|
self.last = Instant::now();
|
||||||
|
|
||||||
let coord = geo::Coordinate { x: info.lon, y: info.lat };
|
if let Some(flight) = entry.flight() {
|
||||||
if let Some(old_info) = self.info.replace(info) {
|
self.info.flight = Some(flight.to_string());
|
||||||
let info = self.info.as_ref().unwrap();
|
}
|
||||||
if old_info.lon != info.lon || old_info.lat != info.lat {
|
if let Some(altitude_m) = entry.altitude_m() {
|
||||||
|
self.info.altitude_m = Some(altitude_m);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos = if let Some(pos) = entry.position() {
|
||||||
|
pos
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let coord = geo::Coordinate { x: pos.longitude, y: pos.latitude };
|
||||||
|
if let Some(old_pos) = self.position.replace(pos.clone()) {
|
||||||
|
if old_pos.longitude != pos.longitude || old_pos.latitude != pos.latitude {
|
||||||
let location = locations.find(&coord);
|
let location = locations.find(&coord);
|
||||||
if location != self.location {
|
if location != self.location {
|
||||||
if let Some(location) = location {
|
if let Some(location) = location {
|
||||||
self.location = Some(location.clone());
|
self.location = Some(location.clone());
|
||||||
Some(Event {
|
Some(Event {
|
||||||
action: Action::Moved,
|
action: Action::Moved,
|
||||||
info: self.info.clone().unwrap(),
|
|
||||||
location,
|
location,
|
||||||
|
info: self.info.clone(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if self.location.is_some() {
|
|
||||||
println!("{}: move to nowhere", info.flight);
|
|
||||||
}
|
|
||||||
// move to no location
|
// move to no location
|
||||||
self.location = None;
|
self.location = None;
|
||||||
None
|
None
|
||||||
|
@ -120,7 +98,7 @@ impl State {
|
||||||
self.location = locations.find(&coord);
|
self.location = locations.find(&coord);
|
||||||
Some(Event {
|
Some(Event {
|
||||||
action: Action::Appeared,
|
action: Action::Appeared,
|
||||||
info: self.info.clone().unwrap(),
|
info: self.info.clone(),
|
||||||
location: self.location.clone()
|
location: self.location.clone()
|
||||||
.unwrap_or_else(|| Arc::new("irgendwo".to_owned())),
|
.unwrap_or_else(|| Arc::new("irgendwo".to_owned())),
|
||||||
})
|
})
|
||||||
|
@ -128,68 +106,49 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
|
pub fn run(host: &'static str, port: u16, locations: Locations) -> Receiver<Event> {
|
||||||
|
|
||||||
async fn fetch(url: &str) -> Result<Vec<Info>> {
|
|
||||||
let values: Vec<serde_json::Value> = reqwest::get(url)
|
|
||||||
.await?
|
|
||||||
.json()
|
|
||||||
.await?;
|
|
||||||
// skip invalid entries
|
|
||||||
let result = values.into_iter()
|
|
||||||
.filter_map(|value| serde_json::from_value(value).ok())
|
|
||||||
.collect();
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(url: &'static str, locations: Locations) -> Receiver<Event> {
|
|
||||||
let (tx, rx) = channel(1);
|
let (tx, rx) = channel(1);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let source = beast::aircrafts::Aircrafts::new();
|
||||||
|
source.connect(host, port);
|
||||||
|
|
||||||
let mut states = HashMap::new();
|
let mut states = HashMap::new();
|
||||||
// ignore anything above MAX_ALTITUDE permanently
|
// ignore anything above MAX_ALTITUDE permanently
|
||||||
let mut ignored = HashSet::new();
|
let mut ignored = HashSet::new();
|
||||||
// cache that lives longer than dump1090's
|
|
||||||
let mut flights = HashMap::new();
|
|
||||||
loop {
|
loop {
|
||||||
let infos = match fetch(url).await {
|
|
||||||
Ok(infos) => infos,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("{}", e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut events = vec![];
|
let mut events = vec![];
|
||||||
for mut info in infos {
|
for (icao_address, entry) in source.read().iter() {
|
||||||
if info.altitude > MAX_ALTITUDE {
|
let hex = format!("{}", icao_address);
|
||||||
if !ignored.contains(&info.hex) {
|
let entry = entry.read().unwrap();
|
||||||
ignored.insert(info.hex.clone());
|
|
||||||
if let Some(_) = states.remove(&info.hex) {
|
if entry.altitude.map(|altitude| altitude > MAX_ALTITUDE)
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
if !ignored.contains(&hex) {
|
||||||
|
ignored.insert(hex.clone());
|
||||||
|
if let Some(_) = states.remove(&hex) {
|
||||||
events.push(Event {
|
events.push(Event {
|
||||||
action: Action::Ignored,
|
action: Action::Ignored,
|
||||||
info,
|
info: Info {
|
||||||
|
hex,
|
||||||
|
flight: entry.flight().map(|s| s.to_string()),
|
||||||
|
altitude_m: entry.altitude_m(),
|
||||||
|
},
|
||||||
location: Arc::new("ignoriert".to_owned()),
|
location: Arc::new("ignoriert".to_owned()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ignored.contains(&info.hex) {
|
if ignored.contains(&hex) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(flight) = info.get_flight() {
|
if let Some(event) = states.entry(hex.clone())
|
||||||
flights.insert(info.hex.clone(), flight);
|
.or_insert(State::new(hex.clone()))
|
||||||
} else if let Some(flight) = flights.get(&info.hex) {
|
.update(&entry, &locations) {
|
||||||
info.flight = flight.to_string();
|
events.push(event);
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(event) = states.entry(info.hex.clone())
|
|
||||||
.or_insert(State::new())
|
|
||||||
.update(info, &locations) {
|
|
||||||
tx.send(event).await.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +156,8 @@ pub fn run(url: &'static str, locations: Locations) -> Receiver<Event> {
|
||||||
if state.last + Duration::from_secs(STATE_TIMEOUT) < Instant::now() {
|
if state.last + Duration::from_secs(STATE_TIMEOUT) < Instant::now() {
|
||||||
events.push(Event {
|
events.push(Event {
|
||||||
action: Action::Disappeared,
|
action: Action::Disappeared,
|
||||||
info: state.info.clone().unwrap(),
|
info: state.info
|
||||||
|
.clone(),
|
||||||
location: Arc::new("weg".to_owned()),
|
location: Arc::new("weg".to_owned()),
|
||||||
});
|
});
|
||||||
false
|
false
|
||||||
|
|
|
@ -21,7 +21,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
tokio::task::LocalSet::new().run_until(async move {
|
tokio::task::LocalSet::new().run_until(async move {
|
||||||
let aircrafts = aircrafts::Aircrafts::load("aircraftDatabase.csv");
|
let aircrafts = aircrafts::Aircrafts::load("aircraftDatabase.csv");
|
||||||
let locations = location::Locations::load("locations.json");
|
let locations = location::Locations::load("locations.json");
|
||||||
let mut events = adsb::run("http://radiobert.serv.zentralwerk.org:8080/data.json", locations);
|
let mut events = adsb::run("radiobert.serv.zentralwerk.org", 30005, locations);
|
||||||
|
|
||||||
let args: Vec<String> = args().collect();
|
let args: Vec<String> = args().collect();
|
||||||
if args.len() != 4 {
|
if args.len() != 4 {
|
||||||
|
@ -36,13 +36,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
while let Some(event) = events.recv().await {
|
while let Some(event) = events.recv().await {
|
||||||
println!("event: {:?}", event);
|
println!("event: {:?}", event);
|
||||||
|
|
||||||
let flight = if let Some(flight) = event.info.get_flight() {
|
let flight = if let Some(flight) = event.info.flight {
|
||||||
format!("Flug {} [{}]", flight, event.info.get_hex())
|
format!("Flug {} [{}]", flight, event.info.hex)
|
||||||
} else {
|
} else {
|
||||||
format!("[{}]", event.info.get_hex())
|
format!("[{}]", event.info.hex)
|
||||||
};
|
};
|
||||||
let identifier;
|
let identifier;
|
||||||
if let Some(aircraft) = aircrafts.find(&event.info.get_hex()) {
|
if let Some(aircraft) = aircrafts.find(&event.info.hex) {
|
||||||
println!("aircraft: {:?}", aircraft);
|
println!("aircraft: {:?}", aircraft);
|
||||||
match (&aircraft.owner, &aircraft.registration, &aircraft.model) {
|
match (&aircraft.owner, &aircraft.registration, &aircraft.model) {
|
||||||
(Some(owner), Some(registration), Some(model)) =>
|
(Some(owner), Some(registration), Some(model)) =>
|
||||||
|
@ -70,13 +70,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
adsb::Action::Appeared =>
|
adsb::Action::Appeared =>
|
||||||
format!("{} ist {:.0}m über {} aufgetaucht",
|
format!("{} ist {:.0}m über {} aufgetaucht",
|
||||||
identifier,
|
identifier,
|
||||||
event.info.get_altitude_m(),
|
event.info.altitude_m.unwrap_or(0.0),
|
||||||
event.location
|
event.location
|
||||||
),
|
),
|
||||||
adsb::Action::Moved =>
|
adsb::Action::Moved =>
|
||||||
format!("{} fliegt jetzt {:.0}m über {}",
|
format!("{} fliegt jetzt {:.0}m über {}",
|
||||||
identifier,
|
identifier,
|
||||||
event.info.get_altitude_m(),
|
event.info.altitude_m.unwrap_or(0.0),
|
||||||
event.location
|
event.location
|
||||||
),
|
),
|
||||||
adsb::Action::Disappeared =>
|
adsb::Action::Disappeared =>
|
||||||
|
@ -84,7 +84,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
adsb::Action::Ignored =>
|
adsb::Action::Ignored =>
|
||||||
format!("{} wird ab {:.0}m ignoriert",
|
format!("{} wird ab {:.0}m ignoriert",
|
||||||
identifier,
|
identifier,
|
||||||
event.info.get_altitude_m()
|
event.info.altitude_m.unwrap_or(0.0),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct Aircraft {
|
||||||
|
|
||||||
impl Aircraft {
|
impl Aircraft {
|
||||||
pub fn new(icao_address: &ICAOAddress, entry: &Entry) -> Self {
|
pub fn new(icao_address: &ICAOAddress, entry: &Entry) -> Self {
|
||||||
let pos = entry.location();
|
let pos = entry.position();
|
||||||
Aircraft {
|
Aircraft {
|
||||||
hex: format!("{}", icao_address),
|
hex: format!("{}", icao_address),
|
||||||
flight: entry.callsign.clone(),
|
flight: entry.callsign.clone(),
|
||||||
|
|
Loading…
Reference in New Issue