大学生の電子工作 ラズパイでスマートロックを自作してみた |じょるブログ

じょるブログ

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

電子工作 ラズベリーパイ

大学生の電子工作 ラズパイでスマートロックを自作してみた

投稿日:2018年12月24日 更新日:

前回前々回に続き、3回目の電子工作です。玄関の鍵が面倒だと感じたことは誰しも一度はありますよね。鍵をかばんやポケットから取り出すのが地味にめんどくさかったり、鍵をなくしてしまって困ってしまったというような経験をしたことがある人も多いでしょう。ということで今回は、鍵を持ち歩かなくてもスマホで(もしくは手ぶらで)簡単に鍵の開閉をできるように玄関の鍵をスマートロック化していきたいと思います。

 

搭載した機能

  

概要

今回搭載したメインの機能はスマホで鍵を開閉できるようにすることです。この機能はスマートリモコンを作成したときと同様にbeebotteとIFTTTというサービスを利用して実現します。鍵はモーターで開閉するため手動では開けにくくなってしまうため、家の中からはスイッチを押すことで鍵を開閉できるようにします。

また、まだ実装はしていませんが、圧力センサーや磁力センサーを利用してドアの開閉を感知し、ドアが閉まったらオートロックしたり、振動センサーを利用してあらかじめ設定したリズムでドアを叩くと鍵を開ける(ただしセキュリティ面を考えて自分のスマホが近くにある場合のみにする)という機能も今後搭載していきます。

 

実行環境

  • RasberryPi3 Model B+ (Raspberrypi zero wh などでも動作します)
  • Python3

 

購入したもの

  • RasberryPi3 Model B+
  • サーボモーター(SG92)
  • ジャンパーワイヤー
  • ボタンスイッチ

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

   

スマートロック本体の作成

サーボモーターの玄関への取り付けは、石膏粘土を使用して作成しました!

石膏粘土は乾燥するとプラスチックのようにカッチカチに固まります。
値段もお手頃価格なので、3Dプリンターなどを持っていない方におすすめです!

ガムボトルを型にし、サーボモーターが入るように調整し成型しました。

  

ドライヤーで乾燥させたためひび割れができてしまいましたが、2~3日ほどでしっかりと固まりました。

サーボモーターに取り付ける、鍵を開ける部分は家にあったスプーンを変形させて即席で作成しましたw

スプーンを二つに折り、そのうちの持つ部分の方を使用して鍵にフィットするように調整して折り曲げたものをサーボモーターに取り付けました。

そして、100均で購入したカモフラージュ用のテープを乾燥した粘土に貼り付けて完成です。

  

セットアップ

・ラズベリーパイの基本設定

ラズベリーパイへのOSのインストールや初期設定がまだの方はこちらの記事をご覧ください。

    

・インストール、ダウンロードするもの

  • paho-mqtt(pythonパッケージ)
  • mqtt.beebotte.com.pem( beebotteの証明書)
sudo pip3 install paho-mqtt
curl -O https://beebotte.com/certs/mqtt.beebotte.com.pem

  

・外部サービスとの連携

ここでは、記事が長くなってしまうので一部省略して説明します。もし、うまく設定できない場合はこちらの記事(Alexa, Google HomeをRasberryPiと連携する)で詳しく解説しているので見てみてください。

 ・ beebotte の設定

beebotteにアカウントを作成し、ログインしたら、”create new” をクリックします。

すると以下のような画面が表示されるので、Channel名とResource名、それからそれらの説明の合計4つを入力したら、”create channel” をクリックします。
(Channel名、Resource名は何でも構いません。例えばChannel名をRaspberryPi、Resource名をSmartLockなどに設定してください。 ) 

以上でChannelの作成は完了です。作成したChannelにアクセスするためにはChannel Tokenが必要なので、以下のように作成したChannel名をクリックして、Channel Tokenをメモしておいてください。

 

 ・IFTTTの設定

アカウントを作成しログインしたら、右上の自分のアカウント名をクリックし、”New Applet”をクリックします。

次の画面で ”+This” というところをクリックし 、画面が切り替わったら“search service” のところに “Google” と入力してGoogle Assistant を探し、Google Assistantのアイコンをクリックします。
(Alexaの設定を行う場合はAlexaを選択します。)

