nfcpy:如何使用NFCPY正确获取发布事件?

时间:2019-02-28 10:58:49

标签: python nfc rfid

我尝试使用ACR122阅读器和nfcpy python库收听不同的RFID ID卡。

我想在用户连接时获得卡的ID(一遍又一遍无法识别),并在用户释放卡时获得一个事件。理想情况下是循环播放,以便在用户将卡拿走时收听下一张卡。

下面是我的代码,但是即使卡仍在读卡器上,也会触发on-release事件。正确的方法是什么

  1. 得到on-connect而又不认识又一遍吗?
  2. 当用户的卡不存在时得到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)

2 个答案:

答案 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标签,这些标签效果很好。