nfcpy
NFCタグを読み書きしたり,別のNFCデバイスと通信するPythonモジュール
サマリ
環境に依存しない話
nfcpyはPyhon3で動く
Windows環境
ZadigでドライバをWinUSBに変更する
libusb 1.0.22以降を使う場合はpyusbは1.0.2より新しい版を使う
OSError: exception: access violation writing 0x0000000000000024が出る
pip install git+https://github.com/pyusb/pyusb.git
examples/tagtool.pyを試したい場合は1.0.3より新しい版を使う
1.0.3のexamples/tagtool.pyはエラーが出る
pip install git+https://github.com/nfcpy/nfcpy.git
Rasbian環境
RC-S370は使えない
/etc/udev/rules.d/nfcdev.rulesでデバイスをplugdevグループに入れておく
RC-S380の場合
code:console
pi@raspberrypi:~ $ sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"06c3\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
リブートする
/icons/hr.icon
code:sample.py
import nfc
import ndef
# 読み取る対象を返す。Noneを返すとconnectがすぐに抜ける
def on_startup(tag):
# Trueを返すと存在確認ループから抜けなくなるのでconnectが抜けなくなる
# tagにはタッチしたタグが入ってくる
def on_connect(tag):
return True
# Trueを返すと存在確認ループから抜ける
# tagにはタッチされていたタグが入る?
def on_release(tag):
return False
if __name__ == "__main__":
clf = nfc.ContactlessFrontend()
if not clf.open('usb'):
raise RuntimeError("Failed to open NFC device.")
config = {
'interval': 0.01,
'on-startup': on_startup,
'on-connect': on_connect,
'on-release': on_release
}
while True:
ret = clf.connect(rdwr=config)
if ret is None:
pass
elif not ret:
print("NFC connection terminated due to an exception.")
break
else:
pass
clf.close()
/icons/hr.icon
注意点
pyusbはリポジトリから1.0.2より新しい版を入れる
libusb 1.0.22 以降を使う場合,pyusb 1.0.2だとaccess violationが出る
pip install git+https://github.com/pyusb/pyusb.git
nfcpy 1.0.3のexamples/tagtool.pyは動かない
code:console
(nfcpy3) c:\home\saito\src\nfcpy> python examples\tagtool.py show
Traceback (most recent call last):
File "examples\tagtool.py", line 620, in <module>
TagTool().run()
File "examples\tagtool.py", line 296, in __init__
super(TagTool, self).__init__(parser, groups="rdwr card dbg clf")
File "C:\home\saito\src\nfcpy\examples\cli.py", line 85, in __init__
ch = ColorStreamHandler()
File "C:\home\saito\src\nfcpy\examples\cli.py", line 500, in __init__
crtlib = ctypes.cdll.LoadLibrary(crtname)
File "C:\home\saito\.conda\envs\nfcpy\lib\ctypes\__init__.py", line 434, in LoadLibrary
return self._dlltype(name)
File "C:\home\saito\.conda\envs\nfcpy\lib\ctypes\__init__.py", line 356, in __init__
self._handle = _dlopen(self._name, mode)
TypeError: LoadLibrary() argument 1 must be str, not None
pip install git+https://github.com/nfcpy/nfcpy.git
OptionsメニューからList All Devicesにチェックを入れるとNFCリーダがリストに出てくる
https://gyazo.com/e571f011a412361408f814ed0e05c20e
USB IDにベンダーIDとプロダクトIDが出る
ソニーRC-S370
プロダクトID:02e1
2つ同じNFCリーダを繋いでいる場合,2つデバイスが見えているけど,ドライバの入れ替えはどちらか一方でいい
saitotetsuya.iconまぁ,そりゃあたりまえだけど
MS64\dll\libusb-1.0.dllをC:\Windows\System32にコピー
MS32\dll\libusb-1.0.dllをC:\Windows\SysWOW64にコピー
Pyhon環境の設定
code:console
(base) c:\home\saito\src> conda create -n nfcpy3 python=3
(base) c:\home\saito\src> conda activate nfcpy3
(nfcpy3) c:\home\saito\src> python -m nfc
This is the 1.0.3 version of nfcpy run in Python 3.8.0
on Windows-10-10.0.19033-SP0
I'm now searching your system for contactless devices
** found SONY RC-S380/P NFC Port-100 v1.11 at usb:001:012
** found SONY RC-S380/P NFC Port-100 v1.11 at usb:001:011
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs
NFCタグの表示
code:console
(base) c:\home\saito\src> conda activate nfcpy3
(nfcpy) c:\home\saito\src> cd nfcpy
(nfcpy) c:\home\saito\src\nfcpy> python examples\tagtool.py show
nfc.clf searching for reader on path usb nfc.clf using SONY RC-S380/P NFC Port-100 v1.11 at usb:001:014 ** waiting for a tag **
Type2Tag 'NXP NTAG213' ID=0458E242XXXXXX
NDEF Capabilities:
readable = yes
writeable = yes
capacity = 137 byte
message = 37 byte
NDEF Message:
record 1
type = 'urn:nfc:wkt:U'
name = ''
usb1.USBErrorNotSupported: LIBUSB_ERROR_NOT_SUPPORTED [-12]で落ちるのはドライバがWinUSBになってない場合
/icons/hr.icon
Raspberry Pi環境でのインストール
RC-S370は使えない
code:console
pi@raspberrypi:~ $ sudo apt istall git
pi@raspberrypi:~ $ sudo apt install python3-dev
pi@raspberrypi:~ $ sudo apt install python3-pip
pi@raspberrypi:~ $ sudo pip3 install nfcpy
pi@raspberrypi:~ $ lsusb | grep Sony
Bus 001 Device 008: ID 054c:06c3 Sony Corp. RC-S380
Bus 001 Device 007: ID 054c:06c3 Sony Corp. RC-S380
※RC-S380を2つ繋いだ状態
$ python3 -m nfc
This is the 1.0.3 version of nfcpy run in Python 3.7.3
on Linux-4.19.73-v7+-armv7l-with-debian-10.1
I'm now searching your system for contactless devices
** found usb:054c:06c3 at usb:001:008 but access is denied
-- the device is owned by 'root' but you are 'pi'
-- also members of the 'root' group would be permitted
-- you could use 'sudo' but this is not recommended
-- better assign the device to the 'plugdev' group
sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"06c3\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
sudo udevadm control -R # then re-attach device
** found usb:054c:06c3 at usb:001:007 but access is denied
-- the device is owned by 'root' but you are 'pi'
-- also members of the 'root' group would be permitted
-- you could use 'sudo' but this is not recommended
-- better assign the device to the 'plugdev' group
sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"06c3\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
sudo udevadm control -R # then re-attach device
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs
Sorry, but I couldn't find any contactless device
※RC-S380をplugdevグループに入れる
pi@raspberrypi:~ $ sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"06c3\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
pi@raspberrypi:~ $ sudo udevadm control -R
pi@raspberrypi:~ $ python3 -m nfc
This is the 1.0.3 version of nfcpy run in Python 3.7.3
on Linux-4.19.73-v7+-armv7l-with-debian-10.1
I'm now searching your system for contactless devices
** found SONY RC-S380/P NFC Port-100 v1.11 at usb:001:012
** found SONY RC-S380/P NFC Port-100 v1.11 at usb:001:011
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs
同じNFCリーダを複数つないだ場合にそれぞれを特定したい
code:console
pi@raspberrypi:~$ lsusb | grep Sony
Bus 001 Device 016: ID 054c:06c3 Sony Corp. RC-S380
Bus 001 Device 011: ID 054c:06c3 Sony Corp. RC-S380
ベンダーIDとプロダクトIDは当然同じ
デバイス番号は挿すたびに変わる
/icons/hr.icon
メモ
code:console
Exception ignored in: <function _AutoFinalizedObjectBase.__del__ at 0x00000249AFEC74C8>
Traceback (most recent call last):
File "C:\ProgramData\Miniconda3\envs\donpisha\lib\site-packages\usb\_objfinalizer.py", line 84, in __del__
self.finalize()
File "C:\ProgramData\Miniconda3\envs\donpisha\lib\site-packages\usb\_objfinalizer.py", line 144, in finalize
self._finalizer()
File "C:\ProgramData\Miniconda3\envs\donpisha\lib\weakref.py", line 572, in __call__
return info.func(*info.args, **(info.kwargs or {}))
File "C:\ProgramData\Miniconda3\envs\donpisha\lib\site-packages\usb\_objfinalizer.py", line 104, in _do_finalize_object_ref
obj._do_finalize_object()
File "C:\ProgramData\Miniconda3\envs\donpisha\lib\site-packages\usb\_objfinalizer.py", line 71, in _do_finalize_object
self._finalize_object()
File "C:\ProgramData\Miniconda3\envs\donpisha\lib\site-packages\usb\backend\libusb1.py", line 604, in _finalize_object
_lib.libusb_unref_device(self.devid)
OSError: exception: access violation writing 0x0000000000000024
libusbの問題ではなくpyusbの問題と言っている
1.0.3に反映されそう?