ラズパイの本体には剣山のようなものがありますが、当たり前ですが花を生けるものではありません。
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
TIME_cycle = 1.0
TIME_interval = 0.2
TIME_wait = 3
target_req_ic = nfc.clf.RemoteTarget("212F")
target_req_ic.sensf_req = bytearray.fromhex("0000030000")
print('ICカードをタッチしてください...')
while True:
clf = nfc.ContactlessFrontend('usb')
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 = binascii.hexlify(tag.idm)
print(idm)
if idm == idm1 or idm == idm2:
uuid = '個人のUUID'
secret_key = '個人のシークレットキー'
api_key = '個人のAPIキー'
headers = { 'x-api-key': api_key }
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()
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)
if not "200" in str_res:
print("NG")
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.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()
記事にしながらプログラムを見返していたんですなんとも見にくい書き方してますね。
正常に動くし見栄えが悪いだけなので特に書き直す予定はありませんが。
完成したプログラムから必要なところを抜粋しながら書いているのでもしかしたら抜けてるところがあってうまく動かないかもしれません。
その際はご指摘いただければと思います。