From 3a73400ac8ed2c78fb15f434bff651c9698270e5 Mon Sep 17 00:00:00 2001 From: lukasadrion Date: Wed, 14 Jan 2026 19:31:05 +0100 Subject: [PATCH] add oauth with openSkies api and plot one flight --- .gitignore | 2 + flight_BEL40V.csv | 5 -- main.Rmd | 203 +++++++++++++++++++++++++++++++--------------- 3 files changed, 141 insertions(+), 69 deletions(-) delete mode 100644 flight_BEL40V.csv diff --git a/.gitignore b/.gitignore index a340143..3aebffd 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,5 @@ rsconnect/ *.pdf *.html bib + +.env diff --git a/flight_BEL40V.csv b/flight_BEL40V.csv deleted file mode 100644 index d2f7834..0000000 --- a/flight_BEL40V.csv +++ /dev/null @@ -1,5 +0,0 @@ -icao24,firstseen,takeofftime,lastseen,landingtime,callsign,estdepartureairport,airportofdeparture,estarrivalairport,airportofdestination,model,typecode,registration -44cdc6,1662053869.0,NA,1662065618,NA,BEL40V,NA,NA,EBBR,NA,A320 214,A320,OO-SNF -44cdc8,1662140070.0,NA,1662153115,NA,BEL40V,NA,NA,EBBR,NA,A320 214,A320,OO-SNH -44ce71,1662231623.0,NA,1662245097,NA,BEL40V,NA,NA,EBBR,NA,A320 112,A320,OO-SSQ -44d076,1662299689.0,NA,1662312316,NA,BEL40V,NA,NA,EBBR,NA,A320 214,A320,OO-TCV diff --git a/main.Rmd b/main.Rmd index 51e5311..386a610 100644 --- a/main.Rmd +++ b/main.Rmd @@ -1,6 +1,8 @@ --- title: "Topic 8" -output: html_document +output: + pdf_document: default + html_document: default date: "`r Sys.Date()`" --- @@ -8,78 +10,151 @@ date: "`r Sys.Date()`" knitr::opts_chunk$set(echo = TRUE) ``` -# Download data -from OpenSky https://opensky-network.org/datasets/states/#flights/ -```{r download} +# Load Library +```{r library} library(dplyr) library(lubridate) library(readr) library(utils) +library(openSkies) +library(dotenv) +library(httr) +library(jsonlite) +``` +# Download flights +```{r get departures from frankfurt airport without account, include=FALSE} +#library(openSkies) +# +#time_now <- Sys.time() +#time_one_hour_ago <- time_now - 3600 +# +## get departures from frankfurt airport +#flights <- getAirportDepartures(airport = "EDDF", startTime = time_one_hour_ago, endTime = time_now) +# +#print(paste("Found flights:", length(flights))) +#head(flights) +``` -# ------------------------------- -# Step 1: Define dates -# ------------------------------- -dates <- seq(as.Date("2022-09-01"), as.Date("2022-09-05"), by = "days") -tmp_dir <- tempdir() -all_flights <- list() +```{r openskies oauth, include=FALSE} +load_dot_env() +my_client_id <- Sys.getenv("OPENSKY_CLIENT_ID") +my_client_secret <- Sys.getenv("OPENSKY_CLIENT_SECRET") -# ------------------------------- -# Step 2: Download each day's CSV -# ------------------------------- -for(d in dates) { - d <- as.Date(d) - - file_name <- paste0("flight_sample_", d, ".csv.gz") - url <- paste0("https://s3.opensky-network.org/data-samples/flightsV5/", file_name) - - message("Downloading: ", url) - - dest <- file.path(tmp_dir, file_name) - - tryCatch({ - download.file(url, dest, mode = "wb") - - # read csv - df <- read_csv(dest, col_types = cols(.default = "c")) - all_flights[[length(all_flights)+1]] <- df - }, error = function(e) { - warning("Failed to download ", file_name) - }) -} +token_url <- "https://auth.opensky-network.org/auth/realms/opensky-network/protocol/openid-connect/token" -# ------------------------------- -# Step 3: Combine all days -# ------------------------------- -flight_data <- bind_rows(all_flights) +token_resp <- POST( + token_url, + body = list( + grant_type = "client_credentials", + client_id = my_client_id, + client_secret = my_client_secret + ), + encode = "form" +) -# ------------------------------- -# Step 4: Inspect data -# ------------------------------- -head(flight_data) -colnames(flight_data) -str(flight_data) - -if(interactive()) { - View(flight_data) -} - -# ------------------------------- -# Step 5: Filter flight BEL40V -# ------------------------------- -flight_number <- "BEL40V" - -if("callsign" %in% colnames(flight_data)) { - flight_BEL40V <- flight_data %>% - filter(callsign == flight_number) - - # save - write_csv(flight_BEL40V, "flight_BEL40V.csv") - - # view first row - head(flight_BEL40V) +if (status_code(token_resp) == 200) { + my_token <- content(token_resp)$access_token + message("Token successfully generated") } else { - warning("Column 'callsign' not found in flight_data!") + stop(paste("Error while collecting token:", content(token_resp, as = "text"))) } -``` +time_now <- as.numeric(Sys.time()) +time_one_hour_ago <- time_now - 3600 + +api_url <- paste0("https://opensky-network.org/api/flights/departure?airport=EDDF&begin=", + round(time_one_hour_ago), "&end=", round(time_now)) + +data_resp <- GET( + api_url, + add_headers(Authorization = paste("Bearer", my_token)) +) + +if (status_code(data_resp) == 200) { + departures_df <- fromJSON(content(data_resp, as = "text", encoding = "UTF-8")) + print(head(departures_df)) +} else { + print(paste("API Error:", status_code(data_resp))) + print(content(data_resp, as = "text")) +} + +``` + +```{r get last 5 flights} + +icao24 <- "4bcdf9" + +time_now <- as.numeric(Sys.time()) +time_then <- time_now - (1 * 24 * 60 * 60) + +api_url_aircraft <- paste0("https://opensky-network.org/api/flights/aircraft?icao24=", + icao24, "&begin=", round(time_then), "&end=", round(time_now)) + +aircraft_resp <- GET( + api_url_aircraft, + add_headers(Authorization = paste("Bearer", my_token)) +) + +if (status_code(aircraft_resp) == 200) { + all_flights <- fromJSON(content(aircraft_resp, as = "text", encoding = "UTF-8")) + + if (length(all_flights) > 0) { + all_flights <- all_flights[order(all_flights$firstSeen, decreasing = TRUE), ] + + last_5_flights <- head(all_flights, 5) + + last_5_flights$firstSeen <- as.POSIXct(last_5_flights$firstSeen, origin="1970-01-01") + last_5_flights$lastSeen <- as.POSIXct(last_5_flights$lastSeen, origin="1970-01-01") + + print(last_5_flights[, c("icao24", "firstSeen", "estDepartureAirport", "estArrivalAirport")]) + } else { + print("No flights in this timespan for this airplane") + } +} else { + print(paste("Error:", status_code(aircraft_resp))) +} +``` + +# Plot the flights + +```{r get flight route} +target_icao <- all_flights$icao24[1] + +target_time <- as.numeric(all_flights$firstSeen[1]) + +api_url_track <- paste0("https://opensky-network.org/api/tracks/all?icao24=", + target_icao, "&time=", target_time) + +track_resp <- GET( + api_url_track, + add_headers(Authorization = paste("Bearer", my_token)) +) + +if (status_code(track_resp) == 200) { + track_data <- fromJSON(content(track_resp, as = "text", encoding = "UTF-8")) + + if (!is.null(track_data$path) && length(track_data$path) > 0) { + + route_df <- as.data.frame(track_data$path) + colnames(route_df) <- c("time", "lat", "lon", "alt", "heading", "on_ground") + + message("Loading of route successfull! Points: ", nrow(route_df)) + + plot(route_df$lon, route_df$lat, type="o", pch=20, col="blue", + main=paste("Geographic route from", target_icao), + xlab="Longitude", ylab="Latitude") + + plot(route_df$time, route_df$alt, type="l", col="red", lwd=2, + main=paste("Altitude profile of", target_icao), + xlab="Time (Unix)", ylab="Height (Meter)") + + } else { + print("No path points from api") + } + +} else { + print(paste("Error while getting the route. Status:", status_code(track_resp))) + print(content(track_resp, as = "text")) +} +``` \ No newline at end of file