This commit is contained in:
Kai Vogelgesang 2023-04-16 05:09:19 +02:00
parent 56d058c2fd
commit d18162e9ba
Signed by: kai
GPG Key ID: 3FC8578CC818A9EB
7 changed files with 366 additions and 10 deletions

266
Cargo.lock generated
View File

@ -174,6 +174,17 @@ dependencies = [
"pin-utils",
]
[[package]]
name = "getrandom"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "h2"
version = "0.3.17"
@ -383,6 +394,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "mime"
version = "0.3.17"
@ -429,6 +446,15 @@ dependencies = [
"libc",
]
[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
"libc",
]
[[package]]
name = "once_cell"
version = "1.17.1"
@ -502,12 +528,59 @@ dependencies = [
"windows-sys 0.45.0",
]
[[package]]
name = "parse-zoneinfo"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41"
dependencies = [
"regex",
]
[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]]
name = "phf"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_codegen"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
dependencies = [
"phf_generator",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_shared"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
@ -526,6 +599,12 @@ version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.56"
@ -544,6 +623,36 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
@ -562,6 +671,21 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "reqwest"
version = "0.11.16"
@ -627,7 +751,10 @@ dependencies = [
"reqwest",
"serde",
"serde_json",
"time",
"time-tz",
"tokio",
"toml",
]
[[package]]
@ -677,6 +804,18 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "serde-xml-rs"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65162e9059be2f6a3421ebbb4fef3e74b7d9e7c60c50a0e292c6239f19f1edfa"
dependencies = [
"log",
"serde",
"thiserror",
"xml-rs",
]
[[package]]
name = "serde_derive"
version = "1.0.160"
@ -699,6 +838,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -720,6 +868,12 @@ dependencies = [
"libc",
]
[[package]]
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]]
name = "slab"
version = "0.4.8"
@ -780,6 +934,69 @@ dependencies = [
"windows-sys 0.45.0",
]
[[package]]
name = "thiserror"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.15",
]
[[package]]
name = "time"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
dependencies = [
"libc",
"num_threads",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
[[package]]
name = "time-macros"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36"
dependencies = [
"time-core",
]
[[package]]
name = "time-tz"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "980bd5c9ec52d862803a716b6f3913881910e96124a618a9a0679a984d5c361d"
dependencies = [
"cfg-if",
"parse-zoneinfo",
"phf",
"phf_codegen",
"serde",
"serde-xml-rs",
"time",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -849,6 +1066,40 @@ dependencies = [
"tracing",
]
[[package]]
name = "toml"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.19.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "tower-service"
version = "0.3.2"
@ -1180,6 +1431,15 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]]
name = "winnow"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.10.1"
@ -1188,3 +1448,9 @@ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
]
[[package]]
name = "xml-rs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"

View File

@ -10,4 +10,7 @@ dotenv = "0.15.0"
reqwest = { version = "0.11.16", features = ["json"] }
serde = { version = "1.0.160", features = ["derive"] }
serde_json = "1.0.96"
time = { version = "0.3.20", features = ["local-offset"] }
time-tz = { version = "1.0.2", features = ["db"] }
tokio = { version = "1.27.0", features = ["full"] }
toml = { version = "0.7.3", features = ["parse"] }

22
config.toml Normal file
View File

@ -0,0 +1,22 @@
[observer]
# UdS
latitude = 49.2550319
longitude = 7.0384001
altitude = 0 # ?
timezone = "Europe/Berlin"
[satellites."Meteor M2"]
norad = 40069
downlink = ["137.1", "137.925"]
[satellites."NOAA 15"]
norad = 25338
downlink = ["137.62"]
[satellites."NOAA 18"]
norad = 28654
downlink = ["137.9125"]
[satellites."NOAA 19"]
norad = 33591
downlink = ["137.1"]

31
src/config.rs Normal file
View File

@ -0,0 +1,31 @@
use std::{collections::HashMap, fs};
use crate::util::Result;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct Config {
pub observer: Observer,
pub satellites: HashMap<String, Satellite>,
}
#[derive(Debug, Deserialize)]
pub struct Observer {
pub latitude: f64,
pub longitude: f64,
pub altitude: f64,
pub timezone: String,
}
#[derive(Debug, Deserialize)]
pub struct Satellite {
pub norad: u64,
pub downlink: Vec<String>,
}
impl Config {
pub fn from_file(filename: &str) -> Result<Self> {
let content = fs::read_to_string(filename)?;
Ok(toml::from_str(&content)?)
}
}

View File

@ -1,19 +1,55 @@
use std::{env, error::Error};
use config::Config;
use time::OffsetDateTime;
use time_tz::{timezones, OffsetDateTimeExt};
use crate::n2yo::N2YO;
mod config;
mod n2yo;
mod util;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
dotenv::dotenv().ok();
let api_key = env::var("N2YO_API_KEY")?;
let config_file = env::var("CONFIG_FILE").unwrap_or("config.toml".into());
let config = Config::from_file(&config_file)?;
let n2yo = N2YO::new(api_key);
let tle = n2yo.tle(25544).await?;
let tz = timezones::get_by_name(&config.observer.timezone)
.ok_or("Could not find observer timezone")?;
println!("{}", tle.tle);
for (name, sat) in &config.satellites {
println!("[{}] {}", sat.norad, name);
let passes = n2yo
.radio_passes(
sat.norad,
config.observer.latitude,
config.observer.longitude,
config.observer.altitude,
1,
0,
)
.await?;
if let Some(passes) = passes.passes {
for pass in passes {
let start = OffsetDateTime::from_unix_timestamp(pass.start_utc as i64)?;
let end = OffsetDateTime::from_unix_timestamp(pass.end_utc as i64)?;
let (h1, m1, s1) = start.to_timezone(tz).to_hms();
let (h2, m2, s2) = end.to_timezone(tz).to_hms();
println!("Pass from {:02}:{:02}:{:02} to {:02}:{:02}:{:02}", h1, m1, s1, h2, m2, s2,);
}
} else {
println!("No passes :(");
}
}
Ok(())
}

View File

@ -2,6 +2,7 @@ use reqwest::Client;
use serde::de::DeserializeOwned;
use self::proto::{Above, Positions, RadioPasses, VisualPasses, TLE};
use crate::util::Result;
mod proto;
@ -12,8 +13,6 @@ pub struct N2YO {
client: Client,
}
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
impl N2YO {
pub fn new(api_key: String) -> Self {
Self {
@ -23,16 +22,14 @@ impl N2YO {
}
async fn query<T: DeserializeOwned>(&self, s: &str) -> Result<T> {
let result = self
Ok(self
.client
.get(s)
.query(&[("apiKey", &self.api_key)])
.send()
.await?
.json()
.await?;
Ok(result)
.await?)
}
/// Get TLE
@ -82,7 +79,7 @@ impl N2YO {
min_visibility: u64,
) -> Result<VisualPasses> {
self.query(&format!(
"{BASE_URL}/positions/{id}/{lat}/{lng}/{alt}/{days}/{min_visibility}"
"{BASE_URL}/visualpasses/{id}/{lat}/{lng}/{alt}/{days}/{min_visibility}"
))
.await
}
@ -104,7 +101,7 @@ impl N2YO {
min_elevation: u64,
) -> Result<RadioPasses> {
self.query(&format!(
"{BASE_URL}/positions/{id}/{lat}/{lng}/{alt}/{days}/{min_elevation}"
"{BASE_URL}/radiopasses/{id}/{lat}/{lng}/{alt}/{days}/{min_elevation}"
))
.await
}

1
src/util.rs Normal file
View File

@ -0,0 +1 @@
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;