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 ID
とClient 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 devices
や Alexa, discover devices
と話しかけると、デバイスの検出のためにLambdaファンクションへ送られてくるリクエストです。
{
"header": {
"messageId": "aaaa-bbbb-cccc-dddd-eeee",
"name": "DiscoverAppliancesRequest",
"namespace": "Alexa.ConnectedHome.Discovery",
"payloadVersion": "2"
},
"payload": {
"accessToken": "OAuth Token"
}
}
このように送られてくるリクエストはheader
とpayload
の組み合わせとなっています。
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とデバイスは繋がっていないので、照明は操作されません)
ソース
サンプルソースはPythonで書いてます。上記の手順では、LambdaファンクションのruntimeでNode.jsを選択していますが、runtimeをPython 2.7
に変更し、Handlerにlambda_function.lambda_handler
と入力すれば、Pythonで動かすことが出来ます。
まとめ
Smart Home Skillを利用することでInteraction Modelの設計が不要であったり、Alexaでの発話が自然になります。
しかし、このSkillはデバイスメーカーが自社のデバイスをAlexaを使って操作するイメージ(と思ってる)であるため、ユーザの登録やデバイスの管理といった仕組みを自分で作る必要があります。
とは言え、個人で家のデバイスをコントロールするのであれば、Lambdaファンクションにデバイスとの連携を直接書いてしまえばいいのかなと思います。(もちろん、公開できませんけどね)