Recipes¶
A recipe is a JSON formatted file that provides a structured way to define the operational setup of the data logger. It is a set of instructions for a logger to execute encapsulating frequently used data logger operations to provision a data logger, or a custom system. The recipe has the ability to configure settings, update operating systems, file management commands [copy, move, delete, rename], format drives, set run options for a program, and more. Recipes are flexible and could be used for a wide variety of data logger configuration tasks or just to combine multiple data logger command and control operations into one file. Recipes provide a convenient way to automate deployment and make data logger setup more efficient and less error-prone.
They are especially useful for onboarding devices to specific environments. For example, a recipe can configure a data logger to connect to Campbell Cloud, setting communication parameters and authentication credentials—all in a single step.
Recipe Format¶
Recipes are defined in JSON and consist of several key components that tell the data logger what to do and how to do it.
Recipe Components¶
name (required) A human-readable name for the recipe.
version (required) A version identifier for the recipe.
id (Optional) An identifier stored with the recipe metadata for tracking.
function (Optional) How the recipe is applied:
"onboard","startup", or"run". With"run"the recipe is retained as the data logger’s active program recipe — its signature and metadata are stored and its program is set to run — so it persists and is re-applied across restarts. (Loading any new recipe resets the previously stored recipe properties.)metadata (Object, Optional) Mostly free-form metadata for tracking or documentation. One key is read by the data logger:
cert_exp_timestamp(an ISO-8601 timestamp) is used to track certificate expiration.reboot (Boolean, Optional) When
truethe data logger restarts once at the end of the recipe, after every operation has been applied, and only if the recipe succeeded. It is a recipe-level directive rather than an operation because a reboot has no meaningful position in the operation sequence — it is always the final action. Use it to force a clean restart into a fresh state, for example from anonboardrecipe that would not otherwise reboot (a recipe delivered by therecipecommand already restarts on success;setting/settingDefaults/program/editConstoperations also reboot on their own when a change requires it). A plain restart; data tables are preserved.- operations (Array of Objects) A list of operations the data logger should execute. These are saved and may be retried if interrupted. Each operation includes:
name — The operation identifier
data (Object) — Parameters required for the operation
Important
Values inside an operation’s data object (settings, variables, constants, file parameters)
must be strings — the data logger converts each string to the appropriate type. Top-level
fields such as metadata may contain nested objects or arrays (e.g. specialization_tags).
Generic Recipe Template¶
{
"name": "<recipe_name>",
"version": "<recipe_version>",
"metadata": {
"<key>": "<value>",
"specialization_tags": ["<tag1>", "<tag2>"]
},
"reboot": false,
"operations": [
{
"name": "<operation_name>",
"data": {
"<parameter_key_1>": "<parameter_value_1>",
"<parameter_key_2>": "<parameter_value_2>"
}
}
// Additional main operations
]
}
Examples¶
Onboarding to an MQTT environment
This recipe configures a data logger to onboard to an MQTT cloud service that requires mutual TLS authentication.
{
"name": "Cloud9_OnBoard",
"version": "1.1.1",
"metadata": {
"cert_exp_timestamp": "2025-06-03T18:28:08Z"
},
"operations": [
{
"name": "setting",
"data": {
"TLSConnections": "2",
"MQTTEnable": "1",
"MQTTEndpoint": "dashboard.oncloud9.io",
"MQTTKeepAlive": "43200",
"MQTTPortNumber": "8883",
"MQTTCleanSession": "1",
"MQTTStateInterval": "1",
"MQTTStatusInterval": "1",
"MQTTWillMessage": "Gone Fishin' ABCD-EFGH-1234",
"MQTTWillQoS": "0",
"MQTTWillRetain": "0",
"MQTTWillTopic": "cs/v2/last/",
"MQTTBaseTopic": "cs/v2/",
"MQTTClientID": "ABCD-EFGH-1234",
"TLSCertificate": "-----BEGIN CERTIFICATE-----<Client Cert>----END CERTIFICATE-----",
"TLSPrivateKey": "-----BEGIN PRIVATE KEY-----<Client Private Key>-----END PRIVATE KEY-----",
"TLSRootCA": "-----BEGIN CERTIFICATE-----<Certificate Authority>-----END CERTIFICATE-----"
}
}
]
}
CRBasic Program Recipe
This recipe downloads and runs a CRBasic program.
{
"name": "ClimaVUE 50",
"version": "0.0.1",
"metadata": {},
"operations": [
{
"name": "program",
"data": {
"url": "https://s3.us-west-2.amazonaws.com/..."
}
}
]
}
Operation List¶
The data logger supports the following operations:
Program Operations¶
This operation is intended for downloading either a program or an operating system, not generic files.
When the data logger detects a program operation, it will attempt to run the specified file.
If the file is a CRBasic program: the Run Now and Run on Power Up options will be set to true.
If the file is an operating system: the data logger will install the downloaded OS.
Properties
"url":{string} The web address of the server from which the program should be retrieved. Required unlesssourceis supplied."fileName":{string} (optional) The desired name for the program on the data logger. If the name has no drive prefix it is placed onCPU:. If omitted, the CRBasic program is saved asCPU:recipe.crb."size":{string} (optional) Expected size in bytes of the downloaded file. If provided, the download is rejected unless the file size matches."source":{string} (optional) The program text itself, embedded in the recipe instead of downloaded. When present,urlis not used."language":{string} (optional) Source language when usingsource. Only CRBasic ("crbasic") is supported; any other value is rejected.
{
"name": "program",
"data": {
"url": "https://DataThings.com/programs/main.crb",
"fileName" : "main.crb"
}
}
Embed CRBasic Program
{
"name": "program",
"data": {
"source": "< long crbasic string >",
"language": "crbasic",
"fileName": "CPU:main_program.CRB"
}
}
OS Operations¶
Downloads and installs an operating system. The "data" object is handed to the same handler
as the command-and-control OS command, so it accepts the same fields. At minimum supply a
"url"; optional fields include "version" (skip the update if it exactly matches the
running version) and the "pre_url" / "post_url" URL segments. See the OS command
documentation for the full field list.
Properties
"minVersion":{string} (optional) A dotted-decimal version (e.g."1.4.0"). The OS update is skipped when this version is less than or equal to the data logger’s current version — i.e. the update only proceeds when it moves the device forward. Trailing components default to zero, so"1.4"is treated as"1.4.0". (Also available on the command-and-controlOScommand.)"manifest_url":{string} (optional) Instead of inlining the download descriptor (url/pre_url/post_url/size/chksum32) in the recipe, the data logger fetches it from this URL with an HTTP GET. The response must be the same JSON object that would otherwise be supplied inline indata; it is used as the OS download descriptor. If the fetch or the parse fails, the OS operation fails.
{
"name": "OS",
"data": {
"url": "https://DataThings.com/Operating_Systems/CR350.1.8.0.obj",
"minVersion": "1.8.0"
}
}
When the OS is delivered in chunks, "url" is a list of segments and the full URL for each
chunk is composed as <pre_url><url><post_url>. Use "pre_url" and "post_url" to avoid
repeating the common parts in every list entry:
{
"name": "OS",
"data": {
"pre_url": "https://DataThings.com/Operating_Systems/",
"url": [
"CR350.1.8.0_0",
"CR350.1.8.0_1",
"CR350.1.8.0_2"
],
"post_url": ".obj",
"minVersion": "1.8.0"
}
}
Setting Operations¶
Configures data logger settings. The "data" object is a flat map where each key is a setting
name (e.g. "PakBusAddress") or its numeric setting ID, and each value is the value to
apply. There are two forms:
"name": "setting"— applies the listed settings, leaving all others unchanged."name": "settingDefaults"— resets the device to factory defaults first, then applies the listed settings on top.
Properties
"<setting name or ID>":{string} The value to apply. All values must be strings.
Only the settings listed in data are written; every other setting keeps its current
value (or, for settingDefaults, its factory default). The settings are applied in a single
edit session and committed together — if any committed setting requires a restart, the data
logger reboots to apply it.
Set Settings
{
"name": "setting",
"data": {
"PakBusAddress": "12",
"StationName": "Rufus"
}
}
Set Settings From Defaults
The settingDefaults operation first resets the entire device configuration to its
factory defaults, then applies the settings listed in data on top of that baseline. The
reset and the overrides happen in a single edit session and result in a single reboot, so the
device ends up at “factory defaults, plus exactly these values” regardless of its prior
configuration.
{
"name": "settingDefaults",
"data": {
"PakBusAddress": "12",
"StationName": "Rufus"
}
}
data may be empty ({}) to reset the device to factory defaults with no overrides:
{
"name": "settingDefaults",
"data": {}
}
Note
This is a full factory reset of all settings before the overrides are applied — including
network/cloud connectivity settings not listed in data. Make sure any settings required
for the device to remain reachable (MQTT, IP, cellular, etc.) are included in data.
File Operations¶
The file operation performs file-system and program-control actions, selected by the
"action" key. Supported actions: create, download, upload, list, checksum,
run, stop, load, format, delete, copy, and move (rename is a move).
The download, upload, list, and checksum actions behave exactly as the matching
fileControl commands; in a recipe they simply run silently
(no command response is published).
Where an action takes a target file, it accepts either "path" (a full DRIVE:file path) or
"fileName" with an optional "drive" (defaulting to CPU). The run and stop
actions reboot the data logger to apply the change.
Format Drive
{
"name": "file",
"data": {
"action": "format",
"drive": "USR"
}
}
Note
Recipes are stored on the CPU: drive, so formatting CPU would normally erase the
running recipe (and the copy used to resume it if interrupted). When a recipe contains a
format operation, the data logger keeps the recipe in memory for the duration of the run and
automatically rewrites it after the format if the file is missing. The remaining operations
and interrupted-recipe resume therefore continue to work even after a CPU format.
Move File
{
"name": "file",
"data": {
"action": "move",
"source": "CRD:file.txt",
"destination": "USR:file.txt"
}
}
Rename File
{
"name": "file",
"data": {
"action": "move",
"source": "CRD:file.txt",
"destination": "CRD:renamed_file.txt"
}
}
Set Run Options
Sets the program to run and reboots. "runOnPowerUp" (default true) controls whether the
program also runs on power-up, and "deleteTables" (default false) clears existing data
tables on the reboot.
{
"name": "file",
"data": {
"action": "run",
"path": "CPU:main_program.CRB",
"runOnPowerUp": "true",
"deleteTables": "true"
}
}
Stop Program
Stops the running program and reboots. Honors "runOnPowerUp" and "deleteTables" as above.
{
"name": "file",
"data": {
"action": "stop"
}
}
Create File
Writes a file from inline data supplied in "source". Text files are written verbatim; binary
files are supplied base64-encoded together with "encoding": "base64".
Properties
"source":{string} The file contents to write. For"encoding": "base64"this is the base64-encoded binary; otherwise it is written verbatim as text."encoding":{string} (optional)"base64"to decode"source"from base64 and write the resulting raw bytes — use this to create binary files. Omit (or"none") to write"source"verbatim."chksum32":{string} (optional) A CRC-32 of the intended contents (the decoded bytes whenbase64is used), as a decimal (or0x-prefixed hex) string. If the target file already exists and its CRC-32 matches, the file is left untouched and creation is skipped. Uses the same checksum as the OS operation.
{
"name": "file",
"data": {
"action": "create",
"path": "CPU:notes.txt",
"source": "file contents",
"chksum32": "3735928559"
}
}
Binary file, supplied base64-encoded:
{
"name": "file",
"data": {
"action": "create",
"path": "CPU:blob.bin",
"encoding": "base64",
"source": "SGVsbG8sIHdvcmxkIQ=="
}
}
Download File
Fetches a file over HTTP(S) and saves it to the logger — the general-purpose file downloader. (To
download and run a program, or download and install an operating system, use the program / OS
operations above instead.)
{
"name": "file",
"data": {
"action": "download",
"url": "https://example.com/files/cal.dat",
"path": "CPU:cal.dat"
}
}
Copy File
{
"name": "file",
"data": {
"action": "copy",
"source": "CRD:file.txt",
"destination": "USR:file.txt"
}
}
Delete File
{
"name": "file",
"data": {
"action": "delete",
"path": "CPU:file.CRB"
}
}
Load OS From Drive
{
"name": "file",
"data": {
"action": "load",
"path": "CPU:CR350.1.8.0.obj"
}
}
EditConst Operations¶
Sets one or more constants in the running CRBasic program’s ConstTable and triggers a
recompile. This is the recipe-embedded form of the editConst command and uses the same
underlying handler (JSON_const_set).
The operation is identified by "name": "editConst". The "data" object is a flat map of
constant name → value, where every value must be a string (the logger casts each string to
the constant’s declared type when it rewrites the program). Only the constants listed are
changed; all others keep their current values, and every key must name an existing constant or
the operation fails. Each value may be at most 79 characters.
Unlike the command-and-control form, the recipe form does not honor the cmd / tranID /
apply keys — those are command-and-control specific. After the constants are applied
successfully the logger reboots to recompile.
{
"name": "editConst",
"data": {
"THRESHOLD": "10.5",
"SENSOR_ID": "99",
"STATION_NAME": "North 40"
}
}
Set Variables¶
Sets one or more variables in the running CRBasic program. The "data" object is a flat map of
variable name → value, using the same handler as the command-and-control variable /
setVar commands. Values must be strings; the data logger converts each string to the
variable’s type when it is applied.
Properties
"<variable name>":{string} The value to assign.
Variable access and examples:
"variable_name": "12.3"— Public variable"Public.variable_name": "12.3"— Public variable with explicit scope"variable_name(2)": "2.013"— Array element of a public variable"StructureName.variable_name": "12.3"— Variable inside a structure"StructureName.variable_name(2)": "12.3"— Array element of a variable inside a structure"trigger_event": "true"— Boolean variables
Every key must name a variable that exists in the running program; if any assignment fails (unknown variable, array index out of bounds, etc.) the operation fails.
{
"name": "variable",
"data": {
"bale_count": "20",
"field_name": "north_40",
"farmall.pto_engaged": "False",
"farmall.engine_rpm": "1780.0"
}
}
Recipe and WEB.OBJ.GZ¶
A Recipe can be included in a WEB.OBJ.GZ for a powerful automated deployment solution