Use Fragments to Configure a Fleet of Machines

If you have multiple machines with similar configurations, you can use a fragment to configure all of the machines at the same time. Fragments are a way of sharing and managing machine configurations across multiple machines.

If there are differences between your machines, you can use a fragment to quickly configure the resources that are the same between machines. You can then configure the differing resources separately, outside of the fragment. For example, if you have multiple similar rovers but one has an arm attached, you can add the rover configuration fragment (including the motors and base components), and then configure the arm on just that one rover.

When you or one of your collaborators edit a fragment that you’ve already deployed to one or more machines, the Viam app updates the configuration on each deployed machine that uses that fragment.

If you attempt to delete a fragment that is currently deployed to a machine, you will receive an error message advising that the fragment is in use, but you can still delete the fragment if desired. You can see the number of machines using your fragment from the fragments page in the Viam app.

Fragments are private to each organization by default. If you would like to make your fragment available to users outside your organization, please reach out to us to request that we make your fragment public. You must be an organization owner in order to create fragments.

A fragment can define one, several, or all resources on a machine. You can add multiple fragments to a single machine, and you can add additional resources to a machine that has already been configured with a fragment.

Create a fragment

Before you create a fragment, you’ll need a JSON configuration file. The easiest way to create a config file is to configure one of your machines on its CONFIGURE tab in the Viam app. Configure all resources that you want to have for all your machines. If there are any additional resources that you do not want to share with all machines, do not configure them until after you’ve created the fragment. When you’ve finished configuring the resources, select JSON mode and copy the entire JSON config. Now you’re ready to share that config by creating a fragment.

To create your own private fragment, go to app.viam.com/fragments or click on Fragments in the left navigation bar on the FLEET page.

  1. Enter a name or use the suggested name for your new fragment and click Add fragment.
  2. Paste the copied JSON configuration in the config field.
  3. Click Save fragment.

Fragment creation view

Add a fragment to a machine

To add a fragment to a machine:

  • Navigate to your machine in the Viam app.

  • Go to the CONFIGURE tab. In the left-hand menu, click the + (Create) icon next to the machine part you want to add the fragment to.

  • Select Insert fragment. Now, you can see the available fragments to add:

    List of available fragments
  • Look through the list of available fragments. Click on a fragment to open its menu. Click View JSON to view the JSON configuration the fragment contains, and click Insert fragment to insert the fragment into your machine’s configuration.

  • Click Save in the upper right corner of the page to save your new configuration.

The components and services included in the fragment will now appear as read-only cards on the CONFIGURE tab, along with a card for your fragment:

List of available fragments

In the JSON configuration, you will see the fragment ID in the fragments section:

{
  "components": [],
  "fragments": ["3e8e0e1c-f515-4eac-8307-b6c9de7cfb84"]
}

For an example of adding a fragment to a machine, see the Add a Rover Fragment to your Machine.

Modify the config of a machine that uses a fragment

The configuration cards of components and services included in the fragment are read-only, meaning they cannot be modified from the fragment specification.

Likewise, when you modify the fragment itself, those changes are pushed to all machines that use that fragment.

If you need to modify the config of just one machine that uses a fragment, you have two options:

  • Use fragment_mods in your machine’s config to overwrite certain fields of the fragment.
  • Copy and paste the contents of the fragment, remove the link to the fragment itself, then modify the config as needed.
    • If you use this method, future updates to the fragment will not be automatically pushed to your machine.

Use fragment_mods

You can modify fragment fields in your machine’s raw JSON config by using update operators. Viam supports all update operators except for $setOnInsert, $, $[], and $[<identifier>].

To configure fragment mods:

  1. Navigate to your machine’s CONFIGURE tab.
  2. Switch to JSON mode.
  3. Add a top-level section called "fragment_mods" (alongside the other top-level sections like "components" and "fragments"):
  "fragment_mods": [
    {
      "fragment_id": "<YOUR FRAGMENT ID>",
      "mods": [
        {
          <INSERT YOUR MODS HERE>
        }
      ]
    }
  ],

This example assumes the fragment with ID abcd7ef8-fa88-1234-b9a1-123z987e55aa contains a motor configured with "name": "motor1".

{
  "components": [],
  "fragment_mods": [
    {
      "fragment_id": "abcd7ef8-fa88-1234-b9a1-123z987e55aa",
      "mods": [
        {
          "$set": {
            "components.motor1.attributes.max_rpm": 1818,
            "components.motor1.attributes.pins.a": 30,
            "components.motor1.attributes.board": "local"
          }
        },
        {
          "$unset": {
            "components.motor1.attributes.pins.pwm": 0
          }
        }
      ]
    }
  ],
  "fragments": ["abcd7ef8-fa88-1234-b9a1-123z987e55aa"]
}
  1. Edit the fragment_id value to match the ID of the fragment you want to modify, for example "12345678-1a2b-9b8a-abcd987654321".

  2. Add any update operators you’d like to apply to the fragment to the mods section. Click to view each example:

Change the name and attributes of a component

