状態および変更レポートについて



状態および変更レポートについて

スマートホームデバイスを操作するAlexaスキルを作成する際、状態および変更レポートのサポートを追加できます。Alexaは、音声応答、Alexaアプリのいずれかでデバイスの状態をユーザーに知らせます。たとえば、ユーザーはAlexaアプリでスマートプラグのリストを表示してどのプラグがオンかオフかを確認できます。

Alexaへの状態レポートは、StateReportイベント、ChangeReportイベント、Responseイベントで行います。

検出中にサポート対象の状態および変更レポートを特定する

デバイスの検出中に、スキルでサポートするAlexaインターフェースを指定します。各インターフェースについて状態および変更レポートのサポートを指定します。検出応答イベントのJSON内で以下のプロパティを使い、状態および変更レポートを指定します。

  • Retrievable — retrievableプロパティは状態レポートを制御します。インターフェースにretrievable = trueを設定すると、Alexaはそのインターフェースの現在の状態をスキルに照会できます。AlexaがReportStateディレクティブを送信し、スキルがStateReportイベントで応答します。デフォルト値はfalseです。

  • ProactivelyReported — ProactivelyReportedプロパティは変更レポートを制御します。インターフェースにproactivelyReported = trueを設定すると、スキルはそのインターフェースのプロパティに何らかの変更があるたびにChangeReportイベントをAlexaに送信します。デフォルト値はfalseです。

応答例

以下は、Alexa.Cookingインターフェース、Alexa.Cooking.TemperatureSensorインターフェース、Alexa.Cooking.TemperatureControllerインターフェースをサポートするオーブンのDiscover.Responseメッセージの例です。(日本未対応)検出コードのその他の例については、Alexaスキルでサポートする各インターフェースのドキュメントを参照してください。

{
  "event": {
    "header": {
      "namespace": "Alexa.Discovery",
      "name": "Discover.Response",
      "payloadVersion": "3",
      "messageId": "<メッセージID>"
    },
    "payload": {
      "endpoints": [
        {
          "endpointId": "<エンドポイントの一意のID>",
          "manufacturerName": "Smart Cooking Device Company",
          "description": "Brand XYZ oven",
          "friendlyName": "Oven",
          "displayCategories": ["OVEN"],
          "additionalAttributes":  {
            "manufacturer" : "Smart Cooking Device Company",
            "model" : "サンプルモデル",
            "serialNumber": "U11112233456",
            "firmwareVersion" : "1.24.2546",
            "softwareVersion": "1.036",
            "customIdentifier": "サンプルカスタムID"
          },
          "cookie": {},
          "capabilities": [
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "cookingMode"
                  },
                  {
                    "name": "foodItem"
                  },
                  {
                    "name": "cookingTimeInterval"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "configuration": {
                "supportedCookingModes": ["REHEAT", "DEFROST", "OFF"]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking.TemperatureSensor",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "cookingTemperature"
                  }
                ],
                "proactivelyReported": false,
                "retrievable": true
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking.TemperatureController",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "targetCookingTemperature"
                  },
                  {
                    "name": "preheatTimeInterval"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "configuration": {
                "supportsRemoteStart": false,
                "supportedCookingModes": ["BAKE", "ROAST"]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa",
              "version": "3"
            }
          ]
        }
      ]
    }
  }
}

StateReportで状態をレポートする

Alexaがエンドポイントの状態をリクエストするReportStateディレクティブを送信した場合、スキルは応答でStateReportイベントを送信します。この応答には、取得可能なすべてのプロパティについて現在の状態を含めます。

たとえば、ユーザーがAlexaアプリで自宅の別の階にある照明の状態をチェックしたとします。Alexaは、その照明へのReportStateディレクティブを送信します。スキルは、その照明の取得可能なすべてのプロパティの状態を含む応答を送信し、アプリがその状態をユーザーにレポートします。

スキルがエンドポイントを定期的にポーリングする場合、応答ではキャッシュされたプロパティ値を送信できます。その時エンドポイントに到達できなくても、すべてのプロパティ値がキャッシュされている場合は、すべてのプロパティ値を含むStateReportを返します。ただし、EndpointHealthのconnectivityプロパティの値はUNREACHABLEと指定してください。エンドポイントに到達できないためプロパティの状態を残らずレポートすることができず、値のキャッシュもない場合は、タイプがBRIDGE_UNREACHABLEまたはENDPOINT_UNREACHABLEErrorResponseを送信する必要があります。

ReportStateディレクティブ

ReportStateディレクティブの例

次の例は、Alexaがスキルに送信するReportStateディレクティブを示しています。

{
  "directive": {
    "header": {
      "namespace": "Alexa",
      "name": "ReportState",
      "messageId": "<メッセージID>",
      "correlationToken": "<opaque相関トークン>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "endpointId": "<エンドポイントID>",
      "cookie": {},
      "scope": {
        "type": "BearerToken",
        "token": "<OAuth2ベアラートークン>"
      }
    },
    "payload": {}
  }
}

StateReportイベント

StateReport応答イベントの例

以下は、スキルがAlexaに送信するStateReportイベントの例です。その他のStateReportコードの例については、Alexaスキルでサポートする各インターフェースのドキュメントを参照してください。

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "StateReport",
      "messageId": "<メッセージID>",
      "correlationToken": "<opaque相関トークン>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<OAuth2ベアラートークン>"
      },
      "endpointId": "<エンドポイント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
      }
    ]
  }
}

ChangeReportで状態をレポートする

