Smart Home Skillsを使ってみる


Smart Home Skillとは?

一部のデバイス(Philips HueやBelkin WeMo)は同じネットワーク上にあれば、Amazon Echoからを直接検出して操作することが可能ですが、Alexa Voice Serviceを使った自作のEchoや、サードパーティーや自作のスマートホームデバイスを利用したい場合は、このSmart Home Skill APIを使うことが推奨されています。

現在のSmart Home Skillの最新はv3です。この記事はv2の時の内容ですので、リクエストのJSONなど微妙にちがいます。
v3のサンプルソースはこちらを参照して下さい。

https://github.com/sparkgene/amazon_alexa_sample/tree/master/smarthome

カスタムスキルとの違い

  • Amazonがスマートホームデバイス向けのinteraction modelを用意しているので、Custom Skillsのようにintraction modelを設計する必要がない
  • Smart Home SkillsはLambda上で実装する必要がある。Custom Skillsは自分でホストしても構わない
  • OAuth2.0を利用したアカウント連携を実装する必要がある
  • デバイスの検出と操作のために、クラウドベースのAPIにアクセスできる必要がある

カスタムスキルを使ってスマートホームデバイスを利用することも可能ではありますが、この例では一般公開はしづらい物が出来上がってしまいます。
また、通常のSkillではSkill名を含めて実行する必要があるため、Alexa, turn on living lightsみたいに直感的な発話で操作できません。

注意

Smart Home Skillsは、クラウドで管理されたデバイスを使うことが前提です。
その為には、SkillでOAuthによって認可したユーザーとデバイスを紐付けたり、クラウドからデバイスを操作したりユーザとのヒモ付を管理する仕組みは、自分で用意する必要があります。
この投稿では全体の流れを知るために、簡単なLogin with AmazonをOAuthプロバイダとして利用しており、デバイスとユーザのヒモ付に関する実装には触れません。

Login With Amazon(LWA) security profileを作成する

今回はOAuthプロバイダとしてAmazon.comを利用するのでデベロッパーコンソールからSecurity Profileを作成します。

デベロッパーコンソール

APPS & SERVICESの中にあるLogin with Amazonをクリック。

Create n New Security Profile をクリック。

必要な情報を入力。
Consent Privacy Notice URL には自分のサービスのプライバシーポリシーサイトを入力する。

作られました!

Client IDClient Secretは後で使うのでメモっておく。

Smart Home Skillsを作成

Skillを登録(1)

デベロッパーコンソールのメニューからAlexaを選択し、Alexa Skills KitのGet Startedをクリックします。

Skillの一覧画面が表示されるので、Add a New Skillをクリックします。
基本情報を入力する画面が表示されたら、Skill TypeでSmart Home Skillを選択して、その他の必要な情報を入力します。

登録が完了すると、Interaction Modelに進みますが、Smart Home Skillの場合は、自分でこのモデルを作成する必要はありません。

このあとの手順でLambdaファンクションのヒモ付を登録するので、一旦Skill Informationに戻ります。
このSkillのApplication Idが表示されているので、これを元にLambdaファンクションの登録に進みます。

空のLambdaファンクションを登録

2016/10月現在は、Skillの作成は以下のリージョンでしか行なえません。(イギリス、ドイツの対応でEUのリージョンが追加されましたね)

  • us-east-1
  • eu-west-1

Lambdaの登録をすすめるとBlue Printの選択が出てくるので、検索のところにalexaと入力して、Smart Home Skillのblue printを選択します。

先程Skillを登録した際に発行されたApplication Idを入力します。
Enable Trigerにもチェックを付けます。

適当な名前を付けてます(現状Smart Home Skillのblue printはnode.jsしか無いので、RuntimeはNode.jsを利用します)

Lambdaファンクションに付与するRoleを作成します。

わかりやすい名前を付け、AllowをクリックしてRoleを作成します。

今作成したRoleを選択し、Lambdaファンクションの作成を完了させます。

Lambdaファンクションが作成されると、画面の右上にARNが表示されるので、この値をコピーします。

Skillの登録(2)

