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:

  • DoCommand: send arbitrary key-value commands to the component and receive key-value responses.

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 data capture, test panels, and SDK support automatically. Browse available generic models in the Viam registry.

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

Steps

1. Add a generic component

  1. Click the + button.
  2. Select Configuration block.
  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 Create.

If no model exists for your hardware, you can write a driver 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 SDK code sample. Toggle Include API key on. Copy the machine address, API key, and API key ID from the code sample. With the fake model, you’ll see your command echoed back. With a real module, the response depends on what commands the module supports.

pip install viam-sdk

Save this as generic_test.py:

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


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)

    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"
    "go.viam.com/rdk/utils"
)

func main() {
    ctx := context.Background()
    logger := logging.NewLogger("generic-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)

    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
  • Verify the command format matches what the module expects. Check the module’s documentation for supported commands and their expected structure.
  • With the fake model, any valid map is accepted.
Module not found or not loading
  • Confirm you’ve added the module to your machine’s configuration.
  • Check that the module is compatible with your machine’s architecture.
  • Look at the machine’s logs for module startup errors.

What’s next