LINEで自作IoTデバイス[スマートロック・リモコン]を操作する(市販品も可) |じょるブログ

じょるブログ

電子工作やプログラミング関連の情報を発信している技術系ブログ

電子工作 web ラズベリーパイ

LINEで自作IoTデバイス[スマートロック・リモコン]を操作する(市販品も可)

投稿日:

   

ラインから手軽にスマートデバイスを操作する方法について解説します。

この記事ではラズパイで自作したスマートデバイスをラインで操作する方法について解説しますが、IFTTT経由で操作できるものであれば市販のスマーロックやスマートリモコンなども操作可能です。

今回作成するのはこのようなLINE BOTです。

初心者でもこの記事で紹介する作成手順で行えば1時間ほどでスマートデバイスとLINEを連携することが可能です。

LINE BOT は GAS(google apps script) で作成します。

   

必要なもの

  • スマートデバイス(今回はラズパイ)
    ※市販のスマートデバイスでも可

必要なものはたったこれだけです。

LINE BOTのサーバーもGASで作るのでgoogleアカウントがあれば作成できます。

  

  


Raspberry Pi4 ModelB 4GB ラズベリーパイ4 技適対応品

   

概要

ラインでスマートデバイスを操作する流れは、

  • GASでMQTTブローカーであるbeebotteにWEBリクエストを送信
  • beebotteから送られてきたデータをラズパイで動かしているpythonのMQTTサブスクライバープログラムで取得
  • そのデータを読み取り、操作するデバイスとアクションを判定し、ラズパイで動かす

といった感じです。後で詳しく説明します。

    

ちなみに市販のスマートデバイスを操作する場合は、

  • GASでIFTTT(webhook)にWEBリクエストを送信
  • IFTTT経由でスマートデバイスを操作

といった感じでできます!

  

導入手順

  • LINE BOTの作成
  • LINEのリッチメニューの実装
  • IoTデバイスとの連携

     

・LINE BOTの作成

今回は GAS(google app script)LINE message APIを使って、LINE BOTを作成していきます。

GASを使用することで20分ほどでLINE BOTを作成 することができます。

LINE BOTの作成方法については以下の記事をご覧ください。

   

・LINEのリッチメニューの実装

リッチメニューとは・・

リッチメニューとは 、よく公式アカウントなどのトーク画面に表示される↑このような メニューのことです。

ちなみにこのリッチメニューでは、ボタンを押した際に、

  • 登録済みのメッセージが送信される
  • 指定済みのURLへ飛ぶ
  • クーポン画面を表示させる
  • ショップカード画面を表示させる

というような動作を行うことができます。

今回はボタンを押したら、

  • 登録済みのメッセージが送信される

という機能を使います。

   

リッチメニューの実装

1. ラインアカウントマネージャーにアクセスします。

ログインすると先ほど作成したBOTのアカウントが表示されるので、クリックします。

    

2. 左サイドバーの中のリッチメニューをクリックします。

    

3. 右上の作成をクリックします。

   

4. リッチメニューの表示設定

リッチメニューの作成画面が表示されたら、

  • タイトル(ライン管理画面に表示されるリッチメニューの名前)
  • 表示期間(リッチメニューを表示させる期間)
  • メニュバーテキスト(リッチメニューの下に表示される名前)

を記入します。

  

5. コンテンツ設定

「コンテンツ設定」→「テンプレートを選択」をクリックすると、以下のようなポップアップが表示されるので、リッチメニューのレイアウトを選択します。

   

「画像を作成」をクリックすると、手軽にリッチメニューのアイコンを作成できます。

今回はリッチメニューをタップしたら自動で登録済みのテキストを送信するという機能を使用するので、「タイプ」では「テキスト」を選択し、その下の入力欄には送信するテキストを指定します。

   

6. 「保存」をクリックする。

最後に画面右上の「保存」をクリックしたら、リッチメニュー作成完了です。

作成したラインアカウントを開いてみると、リッチメニューが反映されているはずなので、リッチメニューをタップしてテキストが自動送信されるか確認してください。

