[英]nfcpy: How to get on-release event correctly with NFCPY?
我嘗試使用 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)
您可能需要在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
這個討論幫助我弄清楚如何解決這個問題。
當非常仔細地閱讀文檔( 'on-release' : function(tag)
)時——是的,我花了一些循環——很明顯,只要on-connect
返回True
就會調用on-release
。
當存在檢查運行( 'on-connect' 函數返回真值)並確定與標簽的通信變得不可能時,或者當'terminate' 函數返回真值時調用此函數。 標記對象可用於清除操作,但不能用於通信。
似乎不能以物理方式理解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})
當我將它呈現給讀者時,我希望它回顯標簽 ID,一旦我刪除它,回顯“再見”。 這在我擁有的 Type4 標簽上按預期工作..
恐怕這些卡是 nfcpy 不支持的 Mifare Classic 1K。 可以讀取 UID,但任何其他命令都需要先進行身份驗證並使用 Mifare 加密方案。 這應該可以通過 NXP 閱讀器 IC 實現 [...]。 恩智浦有很多與 NFC 論壇兼容的 Type 2 標簽,效果很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.