회의 피드백: BLE 연결된 상태에서 HOME으로 가면 연결이 끊겨 다음 측정 때
DeviceScan부터 다시 거쳐야 하는 불편. 연결을 유지하고, Start 시 설정 단계
모두 skip하고 바로 도넛차트로 진입할 수 있도록.
AppState.goHome():
- bleManager.disconnect() 제거 — BLE 연결 유지
- isDeviceConnected reset도 제거 (실제 연결 상태 유지)
- Demo 모드인 경우만 isDeviceConnected=false (가짜 연결 정리)
- NIRS 스트리밍 정지 / 데모 종료 처리는 유지
AppState.startFromHome():
- 연결됨(isDeviceConnected==true) → PIEZO_MONITORING 직진 (도넛차트)
- 미연결 → DEVICE_SCAN (기존 흐름)
HomeView:
- 연결된 상태이면 "● Connected — Start to resume" chip 표시
사용자가 다음 Start가 바로 도넛차트로 갈 것임을 인지 가능
기존 동작 유지:
- ClinicalHome Unpair → appState.isDeviceConnected=false (어제 fix 그대로)
→ HOME 진입 시 chip 안 보임 → Start 시 DeviceScan으로 정상 진입
- PiezoMonitoring Disconnect 다이얼로그 → goHome() 그대로 호출되지만
이젠 BLE 끊기지 않음. 의도적으로 끊고 싶으면 disconnectAndUnbond 사용.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
사내 피드백: PiezoPersonalization 한 화면에 카드 3개를 모은 게 아니라
MaxCapacity 다음 단계로 Auto Scan Interval 화면을 독립적으로 띄우길 원함.
흐름 변경:
before: DeviceScan → PiezoPersonalization (MaxCapacity + Catheter + AutoScan) → Placement
after: DeviceScan → PiezoPersonalization (MaxCapacity + Catheter) → AutoScanSetup → Placement
변경:
- PiezoPersonalizationView 원복: 2카드 / verticalScroll 제거 / spacing 64dp 중앙 정렬
- AutoScanIntervalSetupView 신규 — Bladdy hero + 큰 카드 + Continue 버튼
- AppScreen.AUTO_SCAN_SETUP enum 추가
- personalizationComplete() → AUTO_SCAN_SETUP으로 이동
- autoScanSetupComplete() 신설 — PlacementGuide로 진행, piezoSettings persist
- backFromPlacementGuide() — setup 흐름이면 AUTO_SCAN_SETUP으로 돌아감
- MainActivity 라우팅 + Back handler 추가 (AUTO_SCAN_SETUP → PiezoPersonalization)
PiezoMonitoring의 in-monitoring settings 슬라이더는 그대로 유지 — 측정 중에도
같은 PiezoSettings.autoScanIntervalMs 값을 조정 가능.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
vesiscan_test Section 2 프로토콜 패턴을 안드로이드 앱 안에서 직접 구현.
실제 몸에 센서 붙인 채 6채널 실시간 그래프 보면서 측정 + 저장 가능.
신규 화면 ClinicalLiveView:
- 600ms 간격 mtb? 자동 송신 (Piezo 6ch + IMU 동시)
- 2×3 grid 라이브 차트 (raw ADC waveform, CH0~CH5 색상별)
· y축 0~4095 (12-bit ADC) 고정 + 가로 grid 4분할
· 각 채널 peak 값 표시
- IMU 카드 — ImuAnalysis 기반 자세 + tilt + shake (흔들림 시 빨강 경고)
- 상단: 세션 라벨 + S=Subject TV=TrueVol Ab=Abdomen 한 줄 + #cycle ✓captured
- 컨트롤: Pause/Resume · Capture (수동 저장) · Auto Capture 토글 · End Session
ClinicalSession 모델 확장:
- subjectId / trueVolumeMl / abdomenThicknessMm 필드 추가
- folderName 에 subjectId prefix (예: "S001_VBT26050202_SUPINE_ALIGN_0CM_...")
- meta.json 에 subject_id / true_volume_ml / abdomen_thickness_mm 자동 기록
ClinicalSessionStore:
- lastSubjectId / lastTrueVolumeMl / lastAbdomenThicknessMm 기억 (다음 측정 자동 채움)
ClinicalHomeView 입력 폼 확장:
- Subject ID 텍스트필드
- True Volume (mL) + Abdomen (mm) 2-컬럼 숫자 입력
- Start Live Measurement 버튼 → CLINICAL_LIVE 화면으로 직행
(이전: alignment/BV step에 따라 PlacementGuide/PiezoMonitoring 분기)
AppState/MainActivity:
- AppScreen.CLINICAL_LIVE 추가
- MainActivity Back: LIVE 시 endMeasurement + ClinicalHome 복귀
데이터 흐름:
Start Live → ClinicalLiveView 진입 → mtb? 600ms loop
→ piezoCollector → 6채널 buffer (자동 또는 수동 capture)
→ AdcCsvLogger.log → adc.csv 누적
→ imuCollector → 15 IMU samples
→ ImuCsvLogger.log → imu.csv 누적
End/Back → endMeasurement → meta.json finalize → ClinicalHome 복귀
장점:
- 검사자가 실제 시연 중 6채널 신호 품질 즉시 확인
- Auto Capture로 매 사이클 자동 저장 (Pause로 일시 멈춤)
- subject_id 기반 폴더명으로 피험자별 grouping 자연스럽게
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
이전: 한 세션이 9 conditions × 6 steps를 모두 묶고 마지막에 zip
새로: 한 측정마다 라벨 입력 → 측정 → 자동 finalize → 다음 측정 라벨
사용자 요청: "session 들어가면 일단 BLE 연결을 하고, 연결 이후에 내가 어떤 자세로
어느 위치 측정할건지를 직접 적고 테스트를 완료한 뒤에 로그가 저장되도록"
변경:
- ClinicalSession 모델: 단일 측정 단위로 재정의 (subjectId/device/posture/step
/examiner/notes/startedAt/endedAt). folderName에 라벨 전체 + timestamp 포함:
"S001_A_SUPINE_ALIGN_0CM_2026-05-28_14-30-15"
- ClinicalSessionStore: 단순화. zip 제거. startMeasurement/endMeasurement.
inClinicalFlow boolean 추가 (DeviceScan/Back 라우팅용).
lastSubjectId/Examiner/Notes 기억 (다음 측정 시 자동 채움).
lastFinalizedFolder (UI에 "Saved: ..." 표시용).
- 3 로거: stepLogDir() → currentLogDir() 단순화. 한 폴더에 모든 파일.
- ClinicalHomeView 전면 재작성:
* BLE 연결 상태 카드 (미연결 시 Connect 버튼 → DeviceScan)
* 직전 측정 결과 표시 (lastFinalizedFolder)
* 라벨 입력 폼 (Subject + Device/Posture/Step segmented control + Examiner + Notes)
* 라벨 preview 실시간
* Start Measurement 버튼 (BLE 연결 + Subject ID 있을 때만 활성)
- AppState.deviceConnected: 임상 흐름이면 ClinicalHome 복귀 (Personalization 우회)
- MainActivity Back handler:
* DEVICE_SCAN Back → inClinicalFlow면 ClinicalHome
* PLACEMENT_GUIDE/PIEZO_MONITORING Back → 활성 세션이면 endMeasurement +
ClinicalHome 복귀 (폴더 finalize)
* CLINICAL_HOME Back → inClinicalFlow 해제 + HOME
데이터 구조 (한 측정당):
Downloads/VesiScan_Sessions/{subjectId}_{device}_{posture}_{step}_{timestamp}/
├─ meta.json (라벨 + 앱/펌웨어/디바이스 버전 + 시작/종료 시각)
├─ adc.csv
├─ placements.jsonl (alignment) or events.jsonl (BV)
└─ ble.log
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
회사 내 알고리즘 개발용 임상 시험(3 devices × 3 postures × 6 steps = 54 measurements
per subject)을 위한 데이터 라벨링/라우팅/zip 자동화. Dev 모드 켠 경우에만 노출.
신규 파일:
- models/ClinicalSession.kt — ClinicalDevice/Posture/Step 모델 + 완료 추적
- services/ClinicalSessionStore.kt — 전역 세션 store + 폴더 라우팅 + meta.json + zip
- ui/views/clinical/ClinicalHomeView.kt — 세션 메타 입력 다이얼로그 + 9-conditions
그리드 + 6 steps + Mark Complete + End Session(zip) 화면
로거 라우팅 (세션 존재 시 자동 분기):
- AdcCsvLogger: sessionRoot/{device}_{posture}/{step}/adc.csv +
CSV에 clinical_label 컬럼 추가 (S001_A_SUPINE_ALIGN_0CM 형태)
- MeasurementLogService: 내부 filesDir → Downloads/VesiScan_Events/ 영구 이동.
세션 시 step 폴더의 events.jsonl/placements.jsonl로 분기.
BuildConfig 대신 PackageInfo로 versionName/versionCode 정확 주입.
보관 90일 → 365일 (R&D 장기 보관)
- BleDebugLogger: step 변경 감지해서 ble.log 파일 자동 전환
UI/라우팅:
- AppScreen.CLINICAL_HOME + MainActivity Crossfade/BackHandler 분기
- HomeView에 dev 모드 한정 보라색 "Clinical Mode (Dev)" 버튼
- 측정 화면(PlacementGuide/PiezoMonitoring) Back 시 임상 세션 활성 → ClinicalHome 복귀
Placement 구조화:
- PlacementGuideView가 logService.logPlacement() 호출 시 urineLens/cv/phase/score
추가 인자 전달 → placements.jsonl에 구조화 기록
데이터 구조 (한 세션당):
Downloads/VesiScan_Sessions/{S001_2026-05-28_14:30}/
├─ meta.json
├─ A_SUPINE/align_0cm/{adc.csv, placements.jsonl, ble.log}
├─ A_SUPINE/align_1cm/...
├─ ...
├─ A_SUPINE/bv/{adc.csv, events.jsonl, ble.log}
├─ A_SITTING/... (총 9 conditions × 6 steps)
└─ session.zip (End Session 시 자동 생성)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
기존 hardcoded 600ms를 사용자가 Settings에서 조절 가능하도록 변경.
추가:
- PiezoSettings.autoScanIntervalMs (default 600ms) 필드
- AppState.savePiezoSettings() 헬퍼 — storage에 piezoSettings 영속화
- Settings 패널에 슬라이더 (Catheter Threshold 다음, Bladder Capacity와 동일 톤)
- 범위 600~5000ms, 200ms 단위로 snap (roundToInt + 200 배수)
- 현재값 mL 표시 패턴과 동일하게 "X ms" 우측 표시
- Settings Save 버튼이 실제로 영속화하도록 savePiezoSettings() 호출 추가
(이전에는 showSettings=false만 호출 — maxVolume 등도 메모리만 변경되던 버그 동시 fix)
동작:
- PiezoMonitor Auto loop의 remaining = targetIntervalMs - elapsed
- BleManager throttle(600ms)이 하한이라 600 미만 설정해도 막힘 — 의미 있는 최소가 600
- 5000ms로 설정 시 거의 정적 모니터링 (배터리/CPU 절약)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
빌드 104-105 적용:
- DeviceScanView "No devices found" 화면에 dev 모드 한정 "Enter Measurement Mode" 버튼 추가 (BLE 없이 디자인 작업용)
- AppState.startFromHome() 라우팅 fix — 페어링 후 Personalization → Back → HOME → Start 시 Monitoring 직행 버그를 PIEZO_PERSONALIZATION 부터 시작하도록 변경
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## 측정 화면 (PiezoMonitoringView)
- BoxWithConstraints + donutFitSize: 가로/작은 화면에서도 donut+Bladdy+buttons
모두 들어오도록 height-aware sizing (cap 120~360dp)
- nonDevSpacing: available height 기반 단계 (18/22/28/36) — 큰 화면 답답함 해소
- center 4 중 1개라도 missing → 즉시 realign prompt (이전: AutoMeasure 5회 누적)
- 6채널 중 3개 이상 missing 시 위치 이탈 알림 (모드 무관)
- 다이얼로그 문구: "Position Lost or Insufficient Gel"
- V41 결과 후처리 — walls를 PiezoEchoAnalyzer 기준으로 강제 (UI 차트와 일관)
· ant = analyzer.result.ant
· post = analyzer.result.lowEnd + 3
- CH3 secondary echo 잡힘 / CH4·CH5 lateral ant too-deep 문제 해결
- Bladdy 3-tap → Developer Mode toggle (측정 화면에서도)
## Placement 가이드 (PlacementGuideView)
- 가로 모드 대응: bodyW = min(w, h*0.7f) — 태블릿 가로에서 portrait 비율 유지
- Sensor 이미지를 Canvas drawImage 로 이동 — bladder oval 좌표계와 정확히 정렬
- Start Alignment 버튼: enabled = true 명시
## Settings overlay
- "Ant Offset" 숫자 입력 필드 (0~20mm, dev mode 전용)
· BV 계산 시 ant 를 입력값만큼 probe 쪽으로 당김 (chord 증가 → BV 증가)
· mm→samples 변환은 PiezoHW.distancePerSample
· V41 SphereFit BV 는 offset≠0 일 때 우회 → 6ch estimate
- "Version" row 추가 (BuildConfig.VERSION_NAME)
- Save 버튼: 실제 UserStorage 영구 저장 + state 재전파
· AppState.savePiezoSettingsNow() 추가
- 전체 overlay 에 verticalScroll + Card maxHeight 90% — dev 컨텐츠 길어도 Save 도달
## DPS 동기화 (긴급 수정)
설정의 DPS 변경이 V41Detector(Geometry/AnatomicalGate)에 반영 안 되던 문제:
- WdConfig.DPS_DEFAULT: const val → @Volatile @JvmField var
- PiezoHW.distancePerSample setter 가 WdConfig.DPS_DEFAULT 자동 동기화
- 시작 시점 1.968.also { WdConfig.DPS_DEFAULT = it } 로 두 값 일치
## 버전
- versionName: VBTAND0101 → 2026005-101
- versionCode: 2 → 3
## 신규 모듈
- services/ScanLogStore.kt — dev mode 진단 로그 (마지막 Single Scan summary)
· WALLS CSV (ch,ant,post,urine), DATA CSV (raw ADC), antOffsetMm
- ui/components/ScanLogDialog.kt — 클립보드 복사 다이얼로그
· xbench (CharlesKWONsLaw) MbbLogDialog 패턴 차용
· SelectionContainer + monospace + Copy/Clear/Close
- 측정 화면 dev panel 에 "Scan Log (N)" 버튼 추가
## 데이터 모델
- PiezoSettings.antOffsetMm: Int = 0 필드 추가
## 단위 테스트
- V41DetectorCH4Test.kt — 2026-05-06 floating-signal 캡쳐 6채널 raw 를
V41Detector.detect 에 통과시켜 결과 출력 (CH4 가짜 wall 진단용)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Developer mode: 캐릭터 3탭 토글, dev-only settings/graphs/logs
- SWEEP placement (CKLaw): BladderSphereSeek circle fit + RTracker
+ argmax + coronal lateral + R-peak gate GREEN lock
- Gradient placement: weighted center gradient 기반 상하 판정,
방향 로직 수정 (ch0=위, ch3=아래), 초기 멘트 "치골 위에 배치"
- Spot 측정: isSpotInProgress 플래그로 중간값 화면 깜빡임 제거
- 좌우 애매한 ↔ 멘트 제거 → 구체적 방향 또는 상태 안내
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A. Reminder: ReminderService (AlarmManager chain), ReminderSettingsView,
bell icon in Piezo top bar, reschedule on catheterization
B. Consent: ConsentView (3 mandatory items), onboarding→consent→registration flow,
persistent consent storage, sex field in User + Registration Step 2
C. Diary: 24hUV, NUV, NPI, max capacity, day/night frequency metrics card
D. Design: DesignTokens.kt, 48dp touch targets, DonutChart semantics, pressScale modifier
E. Quality: BuildConfig.DEBUG log wrapping, DateFormatter caching, background I/O for diary store
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Camera was hidden behind PiezoMonitoringView because it was rendered
as a child composable. Now uses AppScreen.URINE_CAMERA for full
Crossfade navigation — camera gets its own screen transition.
Flow: Catheterize → 카메라 → AppScreen.URINE_CAMERA → measure → back to PIEZO_MONITORING
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
VoidingDiaryView:
- Date-grouped record list (grouped by day)
- Shows volume/awake/sleep with icons and colors
- Method badge (수기/음성/카메라)
- Delete with confirmation dialog
- Total record count footer
Navigation changes:
- Piezo screen: ArrowBack → Home icon (집 아이콘)
- Piezo screen: 배뇨일지 icon (Description) added next to home
- NIRS screen: ArrowBack → Home icon
- AppScreen.VOIDING_DIARY route added to Crossfade navigation
- VoidingDiaryView navigates back to HOME
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add "Demo Mode" button in device scan screen that bypasses BLE
connection and calibration. NIRS monitoring generates simulated
random data at 4Hz. Both monitoring views show DEMO badge in top bar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix BLE API deprecation warnings with API 33+ version checks
- Move isServiceReady to onDescriptorWrite for reliable CCCD setup
- Fix battery polling: immediate query on connect, pause during NIRS streaming
- Add mcj retry mechanism for NIRS streaming reliability
- Add debug logging to BLE, NIRS parsing, and processing pipeline
- Add catheter count feature to Piezo monitoring (persistent count, add dialog, auto-decrement on catheterize)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port of MedilightV2 iOS app to Android with Kotlin + Jetpack Compose.
Includes BLE connectivity, NIRS/Piezo sensor modes, Rive animations,
interactive measurement history charts, and foldable device support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>