※補足

今回はラインオフィシャルアカウントマネージャーからリッチメニューを作成しましたが、特定のフォーマットのjsonデータを送信することでもリッチメニューの作成は可能です。この方法で設定を行うと任意の範囲をタップ可能になり、タップ可能な場所も6個以上設定できるようになります。

   

・IoTデバイスとの連携

連携の概要

次にIoTデバイスとの連携を行っていきます。

先ほど作成したリッチメニューでアイコンをタップすると、設定済みのテキストが送信されるので、LINE BOTのサーバー側であるGASでその送信されてきたテキストを読み取り、そのテキストに応じた処理を行うようなプログラムを作成します。

「そのテキストに応じた処理 」というのはMQTTブローカーであるbeebotteにテキストに応じたデータを送信するという処理です。

   

例えば、「エアコンON」というアイコンがタップされると「エアコンつけて」と自動で送信されます。それをGASで受信し、 beebotteに

{"data":[{"terminal":"LINE","device":"エアコン","action":"オン"}]}

といったようなデータを送信します。 beebotteはMQTTサブスクライバーであるラズパイにそのデータを転送し、ラズパイでスマートデバイスを操作(赤外線LEDでエアコンをつける)するという感じです。

 

市販のスマートデバイスを操作する場合は、データの送信先を beebotte ではなく、IFTTTのwebhook 宛にします。

https://maker.ifttt.com/use/fdfaneonjnkjean #送信先の例

そして送るデータは

{"value1":"LINE","value2":"エアコン","value3":"オン"}

というようにします。

   

beebotteの設定

まず、beebotteの設定を行います。

beebotte の設定方法についてはこちらの記事に詳しく書いてあるので参照してください。

  

LINE BOTの編集

次に、「LINE BOTの作成」で作成したGASのプログラムを変更して、特定のメッセージが来たら特定の処理をさせるようにします。

プログラムを以下のように書き変えて、 「Project version」を「new」として公開してください。

function doPost(e) {
  var replyToken= JSON.parse(e.postData.contents).events[0].replyToken;
  if (typeof replyToken === 'undefined') {
    return;
  }
  
  var url = 'https://api.line.me/v2/bot/message/reply';
  var channelToken = 'diangjrnganeje/gaekannogaga/XXXXXXXXXXXXX/145/a=';

  var receive_message = JSON.parse(e.postData.contents).events[0].message.text;  
  var reply_text = receive_message + "\n" + "に対応するアクションはありません" + "\n" + "実行可能なメッセージを確認するには\"ヘルプ\"と言ってみてください";
  
  if(receive_message == "エアコンつけて") {
    beebotte_publish("air_con","on");
    reply_text = "エアコンをつけます";
  } else if(receive_message == "エアコン消して") {
    beebotte_publish("air_con","off");
    reply_text = "エアコンを消します";
  }
  
  if(receive_message == "鍵開けて") {
    beebotte_publish("lock","open");
    reply_text = "玄関の鍵を開錠します";
  } else if(receive_message == "鍵閉めて") {
    beebotte_publish("lock","close");
    reply_text = "玄関の鍵を閉錠します";
  }
  
  if(receive_message == "リビングの電気つけて") {
    beebotte_publish("room_light","on");
    reply_text = "リビングの電気を操作します";
  } else if(receive_message == "玄関の電気つけて") {
    beebotte_publish("entrance_light","off");
    reply_text = "玄関の電気を操作します";
  }
  
  if(receive_message == "ヘルプ") {
    reply_text = "実行可能なコマンドは以下の通りです。\n" + 
                 "・エアコンつけて\n" + 
                 "・エアコン消して\n" + 
                 "・鍵開けて\n" +
                 "・鍵閉めて\n" +
                 "・リビングの電気つけて\n" +
                 "・玄関の電気つけて";
  }
  
  var messages = [{
    'type': 'text',
    'text': reply_text,
  }];
  
  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + channelToken,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
      'messages': messages,
    }),
  });
  
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}



