# 🧩 IoT 容器管理接口文档

**模块**：`container_handler`  
**作者**：licheng5  
**创建时间**：2020-04-26  
**说明**：提供容器的部署、配置、启动、停止、查询等管理 API 接口。

## 服务器地址
    http://127.0.0.1:18090

---
## 📦 模块结构

| 模块 | 说明 |
|------|------|
| `container_handler` | 提供容器管理的 HTTP 接口处理 |
| `iot_util` | 工具模块，用于生成标准化 JSON 响应 |

---

## ⚙️ `iot_util` 模块函数声明

```erlang
%%--------------------------------------------------------------------
%% @doc
%% 将数据封装为标准 JSON 响应：
%% {"result": Data}
%%--------------------------------------------------------------------
json_data(Data) ->
    iolist_to_binary(json:encode(#{
        <<"result">> => Data
    })).

%%--------------------------------------------------------------------
%% @doc
%% 生成错误响应 JSON：
%% {
%%   "error": {
%%     "code": ErrCode,
%%     "message": ErrMessage
%%   }
%% }
%%--------------------------------------------------------------------
json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) ->
    iolist_to_binary(json:encode(#{
        <<"error">> => #{
            <<"code">> => ErrCode,
            <<"message">> => ErrMessage
        }
    })).
```

### 📘 返回格式说明

| 字段 | 说明 |
|------|------|
| `result` | 正常返回数据 |
| `error.code` | 错误代码 |
| `error.message` | 错误信息 |

---

## 🌐 HTTP API 接口列表

以下为 `container_handler` 模块导出的全部 HTTP 接口。

---

### 1️⃣ 获取容器列表

**URL**：`/container/get_all`  
**Method**：`GET`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | list | 容器信息列表 |

#### 示例响应
```json
{
  "result": [
    {"name": "container_1", "status": "running"},
    {"name": "container_2", "status": "stopped"}
  ]
}
```

#### 错误响应
```json
{
  "error": {
    "code": -1,
    "message": "host not found"
  }
}
```

---

### 2️⃣ 下发配置文件

**URL**：`/container/push_config`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |
| container_name | binary (string) | ✅ | 容器名称 |
| config | binary (string, JSON) | ✅ | 容器配置内容（JSON 字符串） |
| timeout | integer | ✅ | 超时时间（秒） |

### 请求示例
```json
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new", "config": "{\"application\":{\"namexyz\":\"RandomConfigApp\",\"version\":\"1.2.7\",\"environment\":{\"debug_mode\":true,\"log_level\":\"info\",\"max_log_files\":10}},\"server\":{\"host\":\"127.0.0.1\",\"port\":8080,\"ssl_enabled\":false,\"allowed_origins\":[\"https:\\/\\/example.com\",\"http:\\/\\/localhost:3000\"]},\"database\":{\"type\":\"postgresql\",\"host\":\"db.example.com\",\"port\":5432,\"username\":\"admin_7xq9f\",\"password\":\"p@ssw0rd!r4nd\",\"connection_pool\":15,\"timeout_seconds\":30},\"features\":{\"enable_analytics\":true,\"enable_cache\":false,\"experimental_features\":[\"ai_enhancement\",\"realtime_sync\"]},\"third_party\":{\"api_key\":\"a3b8c2d4e5f6g7h8i9j0k1l2m3n4o5p\",\"weather_service_url\":\"https:\\/\\/api.weather.example\\/v3\",\"payment_gateway\":{\"endpoint\":\"https:\\/\\/pay.example.com\",\"merchant_id\":\"M123456789\"}},\"scheduled_tasks\":[{\"name\":\"nightly_backup\",\"cron\":\"0 3 * * *\",\"enabled\":true},{\"name\":\"log_cleanup\",\"interval_minutes\":1440,\"retention_days\":7}],\"admins\":[{\"username\":\"alice_dev\",\"email\":\"alice@example.com\",\"permissions\":[\"read\",\"write\",\"admin\"]},{\"username\":\"bob_ops\",\"email\":\"bob@example.org\",\"permissions\":[\"read\",\"audit\"]}]}", "timeout": 10}
```

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | map | 配置结果 |

#### 示例响应
```json
{
  "result": {
    "container_name": "sensor_service",
    "status": "config pushed"
  }
}
```

