Уведомление об изменении состояния устройства

Уведомляет платформу умного дома об изменившемся состоянии устройств.

Пример ситуации, в которой отправляется текущий запрос: пользователь прошел мимо датчика движения, датчик сработал.

Исчерпывающий перечень событий, при которых отправка этого запроса обязательна, — в разделе Требования к уведомлениям.

Условие работы сервиса уведомлений

Уведомления принимаются, если навык был опубликован хотя бы один раз, включая приватную публикацию. На черновике навыка, который ни разу не публиковали, сервис уведомлений не работает — отлаживайте отправку уведомлений на опубликованном навыке. Подробнее см. в разделе Требования к уведомлениям.

Формат запроса

POST https://dialogs.yandex.net/api/v1/skills/{skill_id}/callback/state

Заголовки запроса

Параметр

Описание

Обязательный

Authorization

Авторизационный токен владельца навыка.

Да

Content-Type

Формат передаваемых/отправляемых данных. Возможные значения: application/json.

Да, в операциях с http-методом POST

Формат тела запроса

{
    "ts": Float,
    "payload": {
        "user_id": String,
        "devices": [{
            "id": String,
            "status": String,
            "capabilities": [
                "<capability1>": Object,
                "<capability2>": Object
                    ...
                    ],
            "properties": [
                "<property1>": Object,
                "<property2>": Object
                    ...
                    ]
        }]
    }
}

Параметр

Тип

Описание

Обязательный

ts

Float

Время возникновения события в секундах, формат unix timestamp. Передается время наступления события, а не время отправки запроса.

Подробнее — в разделе Требования к ts.

Да

payload

Object

Объект с устройствами.

Да


Объект payload

Параметр

Тип

Описание

Обязательный

user_id

String

Идентификатор пользователя, который был передан в ответе на запрос Информация об устройствах пользователя.

Да

devices

Array of objects

Массив с устройствами, которые изменили свое состояние. Массив не должен быть пустым.

Да


Объект devices

Параметр

Тип

Описание

Обязательный

id

String

Идентификатор устройства. Должен быть уникален среди всех устройств производителя.

Да

status

String

Статус устройства. Допустимые значения:

  • online,
  • offline.

Если устройство недоступно, в поле передается значение offline, а в приложении Дом с Алисой отобразится статус устройства «не в сети». Если пользователь настроил отправку оповещений (Уведомления о состоянии → Не в сети → Уведомить о состоянии устройства «не в сети»), то ему также придет пуш-уведомление об обрыве соединения.

Примеры запросов при изменении статуса устройства: переход в offline, возврат в online.

Да, если отсутствуют capabilities и properties

capabilities

Array of objects

Массив с информацией о новых состояниях умений устройств.

Пустой массив изменением не считается. Если менять нечего, поле не передается.

Да, если отсутствуют status и properties

properties

Array of objects

Массив с информацией о новых состояниях свойств.

Пустой массив изменением не считается. Если менять нечего, поле не передается.

Да, если отсутствуют status и capabilities


Объект capabilities

Параметр

Тип

Описание

Обязательный

<capability1>

Object

Описание нового состояния умения. Подробнее со списком доступных умений и их параметрами можно ознакомиться в разделе Об умениях. Формат описания нового состояния совпадает с форматом, который используется в ответе на запрос Информация о состояниях устройств пользователя.

Нет

<capability2>

Object

Описание нового состояния умения. Подробнее со списком доступных умений и их параметрами можно ознакомиться в разделе Об умениях. Формат описания нового состояния совпадает с форматом, который используется в ответе на запрос Информация о состояниях устройств пользователя.

Нет


Объект properties

Параметр

Тип

Описание

Обязательный

<property1>

Object

Описание нового состояния свойства. Подробнее со списком доступных свойств и их параметрами можно ознакомиться в разделе О свойствах. Формат описания нового состояния совпадает с форматом, который используется в ответе на запрос Информация о состояниях устройств пользователя.

Нет

<property2>

Object

Описание нового состояния свойства. Подробнее со списком доступных свойств и их параметрами можно ознакомиться в разделе О свойствах. Формат описания нового состояния совпадает с форматом, который используется в ответе на запрос Информация о состояниях устройств пользователя.

Нет

Что должно быть в объекте devices

В объекте каждого устройства из массива devices обязательно передать хотя бы одно из:

  • status — изменение доступности устройства (online или offline);
  • непустой массив capabilities — изменение состояния умений;
  • непустой массив properties — изменение показаний свойств.