Skillから呼び出すLambdaファンクションの準備ができたので、Skillの設定画面に戻って、続きを入力します。
Configurationをクリックして、North Americaにチェックを付けるとARNを入力するところが表示されるので、先程作成したLambdaファンクションのARNを入力します。

Acount Linkingの各項目を入力します。

項目名 説明
Authorization URL https://www.amazon.com/ap/oa?redirect_uri=https://pitangui.amazon.com/api/skill/link/hogefuga OAuthプロバイダでLWAを利用しているので、そのエンドポイントとRedirect URLsに書かれているURL一つをredirect_uri=に指定。lambdaがUSなのでUSがいいのかな
Client Id LWAので発行されたClient Id
Domain List オプション Authorization URLがフェッチするドメイン(最大15個まで)
Scope profile LWAで取得できる情報の指定。customer profile
Authorization Grant Type Auth Code Grant Smart Home Skilsの場合はAuth Code Grantが必須です
Access Token URI https://api.amazon.com/auth/o2/token LWAを利用しているので
Client Secret LWAので発行されたClient Secret
Client Authentication Scheme HTTP Basic (recommended) 変更しないでこのまま
Privacy Policy URL このSkillを利用するに当たってのプライバシーポリシーが書かれているURL(LWAで登録したのと同じになるかな)

Saveボタンをクリックして入力した内容を登録します。

Login with Amazon(LWA)の設定更新

Skillの登録を進めた際に、Redirect URLsにリダイレクト先のURLが表示されたかと思いますが、このURLをLWA側の許可リストに追加します。
Security Profileの画面でWeb Settingsをクリックして、Allowed Return URLsにSkillsの画面で指定したリダイレクトURLを入力します。

ここまで登録したところでやっとSmart Home Skillを利用するための認証&認可の動作確認ができるようになります。

動作確認

http://alexa.amazon.com/spa/index.html
Alexaのポータルにログインして、作成したSkillの画面からYour Skillsを選択します。
すると、今回作成したSkillが表示されます。(Account linkingが必須と表示されてますね)

Skillの詳細を表示するとSkillを有効にできるので、Enable Skillをクリックします。

Amazon.comの認証画面が表示されました。

ログインすると提供する情報のリストが表示されます。
この画面にプライバシーポリシーのリンクが表示されますね。

作成したSmart Home SkillがAlexaで利用できるようになりました!

Alexaの画面に戻ると、デバイスを検索するかポップアップが表示されます。

試しに探してもらいましょう。
まだLambdaの方を全然コーディングしていないので、何も見つからないけど。。
Amazon EchoやAlexa Voice Serviceを実装したデバイスからも、Alexa, Discover Devicesと話しかけて検索することも可能です。

Lambda側のMonitorを見ると、呼び出されたのがわかります。

以上で、Smart Home Skillの登録が完了しました。
とは言ってもまだこれでは家の中のデバイスを操作することは出来ません。
Skillの本体であるLambdaファンクションと実際に操作するデバイスのセットアップが必要です。

動くLambdaファンクションの作成

Smart Home Skillのリクエストの種類

Smart Home skillでは、デバイスを操作するためのInteraction Modelが元から組み込まれているため、操作するためのリクエスのと種類が決まっています。

代表的なものを幾つか解説したいと思います。

DiscoverAppliancesRequest

Alexa, discover my smart home devicesAlexa, discover devices と話しかけると、デバイスの検出のためにLambdaファンクションへ送られてくるリクエストです。

{
    "header": {
        "messageId": "aaaa-bbbb-cccc-dddd-eeee",
        "name": "DiscoverAppliancesRequest",
        "namespace": "Alexa.ConnectedHome.Discovery",
        "payloadVersion": "2"
    },
    "payload": {
        "accessToken": "OAuth Token"
    }
}

このように送られてくるリクエストはheaderpayloadの組み合わせとなっています。
payloadに含まれているのはOAuthプロバイダと認可の手続きを行った際に発行されたtokenですので、このtokenを使って誰からのリクエストなのかを判別します。
今回はLogin with Amazonを利用したので、Amazon APIのエンドポイントに問い合わせると、このリクエストを送ってきたユーザの情報を取得することが出来ます。