#### 错误响应
```json
{
  "error": {
    "code": -1,
    "message": "host not found"
  }
}
```

---

### 3️⃣ 部署容器服务

**URL**：`/container/deploy`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |
| task_id | integer | ✅ | 任务 ID，和 uuid 一起作为部署任务唯一标识 |
| config | map | ✅ | 部署配置内容 |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | map | 部署结果 |

### 请求示例
```json
{
  "uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm",
  "task_id": 1,
  "timeout": 10,
  "config": {
    "image": "docker.1ms.run/library/nginx:latest",
    "container_name": "my_nginx_new",
    "command": [
      "nginx",
      "-g",
      "daemon off;"
    ],
    "entrypoint": [
      "/docker-entrypoint.sh"
    ],
    "envs": [
      "ENV1=val1",
      "ENV2=val2"
    ],
    "env_file": [
      "./env.list"
    ],
    "ports": [
      "8080:80",
      "443:443"
    ],
    "expose": [
      "80",
      "443"
    ],
    "volumes": [
      "/host/data:/data",
      "/host/log:/var/log"
    ],
    "networks": [
      "mynet"
    ],
    "labels": {
      "role": "web",
      "env": "prod"
    },
    "restart": "always",
    "user": "www-data",
    "working_dir": "/app",
    "hostname": "myhost",
    "privileged": true,
    "cap_add": [
      "NET_ADMIN"
    ],
    "cap_drop": [
      "MKNOD"
    ],
    "devices": [
      "/dev/snd:/dev/snd"
    ],
    "mem_limit": "512m",
    "mem_reservation": "256m",
    "cpu_shares": 512,
    "cpus": 1.5,
    "ulimits": {
      "nofile": "1024:2048"
    },
    "sysctls": {
      "net.ipv4.ip_forward": "1"
    },
    "tmpfs": [
      "/tmp"
    ],
    "extra_hosts": [
      "host1:192.168.0.1"
    ],
    "healthcheck": {
      "test": [
        "CMD-SHELL",
        "curl -f http://localhost || exit 1"
      ],
      "interval": "30s",
      "timeout": "10s",
      "retries": 3
    }
  }
}

```

#### 示例响应
```json
{
  "data": "ok"
}
```

部署过程实时日志通过 SSE 获取：

```http
GET /event_stream?uuid=qbxmjyzrkpntfgswaevodhluicqzxplkm&task_id=1
```

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "host not found"
  }
}
```

---

### 4️⃣ 启动容器服务

**URL**：`/container/start`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |
| container_name | binary (string) | ✅ | 容器名称 |

### 请求示例
```json
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new"}
```

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | map | 启动结果 |

#### 示例响应
```json
{
  "result": {
    "container_name": "sensor_service",
    "status": "started"
  }
}
```

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "host not found"
  }
}
```

---

### 5️⃣ 停止容器服务

**URL**：`/container/stop`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |
| container_name | binary (string) | ✅ | 容器名称 |

### 请求示例
```json
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new"}
```

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | map | 停止结果 |

#### 示例响应
```json
{
  "result": {
    "container_name": "sensor_service",
    "status": "stopped"
  }
}
```

### 6 强制停止容器服务

**URL**：`/container/kill`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |
| container_name | binary (string) | ✅ | 容器名称 |

### 请求示例
```json
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new"}
```

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | map | 停止结果 |

#### 示例响应
```json
{
  "result": {
    "container_name": "sensor_service",
    "status": "stopped"
  }
}
```

### 7 删除容器

**URL**：`/container/remove`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |
| container_name | binary (string) | ✅ | 容器名称 |

### 请求示例
```json
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new"}
```

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | map | 停止结果 |

#### 示例响应
```json
{
  "result": {
    "container_name": "sensor_service",
    "status": "stopped"
  }
}
```


