Relay devices have a ring of 12 LEDs surrounding the Talk button in the center of the device. These LEDs are full RGB color, individually addressable, and have effects available (flash, breathe, rotate, etc). In this section, we'll discuss how to add a visual element to your workflows with LEDs. This can complement an audio element (say and listen) and a touch element (vibrate).

πŸ“˜

URN Type for LEDs

The target URN that is needed to be passed into the LED methods is an interaction URN.

Using LEDs

LEDs are useful for giving a visual confirmation or status. By default, when the device is not charging, there should be 3 white LEDs that indicate the device is powered on and connected to the Relay server. In a workflow, you can control the LEDs to show your own pattern. When the workflow exits, control of the LEDs are returned back to the system.

There are 12 configurable LEDs on a Relay that form the ring. You can interact with the whole ring (switchAllLedOn, rotate, flash, breathe, etc), or individual LEDs at a time (switchLedOn(index)). The LEDs can be toggled by their index which range from 1 to 12 respectively. To configure colors, they are passed into the respective function as a string of hex RGB values.

There are currently 8 different LED functions within the Relay SDK:

  • switchLedOn(urn: interaction_uri, led: LedIndex, color: string): Turns on the single specified index of the LED on the device with the specified color. To turn off an LED, use this method with the color "000000".

  • switchAllLedOn(urn: interaction_uri, color: string): Turns on all 12 of the LEDs on the device with the single specified color.

  • switchAllLedOff(urn: interaction_uri): Turns off all of the LEDs on the device.

  • flash(urn: interaction_uri, color="0000FF"): Flashes the device's LEDs in the specified color indefinitely. By default, the color is blue.

  • breathe(urn: interaction_uri, color="0000FF"): Creates a "breathing" effect with the device's LEDs in the specified color. By default, the color is blue.

  • rotate(urn: interaction_uri, color="FFFFFF"): Turns on the device's LEDs in the specified color and rotates them in a static color indefinitely. By default, the color is white.

  • rainbow(urn: interaction_uri, rotations=-1): Creates a rotating rainbow effect on the device, where the colors rotate the specified number of times. By default, the number of rotations is -1, meaning it will rotate indefinitely.

  • ledAction(urn: interaction_uri, effect: LedEffect, args: LedInfo): This is an all-encompassing function that lets you program the LEDs to behave however you want. You can target which LEDs you want on and what color. The LedEffect parameter is the type of effect you want, and the LedInfo parameter is an object of the LED index mappings to colors.

The following code shows how to use some of these LED effects:

workflow.on(Event.INTERACTION_STARTED, async({source_uri: interaction_uri}) => {
  // The LEDs make a rainbow that rotates 3 times
  await workflow.rainbow(interaction_uri, 3)
  
  // All of the LEDs are turned on and set to be blue
  await workflow.switchAllLedOn(interaction_uri, "0000FF")
  
  //All of the LEDs are turned off
  await workflow.switchAllLedOff(interaction_uri)
})
@my_workflow.on_interaction_lifecycle
async def lifecycle_handler(workflow, itype, interaction_uri, reason):
    if itype == relay.workflow.TYPE_STARTED:
        # The LEDs make a rainbow that rotates 3 times
        await workflow.rainbow(interaction_uri, 3)

        # All of the LEDs are turned on and set to be blue
        await workflow.switch_all_led_on(interaction_uri, "0000FF")
  
        # All of the LEDs are turned off
        await workflow.switch_all_led_off(interaction_uri)
public override async void OnInteractionLifecycle(IDictionary<string, object> dictionary)
        {
            var type = (string) dictionary["type"];
            
            if (type == InteractionLifecycleType.Started)
            {
              var interaction_uri = (string) dictionary["source_uri"];
							// The LEDs make a rainbow that rotates 3 times
              await Relay.Rainbow(this, interaction_uri, 3)

              // All of the LEDs are turned on and set to be blue
              await Relay.SwitchAllLedOn(this, interaction_uri, "0000FF")

              //All of the LEDs are turned off
              await Relay.SwitchAllLedOff(this, interaction_uri)

            }
@Override
public void onInteractionLifecycle(Relay relay, InteractionLifecycleEvent lifecycleEvent) {
  super.onInteractionLifecycle(relay, lifecycleEvent);

  String interactionUri = (String)lifecycleEvent.sourceUri;
  if (lifecycleEvent.isTypeStarted()) {
    // The LEDs make a rainbow that rotates 3 times
    relay.rainbow(interactionUri, 3);

    // All of the LEDs are turned on and set to be blue
    relay.switchAllLedOn(interactionUri, "0000FF");

    //All of the LEDs are turned off
    relay.switchAllLedOff(interactionUri);
  }
api.OnInteractionLifecycle(func(interactionLifecycleEvent sdk.InteractionLifecycleEvent) {

  if interactionLifecycleEvent.LifecycleType == "started" {
    interactionUri = interactionLifecycleEvent.SourceUri
    // The LEDs make a rainbow that rotates 3 times
    api.Rainbow(interactionUri, 3)
    
    // All of the LEDs are turned on and set to be blue
    api.SwitchAllLedOn(interactionUri, "0000FF")
    
    //All of the LEDs are turned off
    api.SwitchAllLedOff(interactionUri)
  }
})

The return type for all of these functions is void. You can manipulate the LEDs in different ways to interact with the user and add a visual feature to your workflow.

Demo

There is a built-in workflow that demonstrates several of the LED effects. To see this workflow run, you'll first need to register a trigger to start it. For example:

relay workflow create phrase --trigger lights --uri relay-local://led_demo -n led_demo --install-all

To fire the trigger as registered above, hold down the Assistant button and speak the trigger phrase "lights". It should speak out a verbal request to tap the Talk button. Do that tap. After each effect runs for a few seconds, tap the Talk button again to move to the next effect. Continue until it speaks out that it is finishing the demo. If you no longer wish this registration to be present, you can unregister it like this:

$ relay workflow list
=== Installed Workflows

 ID                                            Name                 Type              
 ───────────────────────────────────────────── ──────────────────── ───────────────── 
 wf_leddemo_9CTtBDhjBaMUAI9BXB0qLvVA           led_demo             phrases:lights

$ relay workflow delete --workflow-id wf_leddemo_9CTtBDhjBaMUAI9BXB0qLvVA
βœ” Deleting led_demo (ID: wf_leddemo_9CTtBDhjBaMUAI9BXB0qLvVA). Are you sure? (y/N) y
Workflow deleted

If desired, afterwards you can register it again using the same relay-local://led_demo URL as before.