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

じょるブログ

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

電子工作 ラズベリーパイ

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

投稿日:2020年5月13日 更新日:

   

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

具体的には、今までラズパイのプログラム上でICカードのIDであるIDM番号を管理していたのをオンライン上(スプレッドシート)で管理できるようにし、いちいちラズパイのプログラムを編集しなくてもスプレッドシート上で新規ICカードの登録や登録済みのICカードの削除を行えるようになりました。

管理方法はデータベースを使用するのではなく、以下のようにスプレッドシートで管理できるようにしました。理由としては、スプレッドシートはオンライン上でどこからでもアクセスでき、スマホからも手軽にアクセスが可能だからです。

   

搭載した機能の概略

・スマートロックプログラム起動時

  1. 現在スプレッドシートに登録されているICカード情報(IDM番号、認証ステータス)を取得
  2. ラズパイ上のICカード情報更新
  3. LINEにICカード情報を通知

・未登録のICカードがタッチされた時

  1. LINEに未登録のカードがタッチされたことを通知
  2. スプレッドシートに、認証ステータスを Unregistered (未登録) として、タッチされたICカードのIDM番号を自動追記
  3. ラズパイ上のICカード情報更新

・非許可のICカードがタッチされた時

  1. LINEに未登録のカードがタッチされたことを通知

・スプレッドシートのICカード情報を更新する場合

  1. スプレッドシートのICカード情報を修正(手動で新規ICカード追加、未許可のICカードを許可または非許可に変更、許可済みのICカードを非許可に変更など)
  2. 修正したらスプレッドシート上の更新ボタンをクリック
  3. ラズパイ側において、スプレッドシートに登録されているICカード情報(IDM番号、認証ステータス)を再取得
  4. ラズパイ上のICカード情報更新
  5. LINEに最新のICカード情報を通知

  

まず、スマートロックプログラムを実行した際にスプレッドシートAPIにアクセスし、現在スプレッドシートに記載されているICカード情報を取得します。取得するICカード情報にはICカードのIDM番号と認証ステータスが含まれており、認証ステータスは許可(Allow)、非許可(Deny)、未登録(Unregistered)の3つの状態が存在します。ICカード情報を取得したら、ラズパイ上のICカードリストを更新します。最後にそのICカード情報がラインでスマホに送信されます。

次に未登録のICカードがタッチされた場合の挙動について説明します。未登録のICカードがタッチされると、まず警告としてラインに通知が行きます。その後スプレッドシートAPIを用いて、タッチされたICカードのIDM番号を認証ステータス未登録(Unregistered) の状態でスプレッドシートに記載します。最後にスマートロックプログラムを実行した際と同じ挙動が起こります。

最後に、スマホやPCから手動でスプレッドシートの情報を編集した場合について説明します。未許可のICカードを許可または非許可に変更したり、許可済みのICカードを非許可に変更なする場合にはスプレッドシートを直接修正します。認証ステータスの変更を行った後、スプレッドシートの右上にある認証情報更新ボタンを押すことで、ラズパイにICカードの更新要求が届きます。その後、スマートロックプログラムを実行した際と同じ動作が起こり、ラズパイ上のICカード情報が更新されます。

    

使い方

・新規カードを登録する場合

  1. ICカードリーダーに登録したいICカードをタッチ
  2. スプレッドシートにタッチしたICカードが、認証ステータスが未登録(Unregistered)として登録されるので、スプレッドシートを手動で編集し認証ステータスを許可(Allow) に変更
  3. スプレッドシートの右上にある認証情報更新ボタンを押す
  4. (ラズパイにICカード情報更新要求が届き、ICカード情報が更新される)

   

搭載した機能

   

実行環境

  • ラズベリーパイ3 B+
  • ICカードリーダー ( PaSoRi RC-S320 )

SONY RC-S320 非接触ICカードリーダ/ライタ PaSoRi 「パソリ」

   

手順

  1. プログラムの作成
    1. メインプログラム
    2. スプレッドシート記載プログラム
    3. ライン通知プログラム
  2. スプレッドシート作成
    1. ICカード情報を記載するシートの作成
    2. スプレッドシートに認証情報更新ボタンを搭載

   

①プログラムの作成

※ラズパイでスマートロック作ってみた①~④で行った、ICカードリーダーの設定などが完了している前提で動作するプログラムとなります。

・メインプログラム

