Alexa.RangeController Interface

The Alexa.RangeController capability interface describes messages used to control the settings of an endpoint that are represented by numbers within a minimum and maximum range. You can use the RangeController interface to model properties of an endpoint that can be set to one of a range of values, such as the speed settings on a blender or a fan. You can also use the RangeController interface to model properties of an endpoint that users can't change.

The RangeController interface is highly configurable and enables you to model many different kinds of settings for many different kinds of devices. Use one of the following more specific interfaces if it's appropriate for your device:

For the list of locales that are supported for the RangeController interface, see List of Capability Interfaces and Supported Locales.

Utterances

When you use the Alexa.RangeController interface, the voice interaction model is already built for you. The following examples show some user utterances:

Alexa, set the bedroom fan speed to 7.
Alexa, set the fan speed on the bedroom fan to maximum.
Alexa, turn up the bedroom fan speed.
Alexa, decrease the fan speed on the bedroom fan by 3.
Alexa, what is the bedroom fan speed?

You can optionally enable additional utterances by using semantics. The following examples show some additional user utterances:

Alexa, raise the living room blinds.
Alexa, lower the living room blinds.
Alexa, open the bedroom blinds.
Alexa, close the bedroom blinds.

Alexa, fahre die Rollläden im Wohnzimmer hoch.
Alexa, fahre die Rollläden im Wohnzimmer runter.
Alexa, öffne das Rollo in der Küche.
Alexa, schließe das Rollo in der Küche.

After the user says one of these utterances, Alexa sends a corresponding directive to your skill.

Properties and Objects

The rangeValue property

The Alexa.RangeController interface uses the rangeValue property as the primary property. The property values are numbers, and you specify the minimum value, maximum value, and precision in your discover response. If the rangeValue property is used to represent a change, then valid values include negative numbers.

An endpoint can support multiple range controllers, so you must always include the instance attribute for a rangeValue property. You identify your instance names in your discovery response.

RangeValue property example

{
  "namespace": "Alexa.RangeController",
  "instance": "Fan.Speed",
  "name": "rangeValue",
  "value": "10"
}

Using semantics to enable additional utterances

When you use the Alexa.RangeController interface, the voice interaction model is already built for you. Users can interact with your device by saying the standard RangeController utterances. For more information, see utterances.

You can optionally enable additional utterances by using semantics. When you use semantics, you manually map the phrases "open", "close", "raise", and "lower" to the RangeController directives SetRangeValue and AdjustRangeValue. For example, if you have a controller for a window shade, you can map the phrase "raise" to the AdjustRangeValue directive.

You can support semantics on different controllers for the same device, however each controller must support different phrases. For example, you can support "raise" on a RangeController, and "open" on a ModeController, but you can't support "open" on both RangeController and ModeController.

To use semantics, include a semantics object in your discover response as described in the following section.

Discovery

You describe endpoints that support Alexa.RangeController using the standard discovery mechanism described in Alexa.Discovery.

Set retrievable to true for the properties that you report when Alexa sends your skill a state report request. Set proactivelyReported to true for the properties that you proactively report to Alexa in a change report.

You can model properties of an endpoint that users can't change by setting nonControllable to true. Set nonControllable to true for range controller properties that you want to report to the user, but don't want the user to change.

For each RangeController entry in the capabilities array, you can optionally include a semantics object. For more information, see using semantics to enable additional utterances.

For the full list of display categories, see display categories.

In addition to the usual discovery response fields, for each RangeController entry in the capabilities array, include the following fields.

Field Description Type
instance The name of the range, for example Fan.Speed. String
capabilityResources Friendly names that users can use to interact with the mode. A CapabilityResources object.
configuration.
supportedRange.
minimumValue
The minimum value for the range. Number
configuration.
supportedRange.
maximumValue
The maximum value for the range. Number
configuration.
supportedRange.
precision
The amount by which the values change when moving through the range. This also serves as the default when a user asks to change the value but doesn't specify by how much. Number
unitOfMeasure The unit of measure for the range. A unit of measure string.
presets Named options that users can specify instead of numbers, such as "medium" or "maximum". An array of objects.
preset.
rangeValue
The value for the preset. Number
preset.
presetResources
Friendly names that users can use to request the preset value. A CapabilityResources object.

Discover response examples

Discover response example

The following example shows a Discover.Response message for a fan that supports the Alexa.RangeController and Alexa.PowerController interfaces.

