このエントリは「Raspberry Piでスマートロックつくった」の解説3つめになります。
スマートロックなのでカッコよくしたいです。なのでNFCリーダを使い、ドアの外からSuicaをタッチしたらカギを開閉できるようにします。このエントリではSONYのNFCリーダPaSoRi RC-S380をRaspberry Piに接続し、SuicaカードをタッチしてIDmを取り出すまでをやってみます。
準備
RC-S380はAmazonなどで3000円くらいで買えます。家電量販店でもたまに売ってます。
PythonでNFCリーダを取り扱うライブラリとしてnfcpyというのがあるのでインストールします。
$ sudo pip install nfcpy
また、Githubからサンプルコードも頂戴しておきます。
nfcpy | Github
それではさっそくRC-S380をRaspberry PiにUSB接続し、examples/tagtool.pyを実行してみます。なおnfcpyはPython2.xで動作します。
$ sudo python2 examples/tagtool.py
うまく行けば、「** waiting for a tag **」と表示されます。ここでSuica等のNFCタグをタッチすると、そのタグを読み込んだ結果が表示されます。Suicaに限らずPasmoやNanacoやマイナンバーカード等、身近にある色んなNFCタグをタッチしてみて下さい。
IDmを取り出す
SuicaやPasmo等のFeLiCaタグにはすべてIDmというユニークなIDが割り振られています。これはいわゆる製造番号のようなものだそうで、これを使えばタッチしたカードの個別な識別が可能になります。※ただしこのIDmはFeLiCaカードのエミュレーションにより偽装できてしまう点は留意しておくべきです。単なるパスワードとして考え厳重に管理し、それをタッチするだけで入力できるのがFeLiCaカード、と考えておくとよいでしょう。
さて、それではSuicaがタッチされた時にIDmを取り出すプログラムを動かしてみます。
# -*- coding: utf-8 -*-
import binascii
import nfc
import time
from threading import Thread, Timer
# Suica待ち受けの1サイクル秒
TIME_cycle = 1.0
# Suica待ち受けの反応インターバル秒
TIME_interval = 0.2
# タッチされてから次の待ち受けを開始するまで無効化する秒
TIME_wait = 3
# NFC接続リクエストのための準備
# 212F(FeliCa)で設定
target_req_suica = nfc.clf.RemoteTarget("212F")
# 0003(Suica)
target_req_suica.sensf_req = bytearray.fromhex("0000030000")
print 'Suica waiting...'
while True:
# USBに接続されたNFCリーダに接続してインスタンス化
clf = nfc.ContactlessFrontend('usb')
# Suica待ち受け開始
# clf.sense( [リモートターゲット], [検索回数], [検索の間隔] )
target_res = clf.sense(target_req_suica, iterations=int(TIME_cycle//TIME_interval)+1 , interval=TIME_interval)
if target_res != None:
#tag = nfc.tag.tt3.Type3Tag(clf, target_res)
#なんか仕様変わったっぽい?↓なら動いた
tag = nfc.tag.activate_tt3(clf, target_res)
tag.sys = 3
#IDmを取り出す
idm = binascii.hexlify(tag.idm)
print 'Suica detected. idm = ' + idm
print 'sleep ' + TIME_wait + ' seconds'
time.sleep(TIME_wait)
#end if
clf.close()
#end while
実行するには管理者権限が必要です。
sudo python2 suica.py
Suicaをタッチしてみて、IDmが表示されれば成功です。
自分が普段使うSuicaのIDmを覚えさせておき、次回以降同じカード=同じIDmがタッチされた時はサーボを回してカギを開ける、という風に実装すればいよいよスマートロックっぽくなってきます。
なお、nfcpyではよくconnect()メソッドを使ってタグ検知する手法が紹介されていますが、これではApple PayのExpress Cardに登録されたSuicaを検知できないようです。sense()を使うことでApple Pay内Suicaを検知できますが、今度は逆にconnect()で検知できていた各種NFCカードが検知できないようです。使用目的やお持ちのカードに合わせて選択すると良いかと思います。(参考:[nfcpy で Apple Pay のエクスプレスカードを扱う - Qiita](https://qiita.com/LinaNfinE/items/945a795e53427e768e47)) # 管理者権限なしで動かす 実行する時にsudoしなくてもいいようにします。 まずlsusbコマンドを打って接続されているRC-S380のIDを調べます。やったーSuicaで鍵の開け閉めするやつできたよー\(^o^)/
— undo (@undo) 2017年12月2日
外からの操作はドア越しのSuicaタッチで。
中からの操作はボタンで。(鍵に被せちゃうと手で直接回すのが大変なので)
LEDの色で鍵の開閉状況もわかるぞ
しかも脳波コントロールできる#RaspberryPi pic.twitter.com/wHOqH1rjl1
$ lsusb
Bus 001 Device 004: ID XXXX:YYYY Sony Corp.
上記のXXXX、YYYYという部分に表示されるIDを使って、下記のとおりコマンドを実行します。
$ sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"XXXX\", ATTRS{idProduct}==\"YYYY\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
これでsudo無しでもRC-S380を使えるようになりました。
Next:Raspberry PiでHueを操作する