以下スマートロックのソースコードです。

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

import paho.mqtt.client as mqtt
import subprocess
import datetime
import json
import sys
import RPi.GPIO as GPIO
import time
from ctypes import *
import concurrent.futures
import gspread
from oauth2client.service_account import ServiceAccountCredentials


#//////////////////////////////////////////////////////////////
# 初期設定
#//////////////////////////////////////////////////////////////

##### beebotteのセッティング #####
HOST = 'mqtt.beebotte.com'
PORT = 8883
CA_CERTS = 'mqtt.beebotte.com.pem'
TOKEN = 'token_xxxxxxxxxxxxxx' #要変更
TOPIC = 'xxxxxxxx/xxxxxxxxxxx' #要変更



##### サーボモーターのセッティング #####
GPIO.setmode(GPIO.BCM)
pin_servo = 4 #要変更
# 指定したpinを出力に設定
GPIO.setup(pin_servo, GPIO.OUT)
# 回転角を定義
left   = 2.5
center = 7.25
right  = 12.0



##### プッシュボタンのセッティング #####
pin_open     = 10 #要変更
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)



##### ICカードのセッティング #####
# libpafe.hの77行目で定義
FELICA_POLLING_ANY = 0xffff
#スプレッドシートに関する設定(グローバル変数)
key_name   = 'gspred-xxxxxxxxxxxxxx.json' #要変更
sheet_key  = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' #要変更
sheet_name = "ICカード許可リスト" #要変更



##### グローバル変数(スプレッドシート記入/ICカード設定) ####
Terminal = 'button'
lock_status = '開'
latest_Idm = '0000000000000000'
Allow_Idm_list = []
Deny_Idm_list  = []
Unregistered_Idm_list = []






#//////////////////////////////////////////////////////////////
# プッシュボタンの関数
#//////////////////////////////////////////////////////////////

def press_open_button(pin_number):
    global Terminal
    counter = 0
    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)


def press_close_button(pin_number):
    global Terminal
    counter = 0
    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)


def press_autolock_button(pin_number):
    global Terminal
    counter = 0
    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(write_flag="True"):
    global Terminal
    global lock_status
    now = datetime.datetime.today()
    now_date = '{0:%Y-%m-%d}'.format(now)
    now_time = '{0:%H:%M:%S}'.format(now)
    lock_status ='開'
    
    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()

    if (write_flag):
        cmd = ('python3 gsp-homeauto.py 0 {0} {1} {2} {3}'.format(now_date, now_time, Terminal, lock_status))
        subprocess.Popen(cmd.split())


def close(write_flag=True):
    global Terminal
    global lock_status
    now = datetime.datetime.today()
    now_date = '{0:%Y-%m-%d}'.format(now)
    now_time = '{0:%H:%M:%S}'.format(now)
    lock_status ='閉'
    
    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()

    if (write_flag):
        cmd = ('python3 gsp-homeauto.py 0 {0} {1} {2} {3}'.format(now_date, now_time, Terminal, lock_status))
        subprocess.Popen(cmd.split())


def autolock():
    global Terminal
    global lock_status
    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(False)
    time.sleep(7)
    close(False)





