# 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:

```json
{
  "epc": "EPC_CODE_HERE",
  "timestamp": "2024-09-17;14: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**

```python
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**

```csharp
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**

```javascript
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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.runonrufus.com/rufus-cloudbox/protocol/receiving-timing-data-passings-during-a-session.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
