--- title: "Scheduling Automatic Syncs" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Scheduling Automatic Syncs} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ``` > **Online version.** This guide is also published — and kept current with the > API — as the > [Scheduling Automatic Syncs](https://docs.zentracloud.io/l/en/article/f2g5u9hc2r-scheduling-automatic-syncs) > article on ZENTRA Cloud. This vignette ships with the package for offline use. Once you have a `zc_sync()` call that keeps a local store up to date, you can run it automatically — when you open a project, once a day, or once a week. `zentraR` deliberately does **not** bundle a scheduler. Instead, `zc_sync()` is designed to be called from a small, self-contained script that you schedule with the standard tool for your platform. If you haven't set up a sync yet, start with the *Getting Started with zentraR* vignette (`vignette("getting-started", package = "zentraR")`), also published as [Getting Started with zentraR](https://docs.zentracloud.io/l/en/article/j1ejykpvpv-getting-started-with-zentra-r). ## A reusable sync script Save this as `sync_zentra.R` in your project. It reads the token from the environment, syncs every accessible device into a CSV store, and logs a one-line summary. ```{r} #!/usr/bin/env Rscript # sync_zentra.R — fetch new ZENTRA Cloud readings into a local store. library(zentraR) # The token comes from the ZENTRACLOUD_API_KEY environment variable # (set it in ~/.Renviron, or via zc_set_key(..., install = TRUE) once). store <- zc_store_csv("data/zentra") summary <- zc_sync(store = store, quiet = TRUE) message( format(Sys.time()), " synced ", nrow(summary), " device(s), ", sum(summary$rows_added), " new reading(s)" ) ``` Test it from a terminal before scheduling it: ```sh Rscript sync_zentra.R ``` Because `zc_sync()` is incremental, running it more often simply means smaller, faster updates — it never re-downloads what you already have. ## Option A — sync when you open a project (RStudio / `.Rprofile`) To refresh data every time you start R in a project, add this to the project's `.Rprofile`. Running it in a background R session keeps startup snappy. ```{r} # .Rprofile setHook("rstudio.sessionInit", function(newSession) { if (newSession && nzchar(Sys.getenv("ZENTRACLOUD_API_KEY"))) { message("Refreshing ZENTRA Cloud data in the background…") system2("Rscript", "sync_zentra.R", wait = FALSE) } }, action = "append") ``` Outside RStudio, call the script directly at the end of `.Rprofile` instead: ```{r} if (interactive() && nzchar(Sys.getenv("ZENTRACLOUD_API_KEY"))) { try(source("sync_zentra.R")) } ``` ## Option B — daily on macOS / Linux (cron via cronR) The [`cronR`](https://cran.r-project.org/package=cronR) package registers cron jobs from R. This schedules the script to run every morning at 6am: ```{r} # install.packages("cronR") library(cronR) cmd <- cron_rscript(normalizePath("sync_zentra.R")) cron_add(cmd, frequency = "daily", at = "06:00", id = "zentra_sync", description = "Daily ZENTRA Cloud sync") # Manage it later: cron_ls() # cron_rm("zentra_sync") ``` `ZENTRACLOUD_API_KEY` must be visible to the cron environment. The simplest route is to keep it in `~/.Renviron`, which R reads on startup regardless of how the session was launched. ## Option C — daily on Windows (Task Scheduler) On Windows, use the built-in Task Scheduler. The [`taskscheduleR`](https://cran.r-project.org/package=taskscheduleR) package wraps it from R: ```{r} # install.packages("taskscheduleR") library(taskscheduleR) taskscheduler_create( taskname = "zentra_sync", rscript = normalizePath("sync_zentra.R"), schedule = "DAILY", starttime = "06:00" ) # Remove it later: # taskscheduler_delete("zentra_sync") ``` To set it up by hand instead, create a Basic Task that runs: ``` "C:\Program Files\R\R-4.6.1\bin\Rscript.exe" "C:\path\to\sync_zentra.R" ``` on your preferred trigger. Set `ZENTRACLOUD_API_KEY` as a user environment variable, or rely on `~/.Renviron`, so the scheduled task can authenticate. ## Tips - **Keep the token out of the script.** Store it in `~/.Renviron` as `ZENTRACLOUD_API_KEY=...`; every scheduled run picks it up from there. See [API Token](https://docs.zentracloud.io/l/en/article/xot1qptzgz-api-token). - **Backfill once, then top up.** Run a single `zc_sync(..., start =)` interactively to seed history. Routine runs then fetch only new data. - **Don't schedule more often than your loggers upload.** The client paces its own requests, so syncing many devices at once is fine, but there's nothing to fetch between uploads. See [Rate Limiting](https://docs.zentracloud.io/l/en/article/f6wdg770d3-rate-limiting) for the limits it observes. - **Check the summary.** When a store is used, `zc_sync()` returns a per-device summary with a `status` column. Log it to catch devices that fail to sync.