#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "host not found"
  }
}
```

---

### 6️⃣ 未知路径处理

**说明**：如果请求路径未匹配任何定义接口，将返回错误信息。

#### 示例响应
```json
{
  "error": {
    "code": -1,
    "message": "url: /unknown/path not found"
  }
}
```

---

## 🧾 返回约定总结

| 类型 | 说明 |
|------|------|
| `{"result": Data}` | 表示请求成功 |
| `{"error": {"code": N, "message": Text}}` | 表示请求失败 |



# 🧩 IoT Endpoint 管理接口文档

**模块**：`endpoint_handler`  
**作者**：licheng5  
**创建时间**：2020-04-26  
**说明**：用于管理 IoT Endpoint 的运行状态，包括启动、停止、重启、状态查询等。

---

## 📦 模块结构

| 模块 | 说明 |
|------|------|
| `endpoint_handler` | 提供 Endpoint 管理的 HTTP 接口处理 |
| `iot_util` | 工具模块，用于生成标准化 JSON 响应 |

---

## ⚙️ `iot_util` 模块函数声明

```erlang
%%--------------------------------------------------------------------
%% @doc
%% 将数据封装为标准 JSON 响应：
%% {"result": Data}
%%--------------------------------------------------------------------
json_data(Data) ->
    iolist_to_binary(json:encode(#{
        <<"result">> => Data
    })).

%%--------------------------------------------------------------------
%% @doc
%% 生成错误响应 JSON：
%% {
%%   "error": {
%%     "code": ErrCode,
%%     "message": ErrMessage
%%   }
%% }
%%--------------------------------------------------------------------
json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) ->
    iolist_to_binary(json:encode(#{
        <<"error">> => #{
            <<"code">> => ErrCode,
            <<"message">> => ErrMessage
        }
    })).
```

### 📘 返回格式说明

| 字段 | 说明 |
|------|------|
| `result` | 正常返回数据 |
| `error.code` | 错误代码 |
| `error.message` | 错误信息 |

---

## 🌐 HTTP API 接口列表

以下为 `endpoint_handler` 模块导出的全部 HTTP 接口。

---

### 1️⃣ 获取 Endpoint 运行状态

**URL**：`/endpoint/run_statuses`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| Ids | list | ✅ | Endpoint ID 列表 |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | list | 每个 ID 对应状态：`0` 未运行，`1` 运行中 |

#### 示例请求
```json
[1, 2, 3]
```

#### 示例响应
```json
{
  "result": [1, 0, 1]
}
```

---

### 2️⃣ 启动 Endpoint

**URL**：`/endpoint/start`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | integer | ✅ | Endpoint 唯一 ID |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | string | 启动结果，如 `"success"` |

#### 示例响应
```json
{
  "result": "success"
}
```

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "endpoint not found"
  }
}
```

---

### 3️⃣ 停止 Endpoint

**URL**：`/endpoint/stop`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | integer | ✅ | Endpoint 唯一 ID |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | string | 停止结果，如 `"success"` |

#### 示例响应
```json
{
  "result": "success"
}
```

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "stop endpoint error"
  }
}
```

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "stop endpoint error"
  }
}
```


---

### 4️⃣ 重启 Endpoint

**URL**：`/endpoint/restart`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | integer | ✅ | Endpoint 唯一 ID |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | string | 重启结果，如 `"success"` |

#### 示例响应
```json
{
  "result": "success"
}
```

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "restart endpoint error"
  }
}
```

### 5. 向endpoint发送消息

**URL**：`/endpoint/publish_metric`  
**Method**：`POST`

###### **示例请求**
    metric字段支持字符串，map或者数组，其他为非法数据; 如何要发送数字，可以采用数字的字符串格式, 比如: "5"

```json
{
  "route_key": "/dhlr/warning",
  "metric": {
    "xyz": "test"
  }
}
```

#### 示例响应
```json
{
  "result": "ok"
}
```

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "restart endpoint error"
  }
}
```

### **POST /endpoint/test
    用于测试指定协议（HTTP / MQTT / Kafka）配置是否可用**

#### **请求方式**

```
POST /endpoint/test
Content-Type: application/json
```

---

#### **通用参数**

| 字段       | 类型     | 必填 | 说明                              |
| -------- | ------ | -- | ------------------------------- |
| protocol | string | 是  | 选择测试类型，可为：`http`、`mqtt`、`kafka` |
| config   | object | 是  | 各协议对应的配置对象                      |

---

#### **一、测试 HTTP Endpoint**

###### **请求参数**

| 字段        | 类型      | 必填 | 说明            |
| --------- | ------- | -- | ------------- |
| url       | string  | 是  | 要请求的 HTTP 地址  |
| pool_size | integer | 是  | 连接池大小（必须 > 0） |

