Previous
Servo
Add a switch to your machine’s configuration so you can read and set switch positions from the Viam app and from code.
A switch component represents a multi-position switch. The API provides:
Physical switch hardware typically comes from a module in the registry that reads GPIO pins or communicates with a switch controller.
The fake built-in model simulates a switch with configurable positions and
is useful for testing. Browse available switch models in the Viam registry.
my-switch) and click Create.For the fake model:
{
"position_count": 3,
"labels": ["off", "low", "high"]
}
| Attribute | Type | Required | Description |
|---|---|---|---|
position_count | int | No | Number of positions. Defaults to 2. |
labels | list of strings | No | Human-readable labels for each position. Must match position_count if provided. |
For a physical switch with a registry module, check the module’s documentation for required attributes.
Click Save, then expand the TEST section.
Read the switch position, cycle through positions, and read labels.
To get the credentials for the code below, go to your machine’s page in the Viam app, click the CONNECT tab, and select SDK code sample. Toggle Include API key on. Copy the machine address, API key, and API key ID from the code sample. When you run the code below, you’ll see the switch cycle through all positions. With the fake model, positions update in memory. With real hardware, verify the switch physically changes state.
pip install viam-sdk
Save this as switch_test.py:
import asyncio
from viam.robot.client import RobotClient
from viam.components.switch import Switch
async def main():
opts = RobotClient.Options.with_api_key(
api_key="YOUR-API-KEY",
api_key_id="YOUR-API-KEY-ID"
)
robot = await RobotClient.at_address("YOUR-MACHINE-ADDRESS", opts)
switch = Switch.from_robot(robot, "my-switch")
# Get number of positions and labels
num_positions, labels = await switch.get_number_of_positions()
print(f"Positions: {num_positions}, Labels: {labels}")
# Get current position
position = await switch.get_position()
print(f"Current position: {position}")
# Cycle through all positions
for pos in range(num_positions):
await switch.set_position(pos)
current = await switch.get_position()
label = labels[pos] if labels else str(pos)
print(f"Set to position {pos} ({label}), read back: {current}")
await robot.close()
if __name__ == "__main__":
asyncio.run(main())
Run it:
python switch_test.py
mkdir switch-test && cd switch-test
go mod init switch-test
go get go.viam.com/rdk
Save this as main.go:
package main
import (
"context"
"fmt"
toggleswitch "go.viam.com/rdk/components/switch"
"go.viam.com/rdk/logging"
"go.viam.com/rdk/robot/client"
"go.viam.com/rdk/utils"
)
func main() {
ctx := context.Background()
logger := logging.NewLogger("switch-test")
robot, err := client.New(ctx, "YOUR-MACHINE-ADDRESS", logger,
client.WithCredentials(utils.Credentials{
Type: utils.CredentialsTypeAPIKey,
Payload: "YOUR-API-KEY",
}),
client.WithAPIKeyID("YOUR-API-KEY-ID"),
)
if err != nil {
logger.Fatal(err)
}
defer robot.Close(ctx)
sw, err := toggleswitch.FromProvider(robot, "my-switch")
if err != nil {
logger.Fatal(err)
}
// Get number of positions and labels
numPositions, labels, err := sw.GetNumberOfPositions(ctx, nil)
if err != nil {
logger.Fatal(err)
}
fmt.Printf("Positions: %d, Labels: %v\n", numPositions, labels)
// Get current position
position, err := sw.GetPosition(ctx, nil)
if err != nil {
logger.Fatal(err)
}
fmt.Printf("Current position: %d\n", position)
// Cycle through all positions
for pos := uint32(0); pos < numPositions; pos++ {
if err := sw.SetPosition(ctx, pos, nil); err != nil {
logger.Fatal(err)
}
current, err := sw.GetPosition(ctx, nil)
if err != nil {
logger.Fatal(err)
}
label := fmt.Sprintf("%d", pos)
if int(pos) < len(labels) {
label = labels[pos]
}
fmt.Printf("Set to position %d (%s), read back: %d\n", pos, label, current)
}
}
Run it:
go run main.go
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!