# KTag Medic Subapp A Jetpack Compose Android application for healing "tagged out" KTag devices via BLE advertising. ## Overview The Medic app scans for KTag devices broadcasting their status via BLE. When a device reports zero health ("tagged out"), it appears in the list. Tapping a device "heals" it by broadcasting a Tag packet, which restores the device's health. ## Architecture The app follows the **MVVM (Model-View-ViewModel)** pattern with Jetpack Compose for the UI layer. ``` ┌─────────────────────────────────────────────────────────┐ │ MedicActivity │ │ (Compose Host) │ └─────────────────────┬───────────────────────────────────┘ │ ┌─────────────────────▼───────────────────────────────────┐ │ MedicViewModel │ │ • BLE scanning & advertising │ │ • Device list management │ │ • MQTT integration (KOTH possession) │ │ • Auto-heal logic │ └─────────────────────┬───────────────────────────────────┘ │ ┌─────────────────────▼───────────────────────────────────┐ │ UI Layer │ │ MedicScreen → KothStatusBar + LazyColumn[DeviceCard] │ └─────────────────────────────────────────────────────────┘ ``` ## File Structure ``` src/main/java/club/clubk/ktag/apps/medic/ ├── MedicActivity.kt # Compose activity with permissions ├── MedicViewModel.kt # State management, BLE, MQTT ├── DeviceModel.kt # Device data class + AutoHealSetting enum ├── ColorUtils.kt # Color manipulation utilities ├── MedicSubApp.kt # Subapp registration ├── MedicSettingsActivity.kt ├── MedicInitializer.kt ├── HexUtils.java # Hex string conversion (kept as Java) ├── ble/ │ └── Packet.java # BLE packet parsing/creation (kept as Java) ├── mqtt/ │ ├── KTagMQTTServer.java # MQTT client (kept as Java) │ └── KingOfTheHillEventListener.java └── ui/ ├── MedicScreen.kt # Main screen composable ├── DeviceCard.kt # Device list item ├── KothStatusBar.kt # KOTH possession display └── theme/ ├── Theme.kt ├── Color.kt └── Type.kt ``` ## Key Components ### MedicViewModel Manages all application state and business logic: - **BLE Scanning**: Listens for KTag Status packets, filters by health and RSSI - **Device List**: Maintains list of tagged-out devices with TTL-based expiration - **Healing**: Broadcasts Tag packets to restore device health - **Auto-Heal**: Automatically heals devices based on team color settings - **MQTT**: Subscribes to KOTH possession updates ### DeviceModel Immutable data class representing a detected device: ```kotlin data class DeviceModel( val name: String, val bleAddress: String, val rssi: Int, val color: Color, val timeToLiveMs: Int ) ``` ### UI Composables | Composable | Purpose | |------------|---------| | `MedicScreen` | Main layout with status bar and device list | | `KothStatusBar` | Shows KOTH flag and possession text | | `DeviceCard` | Clickable card for each tagged-out device | ## Features - **Device Detection**: Scans for KTag devices with zero health - **RSSI Filtering**: Only shows devices within configurable range - **One-Tap Healing**: Tap a device card to heal it - **Auto-Heal Modes**: None, Red team, Blue team, or All - **KOTH Integration**: Displays current hill possession via MQTT - **Visual Feedback**: Background color indicates auto-heal mode ## Settings | Setting | Description | |---------|-------------| | `min_rssi` | Minimum RSSI threshold for device detection | | `auto_heal` | Auto-heal mode (0=None, 1=Red, 2=Blue, 3=All) | | `mqtt_*` | MQTT server configuration | ## Dependencies - Jetpack Compose (Material3) - ViewModel + Compose integration - BLE (BluetoothLeScanner, BluetoothLeAdvertiser) - MQTT (Paho Android client)