{
  "event": {
    "header": {
      "namespace": "Alexa.Discovery",
      "name": "Discover.Response",
      "payloadVersion": "3",
      "messageId": "<message id>"
    },
    "payload": {
      "endpoints": [
        {
          "endpointId": "<unique ID of the endpoint>",
          "manufacturerName": "<the manufacturer name of the endpoint>",
          "description": "<a description that is shown in the Alexa app>",
          "friendlyName": "<device name, displayed in the Alexa app>",
          "displayCategories": ["FAN"],
          "cookie": {},
          "capabilities": [
            {
              "type": "AlexaInterface",
              "interface": "Alexa.PowerController",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "powerState"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.RangeController",
              "instance": "Fan.Speed",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "rangeValue"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true,
                "nonControllable": false
              },
              "capabilityResources": {
                "friendlyNames": [
                  {
                    "@type": "asset",
                    "value": {
                      "assetId": "Alexa.Setting.FanSpeed"
                    }
                  }
                ]
              },
              "configuration": {
                "supportedRange": {
                  "minimumValue": 1,
                  "maximumValue": 10,
                  "precision": 1
                },
                "presets": [
                  {
                    "rangeValue": 10,
                    "presetResources": {
                      "friendlyNames": [
                        {
                          "@type": "asset",
                          "value": {
                            "assetId": "Alexa.Value.Maximum"
                          }
                        },
                        {
                          "@type": "asset",
                          "value": {
                            "assetId": "Alexa.Value.High"
                          }
                        },
                        {
                          "@type": "text",
                          "value": {
                            "text": "highest",
                            "locale": "en-US"
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa",
              "version": "3"
            }
          ]
        }
      ]
    }
  }
}

Discover response example for blinds

The following example shows a Discover.Response message for blinds that support the Alexa.RangeController interface and uses semantics. Use the RangeController interface for blinds that can raise and lower to a range of positions. If your blinds only fully open and fully close, use the ModeController interface instead.

{
  "event": {
    "header": {
      "namespace": "Alexa.Discovery",
      "name": "Discover.Response",
      "payloadVersion": "3",
      "messageId": "<message id>"
    },
    "payload": {
      "endpoints": [
        {
          "endpointId": "<unique ID of the endpoint>",
          "manufacturerName": "<the manufacturer name of the endpoint>",
          "description": "<a description that is shown in the Alexa app>",
          "friendlyName": "<device name, displayed in the Alexa app>",
          "displayCategories": ["INTERIOR_BLIND"],
          "cookie": {},
          "capabilities": [
            {
              "type": "AlexaInterface",
              "interface": "Alexa.RangeController",
              "instance": "Blind.Lift",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "rangeValue"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "capabilityResources": {
                "friendlyNames": [
                  {
                    "@type": "asset",
                    "value": {
                      "assetId": "Alexa.Setting.Opening"
                    }
                  }
                ]
              },
              "configuration": {
                "supportedRange": {
                  "minimumValue": 0,
                  "maximumValue": 100,
                  "precision": 1
                },
                "unitOfMeasure": "Alexa.Unit.Percent"
              },
              "semantics": {
                "actionMappings": [
                  {
                    "@type": "ActionsToDirective",
                    "actions": ["Alexa.Actions.Close"],
                    "directive": {
                      "name": "SetRangeValue",
                      "payload": {
                        "rangeValue": 0
                      }
                    }
                  },
                  {
                    "@type": "ActionsToDirective",
                    "actions": ["Alexa.Actions.Open"],
                    "directive": {
                      "name": "SetRangeValue",
                      "payload": {
                        "rangeValue": 100
                      }
                    }
                  },
                  {
                    "@type": "ActionsToDirective",
                    "actions": ["Alexa.Actions.Lower"],
                    "directive": {
                      "name": "AdjustRangeValue",
                      "payload": {
                        "rangeValueDelta" : -10,
                        "rangeValueDeltaDefault" : false
                      }
                    }
                  },
                  {
                    "@type": "ActionsToDirective",
                    "actions": ["Alexa.Actions.Raise"],
                    "directive": {
                      "name": "AdjustRangeValue",
                      "payload": {
                        "rangeValueDelta" : 10,
                        "rangeValueDeltaDefault" : false
                      }
                    }
                  }
                ],
                "stateMappings": [
                  {
                    "@type": "StatesToValue",
                    "states": ["Alexa.States.Closed"],
                    "value": 0
                  },
                  {
                    "@type": "StatesToRange",
                    "states": ["Alexa.States.Open"],
                    "range": {
                      "minimumValue": 1,
                      "maximumValue": 100
                    }
                  }  
                ]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa",
              "version": "3"
            }
          ]
        }
      ]
    }
  }
}

Directives

SetRangeValue directive

Support the SetRangeValue directive so that users can set the level of features on devices.

The following examples show user utterances:

Alexa, set the bedroom fan speed to 7.
Alexa, set the fan speed on the bedroom fan to maximum.

SetRangeValue directive payload details

Field Description Type
rangeValue The value to set the feature of the device to. Number

SetRangeValue directive example

{
  "directive": {
    "header": {
      "namespace": "Alexa.RangeController",
      "instance": "Fan.Speed",
      "name": "SetRangeValue",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>",
      "cookie": {}
    },
    "payload": {
      "rangeValue": 7
    }
  }
}

SetRangeValue response event

If you handle a SetRangeValue directive successfully, respond with an Alexa.Response event. In the context object, include the values of all properties that changed. You can respond synchronously or asynchronously. If you respond asynchronously, include a correlation token and a scope with an authorization token.

SetRangeValue response event example

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "Response",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {}
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.RangeController",
        "instance": "Fan.Speed",
        "name": "rangeValue",
        "value": "7",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 500
      }
    ]
  }
}

SetRangeValue directive error handling

If you can't handle a SetRangeValue directive successfully, respond with an Alexa.ErrorResponse event. If your error is safety related, respond with an Alexa.Safety.ErrorResponse.

AdjustRangeValue directive

Support the AdjustRangeValue directive so that users can adjust the level of features on devices.

The following examples show user utterances:

Alexa, turn up the bedroom fan speed.
Alexa, decrease the fan speed on the bedroom fan by 3.

AdjustRangeValue directive payload details

Field Description Type
rangeValueDelta The amount by which to change the feature of the device. If the user does not specify the amount, precision is used. Number
rangeValueDeltaDefault False if the user specified the amount of the change. Boolean

AdjustRangeValue directive example

{
  "directive": {
    "header": {
      "namespace": "Alexa.RangeController",
      "instance": "Fan.Speed",
      "name": "AdjustRangeValue",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>",
      "cookie": {}
    },
    "payload": {
      "rangeValueDelta": -3,
      "rangeValueDeltaDefault": false
    }
  }
}

AdjustRangeValue response event

If you handle an AdjustRangeValue directive successfully, respond with an Alexa.Response event. In the context object, include the values of all properties that changed. You can respond synchronously or asynchronously. If you respond asynchronously, include a correlation token and a scope with an authorization token.

AdjustRangeValue response event example

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "Response",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {}
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.RangeController",
        "instance": "Fan.Speed",
        "name": "rangeValue",
        "value": "4",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 500
      }
    ]
  }
}

