Nothing
#' Batch queries API methods
#'
#' @description
#'
#' `r lifecycle::badge('experimental')`
#'
#' Returns the batch of time-series data or last data point for a property of given thing
#' (note: this API method is bugged and waiting to be fixed by Arduino team.
#' Here for completeness and future developments but would not suggest using it)
#'
#' Official documentation:
#' * [seriesV2BatchQuery](<https://www.arduino.cc/reference/en/iot/api/#api-SeriesV2-seriesV2BatchQuery>)
#' * [seriesV2BatchQueryRaw](<https://www.arduino.cc/reference/en/iot/api/#api-SeriesV2-seriesV2BatchQueryRaw>)
#' * [seriesV2BatchQueryRawLastValue](<https://www.arduino.cc/reference/en/iot/api/#api-SeriesV2-seriesV2BatchQueryRawLastValue>)
#' @md
#'
#' @param from A `Posixct` or `Date` object.
#' Get data with a timestamp >= to this value
#' @param to A `Posixct` or `Date` object.
#' Get data with a timestamp < to this value
#' @param interval (numeric) Resolutions in seconds (seems not to affect results)
#' @param Q The query. (Not clear what this means but allows to chose among properties by filling in,
#' for instance, `property.fbf34284-91f0-42be-bbf6-dd46cfb3f1e0`)
#' @param SeriesLimit Maximum number of values (seems not to affect results)
#' @param thing_id The id of the thing
#' @param property_id The id of the property
#' @param store_token Where your token is stored. If `option` it will be retrieved from the .Rprofile (not cross-session and default),
#' if `envir` it will be retrieved from environmental variables list (cross-session)
#' @param token A valid token created with `create_auth_token` or manually.
#' It not `NULL` it has higher priority then `store_token`
#' @param silent Whether to hide or show API method success messages (default `FALSE`)
#' @return A tibble showing of time and value for properties
#' @examples
#' \dontrun{
#' # Sys.setenv(ARDUINO_API_CLIENT_ID = 'INSERT CLIENT_ID HERE')
#' # Sys.setenv(ARDUINO_API_CLIENT_SECRET = 'INSERT CLIENT_SECRET HERE')
#'
#' create_auth_token()
#'
#' ### series_batch_query ###
#' series_batch_query(from = "2022-08-15", to = "2022-08-22",
#' Q = "property.fbf34284-91f0-42be-bbf6-dd46cfb3f1e0")
#'
#' ### series_batch_query_raw ###
#' series_batch_query_raw(from = "2022-08-15", to = "2022-08-22",
#' Q = "property.fbf34284-91f0-42be-bbf6-dd46cfb3f1e0")
#'
#' ### series_batch_last_value ###
#' thing_id = "b6822400-2f35-4d93-b3e7-be919bdc5eba"
#' property_id = "fbf34284-91f0-42be-bbf6-dd46cfb3f1e0"
#'
#' series_batch_last_value(thing_id = thing_id, property_id = property_id)
#' }
#' @name series_batch
#' @rdname series_batch
#' @export
series_batch_query <- function(from, to, interval = NULL, Q, SeriesLimit = NULL,
store_token = "option",
token = NULL,
silent = FALSE){
if(missing(from)){cli::cli_alert_danger("missing from"); stop()}
if(missing(to)){cli::cli_alert_danger("missing to"); stop()}
if(missing(Q)){cli::cli_alert_danger("missing Q"); stop()}
if(!missing(from)){
if(!methods::is(from, "POSIXct") && !methods::is(from, "Date")){
from = tryCatch({as.Date(from)}, error = function(e){
cli::cli_alert_danger("{.field to} not in a valid POSIXct or Date format")})
from = strftime(format(from, tz = "UTC", usetz = TRUE), "%Y-%m-%dT%H:%M:%OSZ")
}else{from = strftime(format(from, tz = "UTC", usetz = TRUE), "%Y-%m-%dT%H:%M:%OSZ")}
}
if(!missing(to)){
if(!methods::is(to, "POSIXct") && !methods::is(to, "Date")){
to = tryCatch({as.Date(to)}, error = function(e){
cli::cli_alert_danger("{.field from} not in a valid POSIXct or Date format")})
to = strftime(format(to, tz = "UTC", usetz = TRUE), "%Y-%m-%dT%H:%M:%OSZ")
}else{to = strftime(format(to, tz = "UTC", usetz = TRUE), "%Y-%m-%dT%H:%M:%OSZ")}
}
if(!is.logical(silent)){cli::cli_alert_danger("silent must be TRUE or FALSE"); stop()}
if(!is.null(token)){token = token}
else if(store_token == "option"){token = getOption('ARDUINO_API_TOKEN')}
else if(store_token == "envir"){token = Sys.getenv('ARDUINO_API_TOKEN')}
else{cli::cli_alert_danger("Token is null and store_token neither 'option' nor 'envir':
use function create_auth_token to create a valid one or choose a valid value
for store_token"); stop()}
url = "https://api2.arduino.cc/iot/v2/series/batch_query"
still_valid_token = FALSE
while(!still_valid_token){
header = c('Authorization' = paste0("Bearer ", token),
'Content-Type' = "text/plain")
body = list("requests" = data.frame('from' = from, 'to' = to, 'Q' = Q),
"resp_version" = 1)
body$requests$interval = interval
body$requests$SeriesLimit = SeriesLimit
res = httr::POST(url = url, body = body, httr::add_headers(header), encode = "json")
if(res$status_code == 200){
res_raw = jsonlite::fromJSON(httr::content(res, 'text', encoding = "UTF-8"))
res = tibble::tibble(time = unlist(res_raw$responses$times),
values = unlist(res_raw$responses$values))
if(nrow(res)>0){
res$time = as.POSIXct(res$time, format = "%Y-%m-%dT%H:%M:%OSZ", tz = "UTC")
}
still_valid_token = TRUE; if(!silent){cli::cli_alert_success("Method succeeded")}}
else if(res$status_code == 401){
cli::cli_alert_warning("Request not authorized: regenerate token")
token = create_auth_token(store_token = store_token, return_token = TRUE, silent = silent)}
else if(res$status_code == 404){
still_valid_token = TRUE; cli::cli_alert_danger("API error: Not found");}
else{
res_detail = jsonlite::fromJSON(httr::content(res, 'text', encoding = "UTF-8"))$detail
cli::cli_alert_danger(cat(paste0("API error: ", res_detail))); stop()}
}
return(res)
}
#' @name series_batch
#' @export
series_batch_query_raw <- function(from, to, interval = NULL, Q, SeriesLimit = NULL,
store_token = "option",
token = NULL,
silent = FALSE){
if(missing(from)){cli::cli_alert_danger("missing from"); stop()}
if(missing(to)){cli::cli_alert_danger("missing to"); stop()}
if(missing(Q)){cli::cli_alert_danger("missing Q"); stop()}
if(!missing(from)){
if(!methods::is(from, "POSIXct") && !methods::is(from, "Date")){
from = tryCatch({as.Date(from)}, error = function(e){
cli::cli_alert_danger("{.field to} not in a valid POSIXct or Date format")})
from = strftime(format(from, tz = "UTC", usetz = TRUE), "%Y-%m-%dT%H:%M:%OSZ")
}else{from = strftime(format(from, tz = "UTC", usetz = TRUE), "%Y-%m-%dT%H:%M:%OSZ")}
}
if(!missing(to)){
if(!methods::is(to, "POSIXct") && !methods::is(to, "Date")){
to = tryCatch({as.Date(to)}, error = function(e){
cli::cli_alert_danger("{.field from} not in a valid POSIXct or Date format")})
to = strftime(format(to, tz = "UTC", usetz = TRUE), "%Y-%m-%dT%H:%M:%OSZ")
}else{to = strftime(format(to, tz = "UTC", usetz = TRUE), "%Y-%m-%dT%H:%M:%OSZ")}
}
if(!is.logical(silent)){cli::cli_alert_danger("silent must be TRUE or FALSE"); stop()}
if(!is.null(token)){token = token}
else if(store_token == "option"){token = getOption('ARDUINO_API_TOKEN')}
else if(store_token == "envir"){token = Sys.getenv('ARDUINO_API_TOKEN')}
else{cli::cli_alert_danger("Token is null and store_token neither 'option' nor 'envir':
use function create_auth_token to create a valid one or choose a valid value
for store_token"); stop()}
url = "https://api2.arduino.cc/iot/v2/series/batch_query_raw"
still_valid_token = FALSE
while(!still_valid_token){
header = c('Authorization' = paste0("Bearer ", token),
'Content-Type' = "text/plain")
body = list("requests" = data.frame('from' = from, 'to' = to, 'Q' = Q),
"resp_version" = 1)
body$requests$interval = interval
body$requests$SeriesLimit = SeriesLimit
res = httr::POST(url = url, body = body, httr::add_headers(header), encode = "json")
if(res$status_code == 200){
res_raw = jsonlite::fromJSON(httr::content(res, 'text', encoding = "UTF-8"))
res = tibble::tibble(time = unlist(res_raw$responses$times),
values = unlist(res_raw$responses$values))
if(nrow(res)>0){
res$time = as.POSIXct(res$time, format = "%Y-%m-%dT%H:%M:%OSZ", tz = "UTC")
}
still_valid_token = TRUE; if(!silent){cli::cli_alert_success("Method succeeded")}}
else if(res$status_code == 401){
cli::cli_alert_warning("Request not authorized: regenerate token")
token = create_auth_token(store_token = store_token, return_token = TRUE, silent = silent)}
else if(res$status_code == 404){
still_valid_token = TRUE; cli::cli_alert_danger("API error: Not found");}
else{
res_detail = jsonlite::fromJSON(httr::content(res, 'text', encoding = "UTF-8"))$detail
cli::cli_alert_danger(cat(paste0("API error: ", res_detail))); stop()}
}
return(res)
}
#' @name series_batch
#' @export
series_batch_last_value <- function(thing_id, property_id,
store_token = "option",
token = NULL,
silent = FALSE){
if(missing(thing_id)){cli::cli_alert_danger("missing thing_id"); stop()}
if(missing(property_id)){cli::cli_alert_danger("missing property_id"); stop()}
if(!is.logical(silent)){cli::cli_alert_danger("silent must be TRUE or FALSE"); stop()}
if(!is.null(token)){token = token}
else if(store_token == "option"){token = getOption('ARDUINO_API_TOKEN')}
else if(store_token == "envir"){token = Sys.getenv('ARDUINO_API_TOKEN')}
else{cli::cli_alert_danger("Token is null and store_token neither 'option' nor 'envir':
use function create_auth_token to create a valid one or choose a valid value
for store_token"); stop()}
url = "https://api2.arduino.cc/iot/v2/series/batch_query_raw/lastvalue"
still_valid_token = FALSE
while(!still_valid_token){
header = c('Authorization' = paste0("Bearer ", token),
'Content-Type' = "text/plain")
body = list("requests" = data.frame('thing_id' = thing_id, 'property_id' = property_id))
res = httr::POST(url = url, body = body, httr::add_headers(header), encode = "json")
if(res$status_code == 200){
res_raw = jsonlite::fromJSON(httr::content(res, 'text', encoding = "UTF-8"))
res = tibble::tibble(time = unlist(res_raw$responses$times),
values = unlist(res_raw$responses$values))
if(nrow(res)>0){
res$time = as.POSIXct(res$time, format = "%Y-%m-%dT%H:%M:%OSZ", tz = "UTC")
}
still_valid_token = TRUE; if(!silent){cli::cli_alert_success("Method succeeded")}}
else if(res$status_code == 401){
cli::cli_alert_warning("Request not authorized: regenerate token")
token = create_auth_token(store_token = store_token, return_token = TRUE, silent = silent)}
else if(res$status_code == 404){
still_valid_token = TRUE; cli::cli_alert_danger("API error: Not found");}
else{
res_detail = jsonlite::fromJSON(httr::content(res, 'text', encoding = "UTF-8"))$detail
cli::cli_alert_danger(cat(paste0("API error: ", res_detail))); stop()}
}
return(res)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.