概要
USB接続のNFC/FelicaリーダーライタであるSONYのPaSoRi(RC-S380)を使って、Mac上のpythonから、安価なNFCタグ(NTAG)を読み書きする方法をまとめます。
基本は nfcpy で一発です。
試していませんが、Raspberry Piでも同じ方法で使える模様。
(追記)Raspbian でも、インストール手順としては、sudo apt-get install python-pip; sudo pip install nfcpy だけで OK でした。
ただし、一般権限で usb にアクセスするためには、Raspberry Pi に nfcpy をインストールする手順 - 2016年3月 私家版の後半に書かれた手順が必要です。
環境セットアップ手順
前提
brew の python 2.7 を用いています。システム側の python でもできるはずですが、openssl のバージョンがどうなっているのか微妙なところですので、うまく動かなかったら試行錯誤してください。
nfcpy
bzr で nfcpy を持ってくる手順が紹介されていることが多いですが、pip で一発です。
> brew install libusb
> pip install nfcpy
openssl 関連でハマったら
python の REPL で import nfc と打って問題なくロードできれば良いですが、openssl に含まれる libcrypto のロードに失敗するケースがあります。
>>> import nfc
(中略)
AttributeError: dlsym(0x7fbc82c404a0, EC_KEY_set_public_key_affine_coordinates): symbol not found
対策として、brew で新しい openssl をインストールして link すれば OK と書いてある記事が多いのですが、
> brew link openssl --force
Warning: Refusing to link: openssl
と言われて link できません。
/usr/local/opt/openssl/lib 以下に最新の libcrypto.1.0.0.dylib がインストールされていますので、ここをダイナミックリンクライブラリのロードパスに指定すればとりあえず動きます。正しい対処方法はどうすればいいのか……。
export DYLD_LIBRARY_PATH=/usr/local/opt/openssl/lib:$DYLD_LIBRARY_PATH
NFC タグの読み書き
nfcpy の公式サンプル
公式のget-startedを読むか、examples にあるサンプルを見れば、だいたい使い方はわかります。サンプル単体でコマンドとしても使えます(使い方)
例えば、以下のコマンドで NFC タグの情報を表示できます。
> python tagtool.py show
YouTube 動画を開くデータを NTAG に書き込むには以下の通り。
> python ndeftool.py make smartposter -t PPAP https://youtu.be/0E00Zuayv9Q | python tagtool.py load -
自力で書く
nfcpy を使って自力で必要な処理を書く場合は以下のようなコードとなります。
import nfc
import nfc.ndef
def startup(targets):
print "waiting for new NFC tags..."
return targets
def connected(tag):
if not tag.ndef or not tag.ndef.is_writeable:
print("not a writeable nfc tag")
return False
print("old message:")
print(tag.ndef.message.pretty())
smartposter = nfc.ndef.SmartPosterRecord("https://youtu.be/0E00Zuayv9Q")
smartposter.title = "PPAP"
new_message = nfc.ndef.Message(smartposter)
if len(str(new_message)) > tag.ndef.capacity:
print "too long message"
return True
if tag.ndef.message == new_message:
print "already same record"
return True
tag.ndef.message = new_message
print("new message:")
print(tag.ndef.message.pretty())
return True
def released(tag):
print("released:")
if tag.ndef:
print(tag.ndef.message.pretty())
clf = nfc.ContactlessFrontend('usb')
print(clf)
if clf:
while clf.connect(rdwr={
'on-startup': startup,
'on-connect': connected,
'on-release': released,
}):
pass
Ctrl-C で止めるまで、ひたすら NFC タグを YouTube 動画を開くものに書き換えます。
参考URL
nfcpy で複数の System Code を持つ NFC タグを扱う方法
Raspberry Pi に nfcpy をインストールする手順 - 2016年3月 私家版