エンドポイントの状態が何らかの理由で変化した場合、スキルはその変化をChangeReportイベントでAlexaにレポートします。その後Alexaからユーザーに状態の変更を提供できます。変更レポートでは、変化のあったプロパティの状態をpayloadオブジェクトに指定します。たとえば、ユーザーが照明を手動で点灯した場合は、Alexa.PowerControllerインターフェースのpowerStateプロパティの値がONに変更になったことを示す変更レポートイベントを送信します。

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

状態の変化がAlexaからのディレクティブによるものの場合は、ディレクティブへの応答と変更レポートイベントの両方を送信します。詳細については、ディレクティブに対する応答を参照してください。

  • ChangeReportpayloadを使用して、新しいプロパティ値と、その変更の理由を提供します。
  • ChangeReportcontextを使用して他の任意のプロパティの状態をレポートすることもできます。
  • 複数のプロパティが変更された場合は、Alexaに対して、ペイロードに1つのプロパティを入れた複数の変更レポートイベントを送信するか、ペイロードに複数のプロパティ値を入れた1つの変更レポートイベントを送信することができます。
  • どのユーザーのどのエンドポイントに対する変更レポートなのかをendpointオブジェクトで必ず指定するようにしてください。

ユーザーエクスペリエンスの向上につなげるためにも、contextオブジェクトには、変化のなかったほかのプロパティも含めてすべてのプロパティの状態を指定することをお勧めします。

ChangeReportイベント

ChangeReportイベントの例

以下は、Alexa.PowerControllerインターフェースとAlexa.BrightnessControllerインターフェースを実装した1つのエンドポイントに関するChangeReportイベントの例です。このイベントは、デバイスの物理的な操作によってエンドポイントのbrightness値が85%に変わったことをレポートしています。このイベントでは新しいbrightness値をpayloadに指定しているほか、値が変わらなかったことから、powerStateプロパティをcontextオブジェクトに指定しています。ChangeReportコードのその他の例については、Alexaスキルでサポートする各インターフェースのドキュメントを参照してください。

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "ChangeReport",
      "messageId": "<メッセージID>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<OAuth2ベアラートークン>"
      },
      "endpointId": "<エンドポイント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オブジェクト

causeアトリビュートは、ChangeReportイベントの送信時に、プロパティ値の変更の理由を記述するために使用します。以下の表に、causeの値をまとめました。

原因の種類 説明
APP_INTERACTION アプリを使ったユーザーの操作です。たとえば、ユーザーはAlexaアプリやデバイスベンダーのアプリを使って照明を点灯したり、ドアをロックしたりします。
PERIODIC_POLL エンドポイントの定期的なポーリングです。たとえば、温度センサーを1時間に1回ポーリングして、更新された温度をAlexaに送信できます。
PHYSICAL_INTERACTION エンドポイントの物理的な操作です。たとえば、ユーザーが手動で照明を点灯したり、ドアをロックしたりします。
RULE_TRIGGER デバイスのルールです。たとえば、ユーザーはモーションセンサーがモーションを検知した場合に照明を点灯するルールを設定します。この場合、Alexaはモーションセンサーからイベントを受信するとともに照明からも別のイベントを受信し、状態の変更がルールによって発生したことを示します。
VOICE_INTERACTION 音声対話です。たとえば、ユーザーがEchoデバイスに話しかけて照明を点灯します。

ディレクティブの応答で状態をレポートする

Alexaがプロパティの状態を変化させるディレクティブを送信し、スキルがそのディレクティブを正常に処理した場合、スキルは応答イベントを送信します。応答では、変化のあったプロパティの状態をcontextオブジェクトに指定します。たとえば、AlexaがAlexa.PowerController.TurnOnディレクティブを送信すると、スキルはcontextに新しい値ONを指定したpowerStateプロパティを含む応答イベントを送信します。

スキルでは、ユーザーエクスペリエンスの向上につなげるためにも、変化のなかったプロパティも含めてすべてのプロパティの状態を指定することをお勧めします。

応答イベントはスキルのLambda関数から同期的に送信するか、イベントゲートウェイから非同期的に送信します。

ディレクティブの例

以下は、Alexaがスキルに送信するディレクティブの例です。

{
  "directive": {
    "header": {
      "namespace": "Alexa.PercentageController",
      "name": "AdjustPercentage",
      "messageId": "<メッセージID>",
      "correlationToken": "<opaque相関トークン>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<OAuth2ベアラートークン>"
      },
      "endpointId": "<エンドポイントID>",
      "cookie": {}
    },
    "payload": {
      "percentageDelta": -20
    }
  }
}

プロパティの状態を含む応答の例

以下は、スキルがAlexaに送信する応答の例です。

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "Response",
      "messageId": "<メッセージID>",
      "correlationToken": "<opaque相関トークン>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<OAuth2ベアラートークン>"
      },
      "endpointId": "<エンドポイントID>"
    },
    "payload": {}
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.PercentageController",
        "name": "percentage",
        "value": 54,
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 500
      }
    ]
  }
}

retrievableではないプロパティの応答の例

スキルは、retrievableではないプロパティを持つエンドポイントへのディレクティブを正常に処理した後、contextにプロパティを含まないresponseイベントを送信する必要があります。

以下は、TurnOnディレクティブが正常に処理されたことをAlexaに対して示すResponseイベントの例です。イベントのcontextの空のproperties配列により、変更後のプロパティの状態が判明していないことを示しています。

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "Response",
      "messageId": "<メッセージID>",
      "correlationToken": "<opaque相関トークン>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<OAuth2ベアラートークン>"
      },
      "endpointId": "<エンドポイントID>"
    },
    "payload": {}
  },
  "context": {
    "properties": []
  }
}