?
サポート

スマートホームスキルの状態レポートについて

スマートホームスキルの新しい機能の1つは、エンドポイントの状態に合わせてAlexaを更新できる機能です。Alexaはこの情報を使用して、音声だけでなくAlexaアプリによっても、お客様に最新の情報を提供します。

状態レポートイベントは、次の3つの理由で送信されます。

  1. 応答イベントの中で: 制御ディレクティブに応答するときには、状態をレポートする必要があります。Alexa.Responseイベントを送信するときには、リクエストが成功したことを示し、追加でエンドポイントのプロパティの状態を応答のcontextオブジェクトに入れてレポートすることができます。たとえば、TurnOnディレクティブに応答するときであれば、Responseイベントを送信する際に、エンドポイントのすべてのプロパティの状態も含めます。
  2. 変更通知イベントの中で: エンドポイントの状態が変更されたら、その変更をChangeReportイベントでAlexaにレポートし、状態の変更をユーザーに提供することができます。たとえば、照明がオンになり、イベントがAlexaに送信されると、Alexaはその状態変更をユーザーに提供することができます。必要に応じて、他の(変更されていない)プロパティの状態を、変更レポートのcontextオブジェクトに入れてレポートすることもできます。
  3. リクエストに応じて: Alexaが状態レポートをリクエストしたら、スキルはそれに対する応答としてStateReportイベントを送信します。この応答には、レポート可能なすべてのプロパティについて現在の状態を含めます。たとえば、ユーザーがAlexaアプリを確認して、1つのエンドポイントの状態をクエリするようにAlexaに指示することが考えられます。これに対して、スキルは、指定されたエンドポイントについてレポート可能なすべてのプロパティの状態を入れた応答を送信します。

検出時に状態レポートのサポートを提示する

検出の際、各プロパティについてエンドポイントが状態をレポートできるレベルを示す必要があります。プロパティのリストと、各プロパティがサポートする状態レポートのレベルを、retrievable属性とproactivelyReported属性で提示します。

プロパティがクエリ可能かどうかを意味するretrievableと、デバイスが変更通知イベントを送信できるかどうかを意味するproactivelyReportedについては、4つの組み合わせがサポートされています。

  • このプロパティではクエリ可能で、変更通知イベントを送信することができる。たとえば、状態のクエリをサポートし、またデバイスを直接操作することで状態が変化した場合にイベントを発行することもできる電球が、それに当たります。

  • このプロパティはクエリはサポートされているが、変更通知イベントは送信することができないものです。これに当たる例は、クエリをサポートしているが、直接操作に関するイベントは発行しない電球です。

  • このプロパティはクエリはできないが、変更通知イベントは送信することができるものです。これの例としては、低エネルギーデバイスが挙げられます。通常は休止状態なのでクエリには応答できませんが、設定が変化して有効になると変更通知イベントを発信します。

  • このプロパティはクエリも変更通知イベントもサポートされていません。これの例としては、赤外線送信機で制御される家電機器があります。赤外線は、片方向の制御メカニズムです。コマンドを家電機器に送信することはできますが、家電機器が自身の状態についてメッセージを送信するメカニズムはサポートされていません。

プロパティを定義した検出メッセージの例

{
  "event": {
    "header": {
      "namespace": "Alexa.Discovery",
      "name": "Discover.Response",
      "interfaceVersion": "3",
      "messageId": "abc-123-def-456"
    },
    "payload": {
      "endpoints": [{
        "endpointId": "uniqueIdOfLight",
        "friendlyName": "Living Room",
        "description": "a description that is shown to the customer",
        "displayCategories": [
          "THERMOSTAT"
        ],
        "cookie": {

        },
        "capabilities": [{
            "type": "AlexaInterface",
            "interface": "Alexa.ColorTemperatureController",
            "version": "3.0",
            "properties": {
              "supported": [{
                  "name": "colorTemperatureInKelvin"
                }
              ],
              "proactivelyReported": true,
              "retrievable": true
            }
          },
          {
            "type": "AlexaInterface",
            "interface": "Alexa.PowerController",
            "version": "3.0",
            "properties": {
              "supported": [{
                "name": "powerState"
              }],
              "proactivelyReported": true,
              "retrievable": true
            }
          }
        ]
      }]
    }
  }
}

