diff --git a/DESCRIPTION b/DESCRIPTION index bde9333..c7d08bd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,6 +23,7 @@ Depends: R (>= 3.6.0) Imports: RcppSimdJson, + jsonlite, openssl, tidyr, dplyr, diff --git a/NAMESPACE b/NAMESPACE index 260d10b..9585901 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,13 +1,18 @@ # Generated by roxygen2: do not edit by hand export("%>%") +export(get_config) export(get_image) +export(get_lep_cci) export(get_status) +export(get_wifi) +export(set_time) export(tcam_connect) export(tidy_radiometric) importFrom(RcppSimdJson,fparse) importFrom(dplyr,mutate) importFrom(dplyr,mutate_at) +importFrom(jsonlite,toJSON) importFrom(magrittr,"%>%") importFrom(openssl,base64_decode) importFrom(stringi,stri_replace_all_regex) diff --git a/R/core.R b/R/core.R index 4e8fb43..6d57651 100644 --- a/R/core.R +++ b/R/core.R @@ -24,37 +24,245 @@ get_status <- function(con) { Sys.sleep(0.5) - readChar( + readBin( + con = con, + what = "raw", + n = 2048L + ) %>% + rawToChar() %>% + stri_replace_all_regex("\002|\003", "") %>% + fparse() + +} + +#' Returns a packet with the camera's current settings. +#' +#' @param con open socket connection from [tcam_connect()] +#' @export +get_config <- function(con) { + + writeBin( + object = c(as.raw(0x02), charToRaw('{"cmd":"get_config"}'), as.raw(0x03)), + con = con, + useBytes = TRUE + ) -> res + + Sys.sleep(0.5) + + readBin( + con = con, + what = "raw", + n = 2048L + ) %>% + rawToChar() %>% + stri_replace_all_regex("\002|\003", "") %>% + fparse() + +} + +#' Reads and returns specified data from the Lepton's CCI interface. +#' +#' @param con open socket connection from [tcam_connect()] +#' @param command decimal representation of the 16-bit Lepton `COMMAND` register +#' value. For example, the value `20172` above is `0x4ECC` (RAD Spotmeter +#' Region of Interest). +#' @param length decimal number of 16-bit words to read (`1-512`). +#' @references [FLIR LEPTON Software Interface Description Document (IDD)](https://www.flir.com/globalassets/imported-assets/document/flir-lepton-software-interface-description-document.pdf) +#' @export +get_lep_cci <- function(con, command, length) { + + stopifnot(((length >= 1) && (length <= 512))) + + list( + cmd = "get_lep_cci", + args = list( + command = as.integer(command), + length = as.integer(length) + ) + ) %>% + jsonlite::toJSON(auto_unbox = TRUE) -> cmd + + Sys.sleep(0.5) + + tmp <- get_status(con) + + Sys.sleep(0.5) + + writeBin( + object = c(as.raw(0x02), charToRaw(cmd), as.raw(0x03)), con = con, - nchars = 2048L, useBytes = TRUE + ) -> res + + Sys.sleep(0.5) + + readBin( + con = con, + what = "raw", + n = 2048L ) %>% + rawToChar() %>% stri_replace_all_regex("\002|\003", "") %>% fparse() } +#' Set the camera's clock. +#' +#' @param con open socket connection from [tcam_connect()] +#' @param time `Date` or `POSIXct` object or a character string that +#' can be coerced to one; defaults to "now". +#' @export +set_time <- function(con, time = Sys.time()) { + + Sys.sleep(0.5) + + tmp <- get_status(con) + + Sys.sleep(0.5) + + time <- as.POSIXlt(as.POSIXct(time[1])) + + list( + cmd = "set_time", + args = list( + sec = as.integer(time$sec), + min = time$min, + hour = time$hour, + dow = time$wday + 1L, + day = time$mday, + mon = time$mon + 1L, + year = time$year + 1900L - 1970L + ) + ) %>% + jsonlite::toJSON(auto_unbox = TRUE) -> cmd + + writeBin( + object = c(as.raw(0x02), charToRaw(cmd), as.raw(0x03)), + con = con, + useBytes = TRUE + ) -> res + + Sys.sleep(0.5) + + readBin( + con = con, + what = "raw", + n = 2048L + ) %>% + rawToChar() %>% + stri_replace_all_regex("\002|\003", "") %>% + fparse() + +} + +# #' Set the camera's Wi-Fi and network configuration. +# #' +# #' The Wi-Fi subsystem is immediately restarted. Which means +# #' `con` is no longer valid and will need to be re-opened. Leave paramaters +# #' as `NULL` if you do not want to change those settings on the tCam. +# #' +# #' @param con open socket connection from [tcam_connect()] +# #' @param ap_ssid Set the AP-mode SSID and also the camera name as reported in the metadata and status objects. +# #' @param ap_pw Set the AP-mode password. +# #' @param ap_ip_addr The camera's IP address when it is in AP mode. +# #' @param flags Set WiFi configuration (see below). +# #' @param sta_ssid Set the client-mode (STA) SSID. +# #' @param sta_pw Set the client-mode (STA) password. +# #' @param sta_ip_addr Set the static IP address to use when the camera as a client and configured to use a static IP. +# #' @param sta_netmask Set the netmask to use when the camera as a client and configured to use a static IP. +# #' @export +# set_wifi <- function(con, ap_ssid = NULL, ap_pw = NULL, ap_ip_addr = NULL, +# flags = NULL, +# sta_ssid = NULL, sta_pw = NULL, sta_ip_addr = NULL, sta_netmask = NULL) { +# +# list( +# ap_ssid = ap_ssid, +# ap_pw = ap_pw, +# ap_ip_addr = ap_ip_addr, +# flags = flags, +# sta_ssid = sta_ssid, +# sta_pw = sta_pw, +# sta_ip_addr = sta_ip_addr, +# sta_netmask = sta_netmask +# ) +# +# writeBin( +# object = c(as.raw(0x02), charToRaw('{"cmd":"get_status"}'), as.raw(0x03)), +# con = con, +# useBytes = TRUE +# ) -> res +# +# Sys.sleep(0.5) +# +# readChar( +# con = con, +# nchars = 2048L, +# useBytes = TRUE +# ) %>% +# stri_replace_all_regex("\002|\003", "") %>% +# fparse() +# +# } + + #' Returns a packet with metadata, radiometric (or AGC) image data and Lepton telemetry objects. #' #' @param con open socket connection from [tcam_connect()] #' @export get_image <- function(con) { + Sys.sleep(0.5) + tmp <- get_status(con) + Sys.sleep(0.5) + writeBin( object = c(as.raw(0x02), charToRaw('{"cmd":"get_image"}'), as.raw(0x03)), con = con, useBytes = TRUE ) -> res + Sys.sleep(1) + + readBin( + con = con, + what = "raw", + n = 65536L + ) %>% + rawToChar() %>% + stri_replace_all_regex("\002|\003", "") %>% + fparse() + +} + +#' Returns a packet with the camera's current WiFi and Network configuration. +#' +#' @param con open socket connection from [tcam_connect()] +#' @export +get_wifi <- function(con) { + + Sys.sleep(0.5) + + tmp <- get_status(con) + Sys.sleep(0.5) - readChar( + writeBin( + object = c(as.raw(0x02), charToRaw('{"cmd":"get_wifi"}'), as.raw(0x03)), con = con, - nchars = 65536L, useBytes = TRUE + ) -> res + + Sys.sleep(0.5) + + readBin( + con = con, + what = "raw", + n = 5120L ) %>% + rawToChar() %>% stri_replace_all_regex("\002|\003", "") %>% fparse() diff --git a/R/tcam-package.R b/R/tcam-package.R index e3b6bd2..f052da9 100644 --- a/R/tcam-package.R +++ b/R/tcam-package.R @@ -16,4 +16,5 @@ #' @importFrom dplyr mutate mutate_at #' @importFrom stringi stri_replace_all_regex #' @importFrom utils hasName +#' @importFrom jsonlite toJSON "_PACKAGE" diff --git a/README.Rmd b/README.Rmd index 615a405..ae21321 100644 --- a/README.Rmd +++ b/README.Rmd @@ -40,17 +40,25 @@ packageVersion("tcam") ``` -Open a connection and get the status of the tCam: +Open a connection to the tCam: -```{r ex-01} +```{r ex-01a-show, eval=FALSE} con <- tcam_connect() +``` + +```{r ex-01a-hidden, echo=FALSE} +con <- tcam_connect("10.1.10.89") +``` + +Get the tCam status: +```{r ex-01b} get_status(con) ``` Take a picture and plot it: -```{r ex-02, cache=TRUE} +```{r ex-02} img <- get_image(con) ggplot(tidy_radiometric(img)) + @@ -75,7 +83,7 @@ ggplot(tidy_radiometric(img)) + ) ``` -Done, so we close the connection. +Done, so we close the connection (kinda important) ```{r ex-99} close(con) diff --git a/README.md b/README.md index 6efdd52..2ae163f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,20 @@ +[![Project Status: Active – The project has reached a stable, usable +state and is being actively +developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) +[![Signed +by](https://img.shields.io/badge/Keybase-Verified-brightgreen.svg)](https://keybase.io/hrbrmstr) +![Signed commit +%](https://img.shields.io/badge/Signed_Commits-100%25-lightgrey.svg) +[![R-CMD-check](https://github.com/hrbrmstr/tcam/workflows/R-CMD-check/badge.svg)](https://github.com/hrbrmstr/tcam/actions?query=workflow%3AR-CMD-check) +[![Linux build +Status](https://travis-ci.org/hrbrmstr/tcam.svg?branch=master)](https://travis-ci.org/hrbrmstr/tcam) +[![Coverage +Status](https://codecov.io/gh/hrbrmstr/tcam/branch/master/graph/badge.svg)](https://codecov.io/gh/hrbrmstr/tcam) +![Minimal R +Version](https://img.shields.io/badge/R%3E%3D-3.6.0-blue.svg) +![License](https://img.shields.io/badge/License-MIT-blue.svg) + # tcam Retrieve Radiometric Image Data from and Configure and Control tCam and @@ -16,9 +32,15 @@ and receive radiometric data from tCam systems. The following functions are implemented: +- `get_config`: Returns a packet with the camera’s current settings. - `get_image`: Returns a packet with metadata, radiometric (or AGC) image data and Lepton telemetry objects. +- `get_lep_cci`: Reads and returns specified data from the Lepton’s + CCI interface. - `get_status`: Returns a packet with camera status. +- `get_wifi`: Returns a packet with the camera’s current WiFi and + Network configuration. +- `set_time`: Set the camera’s clock. - `tcam_connect`: Make a socket connection to a tCam device - `tidy_radiometric`: Return a tidy data frame of Lepton radiometric data retrieved with get_image() @@ -47,11 +69,15 @@ packageVersion("tcam") ## [1] '0.1.0' ``` -Open a connection and get the status of the tCam: +Open a connection to the tCam: ``` r con <- tcam_connect() +``` +Get the tCam status: + +``` r get_status(con) ## $status ## $status$Camera @@ -64,10 +90,10 @@ get_status(con) ## [1] "1.3" ## ## $status$Time -## [1] "2:07:27.287" +## [1] "12:04:24.769" ## ## $status$Date -## [1] "1/1/-30" +## [1] "8/20/21" ``` Take a picture and plot it: @@ -99,7 +125,7 @@ ggplot(tidy_radiometric(img)) + -Done, so we close the connection. +Done, so we close the connection (kinda important) ``` r close(con) @@ -109,10 +135,10 @@ close(con) | Lang | # Files | (%) | LoC | (%) | Blank lines | (%) | # Lines | (%) | |:-----|--------:|-----:|----:|-----:|------------:|-----:|--------:|-----:| -| R | 6 | 0.33 | 74 | 0.28 | 18 | 0.21 | 51 | 0.28 | -| Rmd | 1 | 0.06 | 33 | 0.13 | 23 | 0.27 | 37 | 0.21 | -| YAML | 2 | 0.11 | 23 | 0.09 | 2 | 0.02 | 2 | 0.01 | -| SUM | 9 | 0.50 | 130 | 0.50 | 43 | 0.50 | 90 | 0.50 | +| R | 6 | 0.33 | 174 | 0.38 | 55 | 0.34 | 123 | 0.37 | +| Rmd | 1 | 0.06 | 34 | 0.07 | 25 | 0.15 | 42 | 0.13 | +| YAML | 2 | 0.11 | 23 | 0.05 | 2 | 0.01 | 2 | 0.01 | +| SUM | 9 | 0.50 | 231 | 0.50 | 82 | 0.50 | 167 | 0.50 | clock Package Metrics for tcam diff --git a/man/figures/README-ex-02-1.png b/man/figures/README-ex-02-1.png index ab03b35..cc7bcd4 100644 Binary files a/man/figures/README-ex-02-1.png and b/man/figures/README-ex-02-1.png differ diff --git a/man/get_config.Rd b/man/get_config.Rd new file mode 100644 index 0000000..c71ac90 --- /dev/null +++ b/man/get_config.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/core.R +\name{get_config} +\alias{get_config} +\title{Returns a packet with the camera's current settings.} +\usage{ +get_config(con) +} +\arguments{ +\item{con}{open socket connection from \code{\link[=tcam_connect]{tcam_connect()}}} +} +\description{ +Returns a packet with the camera's current settings. +} diff --git a/man/get_lep_cci.Rd b/man/get_lep_cci.Rd new file mode 100644 index 0000000..4f45d2a --- /dev/null +++ b/man/get_lep_cci.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/core.R +\name{get_lep_cci} +\alias{get_lep_cci} +\title{Reads and returns specified data from the Lepton's CCI interface.} +\usage{ +get_lep_cci(con, command, length) +} +\arguments{ +\item{con}{open socket connection from \code{\link[=tcam_connect]{tcam_connect()}}} + +\item{command}{decimal representation of the 16-bit Lepton \code{COMMAND} register +value. For example, the value \code{20172} above is \code{0x4ECC} (RAD Spotmeter +Region of Interest).} + +\item{length}{decimal number of 16-bit words to read (\code{1-512}).} +} +\description{ +Reads and returns specified data from the Lepton's CCI interface. +} +\references{ +\href{https://www.flir.com/globalassets/imported-assets/document/flir-lepton-software-interface-description-document.pdf}{FLIR LEPTON Software Interface Description Document (IDD)} +} diff --git a/man/get_wifi.Rd b/man/get_wifi.Rd new file mode 100644 index 0000000..8927e79 --- /dev/null +++ b/man/get_wifi.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/core.R +\name{get_wifi} +\alias{get_wifi} +\title{Returns a packet with the camera's current WiFi and Network configuration.} +\usage{ +get_wifi(con) +} +\arguments{ +\item{con}{open socket connection from \code{\link[=tcam_connect]{tcam_connect()}}} +} +\description{ +Returns a packet with the camera's current WiFi and Network configuration. +} diff --git a/man/set_time.Rd b/man/set_time.Rd new file mode 100644 index 0000000..8708db2 --- /dev/null +++ b/man/set_time.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/core.R +\name{set_time} +\alias{set_time} +\title{Set the camera's clock.} +\usage{ +set_time(con, time = Sys.time()) +} +\arguments{ +\item{con}{open socket connection from \code{\link[=tcam_connect]{tcam_connect()}}} + +\item{time}{\code{Date} or \code{POSIXct} object or a character string that +can be coerced to one; defaults to "now".} +} +\description{ +Set the camera's clock. +}