Problem
Inventory Blind Spots
Manual barcode scanning created inventory inaccuracies up to 12%, required 3 full-time staff for daily cycle counts, and caused production delays from missing parts.
Solution
RFID Automation
Zebra FX9600 fixed readers at dock doors, conveyors, and staging areas. Python LLRP middleware published read events via MQTT to AWS IoT for ERP integration.
Result
Reduced Manual Operations
85% reduction in manual cycle counts, inventory accuracy improved from 88% to 99.8%, dock door processing time cut from 12 minutes to under 90 seconds.
99.8%Inventory Accuracy
85%Manual Count Reduction
<90sDock Processing Time
10k+Tags / Day
LLRP Reader Integration
The Zebra FX9600 readers are controlled via LLRP (Low Level Reader Protocol) v1.1. A Python LLRP client connects over TCP, configures ROSpec (Reader Operation Spec) for continuous inventory mode, and streams TagReportData events to the deduplication engine.
class ZebraReader:
def __init__(self, host, port=5084):
self.client = LLRPClient(host, port)
self.seen_tags = TTLCache(maxsize=10000, ttl=5.0) # 5s dedup window
async def start_inventory(self):
rospec = ROSpec(
id=1,
priority=0,
current_state=ROSpecState.DISABLED,
roi_spec=ROISpec(
antenna_ids=[1, 2, 3, 4],
air_protocols=[AirProtocol.EPCGlobalClass1Gen2]
),
ro_report_spec=ROReportSpec(
report_trigger=N_TAG_OBSERVATION,
n=1, # Report every tag immediately
tag_report_content_selector=TagReportContentSelector(
epc=True, antenna_id=True, rssi=True, timestamp=True
)
)
)
await self.client.add_rospec(rospec)
await self.client.enable_rospec(rospec_id=1)
def on_tag_read(self, tag: TagReport):
epc = tag.epc.hex().upper()
if epc not in self.seen_tags: # Deduplicate within 5s window
self.seen_tags[epc] = True
self._publish_mqtt(epc, tag.antenna_id, tag.rssi)
MQTT Event Schema
rfid/read/eventsepc, reader_id, antenna, rssi, timestamp — raw reads, QoS 0
rfid/zone/entryepc, zone_id, item_type, quantity — on zone entry, QoS 1
rfid/zone/exitepc, zone_id, dwell_seconds — on zone departure, QoS 1
rfid/inventory/deltaadded[], removed[], zone_id — per cycle, QoS 1
rfid/alerts/missingepc, expected_zone, last_seen — retained, QoS 2
reader/{id}/statusuptime, read_rate_per_min, antenna_health — 60s heartbeat
Technology Stack
RFID HardwareZebra FX9600 (4-port), Zebra AN620 circularly polarised antennas
RFID TagsImpinj Monza R6-P UHF Gen2, EPC GS1 96-bit encoding
MiddlewarePython 3.11, sllurp LLRP library, asyncio, TTLCache dedup
MessagingMQTT 3.1.1, Eclipse Mosquitto broker, AWS IoT Core (cloud)
ERPSAP S/4HANA REST API, inventory delta sync via Lambda
DashboardReact, WebSocket, live floor-plan SVG, Grafana metrics