Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
256 changes: 92 additions & 164 deletions docs/data-ai/data/visualize.md

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions docs/dev/reference/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,6 @@ Viam has added a [sensor-controlled base](/operate/reference/components/base/sen
You can now [visualize your data](/data-ai/data/visualize/) using many popular third-party visualization tools, including Grafana, Tableau, Google's Looker Studio, and more.
You can visualize any data, such as sensor readings, that you have [synced](/data-ai/capture-data/capture-sync/) to Viam from your machine.

See [Visualize data with Grafana](/tutorials/services/visualize-data-grafana/) for a full walkthrough focused on Grafana specifically.

{{% /changelog %}}

{{% changelog date="2024-01-31" color="added" title="Use triggers to trigger actions" %}}
Expand Down
177 changes: 148 additions & 29 deletions docs/manage/troubleshoot/teleoperate/custom-interface.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
---
title: "Teleoperate with custom control interface"
title: "Teleoperate with a custom control interface"
linkTitle: "Custom interface"
weight: 25
type: "docs"
description: "Use a teleop workspace to create a custom control interface for operating a machine or visualizign and aggregating its data."
description: "Use a teleop workspace to create a custom control interface for operating a machine or visualizing and aggregating its data."
tags: ["teleop", "fleet management", "control", "app"]
languages: []
viamresources: ["sensor", "camera", "movement sensor"]
platformarea: ["viz", "data"]
images: ["/how-tos/teleop/full-workspace.png"]
level: "Intermediate"
date: "2024-11-13"
# updated: "" # When the content was last entirely checked
updated: "2025-09-10"
cost: "0"
prev: "/manage/troubleshoot/alert/"
---

You can remotely operate any configured machine and visualize and aggregate its data using a custom control interface by creating a teleop workspace.
You can remotely operate any configured machine and visualize and aggregate its data using a custom control interface.

### Prerequisites
## Prerequisites

{{% expand "A configured machine with teleoperable components" %}}

Expand All @@ -28,38 +28,157 @@ See [configure a machine](/operate/get-started/supported-hardware/) for more inf

{{% /expand%}}

### Configure a workspace
### Create a workspace

{{< table >}}
{{% tablestep start=1 %}}
**Create a workspace**
1. Navigate to the **FLEET** page's [**TELEOP** tab](https://app.viam.com/teleop).
Click **+ Create workspace**.

Log into [Viam](https://app.viam.com/).
1. Enter a unique name for your workspace in the top left of the page, replacing the placeholder `untitled-workplace` text.

Navigate to the **FLEET** page's **TELEOP** tab.
Create a workspace by clicking **+ Create workspace**.
Give it a name.
1. Use the **Select location** dropdown to select the location that contains the machine that you would like to visualize data from.

{{<imgproc src="/how-tos/teleop/blank-workspace.png" resize="800x" style="width: 700px" class="shadow fill imgzoom" declaredimensions=true alt="Blank teleop page.">}}
1. Use the **Select machine** dropdown to select the machine that you would like to visualize data from.

{{% /tablestep %}}
{{% tablestep %}}
**Add widgets**
## Add a widget

Click **Add widget** and select the appropriate widget for your machine.
Use the widget header to configure the panel.
Repeat as many times as necessary.
1. Click **Add widget** and select a widget type to create a new widget on your workspace.

{{% /tablestep %}}
{{% tablestep %}}
**Select a location and a machine**
See [widget types](/manage/troubleshoot/teleoperate/custom-interface/#widget-types) for more information about each type.

Now, select a location and a machine.
This will make your widgets connect to your machine.
1. To configure the widget, click the pencil icon in the top right of your widget:

Your dashboard now shows the configured widgets for the data from your machine:
{{<imgproc src="/services/data/visualize-widget-configure.png" alt="Click the pencil icon to configure your widget." style="width:500px" resize="1200x" class="imgzoom fill shadow" >}}

{{<imgproc src="/how-tos/teleop/full-workspace.png" resize="800x" style="width: 700px" class="shadow fill imgzoom" declaredimensions=true alt="Teleop workspace with values configured for each of the four widgets on monitor mode.">}}
You can mix and match multiple widgets to visualize many kinds of data collected by your machine:

{{% /tablestep %}}
{{< /table >}}
{{<imgproc src="/services/data/visualize-workspace.png" resize="1200x" style="width: 700px" class="fill imgzoom shadow" declaredimensions=true alt="Workspace containing.">}}

To arrange widgets on your workspace, click and drag the grid icon in the top left of your widget:

{{<imgproc src="/services/data/visualize-widget-move.png" alt="Click the grid icon to move a widget." style="width:500px" resize="1200x" class="imgzoom fill shadow" >}}

## Widget types

Viam provides the following types of widgets that you can customize to visualize data synced from your machines:

### Actuation

The actuation widget allows you to operate actuating components:

{{<imgproc src="/services/data/visualize-widget-actuation.png" resize="800x" style="width: 500px" class="fill imgzoom shadow" declaredimensions=true alt="An actuation widget displaying servo controls.">}}

To configure the actuation widget:

1. Choose a type from the **Component type** dropdown.
1. Choose a method from the **Method** dropdown.
1. Choose a component from the **Actuating component name** dropdown.
1. Click **Save**.

### Camera stream

The camera stream widget displays a live feed of the most recent image captured by a camera component:

{{<imgproc src="/services/data/visualize-widget-camera.png" resize="800x" style="width: 500px" class="fill imgzoom shadow" declaredimensions=true alt="A camera widget displaying a live camera feed.">}}

To configure the camera widget:

1. Choose a camera from the **Camera name** dropdown.
1. Select the **Refresh type**.
1. Click **Save**.

### GPS

The GPS widget displays the current GPS location of any sensor that reports a position:

{{<imgproc src="/services/data/visualize-widget-gps.png" resize="800x" style="width: 500px" class="fill imgzoom shadow" declaredimensions=true alt="A GPS widget displaying a live location.">}}

To configure the camera widget:

1. Choose a movement sensor from the **Movement sensor name** dropdown.
1. Specify the **Refresh rate** in seconds.
1. Choose to include Historic positions.
1. Click **Save**.

### Stat

The stat widget displays the most recent reading recorded by any sensor that produces tabular data:

{{<imgproc src="/services/data/visualize-widget-stat.png" resize="800x" style="width: 500px" class="fill imgzoom shadow" declaredimensions=true alt="A stat widget displaying a live sensor reading.">}}

To configure the stat widget:

1. Choose a sensor from the **Sensor name** dropdown.
1. Select the reading you would like to display from the **Path** dropdown.
1. Assign a title, a unit suffix, and a refresh rate.
1. Click **Save**.

### Table

The table widget displays a grid of historic tabular data values. You can display multiple fields simultaneously in a single table.
Each row in the table represents a separate historic reading; each column represents a field.

{{<imgproc src="/services/data/visualize-widget-table.png" resize="800x" style="width: 500px" class="fill imgzoom shadow" declaredimensions=true alt="A table widget displaying a grid of sensor readings.">}}

To configure the table widget, define the following attributes:

1. From the **Resource name** dropdown, choose a sensor you would like to visualize.
1. From the **Capture method** dropdown, choose a method of data capture (for example **Readings**).
1. Specify the **Refetch rate** in seconds.
1. Specify the **Time range** in seconds.

1. Use a custom MQL aggregation pipeline stage (or series of stages) to transform your sensor data into a flat object where each field corresponds to a column for the table.
Consider the following sensor data, which contains information about air quality in a field named `readings`:

```json
"data" {
"readings": {
"gas_resistance": 114978.66606781945,
"temperature": 22.96,
"pressure": 1016.18,
"humidity": 48.318
}
}
```

To change the displayed names, use a `$project` stage:

```mql
{
"$project": {
"Air Quality": "$data.readings.gas_resistance",
"Humidity": "$data.readings.humidity",
"Temperature": "$data.readings.temperature"
}
}
```

For more information about MQL aggregation operators, see the [MongoDB documentation](https://www.mongodb.com/docs/manual/reference/operator/aggregation/).

1. Click **Save**.

### Time series

The time series widget creates a graph of tabular data. You can add multiple lines to the time series widget to compare multiple readings over the same time period:

{{<imgproc src="/services/data/visualize-widget-time-series.png" resize="1000x" style="width: 500px" class="fill imgzoom shadow" declaredimensions=true alt="A time series widget displaying a live graph of sensor data over time.">}}

To configure the time series widget, define the following attributes for each line in the time series:

1. From the **Resource name** dropdown, choose a sensor you would like to visualize.
1. From the **Capture method** dropdown, choose a method of data capture (for example **Readings**).
1. In the **Title** field, enter a name for the line.
1. From the **Path** dropdown, choose the field of data that this line should visualize.

1. Use the other fields to customize the unit, duration, and other aspects of your visualization.

1. The **Window method** allows you to aggregate sensor readings over specified time intervals instead of displaying raw data points.
Select a window method from the following options:

- **None**: shows raw data with the path specified with no aggregation
- **Count**: shows the number of readings within the window
- **Average**: calculates the average value throughout the window
- **Minimum**: shows the minimum value within the window
- **Maximum**: shows the maximum value within the window
- **Custom query**: shows the result of a custom MQL aggregation pipeline that you define

1. Click **Save**.
6 changes: 1 addition & 5 deletions docs/tutorials/control/air-quality-fleet.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,6 @@ You'll host the website with Viam as a _Viam application_.

The full code is available for reference on [GitHub](https://github.com/viam-labs/air-quality-fleet/blob/main/main.ts).

{{< alert title="Tip" color="tip" >}}
If you'd like to graph your data using a Grafana dashboard, try the [Visualize Data with Grafana tutorial](/tutorials/services/visualize-data-grafana/) next.
{{< /alert >}}

### Set up your TypeScript project

Complete the following steps on your laptop or desktop.
Expand Down Expand Up @@ -1067,5 +1063,5 @@ For an example of setting up text alerts, see the [Detect a Person and Send a Ph
{{< cards >}}
{{% card link="/tutorials/projects/helmet/" %}}
{{% card link="/tutorials/projects/send-security-photo/" %}}
{{% card link="/tutorials/services/visualize-data-grafana/" %}}
{{% card link="/data-ai/data/visualize/" %}}
{{< /cards >}}
2 changes: 1 addition & 1 deletion docs/tutorials/projects/make-a-plant-watering-robot.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,6 @@ sudo python3 plant-watering-robot.py
Now that you have created your automatic plant watering system with a resistive soil moisture sensor, you can easily use Viam to automate other aspects of your garden.
For example, you could add a [light sensor](https://www.amazon.com/Sensor-Module-Raspberry-Integrated-Circuits/dp/B07L15M5JG) or a [temperature sensor](https://www.amazon.com/KY-011-Cathode-Arduino-Starter-2-color/dp/B07869PKKF/ref=as_li_ss_tl?keywords=arduino+two+color+led+module&qid=1556591832&s=gateway&sr=8-2&th=1&linkCode=sl1&tag=murraynet-20&linkId=c36cd98be29498a9883b656c7011b6bb&language=en_US), and get readings from other channels of the MCP3008!

You could set up data capture and [graph your sensor data](/tutorials/services/visualize-data-grafana/), or [create your own custom Typescript dashboard](/tutorials/control/air-quality-fleet/) to display your sensor data.
You could set up data capture and [graph your sensor data](/data-ai/data/visualize/), or [create your own custom Typescript dashboard](/tutorials/control/air-quality-fleet/) to display your sensor data.

If you build something based on this please share it in our [Community Discord](https://discord.gg/viam) - we'd love to see it.
Loading
Loading