curl -H 'x-amz-access-token:<your token>' https://api.amazon.com/user/profile

このリクエストの戻り値に検出したデバイスの情報 DiscoverApplianceResponse として以下のようなフォーマットで返します。

{
  "header": {
    "payloadVersion": "2",
    "namespace": "Alexa.ConnectedHome.Control",
    "name": "DiscoverAppliancesResponse",
    "messageId": "aaaa-bbbb-cccc-dddd-ffff"
  },
  "payload": {
    "discoveredAppliances": [
      {
        "friendlyDescription": "some awsome light description.",
        "modelName": "my-device-model-1",
        "additionalApplianceDetails": {
            "SpecialInfo1": "something special description"
        },
        "version": "1",
        "manufacturerName": "sparkgene.com",
        "friendlyName": "awsome light",
        "actions": [
          "turnOn",
          "turnOff"
        ],
        "applianceId": "my-device-unique-id",
        "isReachable": true
      }
    ]
  }
}

discoveredAppliancesには検出したデバイスすべてを列挙します。
actions に指定されているのが、このデバイスに対して行える操作です。

  • incrementTargetTemperature
  • decrementTargetTemperature
  • setPercentage
  • incrementPercentage
  • decrementPercentage
  • turnOff
  • turnOn

TurnOnRequest

Alexa, turn on the awsome light と話しかけると送られてきます。

{
  "header": {
    "payloadVersion": "2",
    "namespace": "Alexa.ConnectedHome.Control",
    "name": "TurnOnRequest",
    "messageId": "aaa-bbb-ccc-ddd-eee"
  },
  "payload": {
    "appliance": {
      "additionalApplianceDetails": {},
      "applianceId": "my-device-unique-id"
    },
    "accessToken": "OAuth Token"
  }
}

このリクエストの戻り値に検出したデバイスの情報 TurnOnConfirmation として以下のようなフォーマットで返します。

{
  "header": {
    "payloadVersion": "2",
    "namespace": "Alexa.ConnectedHome.Control",
    "name": "TurnOnConfirmation",
    "messageId": "aaa-bbb-2222-ddd-1111"
  },
  "payload": {}
}

TurnOffRequest

Alexa, turn on the awsome light と話しかけると送られてきます。

{
  "header": {
    "payloadVersion": "2",
    "namespace": "Alexa.ConnectedHome.Control",
    "name": "TurnOffRequest",
    "messageId": "aaa-bbb-ccc-ddd-eee"
  },
  "payload": {
    "appliance": {
      "additionalApplianceDetails": {},
      "applianceId": "my-device-unique-id"
    },
    "accessToken": "OAuth Token"
  }
}

このリクエストの戻り値に検出したデバイスの情報 TurnOffConfirmation として以下のようなフォーマットで返します。

{
  "header": {
    "payloadVersion": "2",
    "namespace": "Alexa.ConnectedHome.Control",
    "name": "TurnOffConfirmation",
    "messageId": "aaa-bbb-2222-ddd-1111"
  },
  "payload": {}
}

サンプル

実際にデバイスの検出から、照明のOn/OffができるSkillを用意してみました。(Lambdaとデバイスは繋がっていないので、照明は操作されません)

Alexa Smart Home Skill Sample

ソース

サンプルソースはPythonで書いてます。上記の手順では、LambdaファンクションのruntimeでNode.jsを選択していますが、runtimeをPython 2.7に変更し、Handlerにlambda_function.lambda_handlerと入力すれば、Pythonで動かすことが出来ます。

まとめ

Smart Home Skillを利用することでInteraction Modelの設計が不要であったり、Alexaでの発話が自然になります。
しかし、このSkillはデバイスメーカーが自社のデバイスをAlexaを使って操作するイメージ(と思ってる)であるため、ユーザの登録やデバイスの管理といった仕組みを自分で作る必要があります。

とは言え、個人で家のデバイスをコントロールするのであれば、Lambdaファンクションにデバイスとの連携を直接書いてしまえばいいのかなと思います。(もちろん、公開できませんけどね)

参考リンク