経緯
Amazon Echoを買ったので、自分でも面白いものが作れないか調べたところ、公式の解説がとてもよくまとまっている。
これなら簡単にできるな・・・ということで、練習問題を少し改造して、最寄り駅の次発、次々発、次々々発の電車の時刻を教えてくれるSkillを自作してみた。
時刻表もベタ打ちだし、かなりイケてない作りだけれど、とりあえず使えるはず。
デモ動画
Skillの動作
「Alexa、時刻表で平日の電車を教えて」
「Alexa、時刻表で休日」
「Alexa、時刻表で休日の時刻表」
等の声掛けをすると、
「"平日の時刻表です。次は6時45分,1分,14分です"」
と、現在時刻から10分後以降の電車を3つ列挙して教えてくれる。
私はほぼ乗る電車が確定しているので、路線については決め打ちだが、少し改造するだけで、「○○方面への時刻表を教えて」等のアップグレードも可能。
前提
本説明は、上記Amazonのチュートリアルの入門#1,#2を実行、理解できていることを前提とする。
つまり、
・ AWS Lambdaへの登録
・ Amazon Developerアカウントへの登録
・ スキルを登録するまでの流れ
については説明しない。
Skillの作り方
アレクサのスキルを作るためには、以下2つの作業が必要となる。以降、これらを順に説明していく。
1.AWS Lambdaスクリプトの作成
(サーバーサイドのプログラムを設定、今回はPythonを使用)
2.Alexaの会話フローの作成
(Alexaにどのように声掛けをするか、音声からどのような情報を取得し、サーバーに投げるかを設定)
1. AWS Lambdaスクリプトの作成
まずはサーバーサイドのプログラムを登録する。
WebブラウザでAWSマネジメントコンソール( https://console.aws.amazon.com/ )にアクセス、ログインし、画面左上の「AWSサービス」のテキストボックスに「lambda」と入力し、表示される候補から「Lambda」をクリックする。
AWS Lambdaの初期画面が表示されたら、「関数の作成」を押し、先のチュートリアル同様、求められた項目に入力していく。ランタイムの項目のみ、最初は「Node.js 6.10」となっているが「Python3.6」としておく。
その上で、スクリプト記載画面まで行ったら、以下を入力する。(住まいがわかってしまうので、時刻表の中身は変更済み)
やっていることはごく簡単。スクリプトを追えばすぐに理解できるはず。
jikoku = [,]の2次元配列に対し、時刻表を教えてほしい電車の発車時刻をベタ打ちすれば、様々な環境で使える。
import time from datetime import datetime, timedelta, timezone def train(jikoku,time): nextTrain = [0,0] for i in jikoku[time.hour]: if i >= time.minute: nextTrain = [time.hour,i] break if nextTrain[0] == 0 and nextTrain[1] == 0: for i in jikoku[time.hour+1]: if i >= 0: nextTrain = [time.hour+1,i] break return nextTrain def lambda_handler(event, context): if event['request']['type'] == "IntentRequest": intent = event['request']['intent'] value = intent['slots']['DayType']['value'] else: if (jsttime.weekday() >= 5): value = "休日" else: value = "平日" # タイムゾーンの生成 JST = timezone(timedelta(hours=+9), 'JST') jsttime = datetime.now(JST) + timedelta(minutes=10) if value == '休日' or value == '祝日': jikoku = [ [8,16,25],#0, [],#1, [],#2, [],#3, [52],#4, [10],#5, [3,8],#6, [1,12,55],#7, [2,13,30],#8, [2,13],#9, [2,13],#10, [2,13],#11, [2,13],#12, [2,13],#13, [2,13],#14, [2,13],#15, [2],#16, [2],#17, [2],#18, [2],#19, [2,10],#20, [2,10],#21, [4,50],#22 [4,51]#23 ] else: jikoku = [ [8,16,25],#0, [],#1, [],#2, [],#3, [52],#4, [10],#5, [3,8],#6, [1,12,55],#7, [2,13,30],#8, [2,13],#9, [2,13],#10, [2,13],#11, [2,13],#12, [2,13],#13, [2,13],#14, [2,13],#15, [2],#16, [2],#17, [2],#18, [2],#19, [2,10],#20, [2,10],#21, [4,50],#22 [4,51]#23 ] nextTrain = [[0,0],[0,0],[0,0]] nextTrain[0] = train(jikoku,jsttime) nextTrain[1] = train(jikoku,datetime(jsttime.year,jsttime.month,jsttime.day,nextTrain[0][0],nextTrain[0][1]+1,0)) nextTrain[2] = train(jikoku,datetime(jsttime.year,jsttime.month,jsttime.day,nextTrain[1][0],nextTrain[1][1]+1,0)) if value == '平日': day = "平日の時刻表です。次は" + str(nextTrain[0][0]) + "時" + str(nextTrain[0][1]) + "分," + str(nextTrain[1][1]) + "分," + str(nextTrain[2][1]) + "分です" elif value == '休日' or value == '祝日': day = "休日の時刻表です。次は" + str(nextTrain[0][0]) + "時" + str(nextTrain[0][1]) + "分," + str(nextTrain[1][1]) + "分," + str(nextTrain[2][1]) + "分です" else: day = "平日の時刻表です。次は" + str(nextTrain[0][0]) + "時" + str(nextTrain[0][1]) + "分," + str(nextTrain[1][1]) + "分," + str(nextTrain[2][1]) + "分です" response = { 'version': '1.0', 'response': { 'outputSpeech': { 'type': 'PlainText', 'text': day } } } return response
2. Alexaの会話フローの作成
次に、Alexaの会話フローを作成する。
まずは、以下の開発者コンソールから適当な名前でスキルを登録する。
Amazon Developer Sign In
次に、対話モデルのインテントスキーマの設定する。
{ "intents": [ { "slots": [ { "name": "DayType", "type": "LIST_OF_DAY_TYPE" } ], "intent": "GetNewFactIntent" } ] }
カスタムスロットタイプには平日・休日の種別を設定する。
タイプ: LIST_OF_DAY_TYPE 値:平日、祝日、休日
サンプル発話は以下の通り
GetNewFactIntent {DayType} の時刻表 GetNewFactIntent {DayType} GetNewFactIntent {DayType} の時刻表を教えて GetNewFactIntent {DayType} の次の電車は GetNewFactIntent {DayType} の電車
あとは、先のチュートリアル通りにLambdaとスキルを紐付けたら完成。
試しにシミュレータで「平日は?」等を入力してみると、「平日の時刻表です。次は7時32分,55分,5分です"」等と帰ってくることがわかる。
感想
まとめてみると長いけれど、基本はサンプルから少し改造するだけでOK。買った翌日に試して、2~3時間程度でこの程度のことができます。
簡単なPythonプログラムが書ければ、結構日常生活に役立つSkillが作れるんじゃないかな、と思いました。
後はアイディア勝負・・・・かな。