今回は、PythonでNFCをちょと触ってみました。
つまり、SuicaとかEdyとかに使われている技術です。以前Amazonの支払いでEdyを利用して自宅で支払いをしていたので、SonyのFelicaリーダーがあったので活用してみました。
参考サイト
nfcpy.readthedocs.org | http://nfcpy.readthedocs.org/en/latest/
Qoncept Tech Blog / nfcpyでお手軽NFC開発 | http://techblog.qoncept.jp/?p=165
環境
以前の記事で作成した通りの環境です。
- MacBookAir 2013
- Intel core i5 1.3GHz
- python2.X (anaconda-2.1.0)
- NFCリーダー
SONY RC-S370
NunPyを使うらしい&nfcpy.readthedocs.orgによると、nfcpyはpython2.X系でしか動かないようなので、anaconda-2.Xを使用しました。
最終的に導入したもの
- bzr (2.6.0)
- nfcpy (0.9.1)
- pyusb (1.0.0b2)
- libusb
- libusb-compat
導入作業
bzrのインストール
brew install bzr
bzr(Bazaar)とは
今回、nfcpyをインストールする際に利用しました。
nfcpyのインストール
先ほどインストールしたbzrを利用して、nfcpyをインストールします
bzr branch lp:nfcpy
bzrの使い方は実際、まったくよくわかってないです。これで、nfcpyを自分のPCにもってくることができました。
python-usbのインストール
brew install python-usbが見つからなかったので…http://sourceforge.net/projects/pyusb/にあるpyusb-1.0.0b2.zipを持ってきて解凍しました。(どうやら、pip install –pre pyusbでよかったみたいですね…。)
wget http://cznic.dl.sourceforge.net/project/pyusb/PyUSB%201.0/1.0.0-beta-2/pyusb-1.0.0b2.zip unzip pyusb-1.0.0b2.zip
そして、インストール
cd pyusb-1.0.0b2 python setup.py install
どうやら、pyenvでインストールできましたanaconda以下に入ったみたい。
libusbのインストール
brew install libusb
次にlibusb-compatを入れようとしたら、なんだかエラー
brew install libusb-compat --> Error: You must `brew link libusb' before libusb-compat can be installed
とりあえず実行…。
# brew link hoge でhogeパッケージの有効化を行う。 brew link libusb --> Linking /usr/local/Cellar/libusb/1.0.19... --> Error: Could not symlink lib/libusb-1.0.0.dylib --> Target /usr/local/lib/libusb-1.0.0.dylib --> already exists. You may want to remove it: --> rm '/usr/local/lib/libusb-1.0.0.dylib' --> To force the link and overwrite all conflicting files: --> brew link --overwrite libusb --> To list all files that would be deleted: --> brew link --overwrite --dry-run libusb
なんだかまた言われたので、言われるがままに実行
brew link --overwrite libusb # 今度は、何も言われなかった…。
そしてのインストール
brew install libusb-compat
今度こそ、無事に成功したみたいです。。。めでたしめでたし。
libusbが正しく入っていないと、サンプルを実行した際に以下のようなエラーがでました。
python tagtool.py show --> [nfc.clf] searching for reader with path 'usb' --> Traceback (most recent call last): --> File "tagtool.py", line 512, in <module> --> TagTool().run() --> File "/Users/takunoko/Develop/Python/nfc/nfcpy/examples/cli.py", line 283, in run --> while self.run_once() and self.options.loop: --> File "/Users/takunoko/Develop/Python/nfc/nfcpy/examples/cli.py", line 230, in run_once --> try: clf = nfc.ContactlessFrontend(device) --> File "/Users/takunoko/Develop/Python/nfc/nfcpy/nfc/clf.py", line 105, in __init__ --> if path and not self.open(path): --> File "/Users/takunoko/Develop/Python/nfc/nfcpy/nfc/clf.py", line 156, in open --> self.dev = nfc.dev.connect(path) --> File "/Users/takunoko/Develop/Python/nfc/nfcpy/nfc/dev/__init__.py", line 55, in connect --> found = transport.USB.find(path) --> File "/Users/takunoko/Develop/Python/nfc/nfcpy/nfc/dev/transport.py", line 169, in find --> for d in cls.usb_core.find(find_all=True, **match)] --> File "/Users/takunoko/.pyenv/versions/anaconda-2.1.0/lib/python2.7/site-packages/usb/core.py", line 1199, in find --> raise ValueError('No backend available') --> ValueError: No backend available
サンプルプログラムの実行
とりあえず、nfcpy/examples/にあるサンプルプログラムを実行してみました。
–> [nfc.clf] searching for reader with path ‘usb’
–> [nfc.clf] using Sony RC-S370/P at usb:020:019
–> [main] touch a tag
# (ここでSuicaをかざす)
–> Type3Tag IDm=01010410010f**** PMm=100b4b428485**** SYS=00**
# 隠す必要があるかわからないですが、**で伏せてあります。
[/shell]
おぉ…どうやら無事によめたっぽい。。。
ついでに、以前同好会で購入した書き込み可能なシールタイプのnfcタグも読んでみました。
[shell] python tagtool.py show–> [nfc.clf] searching for reader with path ‘usb’!!!
–> [nfc.clf] using Sony RC-S370/P at usb:020:019!!!
–> [main] touch a tag!!!
–> [nfc.dev] Driver.set_communication_mode() should be implemented.!!!
–> Type2Tag ATQ=4400 SAK=00 UID=04305bd2bb2b80
–> NDEF capabilities:
–> version = 1.0
–> readable = yes
–> writeable = yes
–> capacity = 135 byte
–> message = 36 byte
–> NDEF record list:
–> record 1
–> type = ‘urn:nfc:wkt:T’
–> name = ”
–> data = ‘\x02enHello World!\n\ntakunoko web :)’
[/shell]
おぉ…なんだかきちんと読めてるっぽい…すばらしい!
2016/12/6追記
サンプルを実行しようとしたところ、以下のように怒られました。
AttributeError: dlsym(0x7fdbe065ecf0, EC_KEY_set_public_key_affine_coordinates): symbol not found
opensslの更新をして無事にうまくいきました。
brew upgrade openssl brew link openssl --force
参考記事: nfcopyでNFCをやってみたんだぜ(1) – リハビリエンジニア
python – nfcpy: “Symbol not found”? – Stack Overflow
imoprt nfcをどこでも使えるようにする
※以下のやり方はたぶん正しくないです。あまり参考にしないでください…
lp:nfcpyを適当なディレクトリで実行して、サンプルの動作までを行いました。そこで、他のディレクトリでnfcをimportしようとすると…
python >> import nfc --> Traceback (most recent call last): --> File "<stdin>", line 1, in <module> --> ImportError: No module named nfc
とかって出てきます。これは、nfcへのパスが正しく指定されていないことが問題です。この正しい対処法は環境変数「PYTHONPATH」にnfcディレクトリが置かれている場所までのパスを追加することらしいです。
ですが、自分の場合はpyenvでインストールしていて、モジュールに関してpythonのバージョンごとに管理されています。それに則った対応をしたかったので…もともとパスの通っている場所にコピーしちゃいました。
# "~/.pyenv/versions/(利用しているバージョン)/lib/(pythonのバージョン)/" cp nfc ~/.pyenv/versions/anacoda-2.1.0/lib/python2.7/
これで、どこからでもimport nfcでnfcのモジュールが利用できるようになりました♪
(正しいやり方を知ってる方は、ぜひ教えていただきたい…w)
まとめ
Pythonを使ってnfcタグを読むことができました♪ これをつかって、研究室の入退室管理とか、Twitter連携とかできたら面白そうだな〜と考えています。
以上、”Pythonで遊んでみる -part2- (NFCを使ってみる)” でした! 次回をお楽しみに〜♪
訂正
2015/10/12 : pyusbインストールの際のコマンドにミスがあったので訂正しました。
視覚障害者のスマホやタブレット、PC利用を助ける仕事をやっています。いまWin7からWin10で、いろいろなアプリがNFCで始動できないか、勉強しています。nfcpyでWordやブラウザーを始動させるサンプルがあるでしょうか。
コメントありがとうございます。
nfcからWordやブラウザの起動とのことでしたが、Wordについては知識がなくお答えできないのですが、ブラウザについては自分の知る限りsplinterやseleniumなどといったモジュールを用いて起動することができます。
簡単ではありますがサンプルコードを作成しましたので、参考にしていただけると幸いです。
# coding: utf-8
# nfcからブラウザの起動
from splinter import Browser
import nfc
def start_browser(URL="https://example.com"):
____browser = Browser('firefox')
____browser.visit(URL)
def connected(tag):
____print("connected tag")
____print(tag)
____# nfcタグ書かれているURLなどの情報を取得することも可能だと思います。
____start_browser()
if __name__ == "__main__":
____# NFCポート作成
____clf = nfc.ContactlessFrontend('usb')
____# カード待機
____print("wait card")
____tag_data = clf.connect(rdwr={'on-connect': connected})
____clf.close()
(ブログの仕様上、コメント欄では行頭にあるスペースが省略されてしまうようなので、_アンダーバーに置き換えてあります。
行頭の_アンダーバーが4つ並んでいる箇所を全てスペースに置換したものが本来のソースコードとなります。)
Pingback: 学生証を読む。TuT | たくのこ Web