次の点にご注意ください。

  • サポートされる配列にプロパティを指定しなかった場合、デフォルトの動作として、そのプロパティのproactivelyReportedretrievableはfalseと想定されます。
  • Propertiesオブジェクトがまったく存在しない場合、デフォルトでは、インターフェースによって定義されたプロパティにはクエリ可能なものや変更通知を提供するものは1つもないと想定されます。

それぞれのプロパティについてまずはfalseであることを想定し、機能インターフェースを進化させるのは、安全なアプローチの一つです。たとえば、インターフェースに新しいプロパティやディレクティブを追加することができますが、サポートされていることが検出プロセスで提示されない限り、Alexaがこれらのプロパティやディレクティブをエンドポイントで使用してみることはありません。

状態レポート用のContextオブジェクト

contextオブジェクトは、任意のイベントメッセージでプロパティの状態をレポートするために使用します。Contextには、プロパティオブジェクトの配列とその現在の状態が含まれています。それらの値は、更新されている場合と、更新されていない場合があります。どの値を状態レポートできるかについては、プロパティのスキーマのトピックを参照してください。

Alexa.ThermostatControllerインターフェースを実装したエンドポイントに対するContextの例を次に示します。

Contextオブジェクトの例

"context": {
  "properties": [
    {
      "namespace": "Alexa.ThermostatController",
      "name": "targetSetpoint",
      "value": {
        "value": 25.0,
        "scale": "CELSIUS"
      },
      "timeOfSample": "2017-02-03T16:20:50.52Z",
      "uncertaintyInMilliseconds": 0
    },
    {
      "namespace": "Alexa.ThermostatController",
      "name": "thermostatMode",
      "value": "HEAT",
      "timeOfSample": "2017-02-03T16:20:50.52Z",
      "uncertaintyInMilliseconds": 0
    }
  ]
}

Propertyオブジェクト

変更をレポートするには、プロパティ値が変更されたことを提示します。まず検出時にエンドポイントの状態レポートのレベルを記述し、次にプロパティをイベントに入れ、状態情報を含めて送信します。

フィールド 説明
namespace プロパティのインターフェースを指定します。
name レポートしているプロパティの名前です。
value name で指定されたプロパティの値です。
timeOfSample プロパティ値が提供された時刻(ISO 8601形式)をUTCで示したものです。例: "YYYY-MM-DDThh:mm:ss.sD"
uncertaintyInMilliseconds プロパティ値が取得されたと考えられる時刻から始まる、レポートされたプロパティ値が不確実である期間の経過時間(ミリ秒)。たとえば、ハードウェアデバイスを60秒ごとにポーリングして値を取得している場合であれば、サンプリングされた値の不確実な期間は60000ミリ秒です。

Alexaのネームスペースに含まれるシンプルな成功イベントでは必要を満たすのに不十分な場合は、機能インターフェースに、インターフェース固有の、さらにはディレクティブに固有の成功イベントを自由に実装することができます。

応答メッセージでの状態レポート

ディレクティブを受信した結果として状態が変わった場合の、その状態情報を送信することができます。たとえば、AlexaがTurnOnディレクティブを送信します。

{
  "directive": {
    "header": {
      "namespace": "Alexa.PowerController",
      "name": "TurnOff",
      "interfaceVersion": "3",
      "messageId": "1bd5d003-31b9-476f-ad03-71d471922820",
      "correlationToken": "dFMb0z+PgpgdDmluhJ1LddFvSqZ/jCc8ptlAKulUj90jSqg=="
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "some-access-token"
      },
      "endpointId": "appliance-001",
      "cookie": {}
    },
    "payload": {}
  }
}

