Skip to content

Latest commit

 

History

History
151 lines (107 loc) · 5.88 KB

File metadata and controls

151 lines (107 loc) · 5.88 KB

Summary

Yes—you can fully simulate RFC-OS’s real-time and REST APIs using the public samples to build a React + Python POC. The STOMP/WebSocket shape is revealed by the rfcos-websocket-py example and the barnowl-rfcontrols package, while the REST shapes emerge from the wms-demo-app demo. By mocking the same JSON payloads and URL patterns (items, regions, zones, history) in a Python FastAPI server and consuming them in React via @stomp/stompjs and Axios, you’ll cover 90% of integration work. For 100% schema fidelity, you’ll need RF Controls’ official Programmer’s Reference Guide (or OpenAPI spec) to capture any proprietary fields and edge-case behaviors. Customers obtain API access—usually Basic Auth credentials or tokens—by contacting RF Controls through their partner portal or sales/tech-support channels.


1. Real-time Stream Simulation

1.1 STOMP/WebSocket Frames

  • RFC-OS exposes a STOMP-over-WebSocket endpoint at ws://<host>:8888/websockets/messaging/websocket, secured via Basic Auth in the Authorization header (rf-controls.com).
  • Incoming frames are STOMP MESSAGE frames carrying a JSON body with fields such as epc (tag EPC), antennaId, regionId, timestamp, plus optional position coordinates (github.com).

1.2 Mocking a Python Producer

Use a Python WebSocket library (e.g. websockets) to emit identical frames:

async def stream_tags(ws):
    await ws.accept()
    while True:
        frame = (
            "MESSAGE\n"
            "destination:/topic/tagBlinkLite.*\n\n"
            '{"epc":"EPC0001","antennaId":"ant1","regionId":"reg1","timestamp":1.638e12}\x00'
        )
        await ws.send_text(frame)
        await asyncio.sleep(1)

This mirrors the JSON raddec schema used by barnowl-rfcontrols (github.com).


2. REST API Shape Simulation

2.1 Core Endpoints & JSON Models

The wms-demo-app demo outlines the key REST routes and payloads:

  • GET /api/regions[{"id":"region1","name":"Aisle 1"}]
  • GET /api/items[{"epc":"EPC0001","sku":"ABC123","desc":"Widget"}]
  • GET /api/tags/history?start=&end=[{"epc":"EPC0001","lastSeen":...,"x":0,"y":0}] (github.com).

2.2 Business Logic

  • Regions/Zones group antennas into logical scan areas;
  • Items map EPCs to SKUs and descriptions for user-friendly searches;
  • History endpoints return past reads for analytics and loss detection (github.com).

3. Gaps & Missing Information

3.1 Proprietary Commands & Fields

  • The Programmer’s Reference Guide (ISO/IEC 24730-based) details advanced API calls (e.g., configuration services, diagnostics, batch commands) not exposed in the samples (fcc.report).

3.2 Authentication & Security

  • Public demos default to Basic Auth (admin:admin), but production may use OAuth/JWT, API keys, TLS-enforced credentials, and CSRF safeguards (github.com).

4. Access & Authorization

4.1 Obtaining Credentials

  • Prospective customers request demo kits or partner accounts via RF Controls’ website, emailing info@rf-controls.com or calling +1 314 584 1500 (rf-controls.com).
  • RF Controls tech support then provisions user accounts on the RFC-OS Edge Server, issuing Basic Auth or token credentials.

4.2 Best Practices

  • Store credentials securely (Vault, env vars), rotate regularly, and enforce WSS/HTTPS in all communications (rf-controls.com).

5. Proof-of-Concept Blueprint

5.1 Python Mock Backend (FastAPI)

# mock_server.py
import asyncio
from fastapi import FastAPI, WebSocket
app = FastAPI()

@app.get("/api/regions")
def list_regions():
    return [{"id":"region1","name":"Aisle 1"}]

@app.websocket("/ws/tags")
async def ws_tags(ws: WebSocket):
    await ws.accept()
    while True:
        frame = (
            "MESSAGE\n"
            "destination:/topic/tagBlinkLite.*\n\n"
            '{"epc":"EPC1","antennaId":"ant1","regionId":"region1","timestamp":1.638e12}\x00'
        )
        await ws.send_text(frame)
        await asyncio.sleep(1)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

5.2 React Front End

// App.jsx
import { Client } from '@stomp/stompjs';
import axios from 'axios';
import { useEffect, useState } from 'react';

function App() {
  const [regions, setRegions] = useState([]);

  useEffect(() => {
    // STOMP real-time
    const stompClient = new Client({ brokerURL: 'ws://localhost:8000/ws/tags' });
    stompClient.onConnect = () => {
      stompClient.subscribe('/topic/tagBlinkLite.*', msg => {
        console.log('Tag event:', JSON.parse(msg.body));
      });
    };
    stompClient.activate();

    // REST config
    axios.get('/api/regions').then(res => setRegions(res.data));
  }, []);

  return (
    <div>
      <h1>Regions</h1>
      <ul>{regions.map(r => <li key={r.id}>{r.name}</li>)}</ul>
    </div>
  );
}

export default App;

No Next.js is required unless you need SSR or built-in API routes; plain React (CRA/Vite) plus FastAPI mocks suffices for a complete POC. Once you secure official API specs and production credentials, simply swap the mock URLs and payloads for RFC-OS’s real endpoints.