Functions able to directly read and validate data from .CSV files created by the data loggers built into YoctoPuce USB modules, and metadata extracted from a JSON file with the USB module settings.
Usage
read_yocto_datalog(
file,
settings.file = NULL,
geocode = NULL,
label = NULL,
cols.pattern = NULL,
cols.logical.names = FALSE,
nacols.rm = TRUE,
dec = ".",
sep = ";",
tz = "UTC",
module.descriptor = NULL,
...
)
read_yocto_spctlog(
file,
settings.file = NULL,
cols.pattern = "avg",
cols.rename = TRUE,
dec = ".",
sep = ";",
tz = "UTC",
...
)Arguments
- file
the name of the file which the data are to be read from. Each row of the table appears as one line of the file. If it does not contain an absolute path, the file name is relative to the current working directory,
getwd(). Tilde-expansion is performed where supported. This can be a compressed file (seefile).Alternatively,
filecan be a readable text-mode connection (which will be opened for reading if necessary, and if soclosed (and hence destroyed) at the end of the function call). (Ifstdin()is used, the prompts for lines may be somewhat confusing. Terminate input with a blank line or an signal,Ctrl-Don Unix andCtrl-Zon Windows. Any pushback onstdin()will be cleared before return.)filecan also be a complete URL. (For the supported URL schemes, see the ‘URLs’ section of the help forurl.)- settings.file
character Path to a JSON file containing the module settings used to acquire the data.
- geocode
data.frame Containing columns
lonandlatused to set attribute"where.measured".- label
character Additional text to be appended to the default value used to set attribute
"comment".- cols.pattern
character A string suitable as argument for
patternin a call togrep()on column headings in the imported CSV file.NULLorcharacte(0)retain all data columns, whileNAreturns all data and time columns.- cols.logical.names
logical Use logical names from module metadata instead of column heading in CSV file. Require readable
settings.file.- nacols.rm
logical If
TRUEdelete columns that contain onlyNAvalues.- dec
the character used in the file for decimal points.
- sep
the field separator character. Values on each line of the file are separated by this character. If
sep = ""(the default forread.table) the separator is ‘white space’, that is one or more spaces, tabs, newlines or carriage returns.- tz
a character string that specifies which time zone to parse the date with. The string must be a time zone that is recognized by the user's OS.
- module.descriptor
list A matadata descriptor of the YocotoPuce USB module to be added as an attribute to the returned object.
- ...
Arguments passed on to
utils::read.tablecolClassescharacter. A vector of classes to be assumed for the columns. If unnamed, recycled as necessary. If named, names are matched with unspecified values being taken to be
NA.Possible values are
NA(the default, whentype.convertis used),"NULL"(when the column is skipped), one of the atomic vector classes (logical, integer, numeric, complex, character, raw), or"factor","Date"or"POSIXct". Otherwise there needs to be anasmethod (from package methods) for conversion from"character"to the specified formal class.Note that
colClassesis specified per column (not per variable) and so includes the column of row names (if any).nrowsinteger: the maximum number of rows to read in. Negative and other invalid values are ignored.
skipinteger: the number of lines of the data file to skip before beginning to read data.
check.nameslogical. If
TRUEthen the names of the variables in the data frame are checked to ensure that they are syntactically valid variable names. If necessary they are adjusted (bymake.names) so that they are, and also to ensure that there are no duplicates.comment.charcharacter: a character vector of length one containing a single character or an empty string. Use
""to turn off the interpretation of comments altogether.
- cols.rename
logical Flag, if
TRUEuse channel names from sensor IC specification as column names, and ifFALSEkeep the names used in the imported file.
Value
A data frame with POSIXct time stamps in column time
and data in a variable number of columns containing values converted by
read.csv().
Details
The dataloggers implemented in different USB modules from
YoctoPuce return .CSV files with a consistent format, that varies only
in the number of data columns and their names. Function
read_yocto_datalog() reads any of these files preserving column
names. The UTC times are converted into POSIXct values and added
under column time. A subset of columns can be requested by
passing a regular expression to be used in a call to grep() on the
column names. If nacols.rm = TRUE is passed, columns containing only
NA values are deleted, as these columns in most cases correspond
to logger channels that are not in use.
Warnings are issued if something unexpected, such as dates several years into the past, unsorted or repeated time stamps are encountered in the sequence of UNIX time stamps in the file. These discrepancies can occur when the modules' or the YoctoHub clocks do not acquire a valid time at start-up. Inconsistent time steps are reported through a message, as these are the result of a stop followed by restart of logging. During such a pause it is possible that module settings could have been changed.
If the name of a JSON file as saved from the YoctoPuce module is passed as
an argument to parameter settings.file its contents parsed into an
R list are saved to attribute "yocto.module.settings" in the returned
data frame. The metadata also make it possible to set column names to the
logical names set in the module. The logical name of the module and the
units are also extracted if available, formatted and saved in the
"how.measured" attribute.
A comment attribute is always set with information about the imported file(s) and the import time and package.
Function read_yocto_spctlog() is a wrapper on
read_yocto_datalog() that renames columns using the names used in
the data sheet for the AS7343 sensor.
In modules with multiple channels, the user can enable and disable logging on a channel by channel basis. Thus, the number of data columns can vary, making it necessary to match columns by name when replacing some of the default names by shorter or more informative ones.
Warning!
The units and basis of expression, and in several cases
even the physical quantity measured cannot be decoded from the CSV files.
The values in the returned data frame are those read from the file, and
the read values have to be interpreted based on the module settings which,
scripts used during data acquisition by the USB module. These settings
if available in a JSON file downloaded from the module, can be stored in
attribute "yocto.module.settings" of the data frame returned.
I have access to several different USB modules from YoctoPuce, but not to all of them. There are currently some modules that are not fully supported, and a few others that "should" work but have not been yet tested.
References
Documentation for each YocotoPuce USB module is available at https://www.yoctopuce.com/.
Examples
library(photobiology)
#> Loading required package: SunCalcMeeus
#> Documentation at https://docs.r4photobiology.info/
# Yocto-Meteo module
yocto_meteo.file <-
system.file("extdata", "yocto-meteo-snm.csv",
package = "rYoctoPuceInOut", mustWork = TRUE)
yocto_meteo_json.file <-
system.file("extdata", "METEOMK2-19A230.json",
package = "rYoctoPuceInOut", mustWork = TRUE)
meteo1.df <- read_yocto_datalog(yocto_meteo.file)
#> Period: 2025-08-07 19:32:05 to 2025-08-07 22:50:00
#> Found gaps, time steps range from 55s to 60s (~1 minutes)
head(meteo1.df, n = 5)
#> time humidity.min humidity.avg humidity.max pressure.min
#> 1 2025-08-07 16:32:05 53.310 53.310 53.310 1012.712
#> 2 2025-08-07 16:33:05 53.043 53.352 53.715 1012.472
#> 3 2025-08-07 16:34:05 53.188 53.269 53.394 1012.398
#> 4 2025-08-07 16:35:05 53.219 53.482 53.684 1012.426
#> 5 2025-08-07 16:36:05 53.631 53.794 54.005 1012.413
#> pressure.avg pressure.max temperature.min temperature.avg temperature.max
#> 1 1012.716 1012.717 23.495 23.495 23.495
#> 2 1012.548 1012.712 23.495 23.503 23.506
#> 3 1012.434 1012.477 23.495 23.501 23.506
#> 4 1012.467 1012.525 23.495 23.502 23.506
#> 5 1012.468 1012.525 23.506 23.510 23.517
cat(comment(meteo1.df))
#> Data logged by a YoctoPuce USB module.
#> Data file "yocto-meteo-snm.csv" created on 2026-02-08 16:52:24.
#> Imported on 2026-02-08 19:08:33 using TZ = "UTC" with 'rYoctoPuceInOut' (== 0.0.1.9001).
cat(how_measured(meteo1.df))
#> YoctoPuce USB module type 'unknown'.
read_yocto_datalog(yocto_meteo.file, cols.pattern = "avg") |>
head(n = 5)
#> Period: 2025-08-07 19:32:05 to 2025-08-07 22:50:00
#> Found gaps, time steps range from 55s to 60s (~1 minutes)
#> time humidity.avg pressure.avg temperature.avg
#> 1 2025-08-07 16:32:05 53.310 1012.716 23.495
#> 2 2025-08-07 16:33:05 53.352 1012.548 23.503
#> 3 2025-08-07 16:34:05 53.269 1012.434 23.501
#> 4 2025-08-07 16:35:05 53.482 1012.467 23.502
#> 5 2025-08-07 16:36:05 53.794 1012.468 23.510
read_yocto_datalog(yocto_meteo.file, cols.pattern = "min|max") |>
head(n = 5)
#> Period: 2025-08-07 19:32:05 to 2025-08-07 22:50:00
#> Found gaps, time steps range from 55s to 60s (~1 minutes)
#> time humidity.min humidity.max pressure.min pressure.max
#> 1 2025-08-07 16:32:05 53.310 53.310 1012.712 1012.717
#> 2 2025-08-07 16:33:05 53.043 53.715 1012.472 1012.712
#> 3 2025-08-07 16:34:05 53.188 53.394 1012.398 1012.477
#> 4 2025-08-07 16:35:05 53.219 53.684 1012.426 1012.525
#> 5 2025-08-07 16:36:05 53.631 54.005 1012.413 1012.525
#> temperature.min temperature.max
#> 1 23.495 23.495
#> 2 23.495 23.506
#> 3 23.495 23.506
#> 4 23.495 23.506
#> 5 23.506 23.517
read_yocto_datalog(yocto_meteo.file, cols.pattern = "temperature") |>
head(n = 5)
#> Period: 2025-08-07 19:32:05 to 2025-08-07 22:50:00
#> Found gaps, time steps range from 55s to 60s (~1 minutes)
#> time temperature.min temperature.avg temperature.max
#> 1 2025-08-07 16:32:05 23.495 23.495 23.495
#> 2 2025-08-07 16:33:05 23.495 23.503 23.506
#> 3 2025-08-07 16:34:05 23.495 23.501 23.506
#> 4 2025-08-07 16:35:05 23.495 23.502 23.506
#> 5 2025-08-07 16:36:05 23.506 23.510 23.517
read_yocto_datalog(yocto_meteo.file, nrows = 4L)
#> Period: 2025-08-07 19:32:05 to 2025-08-07 19:35:05
#> time humidity.min humidity.avg humidity.max pressure.min
#> 1 2025-08-07 16:32:05 53.310 53.310 53.310 1012.712
#> 2 2025-08-07 16:33:05 53.043 53.352 53.715 1012.472
#> 3 2025-08-07 16:34:05 53.188 53.269 53.394 1012.398
#> 4 2025-08-07 16:35:05 53.219 53.482 53.684 1012.426
#> pressure.avg pressure.max temperature.min temperature.avg temperature.max
#> 1 1012.716 1012.717 23.495 23.495 23.495
#> 2 1012.548 1012.712 23.495 23.503 23.506
#> 3 1012.434 1012.477 23.495 23.501 23.506
#> 4 1012.467 1012.525 23.495 23.502 23.506
# metadata from JSON file
meteo2.df <- read_yocto_datalog(yocto_meteo.file, yocto_meteo_json.file)
#> Period: 2025-08-07 19:32:05 to 2025-08-07 22:50:00
#> Found gaps, time steps range from 55s to 60s (~1 minutes)
head(meteo2.df, n = 5)
#> time humidity.min humidity.avg humidity.max pressure.min
#> 1 2025-08-07 16:32:05 53.310 53.310 53.310 1012.712
#> 2 2025-08-07 16:33:05 53.043 53.352 53.715 1012.472
#> 3 2025-08-07 16:34:05 53.188 53.269 53.394 1012.398
#> 4 2025-08-07 16:35:05 53.219 53.482 53.684 1012.426
#> 5 2025-08-07 16:36:05 53.631 53.794 54.005 1012.413
#> pressure.avg pressure.max temperature.min temperature.avg temperature.max
#> 1 1012.716 1012.717 23.495 23.495 23.495
#> 2 1012.548 1012.712 23.495 23.503 23.506
#> 3 1012.434 1012.477 23.495 23.501 23.506
#> 4 1012.467 1012.525 23.495 23.502 23.506
#> 5 1012.468 1012.525 23.506 23.510 23.517
cat(comment(meteo2.df))
#> Data logged by a YoctoPuce USB module.
#> Data file "yocto-meteo-snm.csv" created on 2026-02-08 16:52:24.
#> Metadata file "METEOMK2-19A230.json" created on 2026-02-08 16:52:24.
#> Imported on 2026-02-08 19:08:33 using TZ = "UTC" with 'rYoctoPuceInOut' (== 0.0.1.9001).
cat(how_measured(meteo2.df))
#> YoctoPuce USB module named 'C2-Meteo' type 'Yocto-Meteo-V2',
#> s.n. 'METEOMK2-19A230' with firmware '69970'.
#> Units: humidity: % RH, pressure: mbar, temperature: °C.
meteo3.df <- read_yocto_datalog(yocto_meteo.file,
yocto_meteo_json.file,
cols.logical.names = TRUE)
#> Period: 2025-08-07 19:32:05 to 2025-08-07 22:50:00
#> Found gaps, time steps range from 55s to 60s (~1 minutes)
head(meteo3.df, n = 5)
#> time C2_humidity.min C2_humidity.avg C2_humidity.max
#> 1 2025-08-07 16:32:05 53.310 53.310 53.310
#> 2 2025-08-07 16:33:05 53.043 53.352 53.715
#> 3 2025-08-07 16:34:05 53.188 53.269 53.394
#> 4 2025-08-07 16:35:05 53.219 53.482 53.684
#> 5 2025-08-07 16:36:05 53.631 53.794 54.005
#> C2_pressure.min C2_pressure.avg C2_pressure.max C2_temperature.min
#> 1 1012.712 1012.716 1012.717 23.495
#> 2 1012.472 1012.548 1012.712 23.495
#> 3 1012.398 1012.434 1012.477 23.495
#> 4 1012.426 1012.467 1012.525 23.495
#> 5 1012.413 1012.468 1012.525 23.506
#> C2_temperature.avg C2_temperature.max
#> 1 23.495 23.495
#> 2 23.503 23.506
#> 3 23.501 23.506
#> 4 23.502 23.506
#> 5 23.510 23.517
cat(comment(meteo3.df))
#> Data logged by a YoctoPuce USB module.
#> Data file "yocto-meteo-snm.csv" created on 2026-02-08 16:52:24.
#> Metadata file "METEOMK2-19A230.json" created on 2026-02-08 16:52:24.
#> Imported on 2026-02-08 19:08:33 using TZ = "UTC" with 'rYoctoPuceInOut' (== 0.0.1.9001).
cat(how_measured(meteo3.df))
#> YoctoPuce USB module named 'C2-Meteo' type 'Yocto-Meteo-V2',
#> s.n. 'METEOMK2-19A230' with firmware '69970'.
#> Units: C2_humidity: % RH, C2_pressure: mbar, C2_temperature: °C.
str(attr(meteo3.df, "yocto.module.settings"), max.level = 2)
#> List of 3
#> $ api :List of 5
#> ..$ module :List of 13
#> ..$ humidity :List of 15
#> ..$ pressure :List of 13
#> ..$ temperature:List of 17
#> ..$ dataLogger :List of 9
#> $ extras: list()
#> $ files : list()
# Yocto-Spectral module
yocto_spectral.file <-
system.file("extdata", "yocto-spectral-LED.csv",
package = "rYoctoPuceInOut", mustWork = TRUE)
yocto_spectral_json.file <-
system.file("extdata", "SPECTRL1-2CF3B6.json",
package = "rYoctoPuceInOut", mustWork = TRUE)
read_yocto_spctlog(yocto_spectral.file) |> head(n = 5)
#> Period: 2025-12-03 21:54:00 to 2025-12-03 22:52:14
#> Found gaps, time steps range from 10s to 60s (~1 minutes)
#> time F1.avg F2.avg FZ.avg F3.avg
#> 1 2025-12-03 19:54:00 0.00000000 0.00000000 0.01923449 0.00000000
#> 2 2025-12-03 19:55:00 14.81709593 13.26026119 10.70854803 14.03453598
#> 3 2025-12-03 19:56:00 0.20996641 0.62779851 1.43448786 1.28698813
#> 4 2025-12-03 19:57:00 0.01586413 0.01212687 0.01720980 0.01690788
#> 5 2025-12-03 19:58:00 0.01586413 0.01212687 0.01619746 0.01690788
#> F4.avg FY.avg F5.avg FXL.avg F6.avg F7.avg
#> 1 0.01892148 0.08539738 0.00000000 0.09671708 0.08235444 0.06817170
#> 2 14.68704875 14.28618803 17.99289470 19.16909935 17.43903218 68.53901431
#> 3 1.30558184 0.45975569 0.24968026 0.66015027 1.58963228 59.34804452
#> 4 0.01593387 0.01985986 0.01890010 0.02136773 0.02010981 0.02340223
#> 5 0.01493801 0.01787387 0.01691062 0.01799387 0.01436415 0.01933227
#> F8.avg NIR.avg VIS.avg
#> 1 0.00000000 0.000000000 0.08138610
#> 2 69.80591451 3.403664712 37.22971629
#> 3 57.34681909 0.720682303 50.17541353
#> 4 0.02057654 0.003291578 0.02034652
#> 5 0.01943340 0.003464819 0.01592337
read_yocto_spctlog(yocto_spectral.file, cols.pattern = "Channel1\\.") |>
head(n = 5)
#> Period: 2025-12-03 21:54:00 to 2025-12-03 22:52:14
#> Found gaps, time steps range from 10s to 60s (~1 minutes)
#> time F1.min F1.avg F1.max
#> 1 2025-12-03 19:54:00 0.000000000 0.00000000 0.00000000
#> 2 2025-12-03 19:55:00 0.000000000 14.81709593 138.04031355
#> 3 2025-12-03 19:56:00 0.000000000 0.20996641 1.31112355
#> 4 2025-12-03 19:57:00 0.006532288 0.01586413 0.02053005
#> 5 2025-12-03 19:58:00 0.006532288 0.01586413 0.02053005
read_yocto_spctlog(yocto_spectral.file, cols.rename = FALSE) |>
head(n = 5)
#> Period: 2025-12-03 21:54:00 to 2025-12-03 22:52:14
#> Found gaps, time steps range from 10s to 60s (~1 minutes)
#> time spectralChannel1.avg spectralChannel2.avg
#> 1 2025-12-03 19:54:00 0.00000000 0.00000000
#> 2 2025-12-03 19:55:00 14.81709593 13.26026119
#> 3 2025-12-03 19:56:00 0.20996641 0.62779851
#> 4 2025-12-03 19:57:00 0.01586413 0.01212687
#> 5 2025-12-03 19:58:00 0.01586413 0.01212687
#> spectralChannel3.avg spectralChannel4.avg spectralChannel5.avg
#> 1 0.01923449 0.00000000 0.01892148
#> 2 10.70854803 14.03453598 14.68704875
#> 3 1.43448786 1.28698813 1.30558184
#> 4 0.01720980 0.01690788 0.01593387
#> 5 0.01619746 0.01690788 0.01493801
#> spectralChannel6.avg spectralChannel7.avg spectralChannel8.avg
#> 1 0.08539738 0.00000000 0.09671708
#> 2 14.28618803 17.99289470 19.16909935
#> 3 0.45975569 0.24968026 0.66015027
#> 4 0.01985986 0.01890010 0.02136773
#> 5 0.01787387 0.01691062 0.01799387
#> spectralChannel9.avg spectralChannel10.avg spectralChannel11.avg
#> 1 0.08235444 0.06817170 0.00000000
#> 2 17.43903218 68.53901431 69.80591451
#> 3 1.58963228 59.34804452 57.34681909
#> 4 0.02010981 0.02340223 0.02057654
#> 5 0.01436415 0.01933227 0.01943340
#> spectralChannel12.avg spectralChannel13.avg
#> 1 0.000000000 0.08138610
#> 2 3.403664712 37.22971629
#> 3 0.720682303 50.17541353
#> 4 0.003291578 0.02034652
#> 5 0.003464819 0.01592337
# metadata from JSON file
spectral.df <-
read_yocto_spctlog(yocto_spectral.file,
yocto_spectral_json.file)
#> Period: 2025-12-03 21:54:00 to 2025-12-03 22:52:14
#> Found gaps, time steps range from 10s to 60s (~1 minutes)
cat(how_measured(spectral.df))
#> YoctoPuce USB module named 'spectrl-01' type 'Yocto-Spectral',
#> s.n. 'SPECTRL1-2CF3B6' with firmware '69970'.
#> Units: not available.
cat(comment(spectral.df))
#> Data logged by a YoctoPuce USB module.
#> Data file "yocto-spectral-LED.csv" created on 2026-02-08 16:52:24.
#> Metadata file "SPECTRL1-2CF3B6.json" created on 2026-02-08 16:52:24.
#> Imported on 2026-02-08 19:08:33 using TZ = "UTC" with 'rYoctoPuceInOut' (== 0.0.1.9001).