LINEから「ただいま」と送れば、マンションのオートロックを開けてくれるシステムをRaspberryPiで作った
はじめに
僕が住んでるマンションは、共用エントランスに、鍵をさして開くタイプのオートロックがついていて、面倒です。
オートロックこんな感じ↓
自分の部屋番号を呼び出して部屋から解錠ボタンを押すか、エントランスに鍵をさすことで、開く感じです。
疲れて帰宅した中、毎回カバンの中から鍵を探したくないし、さらに、鍵を家に忘れてしまった場合は、近所さんがいないと開けてもらえないので、困ります。
なのでLINEから「ただいま」と送れば「おかえり!」と返してくれて、マンションのオートロックを開けてくれるシステムを作りました。疲れて帰ってきたときに、「おかえり」と返してくれるので、なんか嬉しい気持ちになります。
システム構成概要
システム構成の概要図です。
LINEから「ただいま」と送ると、LINEのMessaging APIを通して、Flaskで作ったローカルサーバーにメッセージが送られます。
Flaskで受け取ったメッセージに応じて、サーボモーターを動かして、オートロックを開けます。LINEとの通信は、Flaskで作ったラズパイ上のローカルサーバーをngrokで公開することで行います。
制作期間: 10時間程度(RaspberryPiの初期設定から始めて)
使用したもの
- Raspberry Pi (モデルはRaspberryPi 4を使用しました)
- microSDカード
- microSD to SD 変換アダプター(MacでRaspberryPiを初期設定する際、microSDカードを読み込むために使用)
- サーボモーター
- ジャンパーワイヤ (RaspberryPiとサーボモーターを接続するために必要)
- 両面テープ (サーボモーターをインターホンに貼り付ける用)
RaspberryPiの初期設定
PCとssh接続できるようにしておく。
LINE Messaging APIの設定
LINE DevelopersコンソールのMessaging APIページにアクセスし、チャンネルを作成します。
チャンネルを作成したら、Basic settingsタブ の Basic Information、Messaging API Settingsタブ の Channel Access Tokenから「チャネルシークレット」と「チャネルアクセストークン」を発行しておく。
Webhook URLの設定
RaspberryPiのterminalを開き、以下のコマンドを実行します。
$ sudo apt-get update
$ sudo apt-get install tmux -y
$ tmux
ssh接続が切れても落ちないように、tmuxを入れておきます。
tmuxを起動したら、先ほど発行したチャネルシークレットとチャネルアクセストークンを環境変数に設定します。
YOUR_LINE_CHANNEL_SECRETとYOUR_LINE_CHANNEL_ACCESS_TOKENは、コピーしたものに置き換えてください。
$ export LINE_CHANNEL_SECRET=YOUR_LINE_CHANNEL_SECRET
$ export LINE_CHANNEL_ACCESS_TOKEN=YOUR_LINE_CHANNEL_ACCESS_TOKEN
続いて、以下のコマンドを実行してngrokをインストールします。
$ wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip
$ unzip ngrok-stable-linux-arm.zip
$ chmod +x ngrok
$ sudo mv ngrok /usr/local/bin/
$ ngrok version
バージョン情報を表示して、ngrokが正しくインストールされていることを確認。ngrok公式サイトにログインして、Your Authtoken
に表示されているトークンをコピーします。
コピーしたAuthtokenをターミナルで認証。
$ ngrok authtoken YOUR_AUTHTOKEN
YOUR_AUTHTOKENは、置き換えてください。これにより、正しいトークンが認識され、認証が行われるはずです。
認証が完了したら、以下のコマンドを実行して、ngrokを起動します。
$ ngrok http 8000
ngrokを起動すると、以下のような画面が表示され、ローカルサーバーを公開するためのURLが生成されます。
表示されたForwardingのURLのうち、httpsのものを確認したら、LINE DevelopersコンソールのMessaging API SettingsタブのWebhook URLに貼り付けます。
urlの最後に /callbackを最後に付け足します(ここ重要です)
参考:https://junpage.com/line-bot-development/
画面の更新(Verify)
をクリックして、Successと表示されたら、Webhook URLの設定は完了。
Webhookの利用を有効にするのを忘れずに。
Pythonプログラムの実装
サーボモーターをラズパイのGPIO18番ピンに接続します。
GPIOピンの接続方法
ラズパイにサーボモーターを接続する
ラズパイのGPIOに接続するために、サーボモーターのコネクタにジャンパワイヤを取り付けます。
茶: GND -> 6番ピン.
赤: 電源 -> 2番ピン.
黄: 制御信号 -> 12番ピン.
ライブラリのインストール
GPIO制御のライブラリーをインストール。
$ sudo pigpiod
続いて、サーボモーターを動かすプログラムをpythonで作成します。
pythonコード
import RPi.GPIO as GPIO
import time
import os
import sys
import pigpio
import random
from argparse import ArgumentParser
from flask import Flask, request, abort
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
)
app = Flask(__name__)
# チャンネルシークレットとチャンネルアクセストークンの登録
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
print('Specify LINE_CHANNEL_SECRET as environment variable.')
sys.exit(1)
if channel_access_token is None:
print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
sys.exit(1)
line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)
# サーボモータを回す関数の登録
SERVO_PIN = 18
# pigpioを初期化
pi = pigpio.pi()
# サーボモーターを特定の角度に設定する関数
def set_angle(angle):
assert 0 <= angle <= 180, '角度は0から180の間に注意する'
# 角度を500から2500のパルス幅にマッピングする
pulse_width = (angle / 180) * (2500 - 500) + 500
# パルス幅を設定してサーボを回転させる
pi.set_servo_pulsewidth(SERVO_PIN, pulse_width)
def open_key():
set_angle(90 - 30) # 通話ボタンを押す
time.sleep(1)
set_angle(90) # 0度に戻す
time.sleep(1)
set_angle(90 + 30) # 解錠ボタンを押す
time.sleep(1)
set_angle(90) # 0度に戻す
time.sleep(1)
# ランダムなメッセージのリストを定義
random_messages = [
'おかえり〜!鍵開けたよー',
'お帰りなさい!',
'おかえりなさいませ!',
'お家に帰ってきたんですね!'
]
@app.route("/callback", methods=['POST'])
def callback():
signature = request.headers['X-Line-Signature']
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
@handler.add(MessageEvent, message=TextMessage)
def message_text(event):
text = event.message.text
# 以下のメッセージが送られてきたら、鍵を開ける
if text in ['ただいま', '鍵開けて']:
# 鍵開ける
open_key()
# ランダムなメッセージを選択
random_message = random.choice(random_messages)
# 返事
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(random_message)
)
# それ以外のメッセージが送られてきたら、木霊
else:
# 木霊
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=event.message.text)
)
if __name__ == "__main__":
arg_parser = ArgumentParser(
usage='Usage: python ' + __file__ + ' [--port ] [--help]'
)
arg_parser.add_argument('-p', '--port', default=8000, help='port')
arg_parser.add_argument('-d', '--debug', default=False, help='debug')
options = arg_parser.parse_args()
app.run(debug=options.debug, port=options.port)
上記のプログラムでは、LINEから ただいま
又は 鍵開けて
のテキストが送られると、open_key()
関数が呼び出されて、サーボモーターが回転して、オートロックが開きます。
open_key()関数の回転角度は、自分のマンションのインターホンに合わせて調整してください。(デフォルトでは、通話ボタンを押すときに-30度回転し、解錠ボタンを押すときに+30度回転します。)
tmuxで、ngrokを実行しているターミナルとは別のターミナルを開き、以下のコマンドでプログラムを実行すれば、準備完了です!
$ python app.py
さて、ただいまと送ってみる
作成したLINE Botに「ただいま」と送ってみる。
既読がついた、
、、、
無事、開きました!
(両面テープの弾性が丁度良くて、クション代わりになってるので、いい感じに押してくれます。)
通信速度は、0.1秒くらい。速いです。
そして、LINEを見ると、
ぶたちゃんが、おかえりなさいませ!と返してくれました。
完成!
おわりに(今後の展望)
これで、鍵を忘れた時でも、ラズパイのサーバーを起動しておけば、LINEから「ただいま」と送るだけで、オートロックを開けることができるようになりました。
ただ、もう一つ解決したいことがあります。
宅急便の置き配です。
うちのマンシションには宅配boxはあるものの、結構な割合で埋まっているため、外出中は再配達になる率が高いです。
(国土交通省が公表した「宅配便再配達実態調査」によると、2023年4月時点での再配達率は約11.4%らしい。思ったよりも低かった。宅配boxの普及や、サインレスが進んで、前よりは少し改善されたのかもしれません。)
せめて、僕の再配達率でも下げられたらなと思い、遠隔でもエントランスを開けて、玄関先に置き配してくれるようにしたい。
この場合になると、セキュリティに十分注意しないといけなくなるので、今どのような方法でうまく実装できるか、検討中です。
何かいい案があれば、コメント欄に書いてくれると嬉しいです。
インターホンをカメラとマイクで監視していて、インターホンの音が鳴ったら、LINEに通知が来るようにして、LINEから「開けて」と送ると、エントランスを開けてくれるようにするとか、
オートロックで困ってる人に、少しでも役に立てたらいいなあ。
おまけ
ラズパイの1ヶ月の電気代を計算してみた。
Raspberry Pi 4 Model B の 電圧 = 5V, 電流 = 0.6A として計算。
1kWh当たりの料金を30円とすると、1ヶ月の電気代は、
100円弱くらい。
Discussion