ラズパイの本体には剣山のようなものがありますが、当たり前ですが花を生けるものではありません。
GPIOピンと言ってデジタル信号の入出力用のものです。電子工作をしていくうえでLチカ(LEDをチカチカさせること)をやる言わば電子工作の登竜門のような作業です。
Lチカに関する記事は腐るほどあるので出力の確認作業のみ行います。
ブザーを鳴らすタイミングは2通りで、
①登録してあるICカード以外のものがタッチされたときピッと0.5秒鳴らす
②何らかの影響でネットワークにエラーが発生してレスポンスが200以外のものが返ってきたときにピッピッピッ(0.5秒ONを3サイクル)と鳴らす
の二通りにしました。 毎回解錠処理の度にブザーが鳴ると鬱陶しそうな気がしたので何か不具合があったときだけにしました。
import datetime, base64, requests, json, binascii, nfc, os, time import RPi.GPIO as GPIO from threading import Thread, Timer from Crypto.Hash import CMAC from Crypto.Cipher import AES idm1 = b"お手持ちのICカード1" idm2 = b"お手持ちのICカード2" pin = 40 #GPIOのピン指定 #ICカード待受の1サイクル秒 TIME_cycle = 1.0 #ICカード待受の反応インターバル秒 TIME_interval = 0.2 #タッチされてから次を開始するまでの無効化する秒 TIME_wait = 3 #NFC接続リクエストのための準備 #212F(Felica)で設定 target_req_ic = nfc.clf.RemoteTarget("212F") #0003(IC cart) target_req_ic.sensf_req = bytearray.fromhex("0000030000") print('ICカードをタッチしてください...') while True: #USB接続されたカードリーダーをインスタンス化 clf = nfc.ContactlessFrontend('usb') #ICカード待受開始 target_res = clf.sense(target_req_ic, iterations=int(TIME_cycle//TIME_interval)+1, interval=TIME_interval) if not target_res is None: tag = nfc.tag.activate_tt3(clf, target_res) tag.sys = 3 #IDmを取り出す idm = binascii.hexlify(tag.idm) print(idm) #特定のIDmだった場合のアクション if idm == idm1 or idm == idm2: uuid = '個人のUUID' secret_key = '個人のシークレットキー' api_key = '個人のAPIキー' # HTTP header headers = { 'x-api-key': api_key } # signの生成 cmac = CMAC.new(bytes.fromhex(secret_key), ciphermod=AES) message = int(datetime.datetime.now().timestamp()).to_bytes(4, 'little', signed=False)[1:4] cmac.update(message) sign = cmac.hexdigest() print("【 特定のIDmにより施解錠 】") #鍵の状態取得 surl = f'https://app.candyhouse.co/api/sesame2/{uuid}' sres = requests.get(surl, headers=headers) #リクエスト print(sres.text) if "unlocked" in sres.text: print("close") cmd = 82 history = 'close (Web API)' else: print("open") cmd = 83 history = 'open (Web API)' history = base64.b64encode(history.encode()).decode() #履歴に「open」or「close」を記載 url = f'https://app.candyhouse.co/api/sesame2/{uuid}/cmd' body = { 'cmd': cmd, 'history': history, 'sign': sign } res = requests.post(url, json.dumps(body), headers=headers) print(res.status_code, res.text) str_res = str(res.status_code) #ネットワークでエラーが発生して200が返ってこない場合の処理 if not "200" in str_res: print("NG") #GPIOピン設定 GPIO.setmode(GPIO.BOARD) GPIO.setup(pin,GPIO.OUT) GPIO.output(pin, 1) time.sleep(0.5) GPIO.output(pin, 0) time.sleep(0.5) GPIO.output(pin, 1) time.sleep(0.5) GPIO.output(pin, 0) time.sleep(0.5) GPIO.output(pin, 1) time.sleep(0.5) GPIO.output(pin, 0) time.sleep(0.5) GPIO.cleanup() time.sleep(TIME_wait) else: print("カードが違います") #GPIOピン設定 GPIO.setmode(GPIO.BOARD) GPIO.setup(pin, GPIO.OUT) GPIO.output(pin, 1) time.sleep(0.5) GPIO.output(pin, 0) GPIO.cleanup() time.sleep(TIME_wait) clf.close() #end while
記事にしながらプログラムを見返していたんですなんとも見にくい書き方してますね。
正常に動くし見栄えが悪いだけなので特に書き直す予定はありませんが。
完成したプログラムから必要なところを抜粋しながら書いているのでもしかしたら抜けてるところがあってうまく動かないかもしれません。
その際はご指摘いただければと思います。