Пустой массив изменением не считается. Если менять нечего, поле не передается.

Допускается запрос, содержащий только status, — например, при потере или восстановлении связи с устройством, когда состояние умений и свойств не изменилось.

Важно

Для устройств, у которых в ответе на запрос Информация об устройствах пользователя указано status_info.reportable: true, отправка поля status обязательна при каждом переходе доступности — как в offline, так и в online.

Требования к ts

Поле ts содержит время возникновения события, а не время отправки уведомления. Формат — unix timestamp в секундах (дробное число).

  • Платформа использует ts для упорядочивания событий. Значение ts должно быть монотонным для каждого устройства: ts последующего события не должен быть меньше ts предыдущего.
  • Если платформа получает уведомление с устаревшим ts (меньшим, чем у уже обработанного события для того же устройства), такое событие игнорируется.
  • Не используйте ts для задержки отправки — событие отправляется по факту его наступления.
  • Часы на серверах провайдера должны быть синхронизированы. Значение ts из будущего приведет к тому, что последующие события будут отброшены как устаревшие.

Формат ответа

HTTP/1.1 202 Accepted

{
  "request_id": String,
  "status": "ok"
}

Параметр

Тип

Описание

Обязательный

request_id

String

Идентификатор запроса. Необходимо логировать для расследования инцидентов.

Да

status

String

Статус обработки запроса. Допустимые значения:

  • ok.

Да

HTTP/1.1 400

{
  "request_id": String,
  "status": "error",
  "error_code": String,
  "error_message": String
}

Параметр

Тип

Описание

Обязательный

request_id

String

Идентификатор запроса. Необходимо логировать для расследования инцидентов.

Да

status

String

Статус обработки запроса. Допустимые значения:

  • error.

Да

error_code

String

Код ошибки. Допустимые значения:

  • BAD_REQUEST;
  • UNKNOWN_USER.

Нет

error_message

String

Сообщение об ошибке.

Нет

Коды ошибок

Обработка ошибок и повторные запросы

Навык должен обрабатывать ответ платформы на свой запрос в соответствии с таблицей ниже.

Принятое уведомление платформа подтверждает кодом 202 Accepted. Код 200 OK в ответ на запрос в сервис уведомлений не возвращается.

HTTP-код

status

error_code

Что произошло

Что делать

202 Accepted

ok

—

Уведомление принято в обработку

Ничего. Повторять запрос не нужно

400

error

BAD_REQUEST

Невалидный JSON или тело запроса не соответствует контракту: не передано ни одно из status, capabilities, properties; неизвестное умение или свойство; невалидное значение

Повтор запроса в неизменном виде не даст результата — он будет отклонен снова. Исправьте формирование запроса на своей стороне

400

error

UNKNOWN_USER

Платформа не знает пользователя с таким user_id: аккаунты не связаны или связка разорвана

Не повторять. Остановить отправку уведомлений для этого user_id до следующей связки аккаунтов

401

—

—

Не передан или истек OAuth-токен

Обновить OAuth-токен для Диалогов и повторить запрос

403

—

—

Владелец токена не является владельцем навыка

Не повторять. Использовать токен пользователя Яндекса, который создал навык

404

—

—

В пути запроса указан неверный skill_id

Не повторять. Проверить идентификатор навыка

5xx, таймаут, сетевая ошибка

—

—

Временная проблема на стороне платформы или сети

Повторить запрос с нарастающей задержкой, сохранив исходное значение ts

429 Too Many Requests

—

—

Прием уведомлений от навыка ограничен — платформа считает отправку нарушающей требования к уведомлениям

Остановить отправку и устранить причину ограничения. Подробнее см. в разделе Ограничение приема уведомлений

При повторной отправке не нужно:

  • повторять запрос, отклоненный с BAD_REQUEST или UNKNOWN_USER, — он будет отклонен снова;
  • подставлять новое значение ts — при повторе передается исходное время события;
  • отправлять уведомление об изменении, которого не было, — например, повторно отправлять последнее состояние по таймеру.

Если после нескольких повторов доставить событие не удалось, отправьте актуальное состояние устройства новым уведомлением с новым ts, а не копию устаревшего события.

Примеры

Переход в offline

curl -i -X POST 'https://dialogs.yandex.net/api/v1/skills/user-test-skill/callback/state' \
-H 'Authorization: OAuth 123qwe456a...' \
-H 'Content-Type: application/json' \
-d '{
    "ts": 1602703322.1,
    "payload": {
        "user_id": "provider-user-id-1",
        "devices": [{
            "id": "lamp-001",
            "status": "offline"
        }]
    }
}'
HTTP/1.1 202 Accepted