この場合は、TurnOnディレクティブをエンドポイントに適用し、Responseイベントで応答します。また、このイベントに、エンドポイントのすべてのプロパティ値を入れたcontextオブジェクトを含めます。Contextを含めた応答イベントを送信する場合は、エンドポイントのすべてのプロパティの状態をレポートする必要があります。このときレポートする値には、リクエストディレクティブを処理した結果起こった全ての結果を組み込む必要があります。この例では、Alexa.PowerControllerインターフェースとAlexa.BrightnessControllerインターフェースを実装したエンドポイントを示しています。これらの応答には、ディレクティブに入っていた同じcorrelationTokenがメッセージヘッダーに含まれています。


{
  "context": {
    "properties": [
      {
        "namespace": "Alexa.PowerController",
        "name": "powerState",
        "value": "ON",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.BrightnessController",
        "name": "brightness",
        "value": 85,
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  },
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "Response",
      "interfaceVersion": "3",
      "messageId": "5f8a426e-01e4-4cc9-8b79-65f8bd0fd8a4",
      "correlationToken": "dFMb0z+PgpgdDmluhJ1LddFvSqZ/jCc8ptlAKulUj90jSqg=="
    },
    "endpoint": {
      "scope": {
        "type": "AlexaUserId",
        "userId": "some-Amazon-user-id"
      },
      "endpointId": "appliance-001"
    },
    "payload": {}
  }
}

状態リクエストへの応答

Alexaがエンドポイントの状態レポートを要求する場合は、状態を要求する相手のエンドポイントを指定して、ReportStateディレクティブが送信されます。この例では、エンドポイントはAlexa.ThermostatController機能インターフェースを実装しています。このメッセージを受け取った場合は、検出プロセス時に定義したプロパティの状態をレポートします。

StateReportリクエストの例

{
  "directive": {
    "header": {
      "messageId": "abc-123-def-456",
      "correlationToken": "abcdef-123456",
      "namespace": "Alexa",
      "name": "ReportState",
      "interfaceVersion": "3"
    },
    "endpoint": {
      "endpointId": "appliance-001",
      "cookie": {},
      "scope":{  
            "type":"BearerToken",
            "token":"some-access-token"
      }
    },
    "payload": {
    }
  }
}

応答するときは、StateReportを送信し、その中に、各機能インターフェースのレポート可能なプロパティとその現在の値をすべて入れたcontextオブジェクトを組み込む必要があります。

StateReport応答の例

{  
   "context":{  
      "properties":[  
         {  
            "namespace":"Alexa.ThermostatController",
            "name":"targetSetpoint",
            "value":{  
               "value":25.0,
               "scale":"CELSIUS"
            },
            "timeOfSample":"2017-02-03T16:20:50.52Z",
            "uncertaintyInMilliseconds":6000
         },
         {  
            "namespace":"Alexa.ThermostatController",
            "name":"thermostatMode",
            "value":"HEAT",
            "timeOfSample":"2017-02-03T16:20:50.52Z",
            "uncertaintyInMilliseconds":6000
         }
      ]
   },
   "event":{  
      "header":{  
         "messageId":"abc-123-def-456",
         "correlationToken":"abcdef-123456",
         "namespace":"Alexa",
         "name":"StateReport",
         "interfaceVersion":"3"
      },
      "endpoint":{  
         "scope":{  
            "type":"BearerToken",
            "token":"some-access-token"
         },
         "endpointId":"appliance-001",
         "cookie":{  

         }
      },
      "payload":{  

      }
   }
}

変更通知

ChangeReport イベントは、Alexaに状態の変更をプロアクティブに通知し、Alexaアプリにデバイスの現在の状態を確実に反映するために送信されます。たとえば、お客様が"キッチンの照明"エンドポイントを手動で点灯した場合は、それをAlexaに通知するために、Alexa.PowerControllerインターフェースのpowerStateプロパティの値が"オン"に変更になったことを示すChangeReportイベントを送信します。

