feat: auto scan interval 500ms 기본 + 배터리 → Disconnect 전환
1) Auto scan interval default 600 → 500ms
PiezoSettings.autoScanIntervalMs default 변경. 사용자가 별도 조정 안 하면
기본 0.5초 간격으로 측정 사이클 진행.
2) BLE canSendMaa throttle 600 → 500ms
응답이 280~420ms 라 500ms = 평균 + 80~220ms 안전 마진. 디바이스에 무리 X.
throttle 도 같이 내려야 autoScanIntervalMs=500 이 실제로 적용됨.
3) PiezoMonitoring 도넛 상단 배터리 → 연결 끊기면 Disconnect 표시
기존: 배터리 바 + xx% (항상 표시, 비-demo)
변경: isConnected=false → Icons.BluetoothDisabled + "Disconnect" (빨강)
isConnected=true → 기존 배터리 바 + %
demo flavor 는 영향 0 (!isDemoMode 가드 그대로).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -586,10 +586,10 @@ class BleManager private constructor(private val context: Context) {
|
|||||||
* 6채널 측정 명령(maa) 송신 가능 여부:
|
* 6채널 측정 명령(maa) 송신 가능 여부:
|
||||||
* (A) 이전 응답이 아직 진행 중(isMultiChannel && !isComplete)이면 차단.
|
* (A) 이전 응답이 아직 진행 중(isMultiChannel && !isComplete)이면 차단.
|
||||||
* 단 3초 넘게 응답이 안 오면 강제 통과(영영 deadlock 방지).
|
* 단 3초 넘게 응답이 안 오면 강제 통과(영영 deadlock 방지).
|
||||||
* (B) 마지막 송신으로부터 600ms 미만이면 차단(펌웨어 burst 방어).
|
* (B) 마지막 송신으로부터 500ms 미만이면 차단(펌웨어 burst 방어).
|
||||||
*
|
*
|
||||||
* FW VBTFW0116 + MTU 247 + CONN_PRIORITY HIGH 조합에서 한 사이클 응답이
|
* FW VBTFW0116 + MTU 247 + CONN_PRIORITY HIGH 조합에서 한 사이클 응답이
|
||||||
* 약 280~420ms이므로, 600ms = 응답 평균 + 안전 마진 ~200ms.
|
* 약 280~420ms이므로, 500ms = 응답 평균 + 안전 마진 ~80~220ms.
|
||||||
*/
|
*/
|
||||||
private var lastMaaSentMs = 0L
|
private var lastMaaSentMs = 0L
|
||||||
private fun canSendMaa(caller: String): Boolean {
|
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")
|
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")
|
android.util.Log.w("BleManager", "maa THROTTLED [$caller] — ${sinceLast}ms since last")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,6 @@ data class PiezoSettings(
|
|||||||
// Charles 833c110: BV calculation tweak — anterior-wall pull-in magnitude in millimetres.
|
// Charles 833c110: BV calculation tweak — anterior-wall pull-in magnitude in millimetres.
|
||||||
var antOffsetMm: Int = 0,
|
var antOffsetMm: Int = 0,
|
||||||
// 우리 4ae25d9: Auto Scan 측정 사이클 목표 간격 (ms).
|
// 우리 4ae25d9: Auto Scan 측정 사이클 목표 간격 (ms).
|
||||||
// BleManager.canSendMaa() time gate와 동일 값이 기본. 600ms 미만은 throttle이 막음.
|
// BleManager.canSendMaa() time gate와 동일 값이 기본 (500ms).
|
||||||
var autoScanIntervalMs: Int = 600
|
var autoScanIntervalMs: Int = 500
|
||||||
)
|
)
|
||||||
|
|||||||
+19
-4
@@ -862,8 +862,25 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
// Battery with icon
|
// Battery with icon — 연결 끊기면 disconnect 표시로 전환
|
||||||
if (!isDemoMode) {
|
if (!isDemoMode) {
|
||||||
|
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 {
|
val batteryColor = when {
|
||||||
batteryLvl >= 60 -> Color(0xFF4CAF50)
|
batteryLvl >= 60 -> Color(0xFF4CAF50)
|
||||||
batteryLvl >= 30 -> Color(0xFFFF9800)
|
batteryLvl >= 30 -> Color(0xFFFF9800)
|
||||||
@@ -873,14 +890,11 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
// 배터리 바 아이콘 (Canvas로 직접 그리기)
|
// 배터리 바 아이콘 (Canvas로 직접 그리기)
|
||||||
Canvas(modifier = Modifier.size(width = 22.dp, height = 12.dp)) {
|
Canvas(modifier = Modifier.size(width = 22.dp, height = 12.dp)) {
|
||||||
val w = size.width; val h = size.height
|
val w = size.width; val h = size.height
|
||||||
// 외곽
|
|
||||||
drawRoundRect(Color.Gray, topLeft = Offset(0f, 0f),
|
drawRoundRect(Color.Gray, topLeft = Offset(0f, 0f),
|
||||||
size = Size(w * 0.88f, h), cornerRadius = androidx.compose.ui.geometry.CornerRadius(3f),
|
size = Size(w * 0.88f, h), cornerRadius = androidx.compose.ui.geometry.CornerRadius(3f),
|
||||||
style = Stroke(width = 1.5f))
|
style = Stroke(width = 1.5f))
|
||||||
// 양극 돌출
|
|
||||||
drawRect(Color.Gray, topLeft = Offset(w * 0.88f, h * 0.25f),
|
drawRect(Color.Gray, topLeft = Offset(w * 0.88f, h * 0.25f),
|
||||||
size = Size(w * 0.12f, h * 0.5f))
|
size = Size(w * 0.12f, h * 0.5f))
|
||||||
// 충전량
|
|
||||||
val fillW = w * 0.84f * (batteryLvl / 100f).coerceIn(0f, 1f)
|
val fillW = w * 0.84f * (batteryLvl / 100f).coerceIn(0f, 1f)
|
||||||
if (fillW > 0) drawRoundRect(batteryColor,
|
if (fillW > 0) drawRoundRect(batteryColor,
|
||||||
topLeft = Offset(2f, 2f), size = Size(fillW, h - 4f),
|
topLeft = Offset(2f, 2f), size = Size(fillW, h - 4f),
|
||||||
@@ -890,6 +904,7 @@ fun PiezoMonitoringView(appState: AppState) {
|
|||||||
Text("$batteryLvl%", fontSize = (12 * fontScale).sp, fontWeight = FontWeight.Bold, color = batteryColor)
|
Text("$batteryLvl%", fontSize = (12 * fontScale).sp, fontWeight = FontWeight.Bold, color = batteryColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user