This example uses $set to make the following changes to the attributes of a motor named motor1:

  • Sets the max_rpm to 1818.
  • Changes the name of motor1 to my_motor. Note that this does not affect the other mods; you still use motor1 for them.
  • Sets the pin number for pin a to 30.
  • Sets the name of the board associated with this motor to local.
"fragment_mods": [
 {
   "fragment_id": "abcd7ef8-fa88-1234-b9a1-123z987e55aa",
   "mods": [
     {
       "$set": {
         "components.motor1.attributes.max_rpm": 1818,
         "components.motor1.name": "my_motor",
         "components.motor1.attributes.pins.a": 30,
         "components.motor1.attributes.board": "local"
       }
     }
   ]
 }
],
Remove an attribute

This example uses $unset to remove the pin number set for the pwm pin, so the motor no longer has a PWM pin set. In other words, it deletes the pwm pin field.

"fragment_mods": [
  {
    "fragment_id": "abcd7ef8-fa88-1234-b9a1-123z987e55aa",
    "mods": [
      {
       "$unset": {
         "components.motor1.attributes.pins.pwm": 0
       }
      }
    ]
  }
],
Modify dependencies

This example uses $set to assign a new list of dependencies to a component named rover_base2.

"fragment_mods": [
  {
    "fragment_id": "abcd7ef8-fa88-1234-b9a1-123z987e55aa",
    "mods": [
      {
       "$set": {
         "components.rover_base2.attributes.depends_on": ["local", "motor1"]
       }
      }
    ]
  }
],
Change motor pins from A and B to PWM and DIR

This example uses $rename to make the following changes to the attributes of a motor named motor1 in the fragment:

  • Retrieves the pin number for pin a and assigns that value to the PWM pin. Deletes the pins.a field.
  • Retrieves the pin number for pin b and assigns that value to the DIR pin. Deletes the pins.b field.

$rename is for changing an attribute’s key, not its value. If you want to change the name of a component (for example, motor1), use $set, as shown in the change the name of a component example.

"fragment_mods": [
 {
   "fragment_id": "abcd7ef8-fa88-1234-b9a1-123z987e55aa",
   "mods": [
     {
       "$rename": {
         "components.motor1.attributes.pins.a": "components.motor1.attributes.pins.pwm",
         "components.motor1.attributes.pins.b": "components.motor1.attributes.pins.dir"
       }
     }
   ]
 }
],
Change a camera path

This example uses $set to change the video path for a camera named camera-one in the fragment:

"fragment_mods": [
  {
    "fragment_id": "abcd7ef8-fa88-1234-b9a1-123z987e55aa",
    "mods": [
      {
        "$set": {
          "components.camera-one.attributes.video_path": "0x11100004a12345"
        }
      }
    ]
  }
],
Modify data sync settings

This example uses $set to change the sync interval for a data management service named data-management in the fragment:

"fragment_mods": [
  {
    "fragment_id": "abcd7ef8-fa88-1234-b9a1-123z987e55aa",
    "mods": [
      {
        "$set": {
          "services.data-management.attributes.sync_interval_mins": "0.5"
        }
      }
    ]
  }
],
Pin a module version

This example uses $set to set version update settings for a module named custom-sensor in the fragment:

"fragment_mods": [
  {
    "fragment_id": "abcd7ef8-fa88-1234-b9a1-123z987e55aa",
    "mods": [
      {
        "$set": {
          "modules.custom-sensor.version": "1.8.0"
        }
      }
    ]
  }
],

Here are the version options:

  • To update with new minor releases of the same major release branch, use "^<major version number>", for example "^1"
  • To update with new patch releases of the same minor release branch, use "~<minor version number>", for example "~1.8"
  • To always update with the latest release, use "latest"
  • To pin to a specific release, use "<version number>", for example "1.8.3"
  1. Click Save in the upper right corner of the page to save your new configuration.
  2. To check that your mods are working, view your machine’s debug configuration. In Builder mode on the CONFIGURE tab, select the (Actions) menu to the right of your main part’s name in the left-hand panel and click the View debug configuration option to view the full configuration file.

Copy and paste method

  1. Navigate to the card belonging to your fragment on the CONFIGURE tab.
  2. Click the View JSON button in the upper right corner of the card. Copy all of the JSON.
  3. Return to the fragment card. Click the (Actions) button in the upper right corner of the card. Click Delete and confirm your choice.
  4. In the left-hand menu of the CONFIGURE tab, click JSON to switch to JSON mode.
  5. Paste the raw fragment contents into the editor and click Save in the upper-right corner of the screen to save your config.
  6. Now, you can edit the config in either JSON or Builder mode.

Next steps

Viam provides several pre-made fragments which you can use as templates for writing your own fragments.

For an example of a fragment that configures multiple components and services, see the Viam Rover fragment.

For an example of creating a fragment and using it to configure a fleet of machines, see the air quality fleet tutorial:

Have questions, or want to meet other people working on robots? Join our Community Discord.

If you notice any issues with the documentation, feel free to file an issue or edit this file.