#//////////////////////////////////////////////////////////////
# ICカードに関する関数
#//////////////////////////////////////////////////////////////
def IC_read():
    global Terminal
    global lock_status
    global latest_Idm
    global Allow_Idm_list
    global Deny_Idm_list
    global Unregistered_Idm_list
    while True:
        felica = libpafe.felica_polling(pasori, FELICA_POLLING_ANY, 0, 0)
        idm = c_ulonglong() 
        libpafe.felica_get_idm.restype = c_void_p
        libpafe.felica_get_idm(felica, byref(idm))
        idm_No = "%016X" % idm.value

        if idm_No == '0000000000000000':
            #print('カードをタッチしてください')
            pass
        elif idm_No in Allow_Idm_list:
            latest_Idm = idm_No
            Terminal = 'IC_card'
            now      = datetime.datetime.today()
            now_date = '{0:%Y-%m-%d}'.format(now)
            now_time = '{0:%H:%M:%S}'.format(now)
            print('Allow: {0}'.format(idm_No))
            # 鍵の開閉
            if (lock_status=='閉'):
                # open()
                autolock()
            elif (lock_status=='開'):
                close()
            else:
                print("lock_status error")
            # スプレッドシートにタッチ記録を記載
            cmd_gsp = ('python3 gsp-homeauto.py 2 {0} {1} {2} {3} {4}'.format(now_date, now_time, Terminal, idm_No, "Allow"))
            subprocess.Popen(cmd_gsp.split())
            # Lineにメッセージを送信
            #message = ('登録済みのICカードがタッチされました {0}錠します Allow:{1}'.format(lock_status, idm_No))#半角スペースを入れると改行 cf:line_notify.py
            #cmd_line = ('python3 line_notify.py {0}'.format(message))
            #subprocess.Popen(cmd_line.split())
        elif idm_No in Deny_Idm_list:
            latest_Idm = idm_No
            Terminal = 'IC_card'
            now = datetime.datetime.today()
            now_date = '{0:%Y-%m-%d}'.format(now)
            now_time = '{0:%H:%M:%S}'.format(now)
            print('deny: {0}'.format(idm_No))
            # スプレッドシートにタッチ記録を記載
            cmd_gsp = ('python3 gsp-homeauto.py 2 {0} {1} {2} {3} {4}'.format(now_date, now_time, Terminal, idm_No, "Deny"))
            subprocess.Popen(cmd_gsp.split())
            # Lineにメッセージを送信
            message = ('警告! 非許可として登録されているICカードがタッチされました deny:{0}'.format(idm_No))#半角スペースを入れると改行 cf:line_notify.py
            cmd_line = ('python3 line_notify.py {0}'.format(message))
            subprocess.Popen(cmd_line.split())
        else:
            latest_Idm = idm_No
            Terminal = 'IC_card'
            now = datetime.datetime.today()
            now_date = '{0:%Y-%m-%d}'.format(now)
            now_time = '{0:%H:%M:%S}'.format(now)
            print('Unregistered: {0}'.format(idm_No))
            # スプレッドシートにタッチ記録を記載
            cmd_gsp = ('python3 gsp-homeauto.py 2 {0} {1} {2} {3} {4}'.format(now_date, now_time, Terminal, idm_No, "Unregistered"))
            subprocess.Popen(cmd_gsp.split())
            # Lineにメッセージを送信
            message = ('警告! 未登録のICカードがタッチされました Unregistered:{0}'.format(idm_No))#半角スペースを入れると改行 cf:line_notify.py
            cmd_line = ('python3 line_notify.py {0}'.format(message))
            subprocess.Popen(cmd_line.split())
            # スプレッドシートにICカード情報が記載されていなければ記載する
            write_Unregistered_IC_info()
        time.sleep(1)

    now = datetime.datetime.today()
    print("ICカードリーダー停止")
    print(now)


def get_IC_list():
    global sh
    IC_list              = []
    Allow_IC_list        = []
    Deny_IC_list         = []
    Unregistered_IC_list = []

    now = datetime.datetime.today()
    print("*** ICカード認証情報更新 {0} ***".format(now))
    ### シートの全ての値を取得する
    all_data = sh.get_all_values()

    ### AllowとなっているIdmリストを取得する
    Authentication = "Allow"
    # 合致する全てのセルを取得する
    cell_list = sh.findall(Authentication)
    # Idmを取得する
    for cell in cell_list:
        row_number = cell.row - 1
        Allow_Idm = all_data[row_number][2]
        Allow_IC_list.append(Allow_Idm)
    print("許可ICリスト")
    print(Allow_IC_list)

    ### DenyとなっているIdmリストを取得する
    Authentication = "Deny"
    # 合致する全てのセルを取得する
    cell_list = sh.findall(Authentication)
    # Idmを取得する
    for cell in cell_list:
        row_number = cell.row - 1
        Deny_Idm = all_data[row_number][2]
        Deny_IC_list.append(Deny_Idm)
    print("非許可ICリスト")
    print(Deny_IC_list)

    ### UnregisteredとなっているIdmリストを取得する
    Authentication = "Unregistered"
    # 合致する全てのセルを取得する
    cell_list = sh.findall(Authentication)
    # Idmを取得する
    for cell in cell_list:
        row_number = cell.row - 1
        Unregistered_Idm = all_data[row_number][2]
        Unregistered_IC_list.append(Unregistered_Idm)
    print("未登録ICリスト")
    print(Unregistered_IC_list)

    print("*** ICカード認証情報更新 {0} ***".format(now))

    # Lineにメッセージを送信
    message = ('ICカード認証情報が更新されました 許可ICリスト:{0} 非許可ICリスト:{1} 未登録ICリスト:{2}'.format(str(Allow_IC_list).replace(" ", ""), str(Deny_IC_list).replace(" ", ""), str(Unregistered_IC_list).replace(" ", "")))#半角スペースを入れると改行 cf:line_notify.py
    cmd_line = ('python3 line_notify.py {0}'.format(message))
    subprocess.Popen(cmd_line.split())

    ### IC_listを返す
    IC_list.append(Allow_IC_list)
    IC_list.append(Deny_IC_list)
    IC_list.append(Unregistered_IC_list)
    return IC_list


