Files
VesiscanClinicalAndroid/app/src/main/java/com/medithings/vesiscan/managers/NirsManager.kt
T
dw.jang bcbc7b440c refactor: 데모 브랜치 패키지 통일 com.example.medilightv2android → com.medithings.vesiscan
사용자앱 (feature/tab-navigation) 과 패키지 이름 일치. namespace + applicationId
둘 다 com.medithings.vesiscan 로 변경 (기존 데모 앱은 재설치 필요).

## 변경 범위
- Kotlin 148 파일: package + import 문 (714 occurrences)
- 디렉토리 이동: com/example/medilightv2android → com/medithings/vesiscan
  (main, test, androidTest 각각)
- app/build.gradle.kts: namespace, applicationId
- docs/FLAVOR_DEMO_STABLE.md: 참조 갱신
- V41DetectorCH4Test: BvDispatchResult.methodChosen → method (dto field name fix)

## 주의
- applicationId 가 바뀌므로 기존 데모 앱 (com.example.medilightv2android.demo) 은
  Android 관점에서 다른 앱으로 취급 — 재설치 시 PIN/설정 초기화됨.
- Fresh install 권장. 기존 앱 (com.example...) 은 별도로 uninstall 필요.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-02 14:30:43 +09:00

95 lines
3.0 KiB
Kotlin

package com.medithings.vesiscan.managers
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import com.medithings.vesiscan.models.NirsMagResponse
import com.medithings.vesiscan.models.NirsMcjPacket
import com.medithings.vesiscan.models.NirsConstants
import com.medithings.vesiscan.BuildConfig
import com.medithings.vesiscan.models.NirsOxyResult
class NirsManager private constructor() {
companion object {
val instance: NirsManager by lazy { NirsManager() }
}
// State
val isStreaming = mutableStateOf(false)
val isCalibrated = mutableStateOf(false)
val isFilterEnabled = mutableStateOf(true)
// Current Values
val currentOxy = mutableStateOf(NirsOxyResult.zero)
val sampleCount = mutableIntStateOf(0)
// Chart History
val oxyHbO2History = mutableStateListOf<Double>()
val oxyHbHistory = mutableStateListOf<Double>()
// Internal
val calcEngine = NirsCalcEngine()
private val maxPoints = NirsConstants.maxHistoryPoints
// Calibration
fun setCalibrationGain(response: NirsMagResponse) {
calcEngine.setGainFromMag(response)
isCalibrated.value = true
}
// Process mcj Packet
fun processMcjPacket(packet: NirsMcjPacket) {
val result = calcEngine.process(packet.ledValues)
currentOxy.value = result.oxyFiltered
sampleCount.intValue++
if (BuildConfig.DEBUG && (sampleCount.intValue <= 3 || sampleCount.intValue % 50 == 0)) {
android.util.Log.d("NirsManager", "Sample #${sampleCount.intValue}: " +
"hasGain=${calcEngine.hasGain}, " +
"led[0..5]=${packet.ledValues.take(6)}, " +
"degain[0..2]=${result.degain.take(3).map { "%.2f".format(it) }}, " +
"oxy=StO2:${"%.1f".format(result.oxyFiltered.stO2)} HbO2:${"%.1f".format(result.oxyFiltered.hbO2)} HHb:${"%.1f".format(result.oxyFiltered.hb)}")
}
appendTrimming(oxyHbO2History, result.oxyFiltered.hbO2)
appendTrimming(oxyHbHistory, result.oxyFiltered.hb)
}
// Controls
fun toggleFilter() {
isFilterEnabled.value = !isFilterEnabled.value
calcEngine.isFilterEnabled = isFilterEnabled.value
if (isFilterEnabled.value) calcEngine.resetFilter()
}
fun clearData() {
oxyHbO2History.clear()
oxyHbHistory.clear()
currentOxy.value = NirsOxyResult.zero
sampleCount.intValue = 0
calcEngine.resetFilter()
}
fun startStreaming() {
isStreaming.value = true
calcEngine.resetFilter()
}
fun stopStreaming() {
isStreaming.value = false
}
fun reset() {
stopStreaming()
clearData()
isCalibrated.value = false
calcEngine.clearGain()
}
// Helpers
private fun appendTrimming(list: MutableList<Double>, value: Double) {
list.add(value)
while (list.size > maxPoints) list.removeAt(0)
}
}