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

じょるブログ

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

電子工作 ラズベリーパイ

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

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

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

 

搭載した機能

  

概要

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

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

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

  

 

実行環境

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

    

手順

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

     

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

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

② 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 開

   

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

#!/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

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

CAPTCHA


関連記事

初めての大学生の電子工作 スマートリモコンを作ってみた

 タイトル通り、初めて電子工作をやってみました。電子工作をやったことがないという方にもこの記事を読めば作れるように、つまづいたとこなども丁寧に説明していきます。もしわからないことなどがございましたら気 …

物理ボタンをIoT化 – ESP32で Swich bot を自作し、スマホからスイッチをON,OFFできるようにしてみた

   この記事ではESP32をIoTデバイスとして使用し、家の電気のボタンや電子レンジのボタンなどの、あらゆる物理ボタンを押すことのできるスイッチボットを作成する方法について解説します。 市販されてい …

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

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

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

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

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

    ラインから手軽にスマートデバイスを操作する方法について解説します。 この記事ではラズパイで自作したスマートデバイスをラインで操作する方法について解説しますが、IFTTT経由で操作できるものであ …




関連記事