# 未登録のカード情報をスプレッドシートに記載する
def write_Unregistered_IC_info():
    global latest_Idm
    global Allow_Idm_list
    global Deny_Idm_list
    global Unregistered_Idm_list
    # 未登録カードとして既にスプレッドシートに記載されているか確認、記載されていない場合は記載する
    if(latest_Idm in Unregistered_Idm_list):
        pass
    else:
        # API再認証
        gspred_recertification()
        now      = datetime.datetime.today()
        now_date = '{0:%Y-%m-%d}'.format(now)
        now_time = '{0:%H:%M:%S}'.format(now)
        cmd = ('python3 gsp-homeauto.py 3 {0} {1} {2} {3}'.format(now_date, now_time, latest_Idm, 'Unregistered'))
        print("未許可カード登録中")
        subprocess.call(cmd.split()) 
        print("未許可カードの登録が完了しました")
        # ICリストを更新する
        all_Idm_list          = get_IC_list()
        Allow_Idm_list        = all_Idm_list[0]
        Deny_Idm_list         = all_Idm_list[1]
        Unregistered_Idm_list = all_Idm_list[2]


# スプレッドシートに記載されている未認証のICカード全ての認証をAllowにする
def register_IC():
    global latest_Idm
    global sh
    global Allow_Idm_list
    global Deny_Idm_list
    global Unregistered_Idm_list

    # API再認証
    gspred_recertification()
    ### UnregisteredとなっているIdmリストを取得する
    Authentication = "Unregistered"
    # 合致する全てのセルを取得する
    cell_list = sh.findall(Authentication)
    # Idmを取得する
    for cell in cell_list:
        sh.update_cell(cell.row, 4, 'Allow')
    # ICリストを更新する
    all_Idm_list          = get_IC_list()
    Allow_Idm_list        = all_Idm_list[0]
    Deny_Idm_list         = all_Idm_list[1]
    Unregistered_Idm_list = all_Idm_list[2]


# スプレッドシートに記載されている未認証のICカード全ての認証をDenyにする
def unregister_IC():
    global latest_Idm
    global sh
    global Allow_Idm_list
    global Deny_Idm_list
    global Unregistered_Idm_list

    # API再認証
    gspred_recertification()
    ### UnregisteredとなっているIdmリストを取得する
    Authentication = "Unregistered"
    # 合致する全てのセルを取得する
    cell_list = sh.findall(Authentication)
    # Idmを取得する
    for cell in cell_list:
        sh.update_cell(cell.row, 4, 'Deny')
    # ICリストを更新する
    all_Idm_list          = get_IC_list()
    Allow_Idm_list        = all_Idm_list[0]
    Deny_Idm_list         = all_Idm_list[1]
    Unregistered_Idm_list = all_Idm_list[2]


# ICカード認証情報を再取得する(スプレッドシートを直接変更した場合等に行う)
def IC_list_update():
    global Allow_Idm_list
    global Deny_Idm_list
    global Unregistered_Idm_list

    # API再認証
    gspred_recertification()
    # ICリストを更新する
    all_Idm_list          = get_IC_list()
    Allow_Idm_list        = all_Idm_list[0]
    Deny_Idm_list         = all_Idm_list[1]
    Unregistered_Idm_list = all_Idm_list[2]


# APIを使用するたびに再認証する(一定期間経過するとAPIにアクセスできなくなってしまうため)
def gspred_recertification():
    global key_name
    global sheet_key
    global sheet_name
    global sh
    #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)

    #workbookを開く
    wb = gc.open_by_key(sheet_key)
    #sheetを指定
    sh = wb.worksheet(sheet_name)





