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

このエントリは「[Raspberry Piでスマートロックつくった](https://qiita.com/undo0530/items/669b6ee6b2277ea64b33)」の解説3つめになります。
スマートロックなのでカッコよくしたいです。なのでNFCリーダを使い、ドアの外からSuicaをタッチしたらカギを開閉できるようにします。このエントリではSONYのNFCリーダPaSoRi RC-S380をRaspberry Piに接続し、SuicaカードをタッチしてIDmを取り出すまでをやってみます。
# 準備
RC-S380はAmazonなどで3000円くらいで買えます。家電量販店でもたまに売ってます。
PythonでNFCリーダを取り扱うライブラリとしてnfcpyというのがあるのでインストールします。

```bash
$ sudo pip install nfcpy
```
また、Githubからサンプルコードも頂戴しておきます。
[nfcpy | Github](https://github.com/nfcpy/nfcpy)
それではさっそくRC-S380をRaspberry PiにUSB接続し、examples/tagtool.pyを実行してみます。なおnfcpyはPython2.xで動作します。

```bash
$ 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を取り出すプログラムを動かしてみます。

```python: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
```
実行するには管理者権限が必要です。

```bash
sudo python2 suica.py
```
Suicaをタッチしてみて、IDmが表示されれば成功です。
自分が普段使うSuicaのIDmを覚えさせておき、次回以降同じカード=同じIDmがタッチされた時はサーボを回してカギを開ける、という風に実装すればいよいよスマートロックっぽくなってきます。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">やったーSuicaで鍵の開け閉めするやつできたよー＼(^o^)／<br>外からの操作はドア越しのSuicaタッチで。<br>中からの操作はボタンで。（鍵に被せちゃうと手で直接回すのが大変なので）<br>LEDの色で鍵の開閉状況もわかるぞ<br>しかも脳波コントロールできる<a href="https://twitter.com/hashtag/RaspberryPi?src=hash&amp;ref_src=twsrc%5Etfw">#RaspberryPi</a> <a href="https://t.co/wHOqH1rjl1">pic.twitter.com/wHOqH1rjl1</a></p>&mdash; undo (@undo) <a href="https://twitter.com/undo/status/936887490635374595?ref_src=twsrc%5Etfw">2017年12月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
なお、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を調べます。

```bash
$ lsusb
Bus 001 Device 004: ID XXXX:YYYY Sony Corp.
```
上記のXXXX、YYYYという部分に表示されるIDを使って、下記のとおりコマンドを実行します。

```bash
$ 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を操作する](https://qiita.com/undo0530/items/0d9eee70da46f906062a)