choose trigerと表示されるので “Say a simple phrase” をクリックします。

次の画面で以下のように、Google Assistant に話しかける(または入力する)フレーズとそのレスポンスを入力し、言語をJapaneseに設定したら “create trigger” をクリックします。 (下の画像ではスマートリモコンの設定をしているので適宜変更してください。例えば ”エアコンつけて” と書いてあるところを ”鍵を開けて” などに変更してください。

次に、Google Assistant と beebotteを連携させるための仲介役となるwebhooksとの連携をしていきます。 ”+That” をクリックし 、画面が切り替わったら“search service” のところに “Webhooks” と入力してWebhooksを探し、Webhooksのアイコンをクリックします。

choose actionと表示されるので “ Make a web request ” をクリックします。

次の画面で以下のように入力してください。

・URL
” https://api.beebotte.com/v1/data/publish/チャンネル名/トピック名?token=[先ほどメモしたBeebotteのトークン] “と入力
・Method
” POST “を選択
・Content Type
” application/json “を選択
・Body
” {“data”:[{“device”:”デバイス名”,”action”:”アクション名”}]} “と入力

URL中のチャンネル名/トピック名にはbeebotteで設定したチャンネル名とトピック名を入力してください。
Bodyのデバイス名とアクション名は、デバイス名をlock、アクション名を鍵を開ける場合はopen、閉める場合はcloseと入力してください。

“Create action” をクリックし、次の画面で “Finish” をクリックすればIFTTTでの設定は完了です。

  

回路図

右側のスイッチが鍵を開ける用のスイッチで、左側が閉める用のスイッチです。

 

プログラム

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import paho.mqtt.client as mqtt
import subprocess
import json
import sys
import time
import RPi.GPIO as GPIO



##### beebotteのセッティング #####
HOST = 'mqtt.beebotte.com'
PORT = 8883
CA_CERTS = 'mqtt.beebotte.com.pem'
TOKEN = 'token_xxxxxxxxxxxxxxxxxx'    #Beebotteで作成したチャンネルのトークンを入力
TOPIC = 'チャンネル名/トピック名'       #Beebotteで作成したトピック名を入力



##### サーボモーターのセッティング #####
# pinの指定方法をBCMに設定(GPIO.BOARDとすると基盤のピン番号となる)
GPIO.setmode(GPIO.BCM)
# pin番号の指定
pin_servo = 4
# 指定したpinを出力に設定
GPIO.setup(pin_servo, GPIO.OUT)
# PWMサイクルを50Hz(20ms)に設定 (都合により関数内で設定を行う)
# servo = GPIO.PWM(pin_servo, 50)
# 回転角を定義
left   = 2.5
center = 7.25
right  = 12.0


##### プッシュボタンのセッティング #####
pin_open  = 10 
pin_close = 27

GPIO.setup(pin_open,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_close,GPIO.IN,pull_up_down=GPIO.PUD_UP)

def press_open_button(pin_number):
    counter = 0
    print("GPIO[%d]のコールバックが発生しました" % pin_number)
    while True:
        status = GPIO.input(pin_open)
        if status == 0:
            counter = counter + 1
            if counter >= 10:
                print("開錠します")
                open()
                break
        else:
            print("開錠を取り消します")
            break
        time.sleep(0.001)
    print(counter)

def press_close_button(pin_number):
    counter = 0
    print("GPIO[%d]のコールバックが発生しました" % pin_number)
    while True:
        status = GPIO.input(pin_close)
        if status == 0:
            counter = counter + 1
            if counter >= 10:
                print("閉錠します")
                close()
                break
        else:
            print("閉錠を取り消します")
            break
        time.sleep(0.001)
    print(counter)


def open():
    servo = GPIO.PWM(pin_servo, 50)
    servo.start(center)
    time.sleep(0.3)
    servo.ChangeDutyCycle(left)
    time.sleep(0.3)
    servo.ChangeDutyCycle(center)
    time.sleep(0.3)
    servo.stop()

def close():
    servo = GPIO.PWM(pin_servo, 50)
    servo.start(center)
    time.sleep(0.3)
    servo.ChangeDutyCycle(right)
    time.sleep(0.3)
    servo.ChangeDutyCycle(center)
    time.sleep(0.3)
    servo.stop()


def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))
    
