# EZOpenSDK HarmonyOS 配网

## 配网模块 import 参考

```typescript
import {
  EZOpenSDK,
  EZError,
  EZErrorCode,
  EZProbeDeviceInfo,
  EZWifiConfigStatus
} from '@ohos/EZOpenSDK'
import wifiManager from '@ohos.wifiManager'
import { connection } from '@kit.NetworkKit'
import EZBusinessTool from '../businesstool/EZBusinessTool'
```

## 一、配网方式概览

| 配网方式 | 说明 |
|----------|------|
| AP 配网 | 设备创建临时热点，手机连接后传输 WiFi 信息。一般设备都支持 |
| 网线配网 | 插网线后直接绑定 |

> 鸿蒙 SDK 当前支持 AP 配网和网线配网两种方式。

## 二、配网方式选择

通过 probeDeviceInfo 获取设备能力后判断：

```typescript
EZOpenSDK.probeDeviceInfo(deviceSerial, deviceType, (deviceInfo, error) => {
  if (error && error.code == EZErrorCode.EZ_HTTPS_DEVICE_OFFLINE_NOT_ADDED) {
    // 设备离线，需要配网
    if (deviceInfo) {
      let supportAP = EZProbeDeviceInfo.supportAP(deviceInfo.supportExtJSON)
      let supportApMode = supportAP == 2
      let supportWiFi5G = EZProbeDeviceInfo.support5GWiFi(deviceInfo.supportExtJSON)
      // 记录设备热点前缀
      let prefix = EZBusinessTool.getWiFiConfigPrefix(
        EZProbeDeviceInfo.getDeviceHotSpot(deviceInfo.supportExtJSON)
      )
    }
  }
})
```

选择逻辑：
- `supportAP == 2` → 接入 AP 配网即可（一般设备都支持）
- 设备有网线 → 网线配网

## 三、AP 配网

### 流程
1. 权限配置（WiFi 权限）
2. 查询设备信息 probeDeviceInfo
3. 连接设备热点
4. 调用 startAPConfigWifi 发起配网
5. 调用 addDevice 添加设备

### 连接设备热点

鸿蒙通过 `wifiManager.addCandidateConfig` 连接设备热点：

```typescript
// 热点名称：前缀_序列号
let deviceWifiName = `${wifiConfigPrefix}_${deviceSerial}`
// 热点密码：前缀_验证码
let deviceWifiPwd = `${wifiConfigPrefix}_${verifyCode}`

let config: wifiManager.WifiDeviceConfig = {
  ssid: deviceWifiName,
  preSharedKey: deviceWifiPwd,
  securityType: wifiManager.WifiSecurityType.WIFI_SEC_TYPE_PSK
}

try {
  let networkId = await wifiManager.addCandidateConfig(config)
  // 通过 connection.createNetConnection 监听连接状态
  let netConn = connection.createNetConnection({
    netCapabilities: { bearerTypes: [connection.NetBearType.BEARER_WIFI] },
    bearerPrivateIdentifier: `${networkId}`
  }, 10000)
  netConn.register((error) => {})
  netConn.on('netAvailable', (error) => {
    // 连接成功，开始配网
    this.startConfigWifi()
  })
} catch (error) {
  // 连接失败，需引导用户手动去系统 WiFi 设置连接设备热点
}
```

**关键注意事项：**
- 自动连接可能失败，此时需引导用户手动去系统设置页连接设备热点
- 连接成功后需验证当前 WiFi 名称是否与设备热点一致，再发起配网
- `onPageShow` 中检查网络状态并重试配网

### 发起 AP 配网
```typescript
EZOpenSDK.startAPConfigWifi(ssid, password, deviceSerial, verifyCode, (status, deviceSerial) => {
  switch (status) {
    case EZWifiConfigStatus.DEVICE_WIFI_SENT_SUCCESS:
      // WiFi 信息已发送给设备
      break
    case EZWifiConfigStatus.DEVICE_WIFI_SENT_FAILED:
      // 发送失败
      break
    case EZWifiConfigStatus.DEVICE_PLATFORM_REGISTED:
      // 设备注册平台成功，可以添加设备
      break
    case EZWifiConfigStatus.DEVICE_PLATFORM_REGIST_FAILED:
      // 注册平台失败
      break
  }
})
```

### 停止 AP 配网
```typescript
EZOpenSDK.stopAPConfigWifi()
```

### 添加设备
```typescript
EZOpenSDK.addDevice(deviceSerial, verifyCode, (error) => {
  if (!error) {
    // 添加成功
  }
})
```

## 四、网线配网

给设备插上网线，待设备提示注册平台成功后，直接添加：
```typescript
EZOpenSDK.addDevice(deviceSerial, verifyCode, (error) => {
})
```

## 五、配网流程页面概览

### 流程全景图

