# 📡 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](#1-overview) - [2. System Architecture](#2-system-architecture) - [3. Communication Protocol (TCP)](#3-communication-protocol-tcp) - [4. Scoreboard (Live Match Display)](#4-scoreboard-live-match-display) - [5. Upcoming Matches Screen](#5-upcoming-matches-screen) - [6. Message Format (JSON)](#6-message-format-json) - [7. C# Server Code (Score Control)](#7-c-server-code-score-control) - [8. Android TV App Logic](#8-android-tv-app-logic) - [9. Display Modes & Transitions](#9-display-modes--transitions) - [10. Best Practices](#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 1. TV powers on → connects to `TKD_SCORING_COURT1` 2. TV app starts → connects to tablet IP (`192.168.4.1`) 3. TV sends identity: ``` DISPLAY:NAME=TV_SCOREBOARD,TYPE=SCOREBOARD,MAC=18:3D:A2:01:02:03 ``` 4. Score Control registers TV 5. 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 ```json { "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 ```json { "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 ```json { "mode": "break", "ad_image": "https://ads/sponsor1.png", "highlight_video": "https://videos/round1.mp4", "countdown": true } ``` #### `call_to_action` Mode ```json { "mode": "call_to_action", "message": "FIGHTERS, RETURN TO THE RING!", "timer": 10 } ``` #### `winner` Mode ```json { "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) ```json { "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) ```csharp public class DisplayServer { private TcpListener _scoreboardServer; private TcpListener _matchesServer; private List _scoreboardClients = new(); private List _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**. 🏆