Trigger cloud sync conditionally

You may want to sync data only when a certain logic condition is met, instead of at a regular time interval. For example, if you rely on mobile data but have intermittent WiFi connection in certain locations or at certain times of the day, you may want to trigger sync to only occur when these conditions are met. Or, you may want to trigger sync only when your machine detects an object of a certain color. You can use the trigger-sync-examples module if one of these examples is what you are looking for.

If you need different logic, this guide will show you the implementation of the sync-at-time:timesyncsensor module which triggers cloud sync based on a defined time interval. You can use it as the basis of your own custom logic.

Prerequisites

A running machine connected to the Viam app. Click to see instructions.
Add a new machine in the Viam app. Then follow the setup instructions to install viam-server or viam-micro-server on the device you’re using for your project and connect to the Viam app. Wait until your machine has successfully connected.
Enable data capture and sync on your machine.

Add the data management service:

On your machine’s CONFIGURE tab, click the + icon next to your machine part in the left-hand menu and select Service.

Select the data management / RDK service and click Create. You can leave the default data sync interval of 0.1 minutes to sync every 6 seconds. Also leave both Capturing and Syncing toggles in the “on” position.

Create a sensor module. Click to see instructions.
Start by creating a sensor module. Your sensor should have access to the information you need to determine if your machine should sync or not. Based on that data, make the sensor return true when the machine should sync and false when it should not. For example, if your want your machine to return data only during a specific time interval, your sensor needs to be able to access the time as well as be configured with the time interval during which you would like to sync data. It can then return true during the specified sync time interval and false otherwise.

Use the CreateShouldSyncReading function to enable sync

Regardless of the specifics of your trigger sync logic, to trigger sync your sensor needs to pass true to the CreateShouldSyncReading function within the definition of your modular sensor’s Readings function.

The sync-at-time sensor does not sense time despite being named a time sensor. It senses whether the data manager should sync or not and determines this based on the time of day. During the configured time of the day, the code will pass true to the CreateShouldSyncReading function which will enable syncing:

func (s *timeSyncer) Readings(context.Context, map[string]interface{}) (map[string]interface{}, error) {
    currentTime := time.Now()
    var hStart, mStart, sStart, hEnd, mEnd, sEnd int
    n, err := fmt.Sscanf(s.start, "%d:%d:%d", &hStart, &mStart, &sStart)
    if err != nil || n != 3 {
        s.logger.Error("Start time is not in the format HH:MM:SS.")
        return datamanager.CreateShouldSyncReading(false), err
    }
    m, err := fmt.Sscanf(s.end, "%d:%d:%d", &hEnd, &mEnd, &sEnd)
    if err != nil || m != 3 {
        s.logger.Error("End time is not in the format HH:MM:SS.")
        return datamanager.CreateShouldSyncReading(false), err
    }

    zone, err := time.LoadLocation(s.zone)
    if err != nil {
        s.logger.Error("Time zone cannot be loaded: ", s.zone)
    }

    startTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(),
        hStart, mStart, sStart, 0, zone)
    endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(),
        hEnd, mEnd, sEnd, 0, zone)

    // If it is between the start and end time, sync.
    if currentTime.After(startTime) && currentTime.Before(endTime) {
        s.logger.Info("Syncing")
        return datamanager.CreateShouldSyncReading(true), nil
    }

    // Otherwise, do not sync.
    return datamanager.CreateShouldSyncReading(false), nil
}

If you wish to see more context, see the entire implementation of the sensor on GitHub.

For additional examples, see the Readings function of the time-interval-trigger code and the color-trigger code.

Add your sensor to determine when to sync

Add your module to your machine and configure it. In this example we will continue to use sync-at-time:timesyncsensor. You will need to follow the same steps with your module:

1. Add the sensor to your machine

On your machine’s CONFIGURE page, click the + button next to your machine part in the left menu. Select Component, then search for and select the sync-at-time:timesyncsensor model provided by the sync-at-time module.

Click Add module, then enter a name or use the suggested name for your sensor and click Create.

2. Configure your time frame

Go to the new component panel and copy and paste the following attribute template into your sensor’s attributes field:

{
  "start": "HH:MM:SS",
  "end": "HH:MM:SS",
  "zone": "<TIMEZONE>"
}
{
  "start": "18:29:00",
  "end": "18:30:00",
  "zone": "CET"
}

The following attributes are available for the naomi:sync-at-time:timesyncsensor sensor:

NameTypeRequired?Description
startstringRequiredThe start time for the time frame during which you want to sync. Example: "14:10:00".
endstringRequiredThe end of the sync time frame, for example: "15:35:00".
zonestringRequiredThe time zone for the start and end time, for example: "CET".

In the next step you will configure the data manager to take the sensor into account when syncing.

Configure the data manager to sync based on sensor

On your machine’s CONFIGURE tab, switch to JSON mode and add a selective_syncer_name with the name for the sensor you configured and add the sensor to the depends_on field:

{
  "name": "data_manager-1",
  "type": "data_manager",
  "namespace": "rdk",
  "attributes": {
    "additional_sync_paths": [],
    "capture_dir": "",
    "capture_disabled": false,
    "selective_syncer_name": "<SENSOR-NAME>",
    "sync_disabled": false,
    "sync_interval_mins": 0.1,
    "tags": []
  },
  "depends_on": ["<SENSOR-NAME>"]
}
{
  "name": "datamanager",
  "type": "data_manager",
  "namespace": "rdk",
  "attributes": {
    "additional_sync_paths": [],
    "selective_syncer_name": "timesensor",
    "sync_interval_mins": 0.1,
    "capture_dir": "",
    "tags": []
  },
  "depends_on": ["timesensor"]
}
Click to view a full configuration example
{
  "components": [
    {
      "name": "camera-1",
      "namespace": "rdk",
      "type": "camera",
      "model": "webcam",
      "attributes": {
        "video_path": "0x114000005a39331"
      }
    },
    {
      "name": "timesensor",
      "namespace": "rdk",
      "type": "sensor",
      "model": "naomi:sync-at-time:timesyncsensor",
      "attributes": {
        "start": "18:29:00",
        "end": "18:30:00",
        "zone": "CET"
      }
    }
  ],
  "services": [
    {
      "name": "data_manager-1",
      "namespace": "rdk",
      "type": "data_manager",
      "attributes": {
        "capture_dir": "",
        "tags": [],
        "additional_sync_paths": [],
        "selective_syncer_name": "timesensor",
        "sync_interval_mins": 0.1
      },
      "depends_on": ["timesensor"]
    }
  ],
  "modules": [
    {
      "type": "registry",
      "name": "naomi_sync-at-time",
      "module_id": "naomi:sync-at-time",
      "version": "2.0.0"
    }
  ]
}

You have now configured sync to happen during a specific time slot.

Test your sync configuration

To test your setup, configure a webcam or another component and enable data capture on the component. For a camera component, use the ReadImage method. The data manager will now capture data. Go to the CONTROL tab. You should see the sensor. Click on GetReadings.

Control tab with sensor panel

If you are in the time frame for sync, the time sync sensor will return true.

You can confirm that if data is currently syncing by going to the Data tab. If you are not in the time frame for sync, adjust the configuration of your time sync sensor. Then check again on the CONTROL and Data tab to confirm data is syncing.

Next steps

You can now use custom logic to trigger sync conditionally. For more information, see:

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.