def on_disconnect(client, userdata, flags, respons_code):
    print('disconect')
    #client.loop_stop()


def on_message(client, userdata, msg):
    print(msg.topic + ' ' + str(msg.payload))
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]
    print(msg.payload.decode("utf-8"))
    print(data)

    if (data["device"] == 'lock'):
        if   (data["action"] == 'open'):
            print('鍵を開けます')
            open()
            print('鍵を開けました')
        elif (data["action"] == 'close'):
            print('鍵を閉めます')
            close()
            print('鍵を閉めました')
        else:
            print('unknown message')

    else:
            print('unknown message')

if __name__ == '__main__':
    try:
        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)

        GPIO.add_event_detect(pin_open, GPIO.FALLING, callback = press_open_button, bouncetime = 1000)
        GPIO.add_event_detect(pin_close, GPIO.FALLING, callback = press_close_button, bouncetime = 1000)
        

        client.loop_forever()
    except KeyboardInterrupt:
        print('finished')
        GPIO.cleanup()

上のコードのbeebotteのセッティングのところに先ほどメモした自分のbeebotteのTokenとTopicを入力し、 先ほどダウンロードしたmqtt.beebotte.com.pemがあるディレクトリにこのプログラムを保存してください。

 

使い方

プログラムを実行して数秒待つと、mqttによる接続が開始され ” status 0 ” と表示されるので、お手持ちのスマホやGoogle HomeからGoogle Assistantを呼び出し、先ほどIFTTTで設定した言葉(エアコンつけてなど)を話してみてください(入力でも可)。先ほどIFTTTで設定した言葉(エアコンをつけますなど)が返ってきて、ターミナルにBeebotteに送られた(publishされた)データ等が表示されたら外部サービスとの連携は成功です。さらに数秒待つと鍵の開け閉めが実行されます。
Alexaから操作する場合は1つ注意する点があり、” アレクサ、エアコンつけて “と話しかけても動作しません。Alexaから IFTTTを使用するには” アレクサ、トリガー、エアコンつけて “といったり、” アレクサ、エアコンつけてをトリガー ” といったように話しかけなければいけません。成功すると ” IFTTTに送信します ” という言葉が返ってきます。

  

続きはこちら↓

google ads




google ads




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

執筆者:


comment

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

CAPTCHA


関連記事

RaspberryPiのセットアップ ② – SSH,VNC(遠隔操作)の設定とファイルサーバーの設定

 この記事では、前回の記事(RaspberryPiのセットアップ ① – 2種類のOSインストール方法と基本設定)に引き続き、ラズパイを遠隔操作するためのSSH・VNCの設定方法と、パソコ …

ラズパイでスマートロック作ってみた② - 扉の開閉状況をGoogleスプレッドシートに記録

以前作成したスマートロックに、扉の開閉状況をGoogleスプレッドシートに記録する、という機能をつけたので、そのやり方について紹介します。   搭載した機能 スイッチで鍵の開閉外部サービス(Googl …

簡単にRasberryPi Zero WH へ node.js, npmを入れる方法

  はじめに  スマートリモコンでPS4を操作するためにはps4-wakerというパッケージが必要であり、これをインストールするにはnode.jsのパッケージ管理ツールであるnpmをインストールする必 …

ラズパイで取得したIoTデータをグーグルスプレッドシートに自動記録

今回はPythonを使って、ラズパイに接続してあるセンサーから取得したデータなどをグーグルスプレッドシートに自動で記載する方法について記載します。グーグルスプレッドシートに記載することで、スマホなどか …

ラズパイでスマートロック作ってみた⑤- スプレッドシートをICカードのデータベースとして使用する

    大学生の電子工作 ラズパイでスマートロック作ってみたの記事の⑤つ目の記事です。今回は、前回追加したICカードで鍵を開ける機能のアップデートを行いました。 具体的には、今までラズパイのプログラム …




関連記事