###### **示例请求**

```json
{
  "protocol": "http",
  "config": {
    "url": "http://example.com/ping",
    "pool_size": 5
  }
}
```

###### **返回结果**

| 状态      | 内容                                   |
| ------- |--------------------------------------|
| success | `{"data":"ok"}`                      |
| failed  | `{"error": -1, "msg": "url failed"}` |

---

##### **二、测试 MQTT Endpoint**

###### **请求参数**

| 字段        | 类型     | 必填 | 说明              |
| --------- | ------ | -- | --------------- |
| host      | string | 是  | MQTT 服务器地址      |
| port      | int    | 是  | MQTT 端口（>0）     |
| client_id | string | 是  | 客户端 ID（仅用于配置校验） |
| username  | string | 是  | 用户名             |
| password  | string | 是  | 密码              |
| topic     | string | 是  | topic 名称        |
| qos       | int    | 是  | 0/1/2           |

###### **参数限制**

* host ≠ 空
* username/password/topic ≠ 空
* qos ∈ {0,1,2}

###### **示例请求**

```json
{
  "protocol": "mqtt",
  "config": {
    "host": "test.mqttserver.com",
    "port": 1883,
    "client_id": "test-client-01",
    "username": "user1",
    "password": "pass123",
    "topic": "device/event",
    "qos": 1
  }
}
```

###### **返回结果**

| 状态      | 内容                                                   |
| ------- |------------------------------------------------------|
| success | `{"data": "ok"}`                                     |
| failed  | `{"error": -1, "msg": "connect mqtt server failed"}` |

---

##### **三、测试 Kafka Endpoint**

###### **请求参数（无认证）**

| 字段                | 类型           | 必填 | 说明                     |
| ----------------- | ------------ | -- | ---------------------- |
| bootstrap_servers | list(string) | 是  | 服务器列表，格式 `"host:port"` |
| topic             | string       | 是  | Topic 名称               |

###### **请求参数（SASL 认证）**

当需要 SASL 认证时，增加：

| 字段                    | 类型     | 必填 | 说明                                |
| --------------------- | ------ | -- | --------------------------------- |
| sasl_config.username  | string | 是  | 用户名                               |
| sasl_config.password  | string | 是  | 密码                                |
| sasl_config.mechanism | string | 是  | `"plain"` `"sha_256"` `"sha_512"` |

###### **合法 mechanism 值**

* `plain` → SASL/PLAIN
* `sha_256` → SCRAM-SHA-256
* `sha_512` → SCRAM-SHA-512

###### **bootstrap_servers 校验规则**

* 必须是 list(binary())
* 每项格式必须为 `"host:port"`
* port 必须为整数并 > 0

---

###### **示例 1：无认证 Kafka**

```json
{
  "protocol": "kafka",
  "config": {
    "bootstrap_servers": ["broker1:9092", "broker2:9092"],
    "topic": "device-log"
  }
}
```

###### **示例 2：带 SASL 认证 Kafka**

```json
{
  "protocol": "kafka",
  "config": {
    "sasl_config": {
      "username": "kafka_user",
      "password": "kafka_pass",
      "mechanism": "sha_256"
    },
    "bootstrap_servers": ["kafka.example.com:9094"],
    "topic": "iot-event"
  }
}
```

---

## **返回结果**

| 状态      | 内容                                                   |
| ------- | ---------------------------------------------------- |
| success | `{"data": "ok"}`                                     |
| failed  | `{"error": -1, "msg": "config kafka server failed"}` |

---

### 5️⃣ 未知路径处理

**说明**：如果请求路径未匹配任何定义接口，将返回错误信息。

#### 示例响应
```json
{
  "error": {
    "code": -1,
    "message": "url: /unknown/path not found"
  }
}
```

---

## 🧾 返回约定总结

| 类型 | 说明 |
|------|------|
| `{"result": Data}` | 表示请求成功 |
| `{"error": {"code": N, "message": Text}}` | 表示请求失败 |


# 🧩 IoT Host 管理接口文档

**模块**：`host_handler`  
**作者**：licheng5  
**创建时间**：2020-04-26  
**说明**：用于管理 IoT 主机，包括主机指标、状态查询、激活、删除、发布事件等接口。

---

## 📦 模块结构

