diff --git a/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt b/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt index c4a2d7c..c26ebfd 100644 --- a/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt +++ b/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt @@ -586,10 +586,10 @@ class BleManager private constructor(private val context: Context) { * 6채널 측정 명령(maa) 송신 가능 여부: * (A) 이전 응답이 아직 진행 중(isMultiChannel && !isComplete)이면 차단. * 단 3초 넘게 응답이 안 오면 강제 통과(영영 deadlock 방지). - * (B) 마지막 송신으로부터 600ms 미만이면 차단(펌웨어 burst 방어). + * (B) 마지막 송신으로부터 500ms 미만이면 차단(펌웨어 burst 방어). * * FW VBTFW0116 + MTU 247 + CONN_PRIORITY HIGH 조합에서 한 사이클 응답이 - * 약 280~420ms이므로, 600ms = 응답 평균 + 안전 마진 ~200ms. + * 약 280~420ms이므로, 500ms = 응답 평균 + 안전 마진 ~80~220ms. */ private var lastMaaSentMs = 0L private fun canSendMaa(caller: String): Boolean { @@ -603,7 +603,7 @@ class BleManager private constructor(private val context: Context) { } android.util.Log.w("BleManager", "maa FORCE [$caller] — prev incomplete after ${sinceLast}ms, abandoning") } - if (sinceLast < 600) { + if (sinceLast < 500) { android.util.Log.w("BleManager", "maa THROTTLED [$caller] — ${sinceLast}ms since last") return false } diff --git a/app/src/main/java/com/example/medilightv2android/models/PiezoSettings.kt b/app/src/main/java/com/example/medilightv2android/models/PiezoSettings.kt index 5a46da7..af13036 100644 --- a/app/src/main/java/com/example/medilightv2android/models/PiezoSettings.kt +++ b/app/src/main/java/com/example/medilightv2android/models/PiezoSettings.kt @@ -18,6 +18,6 @@ data class PiezoSettings( // Charles 833c110: BV calculation tweak — anterior-wall pull-in magnitude in millimetres. var antOffsetMm: Int = 0, // 우리 4ae25d9: Auto Scan 측정 사이클 목표 간격 (ms). - // BleManager.canSendMaa() time gate와 동일 값이 기본. 600ms 미만은 throttle이 막음. - var autoScanIntervalMs: Int = 600 + // BleManager.canSendMaa() time gate와 동일 값이 기본 (500ms). + var autoScanIntervalMs: Int = 500 ) diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt index 192412e..8e9ed12 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt @@ -862,32 +862,47 @@ fun PiezoMonitoringView(appState: AppState) { } Spacer(modifier = Modifier.weight(1f)) - // Battery with icon + // Battery with icon — 연결 끊기면 disconnect 표시로 전환 if (!isDemoMode) { - val batteryColor = when { - batteryLvl >= 60 -> Color(0xFF4CAF50) - batteryLvl >= 30 -> Color(0xFFFF9800) - else -> Color.Red - } - Row(verticalAlignment = Alignment.CenterVertically) { - // 배터리 바 아이콘 (Canvas로 직접 그리기) - Canvas(modifier = Modifier.size(width = 22.dp, height = 12.dp)) { - val w = size.width; val h = size.height - // 외곽 - drawRoundRect(Color.Gray, topLeft = Offset(0f, 0f), - size = Size(w * 0.88f, h), cornerRadius = androidx.compose.ui.geometry.CornerRadius(3f), - style = Stroke(width = 1.5f)) - // 양극 돌출 - drawRect(Color.Gray, topLeft = Offset(w * 0.88f, h * 0.25f), - size = Size(w * 0.12f, h * 0.5f)) - // 충전량 - val fillW = w * 0.84f * (batteryLvl / 100f).coerceIn(0f, 1f) - if (fillW > 0) drawRoundRect(batteryColor, - topLeft = Offset(2f, 2f), size = Size(fillW, h - 4f), - cornerRadius = androidx.compose.ui.geometry.CornerRadius(2f)) + if (!isConnected) { + Row(verticalAlignment = Alignment.CenterVertically) { + Icon( + Icons.Default.BluetoothDisabled, + contentDescription = "Disconnected", + tint = Color.Red, + modifier = Modifier.size(16.dp) + ) + Spacer(modifier = Modifier.width(4.dp)) + Text( + "Disconnect", + fontSize = (12 * fontScale).sp, + fontWeight = FontWeight.Bold, + color = Color.Red + ) + } + } else { + val batteryColor = when { + batteryLvl >= 60 -> Color(0xFF4CAF50) + batteryLvl >= 30 -> Color(0xFFFF9800) + else -> Color.Red + } + Row(verticalAlignment = Alignment.CenterVertically) { + // 배터리 바 아이콘 (Canvas로 직접 그리기) + Canvas(modifier = Modifier.size(width = 22.dp, height = 12.dp)) { + val w = size.width; val h = size.height + drawRoundRect(Color.Gray, topLeft = Offset(0f, 0f), + size = Size(w * 0.88f, h), cornerRadius = androidx.compose.ui.geometry.CornerRadius(3f), + style = Stroke(width = 1.5f)) + drawRect(Color.Gray, topLeft = Offset(w * 0.88f, h * 0.25f), + size = Size(w * 0.12f, h * 0.5f)) + val fillW = w * 0.84f * (batteryLvl / 100f).coerceIn(0f, 1f) + if (fillW > 0) drawRoundRect(batteryColor, + topLeft = Offset(2f, 2f), size = Size(fillW, h - 4f), + cornerRadius = androidx.compose.ui.geometry.CornerRadius(2f)) + } + Spacer(modifier = Modifier.width(4.dp)) + Text("$batteryLvl%", fontSize = (12 * fontScale).sp, fontWeight = FontWeight.Bold, color = batteryColor) } - Spacer(modifier = Modifier.width(4.dp)) - Text("$batteryLvl%", fontSize = (12 * fontScale).sp, fontWeight = FontWeight.Bold, color = batteryColor) } }