chakokuのブログ(rev4)

日々のごった煮ブログです

俺HEMSの開発、、仕様変更、LINEボット経由でエアコンを操作できないか?

Pythonで作ったEchonetLiteパケット送信プログラムも動くようになり、最低限のプロパティは取得できるようになった。勝手にエアコン操作したら家族から怒られるので、プロパティへの設定はやっていないけど、多分設定したらOn/Offや温度変更ができると思われる。おおよそエアコン制御が片付きそうなので、次のお題は、宅外から室内のエアコンを操作する、、ホームエレクトロニクスというか、今風に言えば俺HEMSを作ってみようと。
おおよその構成は左の絵のように考えていて、エアコンを操作するには自宅に制御装置が必要で、ラズパイなんかを使ってHomeGatewayを設置する。スマフォに入れたエアコン操作アプリと自宅内のHomeGatewayはFireWallがあるので直接通信できないので、、仲介役としてクラウド上に仲介サーバを設置する。今風の技術ならMQTTとかWebSocketで宅内のHomeGatewayとサーバ間は連携させるのが良いのだろう。

HomeGatewayとか、クラウドのWebアプリはまぁ力業のやっつけ仕事*1でどうにでもなるけど、厄介なのはスマフォアプリであった。スマフォのアプリ開発は自分の中でもかなりプアな領域なのでいろいろ本を買ってiOSでアプリを作れるようにと勉強を始めていた。

が!!わざわざエアコン操作アプリ入れる!?というアプリ導入の壁があって、普通の人が使っているスマフォアプリといえばLINEだろうと思い、また幸いにLINEにはメッセージ送受信用のAPIがあるらしく、だったら、ボットに向けて、「エアコンON」とかチャット(トーク)すると、「1Fリビングエアコン電源Onしました。設定温度は25℃、ただ今の室内温度は32℃です」とか返事してくれたらいいんじゃないかと思うに至った。この構想に基づく新アーキが左の図。LINEサーバが途中に挟まっています。が、、LINEのAPI(Messaging API)がよくわからず、また勉強なのであった。

■追記
少し調べると、MessagingAPIが提供されており、PushAPI、またはReplyAPIの2種類が使えるらしい。REST形式でPOSTするのだろうけど、分からないのは、、Push先の指定とか、グループラインにどうやってBOTが参加するのか。。といった点か。

■追記
署名検証ができていないのでセキュリティ的には不十分ですが、GoogleAppEngine上で動作するLINE用ボットを作ってみた。多くの人がまず作るオウム返しボットのGAE版というか(左がエアコンボットが返事している例)。
仕組みとしては、LINEでトークされるとLINEサーバに設定したWebhook URLのURLが呼び出されて、GAE上のWebアプリがキックされる。で、その内容は以下のようなもので、POSTされたJSONをばらして、必要な部分を加工して、LINEのReplyAPIを呼び出すという動作をする。
一応WebServer側のひな型ができたので、、トークされた文字列を解釈して、エアコン制御に関する文字列を抽出してHomeGatewayと通信(スマフォからの要求をHomeGatewayに伝達)するようにすれば、宅内のエアコン制御ができるはず。。
今は個人だけでトークしてるのだけど、エアコン制御ボットにするには、家族のグループラインに、制御ボットを招待する必要があるのではと思っています。この辺りもよくわからず。。

@app.route('/lineapi/webhook',methods=['POST','GET'])
def webhook():
    if request.method == 'POST':
       msg = 'POST->'
       msg += ",headers:" + str(request.headers) + '<br>\n'
       if not request.json:
           msg += 'bye'
           return render_template('webhook.html',message=msg,title="webhook")

       import json
       import urllib
       import urllib2

       msg += ",json:" + str(request.json) + '<br>\n'
       message_text0 = request.json['events'][0]['message']['text']
       message_token0 = request.json['events'][0]['replyToken']
       msg += 'text:' + message_text0 + ","
       msg += 'id:' + message_token0 + "<br>\n"

       # reply message
       URL = 'https://api.line.me/v2/bot/message/reply'
       CHANNEL_ACCESS_TOKEN ='!!! set your token !!!'

       headers = {'Content-Type' : "application/json" , 'Authorization' : "Bearer " + CHANNEL_ACCESS_TOKEN }
       message = 'Thank you, Nice message[' + message_text0 + ']!!'
       body = {"replyToken" : message_token0 ,
                "messages" : [{"type" : "text" , "text" : message}]}
       json_data = json.dumps(body).encode("utf-8")

       try:
            req = urllib2.Request(URL,json_data,headers)
            res = urllib2.urlopen(req)
            response = res.read()
       except urllib2.URLError as e:
            msg += str(e)
            msg += str(e.readlines())
       except urllib2.HTTPError as e:
            msg += str(e)
            msg += str(e.readlines())
       else:
            msg += "OK??"

    else:
       msg = 'GET->'
       msg += str(request.args)

    return render_template('webhook.html',message=msg,title="webhook")


■ご参考URL
LINE Messaging API説明ページ
https://business.line.me/ja/services/bot

API開発者向けサイト(Python版)
https://devdocs.line.me/ja/?python#

line/line-bot-sdk-python
https://github.com/line/line-bot-sdk-python

*1:セキュリティ設計は最低限。漏らさずキッチリやるのは非常に難しい