Wendy Data
Record sensor data, application events, and model results on your device with event-triggered campaigns.
Wendy Data records what happened on a device around an event. A campaign defines the sources to record, the events that start recording, and how long to keep recording. Each recording becomes an episode with timestamped files, source details, model versions, and checksums.
Use campaigns to investigate an emergency stop, collect uncertain model
predictions, or save examples of an object detected by a camera. For a single
recording, use wendy data record without deploying a campaign.
What you can record
| Data | How Wendy captures it |
|---|---|
| Camera footage | Video from USB, CSI, and registered IP cameras. Compatible camera streams also support periodic snapshots. |
| Audio | Microphone audio throughout an episode, or fragments triggered by an audio-level threshold during the episode. |
| ROS 2 topics | Published messages such as LiDAR point clouds, odometry, GPS, IMU readings, joint states, and control commands. |
| Device health | Uptime, system load, and total/free RAM, sampled once per second on Linux. |
| Application events | Named events such as emergency_stop, faults, and task completion, with values and attributes supplied by your app. |
| Model results | Predictions, detections, uncertainty, model versions, and references to recorded input samples when supplied. |
| Custom measurements | App-provided time series such as temperature, vibration, motor current, or production counts. Streams accept structured data, images, and custom binary payloads. |
Campaigns select camera, audio, ROS 2, and telemetry sources. They include
application records automatically. Other sensors need to publish ROS 2 topics
or write through an application recording stream.
The built-in telemetry source does not collect every metric shown by
wendy device telemetry.
Record your first episode
Start with a device running Wendy Agent and select it explicitly with
--device. Use wendy discover to find its selector.
wendy data sources --device workshop.local
wendy data record --device workshop.local --name commissioning --source telemetryThe recording runs on the device after the command returns. Stop it when you have captured enough data, then inspect and download the episode ID from the output:
wendy data stop --device workshop.local
wendy data episodes --device workshop.local
wendy data inspect <episode-id> --device workshop.local
wendy data download <episode-id> --device workshop.local --output ./commissioning-episodeinspect verifies the sealed files' checksums. download resumes interrupted
transfers, verifies each file, and saves the episode locally. Camera episodes
include a browser-playable MP4 when the captured stream can be remuxed; the
manifest explains when that file could not be created.
Use the source IDs returned by sources to add a camera or microphone. Repeat
--source for multiple sources. With no source flags, record selects every
healthy discovered source, which can include cameras and microphones.
Deploy a campaign
Save this as campaign.yaml. It records device health for ten seconds after
an app emits machine_fault. You can also trigger it manually to try the
workflow before connecting an app.
version: 1
name: machine-faults
sources:
- telemetry: true
capture:
buffer: 0s
after_trigger: 10s
triggers:
- event: machine_fault
upload:
when: manual
export:
annotation: nonemanual keeps this example out of automatic cloud upload. The required
export.annotation field records labeling intent. Here, none is descriptive
metadata; this release does not create annotation tasks.
wendy data campaign deploy campaign.yaml --device workshop.local
wendy data campaign inspect machine-faults --device workshop.local
wendy data campaign trigger machine-faults --device workshop.local --reason commissioningAfter ten seconds of capture and the default two-second wait for late app
records, use episodes, inspect, and download as above. Check the manifest
for the sources that actually recorded and any errors. A successful deployment
means the campaign is armed, not that a recording has already succeeded.
On a cloud-enrolled device, deployment also registers campaign:<name> in Cloud
Apps. For an intentionally offline deployment, pass --skip-cloud-registration.
Unenrolled devices skip registration automatically.
Add sensors and triggers
Replace sources with selectors from wendy data sources. For example:
sources:
- camera: v4l2:/dev/video0
- audio: audio:16777217
- ros2: /lidar/points
- ros2: /vehicle/odometry
- telemetry: trueThe camera and audio IDs above are examples; use your device's IDs. An audio
selector must resolve to a healthy capture source at deployment. Camera and
ROS 2 sources can be absent when you deploy. Cameras must resolve when recording
starts; a missing ROS 2 topic is reported in the manifest while other sources
record. camera: "*" selects all healthy agent cameras, including cameras added
later, and needs at least one camera when recording starts.
Add model.uncertainty: "> 0.65" as another trigger to capture uncertain
predictions. The app must supply the prediction's uncertainty. Any matching
trigger starts an episode; manual triggering remains available.
Set capture.buffer: 10s for history before the trigger and
capture.after_trigger: 20s for capture afterward. Application records and
continuous camera streams support pre-trigger history. Audio, ROS 2, and
telemetry begin at the trigger; snapshot cameras do not keep a video pre-buffer.
The manifest reports the history each source actually retained.
See the campaign YAML reference for selectors, capture policies, and all fields.
Record data from your app
Add the episode-write entitlement
to your app to submit events and predictions. The agent supplies an app-private
socket and attributes records to that app. Its events can trigger deployed
campaigns; the entitlement does not grant access to sensors.
Declare named streams inside the entitlement for custom data. Lightweight
streams accept raw payloads over Unix sockets. Durable streams use Protobuf
envelopes and acknowledge after syncing the record to local storage, even when
no episode is recording. Time-series streams can declare channels, units, and
sample timestamps separately from the agent's receipt time.
An opaque JSON or binary payload does not trigger a campaign by itself. Declare
the stream's event or model metadata; durable model records can supply
uncertainty and input references.
Export retained durable records with:
wendy data export-stream <app-id> <stream> --device workshop.local --output records.wdrPlain export keeps the device's retained records. Use --follow --reclaim with
an output directory for ongoing collection that reclaims each saved chunk.
The producer must handle a full journal by buffering and retrying; the agent
does not overwrite retained records to make room.
The recording stream reference and WendyRecording examples include configuration, senders, and an export reader.
Detect objects without a model app
A campaign's optional inference block runs object detection on its selected
cameras. Choose a Hugging Face model pinned to a 40-character commit SHA,
labels, a confidence threshold, and an inference rate. The agent supports
Transformers models and compatible YOLO ONNX exports through backend: yolo_onnx.
Set an event such as person_detected and include the same event in
capture.triggers. On first use, the agent installs its managed Python runtime
and downloads the pinned model. This needs network access and storage outside
the episode quota. Check inference_status in campaign inspect to verify
the runtime and each camera.
notify.on: event can deliver a named event immediately; notify.on: detection
requires inference. Delivery can use a configured webhook or Wendy Cloud.
Cloud delivery requires a separately enabled notification grant for the campaign.
notify.on: episode_committed records cloud-side notification intent instead
of sending an immediate device notification.
Use the inference reference and all-camera people example when you are ready to enable model downloads and automatic capture.
Current limits
- Camera snapshots and capture-rate caps require a transport that supplies complete encoded frames, currently local V4L2 cameras with native H.264. Other camera transports record continuously and report unapplied policies in the manifest. Audio supports continuous and level-threshold capture; ROS 2 and telemetry support continuous capture only.
- Buffered continuous cameras use their producer's current parameters.
Explicit
max_resolutionorratesettings on those sources are reported as requested but not achieved. Available history also depends on how long the campaign has been armed and the buffer's byte limit. upload.when: wificurrently behaves asalways. Usemanualwhen automatic upload is not wanted. Local inspection and download work without cloud upload.retention.local_quotais stored but not enforced per campaign. The agent enforces a device-wide episode quota.export.annotation: cvatrecords intent but does not create CVAT tasks; declared privacy transforms are metadata and do not redact captured data.- A campaign records one active episode at a time and drops matching triggers while it is capturing. Different campaigns can record concurrently.
Episodes use a device-local monotonic timeline and carry separate UTC confidence
and clock evidence. Inspect the manifest before assuming that recordings from
different devices are synchronized. See the
full wendy data reference
for clock evidence, storage, playback, and command details.