# TEM Receiver — 瞬变电磁接收机手机 App

六通道瞬变电磁（TEM）接收机的移动端控制与数据采集软件，通过 WiFi TCP 连接设备，实现参数配置、实时波形显示、数据管理与导出。

## 功能概述

- **设备连接** — WiFi TCP 自动连接/重连/心跳保活
- **参数配置** — 通道数、发射频率、采样率、叠加次数、增益等全部参数下发
- **实时采集** — 单次/连续采集，实时波形显示（LIN/LOG 模式）
- **波形交互** — 全屏查看、双指缩放、单指拖拽、横屏支持
- **数据管理** — 工程-测线-测点三级管理，支持新建/删除/切换
- **数据导出** — CSV 导出、.tem 工程打包导出，支持分享到微信等 App
- **数据导入** — 导入 .tem 工程文件，恢复全部测线和波形数据
- **主题适配** — 自动跟随系统深色/浅色模式
- **设备状态** — 实时显示发射电流、电池电压、温度、GPS、SD 卡、姿态角

## 技术栈

| 类别 | 技术 |
|------|------|
| 框架 | React Native 0.85 + Expo SDK 56 |
| 语言 | TypeScript 6.0 |
| 路由 | expo-router (文件式路由) |
| 状态管理 | Zustand 5 (持久化) |
| 数据库 | expo-sqlite (SQLite WAL 模式) |
| 图表 | @shopify/react-native-skia |
| 手势 | react-native-gesture-handler + react-native-reanimated |
| TCP 通信 | react-native-tcp-socket |
| 文件压缩 | fflate (ZIP 压缩/解压) |

## 环境要求

| 工具 | 版本 |
|------|------|
| Node.js | >= 18 |
| npm | >= 9 |
| Android Studio | 最新版（含 Android SDK） |
| JDK | Android Studio 内置 JBR |
| ADB | Android SDK platform-tools |

### 环境变量（Windows）

```
JAVA_HOME = D:\Program Files\Android\Android Studio\jbr
ANDROID_HOME = D:\ProgramData\AndroidSdk
PATH += %JAVA_HOME%\bin;%ANDROID_HOME%\platform-tools
```

## 快速开始

### 1. 安装依赖

```bash
cd TriloopTem_App
npm install
```

### 2. Debug 运行

手机通过 USB 连接电脑，开启 USB 调试：

```bash
npx expo run:android
```

或使用项目自带脚本：

```bash
run-android.bat
```

### 3. Release 构建

双击 `build-release.bat`，或手动执行：

```powershell
$env:JAVA_HOME = "D:\Program Files\Android\Android Studio\jbr"
cd android
.\gradlew.bat assembleRelease
```

APK 输出路径：`android/app/build/outputs/apk/release/app-release.apk`

### 4. 安装到手机

```bash
adb uninstall com.triloop.temreceiver
adb install android/app/build/outputs/apk/release/app-release.apk
```

### 5. iOS 构建

需要 macOS + Xcode + Apple Developer 账号：

```bash
npx expo prebuild --platform ios
npx react-native run-ios
```

或使用 EAS 云构建（无需 Mac）：

```bash
npx eas build --platform ios
```

## 代码结构

