「駅すぱあとWebサービス」をPepperで使えるようにしてみる

2016年10月26日水曜日 kwmt

こんにちはkwmtです。

当社にはPepperが入社していて、毎日受付に立ってお客様をお出迎えしています。
私は働き者のPepperにもっといろいろな仕事ができるように毎日いじる仕事をしています。

受付でお出迎え中のPepper



今日は「駅すぱあとWebサービス」から駅名データを取得するところを作ったら思ってたよりも簡単だったのでここで紹介してみたいと思います。
※使用したPepperのモデルはPepper for Biz、SDKはChoregraphe

Choregrapheで基本的な動きが登録されたボックスを利用できるので、積み木のような感覚で動きを登録しちゃいます。
簡単なことであればコードを全く書かなくても動いてくれます。楽っ!
90日間限定の試用版とありますが、アトリエ秋葉原のブログを参考にして無制限ライセンスに変えることができるので、興味があれば是非試してみてください。
ずっと無料で使えて、プレビュー画面に仮想のPepperもいるので便利ですよ。

今回利用したボックスはText Edit、Say Text。そしてAPIの処理用に新規で作成したボックスを1つ。新規で作成したボックス以外は手を加えていない状態です。(新規のボックスの名前はAPI Callとしました)

Choregrapheのプロジェクト

全体的な流れはText Editに入力されたキーワードで駅名を検索。検索した結果をSay Textを使って読み上げる感じ。
入力はテキストにしていますが、Speech Reco.ボックスを使って対話から入力すると実用的かも。
APIのパラメータで駅の種類を選択できるので、stationTypeという変数を作成してボックスの設定で調整できるようにしてみました。

設定から駅の種別を選択する

作成したAPI Callボックスですが複雑な事は全くしていません。
Text Editの入力値がAPI Callボックスの「onInput_onStart」の第二引数に入るので、
APIを参照するURL文字列に追加し、レスポンスを取得し編集して出力しています。

「onInput_onStart」関数は以下のようなコードになっています。

    def onInput_onStart(self, param):
        import urllib2, json
        stationName = []
        result = ""
        # もしstationTypeでall以外が選択されていれば、typeとしてURLに追加する
        if self.getParameter("stationType") == "all":
            url = "http://(APIのURL)/v1/json/station/light?key=(API認証Key)" + "&name=" + param
        else:
            url = "http://(APIのURL)/v1/json/station/light?key=(API認証Key)" + "&name=" + param + "&type=" + self.getParameter("stationType")
        response = urllib2.urlopen(url)
        root = json.loads(response.read())
        results = root['ResultSet']
        if "Point" in results:
            points = results["Point"]
            if isinstance(points,dict):
                # Point要素が1つだった場合(連想配列)
                stationName.append(points["Station"]["Name"].encode('utf8'))
            else:
                # Point要素が複数だった場合(配列)
                for point in points:
                    stationName.append(point["Station"]["Name"].encode('utf8'))
        # 結果の出力
        if len(stationName) == 0:
            result = "候補がありません"
        else:
            result = ",".join(map(str,stationName))
        self.onStopped(result)

ボックスの変数にしたstationTypeはself.getParameterを使って取得しています。
「all」の時はパラメータが不要なので今回はifで切り分けました。

ソースの後半はjson形式で返却された値を取得して駅名を取得しています。
値の取得方法が違うとエラーになってしまうので、以下の点に気をつけて条件分けしました。

・候補があるかどうか
・単一のものか
・複数存在するか

複数存在する場合はCSV形式で渡すようにしていますが、ここはアプリケーションによって使いやすい形式に置き換えましょう。
結果はご覧の通り、ヴァル研究所社員が大好きな高円寺を含む駅が取得できました。

ヴァル研究所の社員が大好きな「高円寺」での実行結果

もしかしたらもっと綺麗に書く方法があるかもしれませんが、実はPython始めたばかりなので許してください。

今回のコードにはエラー時の処理は含めていない最低限のものですが、
データを取得するだけであれば数行で書けるので、いろいろと連携できれば良いなと思います。