AVS Device SDK Smart Home Endpoints

Device makers wishing to add Smart Home functions to their AVS device can now do so without requiring the implementation of a separate Alexa skill or custom cloud interface. For example, you can control and customize Smart Home devices with unique device names. By enabling Smart Home functionality for AVS devices, device developers can add custom voice control to hardware of a device and support connected endpoints.

You can read more about how Smart Home endpoints work with AVS on the following pages:
Get Started Tutorial

To start developing with endpoints quickly, see the Create an Alexa Built-in Disco Ball tutorial.

v1.21 version changes


SDK endpoint assets

The following SDK Capability Agents (CA) and interfaces communicate with the equivalent AVS Smart Home endpoint.

  • PowerController – Turn the endpoint on or off. Only a single instance of the PowerController can exist on an endpoint.
  • ToggleController – Toggles the state of a single property on an endpoint. Use multiple instances of the ToggleController to control different toggles on the endpoint.
  • RangeController – Changes the value of a property within a range. Use multiple instances of the RangeController to control different values on the endpoint.
  • ModeController – Activates a particular endpoint mode. Use multiple instances of the ModeController to control different modes on the endpoint).

Enable endpoints in the sample app

You identify how to target an endpoint in utterances by assigning the endpoint a friendlyName. For example, on a device that can control a microwave, assigning the friendlyName "microwave" to the endpoint enables you to say "Alexa, turn off the microwave".

For reference code enabling endpoints, see the disco ball endpoint in the sample app. For demonstration purposes, the endpoint has a hard coded friendlyName value of discoball. You can change the name to anything you want.

    /// The friendly name of the Endpoint. This is used in utterance.
    static const std::string SAMPLE_ENDPOINT_FRIENDLYNAME("Discoball");
    

The SDK uses CMake flags to enable building the PowerController, ToggleControlle, ModeController, and RangeController capability agents that the sample discoball endpoint uses. To enable the code in the sample app that uses these capabilities, compile the SDK with the DENABLE_ALL_ENDPOINT_CONTROLLERS=ON CMake flag

For reference, here is a full CMake command that builds the entire SDK with the endpoint command included.

cmake $HOME/my_project/source/avs-device-sdk \
-DGSTREAMER_MEDIA_PLAYER=ON \
-DPORTAUDIO=ON \
-DPORTAUDIO_LIB_PATH=$HOME/my_project/third-party/portaudio/lib/.libs/libportaudio.a \
-DPORTAUDIO_INCLUDE_DIR=$HOME/my_project/third-party/portaudio/include \
-DCMAKE_BUILD_TYPE=DEBUG \
-DENABLE_ALL_ENDPOINT_CONTROLLERS=ON

To enable individual capabilities instead of all of them, specify which capabilities to build by setting the appropriate CMake flags. For example:

Use all controllers except the PowerController

-DENABLE_ALL_ENDPOINT_CONTROLLERS=ON \
-DENDPOINT_CONTROLLERS_POWER_CONTROLLER=OFF

Only use PowerController and ModeController

-DENDPOINT_CONTROLLERS_POWER_CONTROLLER=ON \
-DENDPOINT_CONTROLLERS_RANGE_CONTROLLER=ON

For more details about configuring CMake for endpoints, see the CMake parameters page.

Control the endpoint by voice

  • "Alexa, turn disco ball on."
  • "Alexa, increase discoball's height." or "Alexa, raise the discoball."
  • "Alexa, change discoball's mode to green."

You can also query the state of the endpoint by using the following utterances:

  • "Alexa, what is disco ball's height?"
  • "Alexa, what is disco ball's mode?"

Control the endpoint through the companion app

In the companion app, the discoball endpoint appears as a Smart Home device that you can control by using the GUI.

app

Configuring your own endpoints

