Understand State and Change Reporting
When you create an Alexa skill that interacts with a smart home device, you can include support for state and change reporting. Alexa notifies users about the state of their endpoints either by voice or in the Alexa app. For example, in the Alexa app users can see a list of their smart plugs, and whether each one is on or off.
During device discovery, you identify what state reporting you support for each property of your device. After device discovery, Alexa can request the state of your device properties, and you send the information back to Alexa in response events. You can also proactively report state to Alexa as a change report event.
You report state to Alexa in StateReport events, ChangeReport events, and Response events.
- Identify support for state and change reporting during discovery
- Report state in a StateReport
- Report state in a ChangeReport
- Report state in a directive Response
- Related Topics
Identify support for state and change reporting during discovery
To enable state reporting, you must indicate during device discovery whether each property of an endpoint is retrievable
or proactivelyReported
.
When you set retrievable=true
for a property, it means that Alexa can query the property for its current state. To query for the state, Alexa sends a ReportState
directive, and you respond with a StateReport
event. If you don't specify retrievable
, the default value is false.
When your set proactivelyReported=true
for a property, it means that you send a ChangeReport
event for the endpoint when the state of the property changes for any reason. If you don't specify proactivelyReported
, the default value is false.
When new properties and directives are added to an interface, Alexa only uses them with an endpoint if the endpoint specified them as supported during discovery. For more information about device discovery, see Alexa.Discovery.
For each property, there are four combinations of retrievable
and proactivelyReported
:
Retrievable Value | ProactivelyReported Value | Description |
---|---|---|
"retrievable": true |
"proactivelyReported": true |
Your skill sends both StateReport and ChangeReport events. For example, a light bulb that can be queried for state and also proactively reports when the state changes because of a physical interaction with the device. |
"retrievable": true |
"proactivelyReported": false |
Your skill sends StateReport events but not ChangeReport events. For example, a light bulb that can be queried for state but that does not proactively report when the state changes. |
"retrievable": false |
"proactivelyReported": true |
Your skill sends ChangeReport events but not StateReport events. For example, a low energy device that is normally in a dormant state cannot be queried for state. However, the device activates when a setting changes and proactively reports the changes. |
"retrievable": false |
"proactivelyReported": false |
Your skill sends neither StateReport nor ChangeReport events. For example, a device that is controlled by an infrared transmitter. Infrared is a one-way control mechanism. Commands can be sent to the device, but it does not support a mechanism for sending messages about its state.
|
Discover response example
The following example shows a Discover.Response
message for an endpoint that supports the Alexa.PowerController
and Alexa.ColorTemperatureController
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>",
"modelName": "<the model name of the endpoint>",
"description": "<a description that is shown in the Alexa app>",
"friendlyName": "<device name, displayed in the Alexa app>",
"displayCategories": ["LIGHT"],
"cookie": {},
"capabilities": [
{
"type": "AlexaInterface",
"interface": "Alexa.PowerController",
"version": "3",
"properties": {
"supported": [
{
"name": "powerState"
}
],
"proactivelyReported": true,
"retrievable": true
}
},
{
"type": "AlexaInterface",
"interface": "Alexa.ColorTemperatureController",
"version": "3",
"properties": {
"supported": [
{
"name": "colorTemperatureInKelvin"
}
],
"proactivelyReported": true,
"retrievable": true
}
},
{
"type": "AlexaInterface",
"interface": "Alexa.EndpointHealth",
"version": "3",
"properties": {
"supported": [
{
"name":"connectivity"
}
],
"proactivelyReported": true,
"retrievable": true
}
},
{
"type": "AlexaInterface",
"interface": "Alexa",
"version": "3"
}
]
}
]
}
}
}
Report state in a StateReport
When Alexa sends a ReportState
directive to request the state of an endpoint, you send a StateReport
event in response. This response contains the current state of all of the properties that are retrievable
in the context
object.
For example, a customer might check the Alexa app for the status of a light on a different floor of their house. Alexa sends a ReportState
directive for the light. You send a response that includes the state of all the retrievable
properties for the light, and the app reports the state to the customer.
If you poll your endpoints periodically, you can send cached values for the properties in your response. If the endpoint is currently unreachable, but all property values are cached, then return the StateReport
and include all of the property values. However, specify the value of the connectivity property of EndpointHealth
as UNREACHABLE
. If you can't report the state of all the properties because the endpoint is unreachable and you have not cached the values, send an ErrorResponse
of type BRIDGE_UNREACHABLE
or ENDPOINT_UNREACHABLE
.
ReportState directive
Example ReportState directive
{
"directive": {
"header": {
"namespace": "Alexa",
"name": "ReportState",
"messageId": "<message id>",
"correlationToken": "<an opaque correlation token>",
"payloadVersion": "3"
},
"endpoint": {
"endpointId": "<endpoint id>",
"cookie": {},
"scope": {
"type": "BearerToken",
"token": "<an OAuth2 bearer token>"
}
},
"payload": {}
}
}
StateReport event
Example StateReport response event
{
"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>",
"cookie": {}
},
"payload": {}
},
"context": {
"properties": [
{
"namespace": "Alexa.ThermostatController",
"name": "targetSetpoint",
"value": {
"value": 25.0,
"scale": "CELSIUS"
},
"timeOfSample": "2017-02-03T16:20:50Z",
"uncertaintyInMilliseconds": 6000
},
{
"namespace": "Alexa.ThermostatController",
"name": "thermostatMode",
"value": "HEAT",
"timeOfSample": "2017-02-03T16:20:50Z",
"uncertaintyInMilliseconds": 6000
},
{
"namespace": "Alexa.EndpointHealth",
"name": "connectivity",
"value": {
"value": "OK"
},
"timeOfSample": "2017-02-03T16:20:50Z",
"uncertaintyInMilliseconds": 0
}
]
}
}
Report state in a ChangeReport
When the state of an endpoint changes for any reason, you report that change to Alexa in a ChangeReport
event. Alexa can then provide that status change to the customer. In the change report, specify the state of any changed properties in the payload
object. For example, if a customer manually turns on a light, send a change report event that indicates the powerState
property of the [Alexa.PowerController][alexa-powercontroller] interface has changed its value to ON
.
If a property is specified as proactivelyReported
during discovery, you must send Alexa a ChangeReport
event whenever that property value changes.
If a state change happens because of a directive from Alexa, you send both a directive response and a change report event. For more information, see Report state in response to a directive.
ChangeReport
events, you must request permission to send events to the Alexa event gateway and obtain authentication tokens for each customer, which you include in the scope
of the event message. For more information, see Authenticate a Customer to Alexa with Permissions and Alexa.Authorization.- Use the
payload
of theChangeReport
to provide the new property value and the reason for the change. - You use the
context
of aChangeReport
to report the state of any additional properties. - If multiple properties have changed, you can send Alexa multiple change report events containing a payload with a single property, or a single change report event that contains a payload with multiple property values.
- Make sure to identify the customer and the endpoint for the change report in the
endpoint
object.
In the context
object, specify the state of all the other properties of the endpoint that didn't change, to help improve the customer experience.
payload
or the context
, but not both.ChangeReport event
Example proactive ChangeReport event
The following example shows a ChangeReport
event for an endpoint that implements the Alexa.PowerController
and Alexa.BrightnessController
interfaces. The event reports that the endpoint changed its brightness
value to 85% due to a physical interaction with the device. The event specifies the new brightness
value in the payload
, and it specifies the powerState
property in the context
object because the value did not change.
{
"event": {
"header": {
"namespace": "Alexa",
"name": "ChangeReport",
"messageId": "<message id>",
"payloadVersion": "3"
},
"endpoint": {
"scope": {
"type": "BearerToken",
"token": "<an OAuth2 bearer token>"
},
"endpointId": "<endpoint id>",
"cookie": {
"path": "path/for/this/endpoint"
}
},
"payload": {
"change": {
"cause": {
"type": "PHYSICAL_INTERACTION"
},
"properties": [
{
"namespace": "Alexa.BrightnessController",
"name": "brightness",
"value": 85,
"timeOfSample": "2017-02-03T16:20:50Z",
"uncertaintyInMilliseconds": 0
}
]
}
}
},
"context": {
"properties": [
{
"namespace": "Alexa.PowerController",
"name": "powerState",
"value": "ON",
"timeOfSample": "2017-02-03T16:20:50Z",
"uncertaintyInMilliseconds": 60000
},
{
"namespace": "Alexa.EndpointHealth",
"name": "connectivity",
"value": {
"value": "OK"
},
"timeOfSample": "2017-02-03T16:20:50Z",
"uncertaintyInMilliseconds": 0
}
]
}
}
Cause Object
When you send a ChangeReport
event use the cause
attribute to describe the cause of property value changes. The following table describes the cause
values.
Cause Type | Description |
---|---|
APP_INTERACTION |
Customer interaction with an app. For example, a customer switches on a light or locks a door by using the Alexa app or an app provided by a device vendor. |
PERIODIC_POLL |
Periodic poll of an endpoint. For example, you might poll a temperature sensor every hour and send the updated temperature to Alexa. |
PHYSICAL_INTERACTION |
Physical interaction with an endpoint. For example, the user turned on a light or locked a door lock manually. |
RULE_TRIGGER |
A device rule. For example, a user configures a rule to switch on a light if a motion sensor detects motion. In this case, Alexa receives an event from the motion sensor, and another event from the light to indicate that its state change was caused by the rule. |
VOICE_INTERACTION |
Voice interaction. For example, a user turns on a light by speaking to their Echo device. |
Report state in a directive Response
If Alexa sends a directive to change the state of a property, and you handle the directive successfully, send a Response events. In the response, specify the state of any changed properties in the context
object. For example, if Alexa sends an Alexa.PowerController.TurnOn
directive, you send a response event that includes the powerState
property, with its new value ON
, in the context
.
We recommend that you specify the state of all the properties of the endpoint, including the properties that didn't change, to help improve the customer experience.
You can send response events synchronously from your skill's Lambda function or asynchronously to the event gateway.
Example directive
{
"directive": {
"header": {
"namespace": "Alexa.PercentageController",
"name": "AdjustPercentage",
"messageId": "<message id>",
"correlationToken": "<an opaque correlation token>",
"payloadVersion": "3"
},
"endpoint": {
"scope": {
"type": "BearerToken",
"token": "<an OAuth2 bearer token>"
},
"endpointId": "<endpoint id>",
"cookie": {}
},
"payload": {
"percentageDelta": -20
}
}
}
Example response containing property state
{
"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.PercentageController",
"name": "percentage",
"value": 54,
"timeOfSample": "2017-02-03T16:20:50.52Z",
"uncertaintyInMilliseconds": 500
}
]
}
}
Example response for a property that is not retrievable
After your skill successfully handles a directive for an endpoint with properties that are not retrievable
, the skill must send a response
event that does not include the properties in the context
.
The following example shows a Response
event that indicates to Alexa that the TurnOn
directive was handled successfully. The empty properties
array in the event context
indicates that the property state after the change cannot be determined.
{
"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": []
}
}