# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview POWERFUN Settings App - A React Native application for managing POWERFUN fitness devices (power meters, paddle sensors, T5 trainers) via Bluetooth LE. Supports device scanning, information reading, calibration, firmware updates (DFU), and spindown calibration. ## Build Commands ```sh yarn start # Start Metro bundler yarn android # Run on Android yarn ios # Run on iOS yarn build-a # Android release build (set NODE_OPTIONS=--openssl-legacy-provider) yarn lint # Run ESLint yarn test # Run Jest tests yarn clean-a # Clean Android build (cd android && gradlew clean) ``` ## Architecture ### Navigation Structure - React Navigation Native Stack Navigator - Entry: SplashScreen → HomeScreen - Three device paths from HomeScreen: Power Meter, Paddle, T5 Trainer - Each path: ScanScreen → InfoScreen → DfuScreen - T5 has additional: SpindownScreen - Global: SettingScreen, PrivacyScreen ### Screen to File Mapping | Screen | File | Purpose | |--------|------|---------| | HomeScreen | src/HomeScreen.tsx | Device type selection (3 buttons) | | ScanScreen | src/ScanScreen.tsx | Power meter BLE scanning | | ScanScreen2 | src/ScanScreen2.tsx | Paddle BLE scanning | | ScanScreen3 | src/ScanScreen3.tsx | T5 trainer BLE scanning | | InfoScreen | src/InfoScreen.tsx | Power meter info, real-time data, calibration, power trim | | InfoScreen2 | src/InfoScreen2.tsx | Paddle boat type settings | | InfoScreen3 | src/InfoScreen3.tsx | T5 trainer weight, bike type, ERG smoothing | | DfuScreen | src/DfuScreen.tsx | Nordic DFU firmware upgrade | | SpindownScreen | src/SpindownScreen.tsx | T5 trainer spindown calibration | | SettingScreen | src/SettingScreen.tsx | Language, privacy policy | | PrivacyScreen | src/PrivacyScreen.tsx | Privacy policy content | ### Bluetooth LE Architecture - Library: `@systemic-games/react-native-bluetooth-le` - Central API for scanning, connecting, reading/writing characteristics, subscribing to notifications - Device name prefixes for filtering: - Power meters: `PF-PM5-` or `POWERFUN-` - Paddles: `PF-STK-` or `POWERFUN-` - T5 trainers: `PF-T5-` or `POWERFUN-` - RSSI filtering: devices below -90 dBm are filtered out ### BLE Service/Characteristic UUIDs | Service | Characteristic | Purpose | |---------|----------------|---------| | fff1 | fff2 (write) | Custom power meter commands | | fff1 | fff3 (notify) | Custom power meter responses | | 180a | 2a25 | Serial number | | 180a | 2a28 | Firmware version | | 180a | 2a27 | Hardware version | | 180f | 2a19 | Battery level | | 1818 | 2a63 | Cycling power measurement (real-time) | ### DFU Architecture - Library: `@systemic-games/react-native-nordic-nrf5-dfu` - Firmware manifest: `https://powerfun.oss-cn-shanghai.aliyuncs.com/yecongdfu/latest.json` - Firmware versions parsed as `hardware.iteration.build` (e.g., "1.23.456") - Upgrade only allowed when server iteration > device iteration - Downloads firmware zip to cache, then initiates DFU ### i18n Architecture - Library: i18next with react-i18next - Languages: Chinese (zh) and English (en) - Storage key: `@app_language` in AsyncStorage - Translation files: `src/i18n/locales/zh.json`, `src/i18n/locales/en.json` ## Key Implementation Notes ### Bluetooth Connection Lifecycle - InfoScreens connect to device on mount, disconnect on navigation away (except when going to DfuScreen) - Connection status listener: `Central.addListener("peripheralConnectionStatus", handler)` - Device ready state: `connectionStatus === "ready"` ### Real-time Data Parsing (Power Meter - 2A63) - Byte 2-3: Power value (little-endian) - Byte 4: Left balance (0.5% units) - Byte 5-6: Cadence revolution count (little-endian) - Byte 7-8: Cadence timestamp (1/1024 second units) - Cadence RPM = (revolution_diff / time_in_seconds) * 60 ### Power Trim - Range: 50-200 (represents 50%-200%) - Stored as: value * 100, sent as 2-byte little-endian - Protocol: Write [0x02, low, high] to FFF2, then write [0x04] to trigger update ### Calibration - Command: Write 0x05 to FFF2 - Response: Read from FFF3 notify (0x05 + 2-byte value in 0.1 units) - Timeout: 5 seconds ### Firmware Version Comparison ```typescript // Version format: "hardware.iteration.build" (e.g., "1.23.456") // Only iteration is compared for upgrade decision // hardware mismatch → cannot upgrade // server iteration <= device iteration → no upgrade needed ```