Archive

Today’s post comes from J. Michael Palermo IV, Sr. Evangelist at Amazon Alexa. You will learn how to respond to control directives in code to turn devices on or off, set temperature, and set percentages.

When you build a skill with the Smart Home Skill API, the ultimate goal is to control a device. That control can include turning a device on or off, setting a temperature, or setting a percentage, such as when you’re dimming a light bulb. This post will cover the general process of device control and teach the fundamentals by demonstrating control of the ‘on’ or ‘off’ state in code using Node.js.

This technical walkthrough is a continuation in a series of smart home skill posts focused on development. Please read and follow the instructions found below to reach parity.

How Device Control Works

Figure 1: Device control process

Once a customer has properly installed, configured, and discovered all smart home devices, verbal control commands can be issued to an Alexa-enabled device, such as the Amazon Echo. Consider what happens from a developer perspective when a control command is made, such as turning on a light.

Let’s examine each step above in more detail.

Customer says, “Alexa, turn on desk light.”

Alexa service receives the request and routes this intent to the Smart Home Skill API.

A directive is composed and contains, among other things, the ‘TurnOnRequest’ name in the directive header and the appliance ID matching the friendly name “desk light” in the payload.

The skill adapter hosted in AWS Lambda receives the directive. Included in the directive is an access token to determine the customer’s account making the request. A call is made to device cloud API to turn on the device matching the appliance ID for the associated customer.

The device cloud (likely owned by the device maker) receives a request from the skill adapter, and communicates in its own fashion to the device identified by appliance ID to turn on.

The device, in this example, a desk light), turns on.

Not shown in the process is the confirmation response sent by the skill adapter back to the Smart Home Skill API. You will see this in code later in this post.

Working With Device Information

In a previous post covering device discovery, sample data including five devices was statically returned for testing purposes. As we continue where that post left off, find getAppliances function, and change the data for the device with an appliance ID of “sample-2” to have the value “Desk Light” for the “friendlyName” field as seen below.

Another item worth our consideration is the supported actions for the appliance. This data is determined based on what the device can actually do. Since this device is a light with dimming capabilities, five actions are listed. Now, we will focus on how to implement the “turnOn” and “turnOff” actions.

Once the skill adapter is saved, the next time the customer issues a device discovery command, the updated information will show in the Alexa app (see Figure 2). In this example, the device is named “Desk Light” which is also how the customer will verbally identify it.

Figure 2 : Sample devices returned with update to friendly name

Turning a Device “On” or “Off” in Code

When the Smart Home Skill API makes a request to your skill adapter, it is the responsibility of the developer to parse the incoming directive to determine what type of request it is. The major heavy lifting of this was already covered in this post. In that post, the following function was created to handle incoming requests matching “TurnOnRequest” for the name found in the header.

Let us explore what this function does without any modification. The first line in the function calls on a helper function named “createHeader” passing in values defined as constants a the top of the code file. This is the resulting value passed into the “header” variable.

The resulting output is a valid response to the Smart Home Skill API for turning a device on. While this is good, the function never called a device cloud to trigger a device to turn on. Because device cloud APIs will vary from one implementation to the next, add a new function to simulate a device cloud call as shown here.

The above function simulates a call to a device cloud. The first line is provided for reference because it shows how to acquire the access token needed for an actual call to API using the supported OAuth provider. Because this simulation is not requiring authentication, the line is commented out. If you replace the inner code with a call to requiring an access token, simply uncomment the line.

The next line of code obtains the value of the targeted device. The final line simply logs the device ID and passed in values for the “command” and “commandValue” arguments. To see how this will be called, modify the “handleControlTurnOn” function as seen here.

The only change to the function is the call to “callDeviceCloud” function, which accepts the “event” argument passed down from the call stack, and the values for the “command” and “commandValue” parameters, “state” and “on”.

Using this approach, change the handleControlTurnOff function to resemble the following.

The only line that changed is the call to the “callDeviceCloud” function, with the third parameter indicating “off”.

Testing Device Control

To confirm your skill adapter is receiving and responding appropriately to device control requests, test the behavior in the AWS console. With your code updated to reflect the changes made in this post, click on the “Actions” button above your code and select “Configure test event.”

Figure 3 : Configure test event

Choose any sample event template from the dropdown menu as we're going to overwrite this with our own sample event. Replace the contents with the directive example shown here.

After clicking the “Save and test” button, you should get results in your “Log output” panel similar to what is shown here.

Note how the log reflects the target device found in the incoming directive and that its desired state should be “on”. Repeat the test process, but this time change the name in the header to use “TurnOffRequest” as seen here.

Once again, after clicking the “Save and test” button, you should get a result similar to this in your “Log output” panel.

Figure 5 : Log output for “off”

The device state now shows “off” based on the name in the directive header.

Stay Tuned

In this post, we covered how to control devices that support the actions of turning on or off. Although not calling an actual device cloud API, you simulated it by adding a function to access the target device and set its state to either on or off, based on the incoming directive request. You also learned how to test the features in the AWS console to confirm functionality.

In my next post, I will cover other control actions supported by the Smart Home Skill API. Stay tuned.