function beebotte_publish(device,action) {
  var headers = {
    "Content-Type": "application/json"
  };
  var json = `{"data":[{"terminal":"LINE","device":"${device}","action":"${action}"}]}`;
  var options = {
    "headers": headers,
    "method": "post",
    "payload": json
  };
  UrlFetchApp.fetch("https://api.beebotte.com/v1/data/publish/チャンネル名/トピック名?token=token_XXXXXXXXXXXXX", options);
}

※channelTokenにはラインボットのトークンを、
token_XXXXXXXXXXXXXには、beebotteのトークンを、
チャンネル名/トピック名 には beebotteのチャンネル名とトピック名を入力してください。

  

Pythonプログラムの作成

最後にラズベリーパイ側で実行するプログラムを作成します。

プログラムはこんな感じです。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
#smartremocon.py
 
import paho.mqtt.client as mqtt
import subprocess
import json
from time import sleep
 
HOST = 'mqtt.beebotte.com'
PORT = 8883
CA_CERTS = 'mqtt.beebotte.com.pem'
TOKEN = 'token_xxxxxxxxxxxxxxxxxx'    #Beebotteで作成したチャンネルのトークンを入力
TOPIC = 'RaspberryPi/SmartRemocon'    #Beebotteで作成したトピック名を入力
 
def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))
 
def on_disconnect(client, userdata, flags, respons_code):
    print("Unexpected disconnection.")
    client.loop_stop()
 
 
def on_message(client, userdata, msg):
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]
    
    
    # control air_con
    list_summer=[5,6,7,8,9,10]
    list_winter=[11,12,1,2,3,4]
 
    if (data["device"] == 'air_con'):
        if   (data["action"] == 'on'):
            date = datetime.datetime.now()
            if date.month in list_summer:
                print(date.month,"月 ","冷房をつけます")
                subprocess.call(["python3", "irrp.py", "-p", "-g17", "-f", "codes", data["device"]+":"+"on"])
 
            elif date.month in list_winter:
                print(date.month,"月 ","暖房をつけます")
                subprocess.call(["python3", "irrp.py", "-p", "-g17", "-f", "codes", data["device"]+":"+"on-winter"])

 
    # control ps4
    elif (data["device"] == 'ps4'):
        if (data["action"] == 'on'):
            subprocess.call(["sudo", "ps4-waker"])
        if (data["action"] == 'standby'):
            subprocess.call(["sudo", "ps4-waker", "standby"])
        if (data["action"] == 'torne'):
            subprocess.call(["sudo", "ps4-waker", "start", "CUSA00442"])
        if (data["action"] == 'primevideo'):
            subprocess.call(["sudo", "ps4-waker", "start", "CUSA03099"])
        if (data["action"] == 'youtube'):
            subprocess.call(["sudo", "ps4-waker", "start", "CUSA01065"])
 
 
if __name__ == '__main__':
    client = mqtt.Client()
    client.on_connect = on_connect
    client.on_disconnect = on_disconnect
    client.on_message = on_message
    client.username_pw_set('token:%s' % TOKEN)
    client.tls_set(CA_CERTS)
    client.connect(HOST, PORT)
    client.subscribe(TOPIC)
    client.loop_forever()

※tokenには、beebotteのトークンを、
 topic には beebotteのチャンネル名とトピック名を入力してください。

このプログラムを実行させるには beebotte の証明書やモジュールのインストールが必要です。

詳しくはこちら↓の記事を参照してください。

    

     

以上で完成です!

今回は市販のスマートデバイスをラインで操作する方法については軽くしか説明しませんでしたが、詳しく知りたい方はTwitterやこの記事にコメントをくれればできる限り対応します。

分かりにくいところなどありましたらご指摘ください!

google ads




google ads




-電子工作, web, ラズベリーパイ

