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 has completed, or when their vacuum cleaner gets stuck.

You enable announcements for your device in your skill, but the user must enable announcements for your device in the Alexa app before Alexa begins to send notifications to the user. Users can enable announcements, which Alexa can send to any Echo device, such as an Echo Dot, Echo Plus, Echo Show, or Echo Spot.

You implement the ProactiveNotificationSource interface with other interfaces that provide functionality for your device. Currently, you must use ProactiveNotificationSource with one of the following generic controller interfaces:

Notifications to the user take the form, Your <controller instance friendly name> is <state>. For example:

Alexa: Your vacuum bin is full.

You trigger announcements by sending ChangeReports events.

Using semantics to enable announcements

You can enable announcements by using semantics. When you use semantics, you manually 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

For ModeController, you map the mode property to one of the states. For RangeController, you map the rangeValue property to one of the states. You map your property values to the states by including a semantics object in your discover response as described in the following section.

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

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 named notificationConditions. Each object in the array contains the following fields, as illustrated in the example that follows.

Field Description Type Required
conditionType The type of condition that triggers the notification. The only valid value is PropertyValueChange. String Yes
property The property that triggers the notification. Object Yes
valueChangeCondition The condition that triggers the notification. The condition is an object that contains the comparator and value fields. The only valid comparator is StateEquals. Object Yes

Discover response example

The following example shows a Discover.Response message for a clothes dryer that uses the ProactiveNotificationSource interface. 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"
                    }
                ]
            }]
        }
    }
}

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": {}
}