Raspberry PiにNFCリーダを接続してSuicaを読み取る

More than 1 year has passed since last update.

このエントリは「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を取り出すプログラムを動かしてみます。


suica.py

# -*- 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


管理者権限なしで動かす

実行する時にsudoしなくてもいいようにします。

まずlsusbコマンドを打って接続されているRC-S380のIDを調べます。

$ 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を操作する