Getting Started with zentraR

Online version. This guide is also published — and kept current with the API — as the Getting Started with zentraR article on ZENTRA Cloud. This vignette ships with the package for offline use.

zentraR is an R client for the ZENTRA Cloud v5 API. It handles authentication, pagination, and time-window formatting, and returns readings as a tidy data frame ready for dplyr and ggplot2.

This vignette covers the full workflow: authenticating, discovering your devices, downloading readings, reshaping them, and keeping a local copy up to date. The code chunks are not run when the vignette is built (they need your API token and network access) — copy them into your own session.

library(zentraR)

1. Installation

If you are reading this inside R, zentraR is already installed. To set it up on a new machine, install its dependencies and then the package file itself. The full walkthrough (with screenshots) is in the online Getting Started with zentraR article; in brief:

# 1. Dependencies (from CRAN):
install.packages(c("httr2", "cli", "rlang", "tibble", "tidyr", "vctrs"))

# 2. The package file you were given (use forward slashes; avoid `~`):
install.packages("C:/Users/<you>/zentraR_0.1.0.tar.gz", repos = NULL, type = "source")

Then load it (once per R session):

library(zentraR)

2. Authenticate

zentraR reads your token from the ZENTRACLOUD_API_KEY environment variable. zc_set_key() sets it for you:

# This session only:
zc_set_key("your-api-token")

# Persist to ~/.Renviron so every future session finds it automatically:
zc_set_key("your-api-token", install = TRUE)

If you already set ZENTRACLOUD_API_KEY yourself — in ~/.Renviron or elsewhere in your environment — skip zc_set_key() entirely.

To generate a token, see API Token.

3. Discover your devices

zc_list_devices() returns one row per device your token can access. Pagination is handled for you; all pages are fetched and combined.

devices <- zc_list_devices()
devices

expand attaches additional detail. Pass one or more values as a character vector.

zc_list_devices(expand = c("max_min_timestamp", "settings"))

"max_min_timestamp" is useful before a backfill: it reports each device’s first and last measurement time, so you can choose a sensible start.

For the available expand values and the fields each one adds, see GET List Devices.

4. Download readings

zc_get_readings() returns a tidy long data frame — one row per (port, measurement, timestamp). Give it a device ID and a time window.

readings <- zc_get_readings("z6-00930", start = Sys.Date() - 7)
readings

start and end accept a Date, a POSIXct, epoch seconds, or an ISO 8601 string. Values supplied without a timezone are interpreted as UTC.

zc_get_readings(
  "z6-00930",
  start = as.POSIXct("2026-05-01", tz = "UTC"),
  end   = as.POSIXct("2026-06-01", tz = "UTC")
)

units and direction map directly to the corresponding query parameters:

zc_get_readings("z6-00930", start = Sys.Date() - 1, units = "imperial", direction = "descending")

For the full parameter reference and response field definitions, see GET Device Readings.

Working with error codes

Each row carries an error_code. zc_label_errors() joins human-readable labels onto a readings data frame, and zc_error_codes() returns the lookup table:

zc_label_errors(readings)
zc_error_codes()

For what each code means, see Device & Sensor Error Codes.

The tidy long format works directly with the tidyverse:

library(dplyr)
library(ggplot2)

readings |>
  filter(measurement == "Air Temperature", error_code == 0) |>
  ggplot(aes(datetime, value)) +
  geom_line() +
  labs(y = unique(readings$unit[readings$measurement == "Air Temperature"]))

5. Reshape to wide format

zc_pivot_wider() produces one row per timestamp and one column per measurement — the familiar spreadsheet layout.

zc_pivot_wider(readings)

The wide form drops the per-reading unit and error_code columns. Keep the long form when you need either.

6. Keep a local copy up to date

zc_sync() records what you already have and fetches only newer readings. A store determines where that data lives:

store <- zc_store_csv("data/zentra")

# First run — backfill from `start`, or from each device's first measurement if omitted:
zc_sync("z6-00930", store = store, start = Sys.Date() - 30)

# Later runs — only what's new since last time:
zc_sync("z6-00930", store = store)

# Every device your token can access, in one call:
zc_sync(store = store)

# Read the accumulated record back into R:
all_data <- zc_store_read(store)

With a store, zc_sync() returns a per-device summary (rows added, latest timestamp, status). With store = NULL it returns the combined new readings instead.

Next steps

New to R? The Working with Your Data in R vignette covers the everyday commands for viewing, filtering, summarising, and exporting your readings — also published online as Working with Your Data in R:

vignette("working-with-data", package = "zentraR")

To run syncs automatically — on project open, daily, or weekly — see the Scheduling automatic syncs vignette, also published online as Scheduling Automatic Syncs:

vignette("scheduling", package = "zentraR")