10 KiB
10 KiB
📡 Taekwondo Scoring System – Score Control to Display Communication
Version: 1.0
Last Updated: July 2025
Target Developer: .NET Android (Score Control) & Android TV App Developers
Purpose: Define real-time data signals from Score Control Unit to Scoreboard and Upcoming Matches displays
📌 Table of Contents
- 1. Overview
- 2. System Architecture
- 3. Communication Protocol (TCP)
- 4. Scoreboard (Live Match Display)
- 5. Upcoming Matches Screen
- 6. Message Format (JSON)
- 7. C# Server Code (Score Control)
- 8. Android TV App Logic
- 9. Display Modes & Transitions
- 10. Best Practices
1. Overview
The Score Control Unit (Android tablet) sends real-time data to two Android TVs:
| Display | Purpose |
|---|---|
| Scoreboard TV | Live match: score, timer, fighter info |
| Upcoming Matches TV | Lobby: next matches, tournament flow |
All communication is:
- ✅ Real-time
- ✅ Bidirectional-ready (optional)
- ✅ Over Wi-Fi (TCP)
- ✅ Zero-config for users
2. System Architecture
[Score Control Tablet] → Wi-Fi → [Scoreboard TV (Port 5001)]
↘
[Upcoming Matches TV (Port 5002)]
- Score Control acts as TCP server
- TVs act as TCP clients
- TVs connect at startup and stay connected
- Score Control broadcasts JSON messages
✅ All devices on same network (
TKD_SCORING_COURT1)
3. Communication Protocol (TCP)
🔌 Connection Flow
- TV powers on → connects to
TKD_SCORING_COURT1 - TV app starts → connects to tablet IP (
192.168.4.1) - TV sends identity:
DISPLAY:NAME=TV_SCOREBOARD,TYPE=SCOREBOARD,MAC=18:3D:A2:01:02:03 - Score Control registers TV
- TV listens for JSON messages
4. Scoreboard (Live Match Display)
Displays real-time match data.
🖼️ 13 Display Elements
| Element | Source |
|---|---|
| Court Number | Match data |
| Match Number | Schedule |
| Match Timer | App timer |
| Round Counter | Match state |
| Country Flag | Fighter data |
| Country ISO3 | Fighter data |
| Team Logo | Fighter data |
| Fighter Name | Match setup |
| Fighter Score | Scoring engine |
| Fighter Fouls | Penalty tracker |
| Fighter Weight (kg) | Fighter profile |
| Weight Class & Category | Match data |
| Team Name | Fighter data |
🔄 Display Modes
| Mode | Trigger | Duration |
|---|---|---|
faceoff |
Before match | 10 sec |
score |
Match start | 2:00 |
break |
Round end | 60 sec |
call_to_action |
Last 10 sec of break | 10 sec |
winner |
Match end | 15 sec |
5. Upcoming Matches Screen
Displays next 3–5 matches.
🖼️ Display Elements
- Match number
- Red vs Blue names
- Weight class
- Round
- Scheduled time
- Tournament logo
🔄 Auto-Advance
- Updates when current match ends
- Pulls from CSV or cloud
- Scrolls if more than 5 matches
6. Message Format (JSON)
All messages are JSON and end with \n.
6.1 To Scoreboard TV (Port 5001)
faceoff Mode
{
"mode": "faceoff",
"red": {
"name": "Kim Min-jae",
"country": "KOR",
"flag": "https://flags/kor.png",
"photo": "https://photos/kim.jpg"
},
"blue": {
"name": "Lee Jung-ho",
"country": "CHN",
"flag": "https://flags/chn.png",
"photo": "https://photos/lee.jpg"
},
"weight_class": "Men's -68kg",
"round": "Semifinal"
}
score Mode
{
"mode": "score",
"court": "1",
"match_number": "105",
"weight_class": "Men's -68kg",
"category": "Semifinal",
"round": "2",
"timer": "01:45",
"red": {
"name": "Kim Min-jae",
"country": "KOR",
"team": "Seoul TKD Club",
"logo": "https://logos/seoul.png",
"flag": "https://flags/kor.png",
"score": 8,
"fouls": 1,
"weight_kg": 67.2
},
"blue": {
"name": "Lee Jung-ho",
"country": "CHN",
"team": "Beijing TKD",
"logo": "https://logos/beijing.png",
"flag": "https://flags/chn.png",
"score": 5,
"fouls": 2,
"weight_kg": 67.8
}
}
break Mode
{
"mode": "break",
"ad_image": "https://ads/sponsor1.png",
"highlight_video": "https://videos/round1.mp4",
"countdown": true
}
call_to_action Mode
{
"mode": "call_to_action",
"message": "FIGHTERS, RETURN TO THE RING!",
"timer": 10
}
winner Mode
{
"mode": "winner",
"winner": "red",
"red": {
"name": "Kim Min-jae",
"photo": "https://photos/kim.jpg",
"final_score": 8
},
"blue": {
"name": "Lee Jung-ho",
"photo": "https://photos/lee.jpg",
"final_score": 5
},
"weight_class": "Men's -68kg",
"round": "Final",
"animation": "fireworks"
}
6.2 To Upcoming Matches TV (Port 5002)
{
"mode": "next_matches",
"matches": [
{
"match_number": "106",
"red": "Park S.",
"blue": "Wang L.",
"weight": "+87kg",
"round": "Final",
"time": "11:30",
"category": "Men's"
},
{
"match_number": "107",
"red": "Choi M.",
"blue": "Tanaka Y.",
"weight": "-58kg",
"round": "Semifinal",
"time": "11:50",
"category": "Women's"
}
],
"tournament_name": "National Taekwondo Championship 2025",
"logo": "https://logos/tournament.png"
}
7. C# Server Code (Score Control)
public class DisplayServer
{
private TcpListener _scoreboardServer;
private TcpListener _matchesServer;
private List<TcpClient> _scoreboardClients = new();
private List<TcpClient> _matchesClients = new();
public async Task Start()
{
_scoreboardServer = new TcpListener(IPAddress.Any, 5001);
_matchesServer = new TcpListener(IPAddress.Any, 5002);
_scoreboardServer.Start();
_matchesServer.Start();
_ = AcceptScoreboardClients();
_ = AcceptMatchesClients();
}
private async Task AcceptScoreboardClients()
{
while (true)
{
var client = await _scoreboardServer.AcceptTcpClientAsync();
_scoreboardClients.Add(client);
_ = HandleDisplayClient(client, "SCOREBOARD");
}
}
private async Task AcceptMatchesClients()
{
while (true)
{
var client = await _matchesServer.AcceptTcpClientAsync();
_matchesClients.Add(client);
_ = HandleDisplayClient(client, "MATCHES");
}
}
private async Task HandleDisplayClient(TcpClient client, string type)
{
using var stream = client.GetStream();
using var reader = new StreamReader(stream);
string identity = await reader.ReadLineAsync();
// Validate: DISPLAY:NAME=...,TYPE=...,MAC=...
// Keep connection open
while (client.Connected)
{
await Task.Delay(1000); // Wait for broadcast
}
// Remove on disconnect
if (type == "SCOREBOARD")
_scoreboardClients.Remove(client);
else
_matchesClients.Remove(client);
}
public void BroadcastToScoreboard(object data)
{
string json = JsonSerializer.Serialize(data) + "\n";
byte[] bytes = Encoding.UTF8.GetBytes(json);
for (int i = _scoreboardClients.Count - 1; i >= 0; i--)
{
var client = _scoreboardClients[i];
if (client?.Connected == true)
{
try
{
client.GetStream().Write(bytes, 0, bytes.Length);
}
catch
{
_scoreboardClients.RemoveAt(i); // Cleanup
}
}
}
}
public void BroadcastToMatches(object data)
{
string json = JsonSerializer.Serialize(data) + "\n";
byte[] bytes = Encoding.UTF8.GetBytes(json);
for (int i = _matchesClients.Count - 1; i >= 0; i--)
{
var client = _matchesClients[i];
if (client?.Connected == true)
{
try
{
client.GetStream().Write(bytes, 0, bytes.Length);
}
catch
{
_matchesClients.RemoveAt(i);
}
}
}
}
}
8. Android TV App Logic
📺 Scoreboard TV App
- Connects to
192.168.4.1:5001 - Sends identity
- Listens for JSON
- Renders based on
mode - Supports video playback for
highlight_video
📺 Upcoming Matches TV App
- Connects to
192.168.4.1:5002 - Displays scrollable list
- Updates on new message
- Shows tournament logo
9. Display Modes & Transitions
| Action | Broadcast To | Mode |
|---|---|---|
| Match selected | Scoreboard | faceoff |
| "Shi-jak" pressed | Scoreboard | score |
| Round ends | Scoreboard | break |
| 10 sec before next round | Scoreboard | call_to_action |
| Match ends | Scoreboard | winner |
| Match ends | Upcoming Matches | next_matches |
| Tournament starts | Upcoming Matches | next_matches |
10. Best Practices
| Practice | Why |
|---|---|
| Use separate ports (5001, 5002) | Avoid mode conflicts |
Send \n after each message |
Easy parsing |
| Validate device identity | Security |
| Reconnect logic on TV | Handle Wi-Fi drops |
| Broadcast only on change | Reduce network load |
| Use UTC time in logs | Debugging |
Include mode in every message |
Safe rendering |
🎯 This document fully defines the communication between Score Control and Displays.
You now have everything to build real-time, synchronized, broadcast-quality displays.
📬 For help: Contact project lead.
---
### ✅ How to Use
1. Save as `DISPLAY_COMMUNICATION.md`
2. Place in `/docs` folder
3. Commit to GitHub
---
Let me know if you want:
- A **Figma mockup** of the TV screens
- A **sample Android TV app** (Kotlin)
- A **test tool** to simulate messages
- A **Lottie animation** for the winner screen
You're now building a **fully integrated, professional tournament system**. 🏆