経緯
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が作れるんじゃないかな、と思いました。
後はアイディア勝負・・・・かな。