{
  "request_id": "75442486-0878-440c-9db1-a7006c25a39f",
  "status": "ok"
}

Возврат в online

curl -i -X POST 'https://dialogs.yandex.net/api/v1/skills/user-test-skill/callback/state' \
-H 'Authorization: OAuth 123qwe456a...' \
-H 'Content-Type: application/json' \
-d '{
    "ts": 1602703400.5,
    "payload": {
        "user_id": "provider-user-id-1",
        "devices": [{
            "id": "lamp-001",
            "status": "online"
        }]
    }
}'
HTTP/1.1 202 Accepted

{
  "request_id": "a1b2c3d4-5678-90ef-1234-567890abcdef",
  "status": "ok"
}

Изменение состояния умения

curl -i -X POST 'https://dialogs.yandex.net/api/v1/skills/user-test-skill/callback/state' \
-H 'Authorization: OAuth 123qwe456a...' \
-H 'Content-Type: application/json' \
-d '{
    "ts": 1602703500.0,
    "payload": {
        "user_id": "provider-user-id-1",
        "devices": [{
            "id": "lamp-001",
            "capabilities": [{
                "type": "devices.capabilities.on_off",
                "state": {
                    "instance": "on",
                    "value": true
                }
            }]
        }]
    }
}'
HTTP/1.1 202 Accepted

{
  "request_id": "b2c3d4e5-6789-01ab-cdef-234567890abc",
  "status": "ok"
}

Изменение состояния свойства

curl -i -X POST 'https://dialogs.yandex.net/api/v1/skills/user-test-skill/callback/state' \
-H 'Authorization: OAuth 123qwe456a...' \
-H 'Content-Type: application/json' \
-d '{
    "ts": 1602703600.0,
    "payload": {
        "user_id": "provider-user-id-1",
        "devices": [{
            "id": "sensor-001-snsr",
            "properties": [{
                "type": "devices.properties.event",
                "state": {
                    "instance": "motion",
                    "value": "detected"
                }
            }]
        }]
    }
}'
HTTP/1.1 202 Accepted

{
  "request_id": "c3d4e5f6-7890-12ab-cdef-34567890abcd",
  "status": "ok"
}

Одновременное изменение статуса и состояния

curl -i -X POST 'https://dialogs.yandex.net/api/v1/skills/user-test-skill/callback/state' \
-H 'Authorization: OAuth 123qwe456a...' \
-H 'Content-Type: application/json' \
-d '{
    "ts": 1602703700.0,
    "payload": {
        "user_id": "provider-user-id-1",
        "devices": [{
            "id": "lamp-001",
            "status": "online",
            "capabilities": [{
                "type": "devices.capabilities.on_off",
                "state": {
                    "instance": "on",
                    "value": true
                }
            }],
            "properties": [{
                "type": "devices.properties.float",
                "state": {
                    "instance": "temperature",
                    "value": 23.5
                }
            }]
        }]
    }
}'
HTTP/1.1 202 Accepted

{
  "request_id": "d4e5f6a7-8901-23ab-cdef-4567890abcde",
  "status": "ok"
}

Успешный ответ — 202 Accepted

HTTP/1.1 202 Accepted

{
  "request_id": "75442486-0878-440c-9db1-a7006c25a39f",
  "status": "ok"
}

Ответ с ошибкой

HTTP/1.1 400

{
  "request_id": "same-as-in-request",
  "status": "error",
  "error_code": "UNKNOWN_USER",
  "error_message": "User not found"
}

Как обрабатывать ответ платформы, см. в разделе Обработка ошибок и повторные запросы.

Число с плавающей точкой с точностью до 6-9 десятичных знаков.

Cтрока, выделяется кавычками, например "Hello world".

Список пар "ключ": значение, разделенных запятой. Выделяется фигурными скобками {}.

{
  "name": "John",
  "surname": "Smith"
}

Массив элементов, разделенных запятой. Элементом могут быть стандартные элементы JSON: строка, число, true, false, объект или массив. Массив выделяется квадратными скобками []:

"cities": ["Moscow", "Tokyo", "New York"]

Идентификатор вызываемого навыка, присвоенный при создании.

Чтобы узнать идентификатор своего навыка, откройте его в консоли разработчика — идентификатор можно скопировать на вкладке Общие сведения, внизу страницы.