```
设备列表页[右上角添加按钮]
     │
     ▼
[1] 扫描二维码（EZAddByQRCodePage）
     │ 扫码成功 / 手动输入
     ▼
[1.5] 输入序列号（EZInputSerialPage）
     │ 确认
     ▼
[2] 设备确认（EZDeviceResultPage）
     │ probeDeviceInfo 查询
     │ ├── 设备在线未添加 → 直接 addDevice → 回设备列表
     │ └── 设备离线 → 下一步
     ▼
[3] 准备设备（EZWifiTipsPage）
     │ 确认设备通电指示灯快闪
     ▼
[4] 选择 Wi-Fi / 输入密码（EZWifiInfoPage）
     │ 选择配网方式
     ▼
[5] AP 配网执行（EZAPWiFiConfigPage）
     │ 连接设备热点 → 发送WiFi信息 → 等待注册
     ▼
[6] 配网结果（EZAPConfigResultPage）
     │ 轮询 addDevice → 成功/超时
     ▼
[完成] 返回设备列表
```

### 页面详细描述

#### 二维码解析规则

萤石/海康设备二维码有多种格式，Demo 中的解析逻辑如下：

1. 按换行符拆分二维码内容
2. 第二行为设备序列号（9 位字母数字）
3. 第三行为验证码（6 位）
4. 第四行为设备型号（可选）

如果拆分后序列号长度为 9 则认为合法，否则提示"请扫描萤石设备机身或说明书上的二维码"。

```typescript
// Demo 简化解析逻辑
if (mSerialNoStr && mSerialNoStr.length == 9) {
  GlobalKit.getInstance().deviceSerialNo = mSerialNoStr
  GlobalKit.getInstance().deviceVerifyCode = mSerialVeryCodeStr
  RouterManager.pushUrl(RouterManager.deviceResultPage)
} else {
  // 非萤石二维码，弹框提示
}
```

**验证码长度**：6-8 位（海康 NVR 设备为 8 位，摄像头通常为 6 位）

#### 页面 1：扫描二维码（EZAddByQRCodePage）

**页面内容**：
- 全屏相机预览 + 方形取景框（白色边框 + 扫描提示文字）
- 导航栏：返回按钮 + 标题"扫描二维码" + 右侧"手动输入"按钮
- 底部闪光灯按钮
- 提示文字："对准二维码/条形码，即可自动扫描"

**业务逻辑**：
- 使用 HarmonyOS ScanKit（`customScan`）扫描 QR 码
- 需要相机权限（`ohos.permission.CAMERA`），拒绝则提示引导至设置页
- 扫码成功后震动反馈（`vibrator.startVibration`）
- 解析二维码：判断是否为 9 位序列号，是则跳转设备确认页；否则弹框提示

**跳转**：扫码成功 → 设备确认页；点击手动输入 → 输入序列号页

#### 页面 1.5：输入序列号（EZInputSerialPage）

**页面内容**：
- 序列号输入框：最大 9 位
- 验证码输入框：最大 6 位
- 底部"下一步"按钮

**业务逻辑**：
- 下一步按钮启用条件：序列号长度 == 9 且验证码长度 >= 6
- 输入完成后保存到 GlobalKit 全局单例

**跳转**：下一步 → 设备确认页

#### 页面 2：设备确认（EZDeviceResultPage）

**页面内容**：
- 加载状态：LoadingProgress + 提示文字
- 结果状态：设备图片 + 序列号 + 状态文字 + 操作按钮

**业务逻辑**：
- 进入页面后调用 `EZOpenSDK.probeDeviceInfo` 查询设备状态
- 根据错误码分支处理：
  - 120020/120022/120029（已被添加）→ 显示提示
  - 120023（设备离线未添加）→ 显示"连接网络"按钮，记录配网能力集
  - 无错误（设备在线）→ 显示"添加"按钮，直接 addDevice
- 添加设备需要验证码时弹出输入框

**跳转**：连接网络 → 准备设备页；添加成功 → 回设备列表

#### 页面 3：准备设备（EZWifiTipsPage）

**页面内容**：
- 设备图片
- 说明文字："请将设备插上电源，耐心等待约1分钟，直到指示灯呈蓝色快速闪烁"
- 底部"设备已准备好"按钮
- 文字链接："配网前需要重置？"

**跳转**：设备已准备好 → WiFi 信息输入页；重置 → 设备重启提示页

#### 页面 3.5：设备重启提示（EZDeviceRestartTipsPage）

**页面内容**：
- 引导图：Reset 按钮示意图
- 说明文字："请根据图示长按 reset 键，直到设备提示重置成功后松开"
- 底部"下一步"按钮

**跳转**：下一步 → WiFi 信息输入页

#### 页面 4：WiFi 信息输入（EZWifiInfoPage）

**页面内容**：
- 提示文字（不支持 5G 时显示）
- SSID 输入框
- 密码输入框
- 底部"下一步"按钮

