Alexa.ProactiveNotificationSource Interface

Implement the Alexa.ProactiveNotificationSource interface in your Alexa skill so that Alexa can notify a user when their device needs attention. For example, Alexa can notify a user when their washing machine cycle completes, or when their oven reaches the target preheat temperature.

You configure the announcements for your device in your skill. Before Alexa begins to send notifications to the user, the customer must opt-in to notifications from your device in the Alexa app. After the user enables announcements, Alexa can send notifications to the selected Echo devices, such as an Echo Dot, Echo Plus, Echo Show, or Echo Spot. Customers can opt-out of notifications for each device.

You implement the ProactiveNotificationSource interface with other interfaces that provide functionality for your device. You can use ProactiveNotificationSource with one of the following interfaces:

Announcements for device state

You can use semantics to notify the user when your device requires attention. To enable announcements, you map the states of your device to one of the following Alexa.States values:

  • Alexa.States.Low
  • Alexa.States.Empty
  • Alexa.States.Full
  • Alexa.States.Done
  • Alexa.States.Stuck

To map your device property to an Alexa.States value, include a semantics object in your discovery response. For example, you might map the rangeValue property to one of the states when you use RangeController. For an example discovery response, see Enable announcements with semantics.

Later, you send a ChangeReport event to Alexa to report a change to your device. When the ChangeReport contains a property value mapped to one of the Alexa.States values, Alexa triggers a notification to the user. For an example ChangeReport, see Change reporting.

Notifications to the user take the form, Your <instance friendly name> is <state>. For example: "Your vacuum bin is full."

Announcements for cooking

You can use the Cooking interface to notify the user about the status of their food or when your appliance requires attention. To enable announcements, you include the cooking statuses that your device supports in the discovery response. For an example discovery response, see the Enable announcements for cooking appliances.

Later, you send a ChangeReport event to Alexa to report a change to the status. When the ChangeReport contains a CookingStatus value that has a resulting announcement, Alexa triggers a notification to the user. For example: "Your food in the oven is ready." For an example ChangeReport, see Change reporting. For details about cooking statuses that trigger announcements, see CookingStatus.

Configuration objects

The ProactiveNotificationSource interface uses the following configuration objects.

The NotificationConditions object

To define the conditions that trigger notifications, include the notificationConditions array. For generic controllers, include an NotificationConditions object for each controller instance that supports notifications. For the Cooking interface, you must include one NotificationConditions object only.

NotificationConditions object details

Field Description Type Required
conditionType The type of condition that triggers the notification.
Valid value: PropertyValueChange
String Yes
property The property to evaluate the condition against. A Property object Yes
valueChangeCondition The condition that triggers the notification. If the condition evaluates to true, Alexa sends a notification. A ValueChangeCondition object Yes

The Property object

The Property object defines the specific property of an interface that triggers notifications.

Property object details

Property Description Type Required

type

The type of interface.
Valid value: AlexaInterface

string

Yes

interface

The name of the Alexa interface that enables announcements.
Valid values: Alexa.Cooking, Alexa.ModeController, Alexa.RangeController

String

Yes

instance

(Optional) For generic controller interfaces, the instance of the interface. For example, Dryer.Temperature.
The Cooking interface doesn't support instances.

String

No

name

The name of the property that triggers notifications.

String

Yes

The ValueChangeCondition object

The ValueChangeCondition object defines the condition to evaluate against the property value. If the condition evaluates to true, Alexa sends a notification. For device state announcements, Alexa sends the notification only when the current state is different from the previous state.

To evaluate the property value against multiple cooking statuses, use StringIn. To evaluate the property value against multiple states, use StateIn.

ValueChangeCondition object details

Property Description Type Required

comparator

The comparison operator.
Valid comparators for cooking: StringEquals, StringIn Valid comparators for device state: StateEquals, StateIn

string

Yes

value

The values to which to compare the property value against.
For StringEquals and StateEquals comparators, include a single value.
For StringIn and StateIn comparators, include a list of values.

String or List of Strings

Yes

Discovery

You describe endpoints that support the Alexa.ProactiveNotificationSource interface by using the standard discovery mechanism described in Alexa.Discovery.

In addition to the usual discovery response fields, for ProactiveNotificationSource, include a configuration object that contains an array of notificationConditions that trigger the notification.

Enable announcements with semantics

The following example shows a Discover.Response message for a clothes dryer that uses the ProactiveNotificationSource interface and semantics for announcements. The example uses three instances of the ModeController interface: one for the dryer temperature, one for the dryer cycle, and one for the lint filter. The example shows announcements enabled for two of the controllers by using the ProactiveNotificationSource interface: to notify users when the dryer cycle completes, and to notify users when the lint filter is full.

