如何用Python sllurp库终止Zebra FX9500 RFID阅读器的盘点循环?
解决sllurp单次/限时RFID盘点的问题
我之前用sllurp处理过类似的Zebra阅读器盘点需求,刚好能帮到你!先拆解你的两个核心问题:初始代码返回空标签列表和如何终止无限盘点循环。
为什么初始代码返回tags = []?
你的示例代码只建立了LLRP连接,但没有启动阅读器的盘点任务(ROSpec)。sllurp不会自动启动盘点,必须显式调用startInventory()方法,否则阅读器不会主动发送标签数据,自然返回空列表。
实现单次/限时盘点的两种方法
方法1:用内置的duration参数自动停止(推荐)
sllurp的LLRPClientFactory支持duration参数,它会自动配置阅读器的ROSpecStopTrigger为时间触发,到点后阅读器会主动停止盘点并通知客户端。这种方式最简洁,符合LLRP协议的标准流程。
修改后的代码:
from sllurp import llrp from twisted.internet import reactor import logging from datetime import datetime # 配置日志(可选,方便调试) logging.getLogger().setLevel(logging.INFO) # 存储收集到的所有标签 collected_tags = [] def tag_callback(tagReport): # 解析标签数据 tag_data = tagReport.msgdict['RO_ACCESS_REPORT']['TagReportData'] if tag_data: print(f"收到标签: {tag_data}") collected_tags.extend(tag_data) def cleanup_and_stop(): print(f"\n盘点结束,共收集到 {len(collected_tags)} 个标签") print(f"最终标签列表: {collected_tags}") reactor.stop() if __name__ == "__main__": # 创建工厂,设置盘点持续3秒 factory = llrp.LLRPClientFactory( duration=3, stop_on_disconnect=True # 盘点停止后自动断开连接 ) factory.addTagReportCallback(tag_callback) # 连接成功后启动盘点 def start_inventory(connection): factory.startInventory() # 加个保险定时器,防止ROSpec停止信号没及时触发 reactor.callLater(3.5, cleanup_and_stop) # 连接阅读器(替换成你的阅读器IP) reactor.connectTCP('myreader', llrp.LLRP_PORT, factory).addCallback(start_inventory) reactor.run()
方法2:主动发送STOP_ROSPEC命令
如果需要更灵活的停止条件(比如收集到N个标签后停止),可以在回调函数里判断条件,然后主动调用factory.stopInventory()发送停止命令:
from sllurp import llrp from twisted.internet import reactor import logging from datetime import datetime logging.getLogger().setLevel(logging.INFO) START_TIME = datetime.now() COLLECT_DURATION = 3 # 收集3秒 collected_tags = [] def tag_callback(tagReport): global START_TIME tag_data = tagReport.msgdict['RO_ACCESS_REPORT']['TagReportData'] if tag_data: print(f"收到标签: {tag_data}") collected_tags.extend(tag_data) # 检查是否达到停止条件(这里用时间,也可以换成标签数量) elapsed_time = (datetime.now() - START_TIME).total_seconds() if elapsed_time >= COLLECT_DURATION: print("时间到,停止盘点...") # 发送STOP_ROSPEC命令 factory.stopInventory() # 延迟0.5秒停止reactor,确保阅读器收到停止指令 reactor.callLater(0.5, reactor.stop) if __name__ == "__main__": factory = llrp.LLRPClientFactory() factory.addTagReportCallback(tag_callback) def start_inventory(connection): global START_TIME START_TIME = datetime.now() factory.startInventory() reactor.connectTCP('myreader', llrp.LLRP_PORT, factory).addCallback(start_inventory) reactor.run() print(f"\n最终标签列表: {collected_tags}")
关于CLI工具的优化
你用的sllurp inventory命令可以加--duration参数直接指定盘点时间,不用手动Ctrl+C:
sllurp inventory --duration 3 myreader
这个命令会在3秒后自动停止盘点,并输出收集到的标签。
关键知识点补充
- LLRP协议中,**ROSpec(Reader Operation Specification)**是阅读器的盘点任务配置,必须激活(启动)才能开始盘点。
STOP_ROSPEC是LLRP的标准命令,用于终止正在运行的ROSpec,sllurp的stopInventory()方法已经封装了这个命令的发送逻辑,不用手动构造LLRP报文。- Twisted的
reactor是事件循环核心,必须调用reactor.stop()才能正常退出程序。
内容的提问来源于stack exchange,提问作者Bogdan Prădatu
相关产品推荐
相关产品推荐