| 模块 | 说明 |
|------|------|
| `host_handler` | 提供 Host 管理的 HTTP 接口处理 |
| `iot_util` | 工具模块，用于生成标准化 JSON 响应 |

---

## ⚙️ `iot_util` 模块函数声明

```erlang
%%--------------------------------------------------------------------
%% @doc
%% 将数据封装为标准 JSON 响应：
%% {"result": Data}
%%--------------------------------------------------------------------
json_data(Data) ->
    iolist_to_binary(json:encode(#{
        <<"result">> => Data
    })).

%%--------------------------------------------------------------------
%% @doc
%% 生成错误响应 JSON：
%% {
%%   "error": {
%%     "code": ErrCode,
%%     "message": ErrMessage
%%   }
%% }
%%--------------------------------------------------------------------
json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) ->
    iolist_to_binary(json:encode(#{
        <<"error">> => #{
            <<"code">> => ErrCode,
            <<"message">> => ErrMessage
        }
    })).
```

### 📘 返回格式说明

| 字段 | 说明 |
|------|------|
| `result` | 正常返回数据 |
| `error.code` | 错误代码 |
| `error.message` | 错误信息 |

---

## 🌐 HTTP API 接口列表

以下为 `host_handler` 模块导出的全部 HTTP 接口。

---

### 1️⃣ 获取主机指标

**URL**：`/host/metric`  
**Method**：`GET`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | map | 主机指标信息 |

#### 示例响应
```json
{
  "result": {"cpu": 20, "memory": 1024, "disk": 51200}
}
```

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "host not found"
  }
}
```

#### 无指标信息响应
```json
{
  "error": {
    "code": 404,
    "message": "no metric info"
  }
}
```

---

### 2️⃣ 查询主机状态

**URL**：`/host/status`  
**Method**：`GET`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | map | 主机状态信息 |

#### 示例响应
```json
{
  "result": {"authorize_status": 1, "active": true}
}
```

---

### 3️⃣ 重新加载主机信息

**URL**：`/host/reload`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | string | 重新加载结果，如 `"success"` |

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "reload error"
  }
}
```

---

### 4️⃣ 删除主机

**URL**：`/host/delete`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | string | 删除结果，如 `"success"` |

#### 错误响应
```json
{
  "error": {
    "code": 404,
    "message": "error"
  }
}
```

---

### 5️⃣ 激活主机

**URL**：`/host/activate`  
**Method**：`POST`

#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| uuid | binary (string) | ✅ | 主机唯一标识符 |
| auth | boolean | ✅ | `true` 激活, `false` 取消激活。该操作只修改 iot 本地和持久化授权状态，不通知 efka；efka 连接可继续保持在线，数据是否处理由 iot_host 状态决定。 |

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | string | 激活结果，如 `"success"` |

#### 错误响应
```json
{
  "error": {
    "code": 400,
    "message": "host not found"
  }
}
```

---

### 6️⃣ 发布主机事件

**URL**：`/host/pub`  
**Method**：`POST`

#### 请求参数
| 参数名     | 类型              | 必填 | 说明               |
|---------|-----------------|------|------------------|
| uuid    | binary (string) | ✅ | 主机唯一标识符          |
| topic   | binary (string) | ✅ | 事件主题             |
| qos     | integer | ✅ | 消息的qos，qos = 0,1 |
| content | binary (string) | ✅ | 发布内容             |

### 请求示例

```json
{
  "uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm",
  "topic": "/device/1234/all",
  "qos": 1,
  "content": "this is a topic payload",
  "timeout": 10
}
```

#### 响应参数
| 字段 | 类型 | 说明 |
|------|------|------|
| result | string | 发布结果，如 `"success"` |

#### 错误响应
```json
{
  "error": {
    "code": 400,
    "message": "host not found"
  }
}
```

---

### 7️⃣ 未知路径处理

**说明**：如果请求路径未匹配任何定义接口，将返回错误信息。

#### 示例响应
```json
{
  "error": {
    "code": -1,
    "message": "url: /unknown/path not found"
  }
}
```

---

## 🧾 返回约定总结

| 类型 | 说明 |
|------|------|
| `{"result": Data}` | 表示请求成功 |
| `{"error": {"code": N, "message": Text}}` | 表示请求失败 |
