# 克隆设备 device_id 冲突问题及解决方案

## 问题描述

部署多台 RK3588 设备时，如果它们是使用同一个镜像克隆的，可能会出现以下问题：

- UDP 发现只能找到部分设备（如 7 台中只能发现 2 台）
- 设备列表中某些设备时隐时现
- 下发配置时提示设备离线，但实际服务运行正常

## 原因分析

管理端通过 UDP 广播发现设备时，使用 `device_id` 作为唯一标识存储设备信息。

```go
// 发现服务使用 device_id 作为 map 的 key
found := make(map[string]*models.Device)
...
found[dev.DeviceID] = dev  // 相同的 device_id 会覆盖之前的设备
```

RK3588 Agent 的 `device_id` 生成优先级：
1. `/etc/machine-id` 文件内容
2. MAC 地址或序列号
3. 自动生成并落盘

**克隆设备的 `/etc/machine-id` 完全相同**，导致所有克隆设备返回相同的 `device_id`，在发现过程中互相覆盖，最终只能看到一台。

## 解决方案

### 方案一：修复克隆设备（推荐，根治方案）

**⚠️ 注意：必须同时删除 dbus 的 machine-id，否则可能生成相同的 ID**

`systemd-machine-id-setup` 会优先复制 `/var/lib/dbus/machine-id`，克隆镜像中这个文件也是相同的，导致生成的 ID 仍然冲突。

**正确的修复步骤：**

```bash
# 1. 同时删除两个 machine-id 文件
sudo rm -f /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id

# 2. 重启（系统会自动生成新的随机 ID）
sudo reboot

# 3. 验证新生成的 ID
# 在每台设备上执行，确认输出不同
cat /etc/machine-id
```

**错误的做法（可能生成相同 ID）：**

```bash
# ❌ 不要只删除 /etc/machine-id
sudo rm -f /etc/machine-id
sudo systemd-machine-id-setup  # 会复制 dbus 的相同 ID！
```

**替代方案：手动生成随机 ID**

```bash
# 删除旧的
sudo rm -f /etc/machine-id /var/lib/dbus/machine-id

# 手动生成新的随机 ID（每台设备分别执行）
uuidgen | tr -d '-' | sudo tee /etc/machine-id

# 重启
sudo reboot
```

重启后，执行以下命令验证新的 device_id：

```bash
cat /etc/machine-id
```

然后重新在管理端点击"UDP 搜索"，所有设备应该都能被发现。

### 方案二：手动添加设备（临时方案）

如果暂时无法登录设备修改 machine-id，可以通过管理端的"手动添加设备"功能：

1. 打开管理端 Web 界面
2. 进入设备页面
3. 点击"手动添加设备"按钮
4. 填写以下信息：

| 字段 | 必填 | 说明 |
|------|------|------|
| 设备 ID | 是 | 必须唯一，建议从设备执行 `cat /etc/machine-id` 获取，或使用 `uuidgen` 生成 |
| 设备名称 | 否 | 便于识别的名称，如 cam-02 |
| IP 地址 | 是 | 设备的实际 IP 地址 |
| Agent 端口 | 否 | 默认 9100 |
| Media 端口 | 否 | 默认 9000 |

**注意**：手动添加的设备，如果 device_id 与设备实际报告的 device_id 不一致，UDP 发现时可能会产生重复条目。

## 获取 device_id 的方法

在 RK3588 设备上执行：

```bash
# 方法1：查看 machine-id（device_id 的来源）
cat /etc/machine-id

# 方法2：查看 agent 信息（包含 device_id）
curl http://127.0.0.1:9100/v1/info

# 方法3：生成新的唯一 ID
uuidgen | tr -d '-'
```

## 预防措施

制作克隆镜像前，建议清空 machine-id：

```bash
# 在制作镜像前执行
sudo rm -f /etc/machine-id
sudo touch /etc/machine-id  # 确保文件存在但为空
```

这样设备首次启动时会自动生成新的 machine-id。

## 相关接口

管理端提供以下相关接口：

### 手动添加设备（API）

```bash
POST /api/devices
Content-Type: application/json

{
  "device_id": "rk3588-xxx",
  "device_name": "cam-01",
  "ip": "10.0.0.10",
  "agent_port": 9100,
  "media_port": 9000
}
```

### UDP 发现

```bash
POST /api/discovery/search
Content-Type: application/json

{
  "timeout_ms": 1200
}
```

## 参考

- [PRD_04_Manager_ConfigGUI_AgentAPI.md](../PRD_04_Manager_ConfigGUI_AgentAPI.md) - Agent API 文档
- [API_Device_RemoteMgmt_InterfaceTable.md](../API_Device_RemoteMgmt_InterfaceTable.md) - 设备远程管理接口