検出時にproactivelyReportedとして提示したプロパティは、そのプロパティ値が変更されたときにはいつでもAlexaにChangeReportイベントを送信する必要があります。

  • ChangeReportpayloadを使用して、新しいプロパティ値と、その変更の理由を提供します。
  • オプションとして、ChangeReportcontextを使用して他の任意のプロパティの状態をレポートすることもできます(変更された可能性のあるプロパティをレポートしたり、すべてのプロパティの現在の状態をレポートしたりできます)。
  • 複数のプロパティが変更された場合は、Alexaに対して、ペイロードに1つのプロパティを入れた複数の変更レポートイベントを送信するか、ペイロードに複数のプロパティ値を入れた1つの変更レポートイベントを送信することができます。

次の例は、Alexa.PowerControllerインターフェースとAlexa.BrightnessControllerインターフェースを実装した1つのエンドポイントに関するChangeReportイベントを示しています。このイベントは、エンドポイントのpowerStateがデバイスを直接操作することによって"OFF"から"ON"に変更されたことをレポートし、輝度のレベルには変更がなかったため、輝度をcontextオブジェクトに入れてレポートしています。

{
  "context": {
    "properties": [
      {
        "namespace": "Alexa.BrightnessController",
        "name": "brightness",
        "value": 85,
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 60000
      }
    ]
  },
  "event": {
    "header": {
      "messageId": "abc-123-def-456",
      "namespace": "Alexa",
      "name": "ChangeReport",
      "interfaceVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "AlexaUserId",
        "userId": "some-Amazon-user-id"
       },
       "endpointId" :  "<the endpoint identifier of the endpoint >" ,
    },
    "payload": {
      "change": {
        "cause": {
          "type": "PHYSICAL_INTERACTION"
        },
        "properties": [
          {
            "namespace": "Alexa.PowerController",
            "name": "powerState",
            "value": "ON",
            "timeOfSample": "2017-02-03T16:20:50.52Z",
            "uncertaintyInMilliseconds": 0
          }
        ]
      }
    }
  }
}

ペイロードの詳細

ChangeReportイベントのペイロードには、変更されたプロパティの配列の入ったChangeオブジェクトと、変更の理由を示す理由(Cause)オブジェクトを組み込みます。

理由(Cause)オブジェクト

cause属性は、ChangeReportイベントの送信時に、プロパティ値の変更の原因を記述するために使用されます。これは、次に挙げる子要素の型を持つポリモーフィックな型です。

理由の種類 説明
ALEXA_INTERACTION イベントの原因が、Alexaとの音声による操作またはGUIによる操作にあったことを示します。たとえば、ユーザーがEcho端末に話しかけた場合や、Alexaコンパニオンアプリケーションで操作が行われた場合です。
PHYSICAL_INTERACTION イベントの原因が、エンドポイントを直接操作したことにあったことを示します。たとえば、照明を手動でオンにした場合や、ドアの鍵を手動でロックした場合があります。
PERIODIC_POLL 機器への定期的なポーリングにより値の変更が検出されたために、状態レポートが送信されたことを示します。たとえば、温度センサーを1時間に1回ポーリングして、更新された温度をAlexaに送信する場合があります。

APIが充実していくにつれて、原因の種類は増えていくものと考えられます。

プロパティのスキーマ

サポートされるプロパティの全種類については、プロパティのスキーマで説明しています。機能インターフェースからプロパティへのマッピングと、各プロパティからスキーマへのマッピングについては、各インターフェースのトピックで説明しています。

クエリができないプロパティ

場合によっては、デバイスのプロパティを変更できても、プロパティの状態をレポートできないことがあります。たとえば、赤外線リモコンでコントロールできるスマート電球の場合であれば、リモコンと電球の間には片方向の通信しか存在しません。この場合は、検出の応答メッセージの中で、このプロパティをレポートできないことを示す必要があります。

クエリできないpowerStateプロパティに関するStateReportの例

