The fatal flaw of HTTP polling Traditional RFID gateways report events to Odoo via HTTP polling, which has three problems: first, high-frequency polling overwhelms Odoo's worker pool; second, network jitter causes event loss; third, no bidirectional communication (Odoo can't push to the gateway). MQTT's pub-sub model solves all three.
MQTT topic design and message format We use a hierarchical topic design: rfid/{siteId}/{readerId}/event for reader event reporting, rfid/{siteId}/command for Odoo pushing commands to readers. Message format is JSON: {epc, timestamp, rssi, readerId, antennaId, eventType}. The key design is the eventType field distinguishing inventory, entry, exit, and alarm — letting subscribers consume on demand.
QoS level selection QoS 0 (at most once): for high-frequency real-time inventory events, tolerating minor loss. QoS 1 (at least once): for inbound/outbound events, ensuring no loss but possible duplicates — subscribers need idempotency. QoS 2 (exactly once): for loss-prevention alarms, ensuring no loss and no duplicates, but highest overhead. Our practice: inventory QoS 0, inbound/outbound QoS 1, loss-prevention QoS 2.
Odoo-side MQTT subscriber A standalone Python subscriber process (paho-mqtt) runs on the Odoo server, subscribes to rfid/+/+/event, and writes to Odoo via XML-RPC or OCA's connector module on message receipt. A Redis queue buffers between subscriber and Odoo to prevent event loss during Odoo restarts. A single subscriber handles 5,000 events/sec — sufficient for most warehouse scenarios.