執筆者:


  1. より:

    とても面白いです。自分でもやってみたくなりました。

    1つ気になったのですが、もしもLINE BotのIDを誰かに知られてしまった場合、その人が部屋のエアコンなどを操作できてしまうことになりませんか?

    知識不足故に的はずれなことを言っていたら申し訳ありません。LINE Botは非公開設定にできない仕様なので気になりました。

    • joruji より:

      コメントありがとうございます!
      この記事ではセキュリティー面についてはあまり深く考えていません。
      あくまで”こんな使い方があるよ”というようなことを紹介するために書かせていただいており、誰でも簡単に実装できるようにセキュリティに関する部分は省略しています。
      ですのでセキュリティ面も考えて実装したい場合は、もう少し工夫する必要があります。

      仰る通り、LINE BotアカウントのIDを何らかの方法で知られてしまった場合、誰でもアクセスすることができてしまいます。
      これに対する対策法のひとつとしてuseridを使用する方法があります。
      useridは個人のLINEアカウント一つ一つに固有に割り当てられているものであり、

        
      var userid = JSON.parse(e.postData.contents).events[0].source.userId;
      

      とすることで、LINE Botアカウントに対してメッセージを送信した人のuseridを取得することができます。
      これを利用して自分のuseridを取得し、自分以外のuseridからのアクセスの場合は拒否するようにGASプログラムを作成することで、第三者からスマートデバイスを操作されることを防ぐことができます。
      (ただし、もちろんこれだけではハッキングされたりした場合は防げない可能性はあります。あくまで通常の方法でのアクセスから防げるようになるだけです。)

      また、セキュリティに関して、Messaging APIの開発ガイドラインでは、リクエストがなりすましではなくLINから送られたことを確認するために署名を検証することが推奨されています。
      ですので、本来ならば署名の確認処理も実装する必要があります。今回は上記の理由につき、この処理の部分についての説明はこの記事では割愛しています。
      本気でセキュリティ対策をしたい場合は以下のMessaging Apiの公式ドキュメントをご覧になってみてください。
      https://developers.line.biz/ja/docs/messaging-api/

      また、気になることや分からないことがありましたら、お気軽にコメントください!

      • より:

        お返事ありがとうございます。
        具体的な方法までお教えいただき感謝致します。理解しました。

        他の記事もいくつか拝読致しましたが、どれも大変分かりやすい解説で助かっております。初心者なので適宜それらを参照しながら、自分でできることを増やしていきたいと思います。ありがとうございました。

comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


関連記事

Raspberry Pi のSDカードが壊れ、起動しなくなってしまった場合の修復方法

スマートリモコンとして使用していたラズベリーパイ(zero WH)の調子が最近悪く、ちょっと動作が遅くなってきたなと思っていたら突然反応しなくなってしまいました。半年以上問題なく稼働していましたが、起 …

電子工作 ラズパイで玄関モニター(兼防犯カメラ)作ってみた

今回は前回のスマートリモコンに続き、2回目のIoTデバイス制作です。玄関モニター兼防犯カメラを作ってみました。作成難易度はスマートリモコンよりも簡単ですので皆さんも是非作ってみてください! 玄関モニタ …

大学生の電子工作 スマートリモコン(回路)

この記事ではスマートリモコンを作ってみたで作成したスマートリモコンの回路について記載していきます。今回作成したスマートリモコンの回路は、 以下の3つからなっています。 赤外線学習回路 赤外線発信回路( …

ラズパイに4TBの外付けHDDを接続しNAS(ファイルサーバー)を構築してみた

私は256GBのSSDが搭載されているWindowsパソコンを使用しているのですが、最近空き容量が30GBくらいになってきてしまいました。空き容量がギリギリになると色々と不具合が発生してくるとどこかで …

ラズパイで SPI 7セグLED Module 8 Digital を使ってみた

半年ほど就活に専念するため、ブログの更新をしていませんでしたが、なんとか就活の方が落ち着いてきたのでまたブログを再開しようと思います。 就活中はブログは一時中断していましたが、電子工作の方は続けていた …




関連記事