# 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](https://docs.viam.com/hardware/common-components/add-a-camera/). If it produces readings, use [sensor](https://docs.viam.com/hardware/common-components/add-a-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](https://app.viam.com/registry) to see available models.

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

### Built-in models

- [`fake`](https://docs.viam.com/reference/components/generic/fake/) — A model used for testing, with no physical hardware.

### Registry modules

For hardware the built-in models don’t cover, search for `generic` in the [Viam registry](https://app.viam.com/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](https://docs.viam.com/build-modules/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:

```json
{}
```

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.

- [Python](https://docs.viam.com/hardware/common-components/add-a-generic/#tabset-hardwarecommon-componentsadd-a-generic-1-0)
- [Go](https://docs.viam.com/hardware/common-components/add-a-generic/#tabset-hardwarecommon-componentsadd-a-generic-1-1)

Install the Viam Python SDK in a virtual environment by following [Install the Python SDK](https://docs.viam.com/reference/sdks/python/python-venv/).

Save this as `generic_test.py`:

```python
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:

```bash
python generic_test.py
```

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

```text
Response: {'action': 'status', 'verbose': True}
```

```bash
mkdir generic-test && cd generic-test
go mod init generic-test
go get go.viam.com/rdk
```

Save this as `main.go`:

```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:

```bash
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.

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.