AdjustRangeValue directive error handling

If you can't handle an AdjustRangeValue directive successfully, respond with an Alexa.ErrorResponse event. If your error is safety related, respond with an Alexa.Safety.ErrorResponse.

State reporting

Alexa sends a ReportState directive to request information about the state of an endpoint. When Alexa sends a ReportState directive, you send a StateReport event in response. The response contains the current state of all of the retrievable properties in the context object. You identify your retrievable properties in your discovery response. For more information about state reports, see Understand State Reporting.

Support the ReportState directive so that users can ask about the features of their devices.

The following examples show some user utterances:

Alexa, what is the fan speed?

StateReport response event example

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "StateReport",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {}
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.RangeController",
        "instance": "Fan.Speed",
        "name": "rangeValue",
        "value": "4",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 500
      },
      {
        "namespace": "Alexa.PowerController",
        "name": "powerState",
        "value": "ON",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Change reporting

You send a ChangeReport event to proactively report changes in the state of an endpoint. You identify the properties that you proactively report in your discovery response. For more information about change reports, see Understand State Reporting.

ChangeReport event example

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "ChangeReport",
      "messageId": "<message id>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {
      "change": {
        "cause": {
          "type": "PHYSICAL_INTERACTION"
        },
        "properties": [
          {
            "namespace": "Alexa.RangeController",
            "instance": "Fan.Speed",
            "name": "rangeValue",
            "value": "10",
            "timeOfSample": "2017-02-03T16:20:50.52Z",
            "uncertaintyInMilliseconds": 500
          },
          {
            "namespace": "Alexa.PowerController",
            "name": "powerState",
            "value": "ON",
            "timeOfSample": "2017-02-03T16:20:50.52Z",
            "uncertaintyInMilliseconds": 0
          }
        ]
      }
    }
  },
  "context": {}
}