# RoomfitV2

BLE 기반 디지털 케이블 운동기구 제어 앱 (Flutter).

## 개요

Roomfit은 전류 제어 기반 디지털 웨이트 머신이다. 물리적 추 대신 모터 전류로 저항을 생성하며,
모든 운동 데이터를 실시간 BLE 스트리밍으로 앱에 전달한다.

## 기술 스택

- **Flutter** (Dart 3.10+) + **Riverpod** + **Freezed**
- **flutter_blue_plus** (BLE)
- **roomfit_protocol** — 순수 Dart MCU 프로토콜 패키지

## 프로젝트 구조

```
lib/
├── core/                    # Infrastructure (BLE, DeviceGateway, Logger)
└── features/
    └── {feature}/
        ├── domain/providers/ # Business logic (facade providers)
        └── presentation/    # UI (screens, widgets)

packages/roomfit_protocol/   # 순수 Dart — MCU 통신 프로토콜
├── lib/src/commands/        # 26개 Command 클래스
├── lib/src/responses/       # 17개 Response 클래스
├── lib/src/codec/           # 패킷 빌더, 프레임 코덱
└── lib/src/constants/       # 커맨드 코드, BLE UUID, 물리 단위
```

## MCU 통신

### BLE (Nordic UART Service)

| 방향 | UUID |
|------|------|
| App → MCU (TX) | `6e400002-b5a3-f393-e0a9-e50e24dcca9e` |
| MCU → App (RX) | `6e400003-b5a3-f393-e0a9-e50e24dcca9e` |

패킷 포맷: `[0xFF, 0xFF, SIZE, CMD, DATA..., CHECKSUM]`

### 리포트 스트림 (50ms 주기, 36바이트)

앱은 연결 직후 `0xF5 0x20`을 전송하여 dev report를 활성화한다.

```
Byte    Field           Unit              Description
──────────────────────────────────────────────────────────
[0-1]   timeTick        50ms/tick         경과 시간
[2-3]   positionL       0.05mm/unit       좌측 모터 위치 (엔코더)
[4-5]   positionR       0.05mm/unit       우측 모터 위치
[6-7]   speedL          mm/s, signed      좌측 속도
[8-9]   speedR          mm/s, signed      우측 속도
[10-11] accelL          mm/s², signed     좌측 가속도
[12-13] accelR          mm/s², signed     우측 가속도
[14-15] icmdL           mA, signed        좌측 전류 명령 (토크)
[16-17] icmdR           mA, signed        우측 전류 명령
[18-19] ifbL            mA, signed        좌측 피드백 전류
[20-21] ifbR            mA, signed        우측 피드백 전류
[22-23] fLoadL          0.01kg, signed    좌측 계산 부하
[24-25] fLoadR          0.01kg, signed    우측 계산 부하
[26-27] voltage         0.01V             전원 전압
[28]    weightModeL     enum              좌측 모드 (0=const, 1=ecc, 2=band)
[29]    weightModeR     enum              우측 모드
[30]    regionL         enum              좌측 포지션 리전
[31]    regionR         enum              우측 포지션 리전
[32-33] weightSetL      0.01kg, signed    좌측 설정 무게
[34-35] weightSetR      0.01kg, signed    우측 설정 무게
```

### 무게 모드

| 모드 | 값 | 동작 |
|------|-----|------|
| Constant | 0 | 일정 저항 (일반 웨이트) |
| Negative | 1 | 편심 수축 시 저항 증가 (근비대) |
| Squeeze  | 2 | 늘릴수록 저항 증가 (밴드형) |

## 빌드 & 테스트

```bash
flutter test                           # 전체 테스트
dart test packages/roomfit_protocol/   # 프로토콜 패키지 테스트
flutter analyze                        # 정적 분석
flutter run                            # 디바이스 실행
```