For each controller capability agent, the SDK provides a corresponding controller interface. You build complex endpoints by implementing an instance of a controller interface for each capability supported by your endpoint. Your controller interface implementation performs the actions needed to control your endpoint when the corresponding capability agent invokes it – for example, implement a PowerControllerInterface that sends a signal to turn on your endpoint when its corresponding PowerController capability agent receives a TurnOn directive.

For example

To design a smart air conditioner, you could combine the PowerController, ModeController, ToggleController, and RangeController.

In this example you might configure the following:

  • A PowerController to turn the air conditioner on or off.
  • A RangeController to control the fan speed
  • A RangeController to control the temperature.
  • A ModeController to change between preset air conditioner modes, such as "dry," "cool," or "fan."
  • A ToggleController to toggle the energy-saver mode.

To implement your air conditioner

1. Implement a PowerController, RangeController, ModeController, and ToggleController interface to implement your features.

You can see a full example of a controller interface in the sample app. Here, the sample app implements a ModeControllerInterface for the color of the discoball. The sample implementation prints the new mode when the user asks Alexa to set the color of the discoball.

2. Configure your PowerController, RangeController, ModeController, and ToggleController interfaces using the corresponding AttributeBuilder classes.

In SampleApplication.cpp, the sample app uses a ModeControllerAttributeBuilder to define the configuration of this ModeController. It also uses uses the EndpointBuilder created for the discoball to register the sample ModeControllerInterface and the ModeControllerAttributes with the discoball endpoint. This EndpointBuilder takes care of instantiating the ModeControllerCapabilityAgent that invokes the sample ModeController Interface.

You can see an example usage of an AttributeBuilder class in the sample app.

    /// Use a Controllerinterface to define a capabiltiy for an endpoint
    class ModeControllerInterface {
    ...
    };
    

Dynamic endpoints

Dynamic endpoints allow you to add, modify, or delete endpoints at any point after the at any point after the DefaultClient connects to AVS.

The updated interfaces that support dynamic endpoints include:

Dynamic endpoint example

You can experiment with a sample dynamic endpoint in the sample app by building the SDK with the following CMake flags, ENABLE_ALL_ENDPOINT_CONTROLLERS and ENDPOINT_CONTROLLERS_POWER_CONTROLLER.

Here is an example CMake command with the sample dynamic endpoint available in the sample app. After the sample app builds, select y in the sample app main menu to add a dynamic endpoint, modify its friendly name, and delete it.

cmake $HOME/my_project/source/avs-device-sdk \
-DGSTREAMER_MEDIA_PLAYER=ON \
-DPORTAUDIO=ON \
-DPORTAUDIO_LIB_PATH=$HOME/my_project/third-party/portaudio/lib/.libs/libportaudio.a \
-DPORTAUDIO_INCLUDE_DIR=$HOME/my_project/third-party/portaudio/include \
-DCMAKE_BUILD_TYPE=DEBUG \
-DENABLE_ALL_ENDPOINT_CONTROLLERS=ON
-DENDPOINT_CONTROLLERS_POWER_CONTROLLER=ON

Semantic Annotation

You can use Smart Home for AVS semantic annotation to control the following SDK Capability Agents: ModeController, RangeController and ToggleController. Semantic annotations allow you to map specific utterances to the behaviors and states of capability instances. This mapping helps provide a more intuitive experience for your users.

The supported actions for semantic annotations are "open", "close", "raise", and "lower".

For example

In the sample app, the following two statements are equivalent and control the height of the disco ball.

  • Regular Phrase: "Alexa, increase discoball's height."
  • Semantic Annotation: "Alexa, raise the discoball."

A semantic annotation maps the word raise to replace the words increase and height. This phrase is more natural to speak and is closer to what a user might say when interacting with your device.

The following interfaces include methods to enable semantic annotations in a capability configuration:

To enable semantic annotations on an endpoint, identify the capability instance that implements behavior that matches the desired utterance for the endpoint. Construct a CapabilitySemantics that specifies the utterance to directive and state mappings, and use it as an argument to the method withSemantics() on the AttributeBuilder class you use to configure the capability.