Add a generic component | Add a component

Add a generic component

Add a generic component to your machine’s configuration for hardware that doesn’t fit any standard component type.

Concepts

A generic component is a catch-all for hardware with non-standard interfaces. The API provides a single method:

Because the API is entirely model-defined, generic components almost always come from modules in the registry (or modules you write yourself). The module author defines what commands are supported and what they do.

Use generic when no other component type fits. If your hardware produces images, use camera. If it produces readings, use sensor. Standard types give you typed SDK methods like GetImage or GetReadings, richer test-panel controls tailored to the component, and motion or vision services that know how to work with them. Generic exposes only DoCommand, so callers have to know the module-specific command shape.

Search for generic in the Viam registry to see available models.

The fake built-in model echoes commands back for testing.

Built-in models

Registry modules

For hardware the built-in models don’t cover, search for generic in the Viam registry. Each module’s configuration is documented on its registry page.

Steps

1. Add a generic component

  1. Click the + button.
  2. Select Blocks.
  3. Search for the model that matches your hardware. Search by manufacturer name, chip, or device type.
  4. Name your component (for example, my-device) and click Add to machine.

If no model exists for your hardware, you can write your own module that implements the generic component API.

2. Configure attributes

Attributes are entirely model-defined. For the fake model, no attributes are needed:

{}

For a registry module, check the module’s documentation for required attributes.

3. Save and test

Click Save. Generic components can be tested using DoCommand from code or the Viam app’s test panel.

Try it

Send a command to the generic component and read the response.

To get the credentials for the code below, go to your machine’s page in the Viam app, click the CONNECT tab, and select API keys. Copy the Key and ID. Then click the CONFIGURE tab, and click Details, and copy the Remote address. With the fake model, you’ll see your command echoed back. With a real module, the response depends on what commands the module supports.

Install the Viam Python SDK in a virtual environment by following Install the Python SDK.

Save this as generic_test.py:

import asyncio
from viam.robot.client import RobotClient
from viam.components.generic import Generic

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)

device = Generic.from_robot(robot, "my-device")

# Send a command (the fake model echoes it back)
    result = await device.do_command({"action": "status", "verbose": True})
    print(f"Response: {result}")

await robot.close()

if __name__ == "__main__":
    asyncio.run(main())

Run it:

python generic_test.py

With the fake model, you’ll see your command echoed back:

Response: {'action': 'status', 'verbose': True}
mkdir generic-test && cd generic-test
go mod init generic-test
go get go.viam.com/rdk

Save this as main.go:

package main

import (
    "context"
    "fmt"

"go.viam.com/rdk/components/generic"
    "go.viam.com/rdk/logging"
    "go.viam.com/rdk/robot/client"
)

func main() {
    ctx := context.Background()
    logger := logging.NewLogger("generic-test")

robot, err := client.New(ctx, "YOUR-MACHINE-ADDRESS", logger,
        client.WithDialOptions(client.WithEntityCredentials(
            "YOUR-API-KEY-ID",
            client.Credentials{
                Type:    client.CredentialsTypeAPIKey,
                Payload: "YOUR-API-KEY",
            })),
    )
    if err != nil {
        logger.Fatal(err)
    }
    defer robot.Close(ctx)

device, err := generic.FromProvider(robot, "my-device")
    if err != nil {
        logger.Fatal(err)
    }

// Send a command (the fake model echoes it back)
    result, err := device.DoCommand(ctx, map[string]interface{}{
        "action":  "status",
        "verbose": true,
    })
    if err != nil {
        logger.Fatal(err)
    }
    fmt.Printf("Response: %v\n", result)
}

Run it:

go run main.go

Troubleshooting

DoCommand returns an error
Module not found or not loading

If your generic component is not working as expected, follow these steps:

  1. Check your machine logs on the LOGS tab to check for errors.
  2. Review this generic component model’s documentation to ensure you have configured all required attributes.
  3. Click on the TEST panel on the CONFIGURE or CONTROL tab and test if you can use the generic component there.