#//////////////////////////////////////////////////////////////
# beebotteに関する関数
#//////////////////////////////////////////////////////////////
def on_connect(client, userdata, flags, respons_code):
    now = datetime.datetime.today()
    now_date = '{0:%Y-%m-%d}'.format(now)
    now_time = '{0:%H:%M:%S}'.format(now)
    print('status {0} : {1} {2}'.format(respons_code, now_date, now_time))


def on_disconnect(client, userdata, flags, respons_code):
    if  respons_code != 0:
        print("Unexpected disconnection.")
    else:
        print('disconect')
        print(respons_code)
    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]

    global Terminal
    Terminal = data["terminal"]

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

    elif (data["device"] == 'IC'):
        if   (data["action"] == 'register'):
            register_IC()
        elif (data["action"] == 'unregister'):
            unregister_IC()
        elif (data["action"] == 'update'):
            IC_list_update()
        else:
            print('unknown message')

    else:
            print('unknown message')





#//////////////////////////////////////////////////////////////
# メイン処理
#//////////////////////////////////////////////////////////////
if __name__ == '__main__':

    try:
        # Idmリストをスプレッドシートから取得
        gspred_recertification()
        all_Idm_list          = get_IC_list()
        Allow_Idm_list        = all_Idm_list[0]
        Deny_Idm_list         = all_Idm_list[1]
        Unregistered_Idm_list = all_Idm_list[2]

        # beebotte
        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, 60)
        client.subscribe(TOPIC)

        # libpafe
        libpafe = cdll.LoadLibrary("/usr/local/lib/libpafe.so")
        libpafe.pasori_open.restype = c_void_p
        pasori = libpafe.pasori_open()
        libpafe.pasori_init(pasori)
        libpafe.felica_polling.restype = c_void_p
        executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
        executor.submit(IC_read)

        # プッシュボタン
        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()
        # libpafe.free(felica)
        # libpafe.pasori_close(pasori)

プログラム上のコードの右側に #要変更 と書いてある部分は適宜変更してください。

また、コード中の

python3 gsp-homeauto.py x {0} {1} {2} {3} 

の部分の一つ目の引数(上記のxの部分はスプレッドシートの番号にあたる部分なので、こちらも変更してください)

   

・スプレッドシート記入プログラム

メインプログラムで gsp-homeauto.py として呼び出している、 鍵の開閉状況をスプレッドシートに記載するためのプログラムは、以下の記事の gspred.py にあたるプログラムです。

このプログラムや使い方については以前紹介したのでここでは省略します。
詳しくは以下を参照してください。

   

・LINE通知プログラム

メインプログラムで line_notify.py として呼び出している、ラインに任意のメッセージを送信できるプログラムです。

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

import argparse
import requests
import sys
 
def PythonNotify(message):
    # 設定
    line_notify_api = 'https://notify-api.line.me/api/notify'
    line_notify_token = 'xxxxxxxxxxxxxxxxxxxxxxxx' 
    headers = {'Authorization': 'Bearer ' + line_notify_token}   
    
    # メッセージ
    payload = {'message': message}

    # 送信
    requests.post(line_notify_api, data=payload, headers=headers)
  
 
if __name__=='__main__':

    #引数の設定
    parser = argparse.ArgumentParser()
    parser.add_argument("message", help="Please enter your message", type=str, nargs='?', default='メッセージが入力されていません')
    parser.add_argument("message1", help="Please enter your message", type=str, nargs='?', default='')
    parser.add_argument("message2", help="Please enter your message", type=str, nargs='?', default='')
    parser.add_argument("message3", help="Please enter your message", type=str, nargs='?', default='')
    parser.add_argument("message4", help="Please enter your message", type=str, nargs='?', default='')
    parser.add_argument("message5", help="Please enter your message", type=str, nargs='?', default='')
    parser.add_argument("message6", help="Please enter your message", type=str, nargs='?', default='')
    parser.add_argument("message7", help="Please enter your message", type=str, nargs='?', default='')
    parser.add_argument("message8", help="Please enter your message", type=str, nargs='?', default='')
    parser.add_argument("message9", help="Please enter your message", type=str, nargs='?', default='')


    args = parser.parse_args()

    #引数受け取り
    message = '\n' + args.message + '\n' + args.message1 + '\n' + args.message2 + '\n' + args.message3 + '\n' + args.message4 + '\n' + args.message5 + '\n' + args.message6 + '\n' + args.message7 + '\n' + args.message8 + '\n' + args.message9
    PythonNotify(message)

   

