我尝试使用ACR122阅读器和nfcpy python库收听不同的RFID ID卡。
我想在用户连接时获得卡的ID(一遍又一遍无法识别),并在用户释放卡时获得一个事件。理想情况下是循环播放,以便在用户将卡拿走时收听下一张卡。
下面是我的代码,但是即使卡仍在读卡器上,也会触发on-release
事件。正确的方法是什么
on-connect
而又不认识又一遍吗?on-release
吗? import nfc
def on_startup(targets):
return targets
def on_connect(tag):
uid = str(tag.identifier).encode("hex").upper()
print(uid)
return True
def on_release(tag):
print('Released')
return tag
rdwr_options = {
'on-startup': on_startup,
'on-connect': on_connect,
'on-release': on_release,
'beep-on-connect': False,
}
with nfc.ContactlessFrontend('usb') as clf:
tag = clf.connect(rdwr=rdwr_options)
答案 0 :(得分:0)
您可能需要在ContactlessFrontend
配置中设置间隔。试试这个例子:
import nfc
import ndef
tags = set()
rec = ndef.UriRecord("https://google.com")
def on_connect(tag):
if tag.identifier not in tags:
tags.add(tag.identifier)
fmt = tag.format()
if fmt is None:
print("Tag cannot be formatted (not supported).")
elif fmt is False:
print("Tag failed to be formatted (for some reason).")
else:
tag.ndef.records = [rec]
if __name__ == "__main__":
clf = nfc.ContactlessFrontend()
if not clf.open('usb'):
raise RuntimeError("Failed to open NFC device.")
while True:
config = {
'interval': 0.35,
'on-connect': on_connect
}
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()
https://gist.github.com/henrycjc/c1632b2d1f210ae0ff33d860c7c2eb8f
答案 1 :(得分:0)
This discussion帮助我弄清了解决方法。
当非常仔细地阅读the docs (‘on-release’ : function(tag)
)时–是的,这花了我一些时间–很明显on-release
返回on-connect
时就会调用True
。
当运行存在检查(“ on-connect”功能返回真实值)并确定无法与标签进行通信时,将调用此函数,或当“终止”函数返回真值时。标记对象可用于清除操作,但不可用于通信。
似乎on-release
不能以物理的方式来理解,而应该以一种交流的方式来理解(从通信中释放后,您现在可以删除卡)。
要解决此问题,需要确定卡连接后(或更确切地说,在释放后-稍后再进行介绍)是否存在卡。以下代码可以解决问题:
import nfc
import time
import logging
import inspect
logging.basicConfig(format="[%(name)s:%(levelname).4s] %(message)s")
logging.getLogger().setLevel(logging.DEBUG)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
def on_startup(targets):
logger.debug(inspect.currentframe().f_code.co_name)
for target in targets:
target.sensf_req = bytearray.fromhex("0012FC0000")
return targets
def on_discover(target):
logger.debug(inspect.currentframe().f_code.co_name)
logger.info(target)
return True
def on_connect(tag):
logger.debug(inspect.currentframe().f_code.co_name)
logger.info(tag)
return True
def on_release(tag):
logger.debug(inspect.currentframe().f_code.co_name)
# Loop while card is present
while True:
time.sleep(1)
if not clf.sense(*[nfc.clf.RemoteTarget(target) for target in rdwr_options["targets"]]):
logger.info("Card removed")
break
return True
rdwr_options = {
"targets": ("106A", "106B", "212F"),
"on-startup": on_startup,
"on-discover": on_discover, # Here just for completeness :)
"on-connect": on_connect,
"on-release": on_release,
}
if __name__ == "__main__":
logger.debug(inspect.currentframe().f_code.co_name)
with nfc.ContactlessFrontend() as clf:
if not clf.open("usb"):
raise RuntimeError("Failed to open NFC device.")
while True:
ret = clf.connect(rdwr=rdwr_options)
if not ret:
break
现在晚了:如果我们在on-connect
状态下等待卡的取出,则会遇到麻烦,因为on-release
希望从卡中检索信息(tag
参数),拔出卡后无法进行通讯,因此无法再使用。
PS:上面的讨论表明,on-release
的行为取决于一个人正在使用的卡的类型。
因此,我需要在有卡时和离开时都进行注册。我为此有一些Type2标签。
给出以下代码:
def connected(tag): print(tag) return True def released(tag): print("Bye") tag = clf.connect(rdwr={'on-connect': connected, 'on-release': released})
当我将其提供给 阅读器,并在删除后回显“ Bye”。这按预期工作 我有一个Type4标签。
恐怕这些卡是nfcpy不支持的Mifare Classic 1K。可以读取UID,但任何其他命令都需要先进行身份验证并使用Mifare加密方案。恩智浦读取器IC应该可以做到这一点。恩智浦提供了一系列与NFC论坛兼容的Type 2标签,这些标签效果很好。