Copied to clipboard.

{
    "event": {
        "header": {
            "namespace": "Alexa.Discovery",
            "name": "Discover.Response",
            "payloadVersion": "3",
            "messageId": "<message id>"
        },
        "payload": {
            "endpoints": [{
                "endpointId": "<unique ID of the endpoint>",
                "manufacturerName": "Clothes Dryer Maker",
                "description": "Smart Clothes Dryer by Dryer Maker",
                "friendlyName": "Dryer",
                "displayCategories": [
                    "DRYER"
                ],
                "additionalAttributes": {
                    "manufacturer" : "Clothes Dryer Maker",
                    "model" : "Sample Model",
                    "customIdentifier": "Your custom identifier for the device"
                },
                "cookie": {},
                "capabilities": [{
                        "type": "AlexaInterface",
                        "interface": "Alexa.ModeController",
                        "instance": "Dryer.Temperature",
                        "version": "3",
                        "properties": {
                            "supported": [{
                                "name": "mode"
                            }],
                            "retrievable": true,
                            "proactivelyReported": true,
                            "nonControllable": false
                        },
                        "capabilityResources": {
                            "friendlyNames": [{
                                "@type": "text",
                                "value": {
                                    "text": "Temperature",
                                    "locale": "en-US"
                                }
                            }]
                        },
                        "configuration": {
                            "ordered": true,
                            "supportedModes": [{
                                    "value": "Dryer.Temperature.Cool",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "Cool",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                },
                                {
                                    "value": "Dryer.Temperature.Warm",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "Warm",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                },
                                {
                                    "value": "Dryer.Temperature.Hot",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "Hot",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                }
                            ]
                        }
                    },
                    {
                        "type": "AlexaInterface",
                        "interface": "Alexa.ModeController",
                        "instance": "Dryer.CurrentDryerCycle",
                        "version": "3",
                        "properties": {
                            "supported": [{
                                "name": "mode"
                            }],
                            "retrievable": true,
                            "proactivelyReported": true,
                            "nonControllable": true
                        },
                        "capabilityResources": {
                            "friendlyNames": [{
                                "@type": "text",
                                "value": {
                                    "text": "Current dryer cycle",
                                    "locale": "en-US"
                                }
                            }]
                        },
                        "configuration": {
                            "ordered": true,
                            "supportedModes": [{
                                    "value": "CurrentDryerCycle.NotStarted",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "NotStarted",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                },
                                {
                                    "value": "CurrentDryerCycle.Drying",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "Drying",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                },
                                {
                                    "value": "CurrentDryerCycle.CoolDown",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "CoolDown",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                },
                                {
                                    "value": "CurrentDryerCycle.Completed",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "Completed",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                }
                            ]
                        },
                        "semantics": {
                            "stateMappings": [{
                                "@type": "StatesToValue",
                                "states": [
                                    "Alexa.States.Done"
                                ],
                                "value": "CurrentDryerCycle.Completed"
                            }]
                        }
                    },
                    {
                        "type": "AlexaInterface",
                        "interface": "Alexa.ModeController",
                        "instance": "Dryer.LintTrap",
                        "version": "3",
                        "properties": {
                            "supported": [{
                                "name": "mode"
                            }],
                            "retrievable": true,
                            "proactivelyReported": true,
                            "nonControllable": true
                        },
                        "capabilityResources": {
                            "friendlyNames": [{
                                "@type": "text",
                                "value": {
                                    "text": "Lint trap",
                                    "locale": "en-US"
                                }
                            }]
                        },
                        "configuration": {
                            "ordered": false,
                            "supportedModes": [{
                                    "value": "Dryer.LintTrap.Clean",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "Clean",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                },
                                {
                                    "value": "Dryer.LintTrap.Medium",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "Medium",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                },
                                {
                                    "value": "Dryer.LintTrap.Full",
                                    "modeResources": {
                                        "friendlyNames": [{
                                            "@type": "text",
                                            "value": {
                                                "text": "Full",
                                                "locale": "en-US"
                                            }
                                        }]
                                    }
                                }
                            ]
                        },
                        "semantics": {
                            "stateMappings": [{
                                "@type": "StatesToValue",
                                "states": [
                                    "Alexa.States.Full"
                                ],
                                "value": "Dryer.LintTrap.Full"
                            }]
                        }
                    },
                    {
                        "type": "AlexaInterface",
                        "interface": "Alexa.ProactiveNotificationSource",
                        "version": "3.0",
                        "proactivelyReported": true,
                        "configuration": {
                            "notificationConditions": [{
                                    "conditionType": "PropertyValueChange",
                                    "property": {
                                        "type": "AlexaInterface",
                                        "interface": "Alexa.ModeController",
                                        "instance": "Dryer.CurrentDryerCycle",
                                        "name": "mode"
                                    },
                                    "valueChangeCondition": {
                                        "comparator": "StateEquals",
                                        "value": "Alexa.States.Done"
                                    }
                                },
                                {
                                    "conditionType": "PropertyValueChange",
                                    "property": {
                                        "type": "AlexaInterface",
                                        "interface": "Alexa.ModeController",
                                        "instance": "Dryer.LintTrap",
                                        "name": "mode"
                                    },
                                    "valueChangeCondition": {
                                        "comparator": "StateEquals",
                                        "value": "Alexa.States.Full"
                                    }
                                }
                            ]
                        }
                    },
                    {
                        "type": "AlexaInterface",
                        "interface": "Alexa",
                        "version": "3"
                    }
                ]
            }]
        }
    }
}

