Receiving Timing Data Passings During a Session

Once a timing session is started by sending the START command to the CloudBox, the TCP connection must remain open to continuously receive real-time streams of timing data, known as passings. Each passing represents an instance of an RFID tag being detected by the system, and contains important information about the athlete or object that triggered the RFID read.

The passing data is sent to the connected client in JSON format, with the following structure:

{
  "epc": "EPC_CODE_HERE",
  "timestamp": "2024-09-17T14:34:23.123Z",
  "seenCount": 3,
  "antenna": 1,
  "rssi": -65,
  "passingNumber": 145,
  "tagStr": "TAG_STRING",
  "latitude": 41.28425,
  "longitude": 1.98251,
  "chksum": "CHECKSUM_HERE"
}

Key Elements of a Passing

  1. epc (Electronic Product Code)(*):

    This is the unique identifier of the RFID tag that was detected. The EPC helps identify which specific tag was read during the session.

  2. timestamp:

    The exact time the passing was recorded, provided in ISO 8601 format (YYYY-MM-DDTHH:mm:ss.sssZ). This allows precise tracking of the moment the tag was detected.

  3. seenCount (*):

    The number of times this tag has been detected within the same reading cycle. This value can help with determining the proximity or quality of the tag read.

  4. antenna (*):

    Identifies which antenna detected the tag. In systems with multiple antennas, this helps to determine which part of the course or checkpoint the passing occurred at.

  5. rssi (*):

    The Received Signal Strength Indicator (RSSI) measures the strength of the signal received from the RFID tag. This value can help with determining the proximity or quality of the tag read.

  6. passingNumber:

    A sequential number that increments with each passing, providing a unique identifier for each passing event during the timing session.

  7. tagStr (*):

    A string representation of the tag extracted from the epc code. Data available when reading RUFUS encoded tags.

  8. latitude (*):

    The latitude coordinates from the GPS device (if available). This value can help track the exact location of the passing on a global map.

  9. longitude (*):

    The longitude coordinates from the GPS device (if available). This value, along with latitude, provides the geographic location of the passing.

  10. chksum: The checksum is used for verifying data integrity, ensuring the passing data was transmitted correctly without errors.

(*) Information may not be available depending on RFID reader installed or CloudBox configuration. Keys will always be present and if no data is available, the value will be null.

Handling the Passing Data

Once the START command is issued and the session is active, passings are sent over the same open TCP connection to the connected clients. Each passing is transmitted as a separate JSON object, similar to the example provided above. The passings continue to stream in real-time as athletes or objects with RFID tags pass through the detection antennas.

The format of each passing is consistent, allowing the receiving system to parse and process the data for timing, classification, and tracking purposes.

The client application needs to handle the continuous stream of passings by parsing the incoming data, processing it, and storing it as needed. Below are examples in Python, C#, and Node.js to handle incoming passings.

Python Example

import json

HOST = '192.168.1.10'
PORT = 8080

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall("START\r\n".encode('utf-8'))  # Start the timing session
    
    while True:
        data = s.recv(1024)
        if data:
            passing = json.loads(data.decode('utf-8'))
            print(f"Passing received: {passing}")
            # Process the passing data here (e.g., save to database, analyze, etc.)

C# Example

using System;
using System.Net.Sockets;
using System.Text;
using Newtonsoft.Json.Linq; // Install via NuGet

class Program
{
    static void Main(string[] args)
    {
        string host = "192.168.1.10";
        int port = 8080;

        try
        {
            TcpClient client = new TcpClient(host, port);
            NetworkStream stream = client.GetStream();

            byte[] startCommand = Encoding.ASCII.GetBytes("START\r\n");
            stream.Write(startCommand, 0, startCommand.Length);

            byte[] buffer = new byte[1024];
            while (true)
            {
                int bytesRead = stream.Read(buffer, 0, buffer.Length);
                if (bytesRead > 0)
                {
                    string passingData = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                    JObject passing = JObject.Parse(passingData);
                    Console.WriteLine($"Passing received: {passing}");
                    // Process the passing data (e.g., save to database, analyze, etc.)
                }
            }

            stream.Close();
            client.Close();
        }
        catch (Exception e)
        {
            Console.WriteLine($"Error: {e.Message}");
        }
    }
}

Node.js Example

const net = require('net');

// CloudBox IP and port
const HOST = '192.168.1.10';
const PORT = 8080;

// Create a socket connection to CloudBox
const client = new net.Socket();

client.connect(PORT, HOST, () => {
    console.log(`Connected to CloudBox at ${HOST}:${PORT}`);
    
    // Send the START command to initiate timing session
    client.write("START\r\n");
});

// Receive and process passings
client.on('data', (data) => {
    const passing = JSON.parse(data.toString());
    console.log(`Passing received: ${JSON.stringify(passing)}`);
    // Process the passing data (e.g., save to database, analyze, etc.)
});

// Handle connection close
client.on('close', () => {
    console.log('Connection closed');
});

// Handle errors
client.on('error', (err) => {
    console.error(`Error: ${err.message}`);
});

Conclusion

Once a timing session is started, the CloudBox sends streams of passings over the open TCP connection in real-time, each containing vital RFID detection data. You can handle these passings in Python, C#, or Node.js, depending on your application’s needs. The passings can then be processed for storage, analysis, and race timing operations.

Last updated