diff --git a/NEWS.md b/NEWS.md index 1860e00..54ba739 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,8 @@ - Improved messages regarding what date/time ranges are being queried and returned by data retrieval functions. - `az_hourly()` now returns data from the previous hour when `start_date_time` and `end_date_time` are not supplied rather than returning the previous day of hourly data. - `azmet` is now much more verbose, printing messages about which data are requested and which data are returned. +- Added an option `"azmet.print_api_call"` which, when set to `TRUE` prints the HTTP request sent to the APIā€”for debugging purposes. +- Fixed a bug that caused an error when data was requested from all stations but some stations didn't have data for all variables. - Requests for data before January 1, 2021 now error, since these data are not on the AZMet API (yet). # azmetr 0.2.1 diff --git a/R/az_heat.R b/R/az_heat.R index a66a12d..dcb077b 100644 --- a/R/az_heat.R +++ b/R/az_heat.R @@ -64,6 +64,12 @@ az_heat <- function(station_id = NULL, start_date = NULL, end_date = NULL) { } } params <- parse_params(station_id, start = start_date, end = end_date) + # always add a day to time_interval for heat endpoint to match how API works + if (params$time_interval != "*") { + params$time_interval <- + lubridate::format_ISO8601(lubridate::as.period(params$time_interval) + + lubridate::days(1)) + } # Query API -------------------------------------------- @@ -112,9 +118,8 @@ az_heat <- function(station_id = NULL, start_date = NULL, end_date = NULL) { dplyr::if_else(x %in% c(-999, -9999, -99999, -7999, 999, 999.9, 9999), NA_real_, x)) ) - # Since output from API doesn't contain any information about dates, this is just an assumption message("Returning data from ", format(params$start, "%Y-%m-%d"), - " through ", format(params$end, "%Y-%m-%d")) + " through ", format(max(out$datetime_last), "%Y-%m-%d")) return(out) } diff --git a/R/retrieve_data.R b/R/retrieve_data.R index 0efc0b0..530f30e 100644 --- a/R/retrieve_data.R +++ b/R/retrieve_data.R @@ -4,12 +4,14 @@ #' @param start_f character; ISO formatted date time string #' @param time_interval character; ISO8601 formatted time interval string #' @param endpoint character; one of "daily", "hourly", or "hueto" +#' @param print_call logical; when TRUE, prints the HTTP request to the AZMet API #' #' @return tibble #' @noRd #' retrieve_data <- function(station_id, start_f, time_interval, - endpoint = c("daily", "hourly", "hueto")) { + endpoint = c("daily", "hourly", "hueto"), + print_call = getOption("azmet.print_api_call")) { endpoint <- match.arg(endpoint) req <- httr2::request(base_url) %>% @@ -19,6 +21,10 @@ retrieve_data <- function(station_id, start_f, time_interval, #limit rate to 4 calls per second httr2::req_throttle(4 / 1) + if (isTRUE(print_call)) { + print(req) + } + resp <- req %>% httr2::req_perform() @@ -29,7 +35,10 @@ retrieve_data <- function(station_id, start_f, time_interval, } data_tidy <- data_raw$data %>% - purrr::map_df(tibble::as_tibble) + purrr::compact() %>% + purrr::map(purrr::compact) %>% #removes any columns that are NULL (i.e. no data) + purrr::map(tibble::as_tibble) %>% + purrr::list_rbind() # missing columns for individual sites will be all NAs attributes(data_tidy) <- append(attributes(data_tidy), list( diff --git a/tests/testthat/test-az_heat.R b/tests/testthat/test-az_heat.R index e834a2c..9eac87e 100644 --- a/tests/testthat/test-az_heat.R +++ b/tests/testthat/test-az_heat.R @@ -17,6 +17,28 @@ test_that("az_heat() returns only one row per station even with dates", { expect_equal(nrow(res_start), 1) }) +test_that("start and end dates interpreted correctly", { + res <- az_heat(station_id = 1, start_date = "2023-10-10", end_date = "2023-10-30") + + expect_equal(res$datetime_last, lubridate::ymd("2023-10-30")) + + + skip("not sure of desired behavior") + expect_error(az_heat(station_id = 1, end_date = "2022-09-01"), "`end_date` is before `start_date`!") +}) + +test_that("end_date can be specified without start_date", { + yesterday <- lubridate::today() - lubridate::days(1) + res_end_old <- az_heat(station_id = 1, end_date = "2022-09-27") + res_end_yesterday <- az_heat(station_id = 2, end_date = yesterday) + + expect_s3_class(res_end_yesterday, "data.frame") + expect_equal(res_end_yesterday$datetime_last, yesterday) + + skip("not sure of desired behavior here") + expect_equal(res_end_old$datetime_last, lubridate::ymd("2022-09-27")) +}) + test_that("works with station_id as a vector", { res_2 <- az_heat(station_id = c(1, 2)) @@ -67,13 +89,16 @@ test_that("start_date = NULL, end_date specified works", { az_heat(station_id = 1, end_date = yesterday), glue::glue("Returning data from {lubridate::floor_date(yesterday, 'year')} through {yesterday}") ) + expect_s3_class( + az_heat(end_date = "2022-02-01"), + "tbl_df" + ) expect_message( - az_heat(station_id = 1, end_date = "2022-02-01"), + az_heat(end_date = "2022-02-01"), "Returning data from 2022-01-01 through 2022-02-01" ) }) - test_that("start_date specified, end_date=NULL works", { yesterday <- lubridate::today(tzone = "America/Phoenix") - 1 last_month <- yesterday - lubridate::days(30)