Enable announcements for cooking appliances

The following example shows a Discover.Response message for an oven that uses the Cooking interfaces. The example includes the ProactiveNotificationSource interface to enable announcements when cooking completes.

Copied to clipboard.

{
  "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",
          "description": "a description that is shown in the Alexa app",
          "friendlyName": "Oven",
          "displayCategories": ["OVEN"],
          "additionalAttributes": {
            "manufacturer": "manufacturer name",
            "model": "sample model",
            "serialNumber": "the serial number of the oven",
            "customIdentifier": "your custom identifier for the oven"
          },
          "cookie": {},
          "capabilities": [
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "cookingMode"
                  },
                  {
                    "name": "foodItem"
                  },
                  {
                    "name": "cookingTimeInterval"
                  },
                  {
                    "name": "cookingStatus"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "configuration": {
                "supportsRemoteStart": false,
                "supportedCookingModes": [
                  "OFF",
                  "PREHEAT",
                  "COOK"
                ],
                "supportedCookingStatuses": [
                  "COOKING",
                  "COOKING_COMPLETED",
                  "NOT_IN_USE"
                ]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking.TimeController",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "requestedCookTime"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "configuration": {
                "supportsRemoteStart": false,
                "supportedCookingModes": [
                  "PREHEAT",
                  "COOK"
                ]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking.PresetController",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "presetName"
                  },
                  {
                    "name": "requestedFoodDoneness"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "configuration": {
                "presetCatalogId": "<catalog ID>",
                "supportsRemoteStart": false,
                "supportedCookingModes": [
                  "PRESET",
                  "PREHEAT",
                  "COOK"
                ]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.ProactiveNotificationSource",
              "version": "3.0",
              "proactivelyReported": true,
              "configuration": {
                "notificationConditions": [
                  {
                    "conditionType": "PropertyValueChange",
                    "property": {
                      "type": "AlexaInterface",
                      "interface": "Alexa.Cooking",
                      "name": "cookingStatus"
                    },
                    "valueChangeCondition": {
                      "comparator": "StringEquals",
                      "value": "COOKING_COMPLETED"
                    }
                  }
                ]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa",
              "version": "3"
            }
          ]
        }
      ]
    }
  }
}

Change reporting

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

ChangeReport event example for a dryer cycle completed

The following ChangeReport results in the following notification: Alexa: Your current dryer cycle is done.

Copied to clipboard.

{  
  "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": "PERIODIC_POLL"
        },
        "properties": [
          {
            "namespace": "Alexa.ModeController",
            "instance": "Dryer.CurrentDryerCycle",
            "name": "mode",
            "value": "CurrentDryerCycle.Completed",
            "timeOfSample": "2017-02-03T16:20:50Z",
            "uncertaintyInMilliseconds": 0
          }
        ]
      }
    }
  },
  "context": {
  }
}

ChangeReport event example for a full vacuum bin

The following ChangeReport results in the following notification: Alexa: Your vacuum bin is full.

Copied to clipboard.

{
  "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": "PERIODIC_POLL"
        },
        "properties": [
          {
            "namespace": "Alexa.RangeController",
            "instance": "Vacuum.Bin",
            "name": "rangeValue",
            "value": "95",
            "timeOfSample": "2017-02-03T16:20:50Z",
            "uncertaintyInMilliseconds": 0
          }
        ]
      }
    }
  },
  "context": {}
}

ChangeReport event example for cooking status

The following ChangeReport results in the following notification: Alexa: Your food in the oven is ready.

Copied to clipboard.

{
  "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.Cooking",
            "name": "cookingStatus",
            "value": "COOKING_COMPLETED",
            "timeOfSample": "2017-02-03T16:20:50Z",
            "uncertaintyInMilliseconds": 0
          }
        ]
      }
    }
  },
  "context": {}
}