**业务逻辑**：
- 不支持 5G 频段的设备，如果 SSID 包含"5G"则提示用户
- 下一步弹出配网方式选择 SheetDialog（AP配网/网线配网）

**跳转**：选择 AP 配网 → AP 配网执行页

#### 页面 5：AP 配网执行（EZAPWiFiConfigPage）

**页面内容**：
- 设备热点名称和密码显示
- 操作步骤（1.复制密码 2.去设置连接 3.返回等待配网）
- 复制密码按钮
- 跳转系统设置按钮
- 配网中 LoadingProgress
- "添加设备"按钮（配网成功后显示）

**业务逻辑**：
- 自动尝试通过 `wifiManager.addCandidateConfig` 连接设备热点
- 如自动连接失败，显示手动引导步骤，引导用户去系统设置页连接
- `onPageShow` 中检查当前 WiFi 是否为设备热点，是则发起 `startAPConfigWifi`
- 监听 `EZWifiConfigStatus` 回调状态
- 设备注册平台成功后显示"添加设备"按钮

**跳转**：添加设备 → 配网结果页

#### 页面 6：配网结果（EZAPConfigResultPage）

**页面内容**：
- LoadingProgress（轮询中）
- 成功图标（添加成功后）
- 重试按钮（超时后）
- 完成按钮（成功后）

**业务逻辑**：
- 每 5 秒轮询一次 `probeDeviceInfo` + `addDevice`
- 最多轮询 20 次（约 100 秒），超时显示重试按钮
- 添加成功后发送 `emitter` 通知设备列表页刷新
- 处理各种 addDevice 错误码（验证码错误、已被添加等）

**跳转**：完成 → 回设备列表页

### 页面返回导航

| 当前页面 | 返回目标 | 说明 |
|---------|---------|------|
| 扫描二维码 | 设备列表 | 关闭配网流程 |
| 输入序列号 | 扫描二维码 | |
| 设备确认 | 上一页 | |
| 准备设备 | 设备确认 | |
| WiFi 信息 | 准备设备 | |
| AP 配网执行 | WiFi 信息 | |
| 配网结果 | 设备列表 | 完成/超时后回到列表 |

### 生命周期清理

配网页面退出时必须调用：
```typescript
EZOpenSDK.stopAPConfigWifi()
```

---

## 六、实战要点

### 6.1 probeDeviceInfo 返回的错误码区分

```typescript
EZOpenSDK.probeDeviceInfo(serialNo, '', (deviceInfo, error) => {
  if (!error) {
    // 设备在线未添加 → 直接 addDevice
  } else {
    switch (error.code) {
      case EZErrorCode.EZ_HTTPS_DEVICE_OFFLINE_NOT_ADDED: // 120023
      case 120002: // 设备不存在
      case 120029: // 设备不在线，已被自己添加
        // 可以走配网流程
        break
      case 120020: // 设备在线，已被自己添加
      case 120022: // 设备在线，已被别人添加
      case 120024: // 设备不在线，已被别人添加
        // 无需配网，显示提示
        break
    }
  }
})
```

### 6.2 设备热点前缀
```typescript
let prefix = EZBusinessTool.getWiFiConfigPrefix(
  EZProbeDeviceInfo.getDeviceHotSpot(deviceInfo.supportExtJSON)
)
// 0-EZVIZ，1-SoftAP，2-CAMGO
```

### 6.3 配网完成后刷新设备列表

配网成功后应通过 `emitter` 通知设备列表页刷新：
```typescript
import emitter from '@ohos.events.emitter'
emitter.emit({ eventId: EmitterEvents.EZDeviceListPageRefresh })
```

### 6.4 5G WiFi 过滤

多数摄像头不支持 5GHz，输入的 SSID 如包含 "5G" 且设备不支持 5G（`supportWiFi5G == false`），应提示用户。

### 6.5 配网页面退出时必须清理

```typescript
aboutToDisappear() {
  EZOpenSDK.stopAPConfigWifi()
}
```

### 6.6 重要提示
账户下删除设备重新配网时，请在重置设备后等待 2 分钟再调用配网接口，等平台确认设备下线后配网成功率更高。

## 七、配网常见问题

**Q：AP 配网自动连接设备热点失败**
A：鸿蒙通过 `wifiManager.addCandidateConfig` 连接，部分场景下可能失败。此时需引导用户手动去系统设置页连接设备热点，返回 App 后自动检测网络并发起配网。

**Q：AP 配网故意输错 WiFi 密码，SDK 还在轮询**
A：SDK 将 WiFi 信息发送给设备后，手机和设备没有通讯联系。SDK 只能等待轮询设备是否注册到平台，超时后回调配网失败。

**Q：设备配网时提示"当前网络环境复杂"**
A：环境中 WiFi 信号过多，设备未搜索到指定 WiFi。换个信号干扰少的环境重试。