レポートできないプロパティをもつエンドポイントへのTurnOnディレクティブの処理に成功した場合は、Responseイベントを使用して応答する必要があります。

この例では、context.properties配列属性の値が空のリストであり、イベント名がResponseであることから、Alexaは、TurnOnリクエストが正常に処理されたと判断できますが、結果の状態は判別できません。必要に応じて、定義されているエラー応答の1つを返すこともできます。たとえば、クラウドからデバイスに到達できなかった場合です。

{
  "context": {
    "properties": [
    ]
  },
  "event": {
    "header": {
      "messageId": "abc-123-def-456",
      "correlationToken": "abcdef-123456",
      "namespace": "Alexa.PowerController",
      "name": "Response",
      "interfaceVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "AlexaUserId",
        "userId": "some-Amazon-user-id"
       },
       "endpointId" :  "endpoint-id" ,
    },
    "payload": {
    }
  }
}

状態情報と一緒にメッセージを送信する

非同期応答、変更レポート、状態レポートのイベントをAlexaに送るには、HTTP POSTメッセージをAlexaのインバウンドイベントエンドポイントに送信します。

https://api.amazonalexa.com/beta/eventChannel

次の内容を含めます。

  • コンテンツのタイプがJSONであることを示す、次のようなヘッダー。

Content-Type:application/json

  • JSON形式のメッセージ本文。本文には、メッセージの目的に応じてAlexa.ResponseChangeReportStateReportのいずれかを含めることができます。

メッセージの例については、このトピック内の変更通知状態リクエストへの応答や、各インターフェースのトピックにあるAlexa.Responseの例を参照してください。

インバウンドイベントエンドポイントへのメッセージの例を次に示します。

POST /beta/eventChannel HTTP/1.1
Host: api-amazonalexa.amazon.com
Content-Type: application/json

{
  "context": {
    "properties": [
    ]
  },
  "event": {
    "header": {
      "messageId": "abc-123-def-456",
      "correlationToken": "abcdef-123456",
      "namespace": "Alexa",
      "name": "Response",
      "interfaceVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "Alexa-access-token"
       },
       "endpointId" :  "endpoint-id" 
    },
    "payload": {
    }
  }
}

状態レポートのパフォーマンスに関する要件

開発しているスマートホームスキルが認定を受けるには、このサービスとやり取りする際に一定のパフォーマンス要件を満たす必要があります。そこで、今からその要件を満たすように作成および計画することをお勧めします。次の件についてガイドラインが定められています。

  • イベントの応答性に関する要件
  • イベントのトランザクションレート(エンドポイントあたり)の制限

イベントの応答性

ディレクティブを受信したときは、同期応答を送信するか、または、ディレクティブを受信したことを示すDeferredResponseを送信し、後でAlexaのエンドポイントに非同期イベントを送信することができます。

それに加えて、エンドポイントの状態が変更されたときに、変更通知イベントを送信することができます。状態の変更は、ユーザーがAlexaに命じた結果であることも、スイッチをオンにするなどの直接の操作の結果であることもあります。パフォーマンス要件は、イベントの種類に応じて異なります。それぞれの種類に対するガイドラインを次の表に示します。

イベントの種類 90%要件
ディレクティブを受信したことを示す同期応答 リクエストを受信してから100ミリ秒以内に応答する
非同期応答イベント リクエストを受信してから3000ミリ秒以内に応答する
状態レポートイベント 変更されてから100ミリ秒以内に応答する

イベントトランザクションレート

スキルから状態レポートサービスに送信するメッセージ数を制限するためのロジックをスキルに組み込む必要があります(デバウンシングと呼ばれます)。Alexaは次のようなメッセージ制限を設定しています。

  • エンドポイントあたり10TPS(トランザクション/秒)

この制限を超える数のメッセージを送信していることがわかった場合は、遅延キューやメッセージのバッチ処理をセットアップするなど、何らかのメカニズムを使用してメッセージ数を減らす必要があります。Alexaサービスは、デバウンシングのロジックを実装する責任を負いません。

.