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

じょるブログ

現役理系大学生による大学生に向けた情報サイト

電子工作

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

投稿日:2019年3月23日 更新日:

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

 

搭載した機能

  

概要

外出するときによく鍵を閉めたかどうか忘れてしまうことはありませんか?僕は心配性なので、そのようなことがしょっちゅうあります。そんなとき、扉の開閉記録が記録されていて、それをスマホで手軽に見れるとしたら便利ですよね。(スマートロックがあれば開閉状況に関わらず、遠隔で閉めればいいだけですが…)

そこで、今回は扉を開閉する度に自動でGoogleスプレッドシートに以下の画像のように開閉日時、開閉方法(デバイス)、開閉状況を記録するプログラムを作成したのでそれについて紹介します。

ちなみにエクセルなどではなく、Googleスプレッドシートに記録する理由は、オンライン上に情報が記録され、どこからでも確認できるからです!

  

 

実行環境

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

 

手順

  1. GoogleスプレッドシートのAPI設定
  2. Googleスプレッドシートに記録するプログラムを作成
  3. 作成したプログラムをスマートロックのプログラムに組み込む

1. GoogleスプレッドシートのAPI設定

GoogleスプレッドシートのAPIの設定方法についてはこちらの記事(ラズパイで取得したIoTデータをグーグルスプレッドシートに自動記録)にまとめたので参照してください。

2. Googleスプレッドシートに記録するプログラムを作成

次に、プログラムを作成します。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import gspread
from oauth2client.service_account import ServiceAccountCredentials
import datetime
import argparse


#変更してください
key_name = '**************.json'
sheet_key = 'xxxxxxxxxxxxxxxxxxxxx'

#引数の設定
parser = argparse.ArgumentParser()
parser.add_argument("sheet_number", help="input using spreadsheet number", type=int)
parser.add_argument("value1", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value2", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value3", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value4", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value5", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value6", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value7", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value8", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value9", help="input write value", type=str, nargs='?', default='')
parser.add_argument("value10", help="input write value", type=str, nargs='?', default='')
args = parser.parse_args()

sheet_num = args.sheet_number

#APIにログイン
scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name(key_name, scope)
gc = gspread.authorize(credentials)

#bookを開く
workbook = gc.open_by_key(sheet_key)

#sheetを指定
worksheet = workbook.get_worksheet(sheet_num)

#セルに入力
cell_value = [args.value1, args.value2, args.value3, args.value4, args.value5, args.value6, args.value7, args.value8, args.value9, args.value10]
worksheet.append_row(cell_value)

print("written")

プログラム中のkey_nameはGoogleスプレッドシートのAPI設定時にダウンロードしたjsonファイル名に変更してください。

また、sheet_keyにはスプレッドシートのURLの

https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxx/edit?usp=drivesdk

のxxxxxxxxxxxxxxxxxxxxxの部分の英数字を入力してください。

このプログラムは、実行時に引数を入力(最大10個)することで、その引数がGoogleスプレッドシートに記載されます。ただし、一番目の引数にはスプレッドシートのシート番号(0から数える)を入力します。

例 : python gspred.py  0 2019/01/01 12:34:56 alexa 開

   

3. 作成したプログラムをスマートロックのプログラムに組み込む

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

import paho.mqtt.client as mqtt
import subprocess
import datetime
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 #17error
pin_close    = 27
pin_autolock = 9

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


#### グローバル変数(スプレッドシート記入)
Terminal = 'button'

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

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

def press_autolock_button(pin_number):
    global Terminal
    counter = 0
    print("GPIO[%d]のコールバックが発生しました" % pin_number)
    while True:
        status = GPIO.input(pin_autolock)
        if status == 0:
            counter = counter + 1
            if counter >= 10:
                Terminal = 'button'
                print("オートロックします")
                autolock()
                break
        else:
            print("オートロックを取り消します")
            break
        time.sleep(0.001)
    print(counter)    

def open():
    global Terminal
    now = datetime.datetime.today()
    now_date = '{0:%Y-%m-%d}'.format(now)
    now_time = '{0:%H:%M:%S}'.format(now)
    lock_status ='開'
    cmd = ('python3 gsp-homeauto.py 0 {0} {1} {2} {3}'.format(now_date, now_time, Terminal, lock_status))
    subprocess.Popen(cmd.split())

    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():
    global Terminal
    now = datetime.datetime.today()
    now_date = '{0:%Y-%m-%d}'.format(now)
    now_time = '{0:%H:%M:%S}'.format(now)
    lock_status ='閉'
    cmd = ('python3 gsp-homeauto.py 0 {0} {1} {2} {3}'.format(now_date, now_time, Terminal, lock_status))
    subprocess.Popen(cmd.split())

    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 autolock():
    global Terminal
    now = datetime.datetime.today()
    now_date = '{0:%Y-%m-%d}'.format(now)
    now_time = '{0:%H:%M:%S}'.format(now)
    lock_status ='オートロック'
    cmd = ('python3 gsp-homeauto.py 0 {0} {1} {2} {3}'.format(now_date, now_time, Terminal, lock_status))
    subprocess.Popen(cmd.split())

    open()
    time.sleep(7)
    close()

def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))
    #subprocess.call({"python", "ltika1.py"})

def on_disconnect(client, userdata, flags, respons_code):
    if  respons_code != 0:
        print("Unexpected disconnection.")
        #subprocess.call(python homeauto.py)
        #sys.exit()
        #subprocess.call({"python", "ltika1.py"})
    else:
        print('disconect')
        print(respons_code)
    client.loop_stop()
    print('11')

def on_message(client, userdata, msg):

    print(msg.topic + ' ' + str(msg.payload))
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]

    global Terminal
    Terminal = data["terminal"]

    # control
    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)
        GPIO.add_event_detect(pin_autolock, GPIO.FALLING, callback = press_autolock_button, bouncetime = 1000)
        
        client.loop_forever()

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

上のコードのbeebotteのセッティングのTokenとTopicのところに自分の値を入力し、 先ほど作成したGoogleスプレッドシートのプログラムと同じフォルダーに保存すれば完了です。

続きはこちら↓

   

google ads




google ads




-電子工作

執筆者:


comment

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

関連記事

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

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

AmazonDushボタンを改造してできること- ラズパイやIoT製品との連携方法

AmazonDushボタンはひと手間加えるだけで、IoT製品等の遠隔ボタンとして使用することができます。これにより、スマートロックと連携させダッシュボタンで鍵を開閉したり、スマートリモコンのボタンとし …

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

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

ラズパイでスマートロック作ってみた④ – ICカードでドアを開閉する

大学生の電子工作 ラズパイでスマートロック作ってみたの記事の④つ目の記事です。今回はSuicaや学生証、電子マネー(nanacoとか)等のICカードで鍵を開けられるようにしました。 近くのコンビニに買 …

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

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