(※このプログラムはラインのAPIであるLINE Notifyというものを使用しています。 LINE Notify の設定方法などについてはたくさん投稿されており、非常に簡単に設定できるのでここでは省略します。)

プログラム中の line_notify_token の部分はご自身のトークンを設定してください。

このプログラムは、実行時に引数にメッセージを入力することで、その引数で指定したメッセージがラインで送信されるプログラムです。また、引数は最大10個まで入力することができ、2つ以上の引数を入力した場合、その各メッセージが改行されて送信されます。

例えば、

python3 line_notify.py スマートロック情報 許可済みID:xxxx 非許可ID:xxxx

として実行すると、

ラインに

スマートロック情報 
許可済みID:xxxx 
非許可ID:xxxx

として送信されます。

     

②スプレッドシート作成

図の認証情報更新をクリックすると、Google Apps Script (GAS)が実行されて、MQTTのブローカーである Beebotte にHTTPリクエストが送られ、ラズパイのICカード情報更新処理が実行されるという流れです。

記事が長くなってしまうので、別の記事に記載しました。

以下の記事をご覧ください。

    

google ads




google ads




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

執筆者:


  1. sesameをsuicaで より:

    ワクワクしながら拝見させて頂きました。
    当方、スマートロックにsesameを利用しています。
    https://jp.candyhouse.co/

    先月新しいsesame3の発表がありました。
    https://www.youtube.com/watch?v=gODCjYqQdp4

    sesameユーザーには
    スマホなしでsuicaで鍵を開けたい方が多くいると思います。
    特に携帯・スマホ禁止の小学生を持つ親には
    suicaでsesameを開けたい方は多いと思います。

    みんながjorujiさんみたいなスキルを持っていればいいのですが、
    世の中そんな風には行きません。

    sesameの公式ブログでも紹介はしてますが、
    実際にこの記事だけで出来る人はそんなに多くないと思っています。
    https://ameblo.jp/candyhouse-inc/entry-12413908790.html

    jorujiさんのブログでsesameユーザーが簡単に
    suicaで鍵を開ける事が出来る記事を1から書いて貰えると助かります。
    それなりにアクセス取れるんじゃないかと思ってますが…。

    よろしくお願いいたします。

    • joruji より:

      コメントおよび情報提供ありがとうございます!

      セサミ自体は知っていたのですが、数万円するという認識だってので手が出せずにいました。
      私がスマートロックを自作しようとした理由は自作すれば自分好みにカスタマイズできるという理由もありますが、一番はやはり市販のスマートロックが高いからでした。
      youtubeをみて驚きましたが、最新のモデルではセサミは5000円ほどで買えるほどに値下げしたんですね、驚きです!
      セサミはAPIもサポートしているとのことなので、ICカードとの連携は簡単にできそうですね。
      もうすでにこの自作のスマートロックを利用していて必要ないのですが、面白そうなので早速購入させていただきました(^^)
      届くのは早くて2月末くらいになるようです。
      届き次第suicaとの連携を実装し、できる限り誰でも簡単にできるように記事を書いてみたいと思います!

comment

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

CAPTCHA


関連記事

1200円でカメラ、wi-fi、Bluetooth付きの激安マイコンで遊んでみた

    最近、研究室の3Dプリンターの稼働状況を監視するためにカメラを設置しようと思いたち、激安のカメラを探していました。 最初は以前こちらの記事で紹介したようにWebカメラとラズパイを用いてストリー …

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

前回、前々回に続き、3回目の電子工作です。玄関の鍵が面倒だと感じたことは誰しも一度はありますよね。鍵をかばんやポケットから取り出すのが地味にめんどくさかったり、鍵をなくしてしまって困ってしまったという …

壊れたイヤホンを半田ごてを使って直してみた – 修理方法解説

   長年使用していたイヤホンが壊れてしまったので、半田ごてを使用して直してみました。この記事ではイヤホンの直し方について解説します。 (イヤホンの構造によって多少直し方は異なる場合があります。) 今 …

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

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

RaspberryPiのセットアップ ① – 2種類のOSインストール方法と基本設定

 この記事では、私がラズパイにOSをインストールするたびに行っているRaspberryPiのセットアップについて記載します。ここでは、NOOBSとイメージファイルによる2種類のOSのインストール方法と …




関連記事