```
TriloopTem_App/
├── app/                          # 页面路由 (expo-router 文件式路由)
│   ├── _layout.tsx               # 根布局，初始化数据库
│   ├── connect.tsx               # 连接页面
│   ├── +not-found.tsx            # 404 页面
│   └── (tabs)/                   # Tab 页面
│       ├── _layout.tsx           # Tab 栏配置
│       ├── wave.tsx              # 波形页 — 实时采集与波形显示
│       ├── records.tsx           # 测点页 — 测点列表与数据管理
│       ├── profile.tsx           # 剖面页 — 剖面分析与门窗配置
│       └── projects.tsx          # 工程页 — 工程/测线/测点管理
│
├── src/
│   ├── protocol/                 # 设备通信协议
│   │   ├── constants.ts          # 功能码、频率表、增益表
│   │   ├── packet.ts             # 发送包构建 (Setup/Start/Stop)
│   │   ├── parser.ts             # 接收帧解析 + ADC 转换
│   │   └── types.ts              # 协议数据类型定义
│   │
│   ├── services/                 # 业务服务层
│   │   ├── TcpService.ts         # TCP 连接管理 (连接/重连/心跳)
│   │   ├── DeviceService.ts      # 设备交互 (命令发送/ACK/数据处理)
│   │   ├── StorageService.ts     # SQLite 数据持久化
│   │   ├── BinLoader.ts          # TEMF 二进制波形文件读写
│   │   └── TemBundle.ts          # .tem 工程打包/解包 (ZIP)
│   │
│   ├── stores/                   # 状态管理 (Zustand)
│   │   ├── dataStore.ts          # 会话/帧数据/工程关联
│   │   ├── deviceStore.ts        # 设备配置/遥测状态
│   │   └── connectionStore.ts    # TCP 连接状态
│   │
│   ├── components/               # 可复用组件
│   │   ├── WaveformChart.tsx     # Skia 波形图表 (缩放/拖拽)
│   │   ├── ParamForm.tsx         # 参数配置表单
│   │   ├── SessionSelector.tsx   # 测线选择器
│   │   ├── NoProjectGate.tsx     # 无工程提示页
│   │   ├── device/
│   │   │   └── GlobalStatusBar.tsx  # 全局状态栏
│   │   └── modals/
│   │       └── ConnectModal.tsx  # 连接弹窗
│   │
│   ├── hooks/                    # 自定义 Hooks
│   │   ├── useDevice.ts          # 设备操作封装
│   │   └── useWaveform.ts        # 波形数据处理与降采样
│   │
│   ├── design/
│   │   └── tokens.ts             # 主题色板 (深色/浅色) + useTheme()
│   │
│   └── utils/
│       ├── export.ts             # CSV 导出与文件分享
│       ├── format.ts             # 数值/坐标/时间格式化
│       └── storage.ts            # Zustand 持久化存储适配
│
├── assets/images/                # 图标与闪屏资源
├── docs/
│   └── commercial-audit.md       # 商业化审计报告
├── android/                      # Android 原生工程
├── app.json                      # Expo 配置
├── package.json                  # 依赖管理
├── build-release.bat             # Release 一键构建脚本
└── run-android.bat               # Debug 运行脚本
```

## 通信协议

### 帧格式

```
┌──────────┬──────┬─────┬────────────┬────────────┐
│ Magic 4B │ Flag │ CMD │ Length     │ Tail/Len   │
│ 68 68    │ FF/FE│     │ 2B or 4B  │ 68 68 / -- │
│ FF FF    │      │     │           │            │
└──────────┴──────┴─────┴────────────┴────────────┘
```

- **Flag bit0=1** (0xFF)：2 字节长度 + `68 68` 尾部（App 发送使用）
- **Flag bit0=0** (0xFE)：4 字节长度，无尾部（设备回复使用）

### 功能码

| 方向 | CMD | 说明 |
|------|-----|------|
| App→设备 | 0x01 | 参数配置 (Setup) |
| App→设备 | 0x02 | 连续采集启动 |
| App→设备 | 0x03 | 单次采集 |
| App→设备 | 0x04 | 停止采集 |
| App→设备 | 0x08 | 分帧传输 |
| 设备→App | 0x81 | 配置 ACK |
| 设备→App | 0x82 | 连续采集 ACK |
| 设备→App | 0x83 | 单次采集 ACK |
| 设备→App | 0x84 | 停止 ACK |
| 设备→App | 0x85 | 测量数据帧 |
| 设备→App | 0x95 | 组合源数据帧 |

### ADC 转换公式

```
电压(μV) = (raw_int32 / 0x7FFFFFFF) × 5.0 × 1e6 / gain
发射电流(A) = (raw_uint32 / 0x7FFFFFFF) × 5.0 × 50
```

### 设备默认参数

| 参数 | 默认值 | 说明 |
|------|--------|------|
| 通道数 | 3 | 1-6 通道 |
| 发射频率 | code 5 = 16Hz | 0.5Hz ~ 64Hz |
| 采样率 | code 0 = 250kHz | 250kHz ~ 48Hz |
| 采样深度 | 2000 | 每通道采样点数 |
| 叠加次数 | 32 | 1-16383 |
| 增益 | code 3 = 1× | 1/8× ~ 128× |
| 回传方式 | WiFi | USB/P900/WiFi |
| 补偿电阻 | 12 | |
| 补偿去使能延时 | 60 | |

## 数据管理

### 三级结构

```
工程 (Project)
 └── 测线 (Session)
      └── 测点 (Frame)
           ├── 元数据 (GPS/电流/温度/姿态角...)
           └── 波形数据 (.bin 文件)
```

### 数据库表

- `projects` — 工程信息
- `sessions` — 测线，必须归属工程
- `frames` — 测点，关联测线和 .bin 波形文件

### 导出格式

- **CSV** — 测线级导出，包含所有测点的元数据和各通道峰值
- **.tem** — 工程级导出，ZIP 压缩包含 `project.json` 和所有 `.bin` 波形文件

### TEMF 二进制格式

每个测点的波形数据存储为 `.bin` 文件（TEMF v1 格式）：
- 64 字节文件头：通道数、采样深度、GPS、电流、温度、姿态角等
- 数据区：int32 LE，按通道顺序存储
