# 中继程序接口定义

本文档定义了猪场控制器系统主动向中继程序发送请求时使用的接口规范。

## 1. 概述

中继程序作为猪场控制器系统与现场设备之间的桥梁，负责接收来自控制器系统的指令并转发给相应的设备，同时将设备的响应和状态信息回传给控制器系统。

通信方式采用WebSocket协议，确保双向实时通信。

## 2. WebSocket连接

### 2.1 连接建立

设备通过WebSocket连接到平台，连接地址格式：
```
ws://[server_address]:[port]/ws/device?device_id=[device_id]
```

参数说明：
- `device_id`: 中继设备唯一标识符

### 2.2 心跳机制

为保持连接活跃状态，中继设备需要定期发送心跳消息：

**心跳请求**
```json
{
  "type": "heartbeat",
  "device_id": "relay-001",
  "timestamp": "2023-01-01T12:00:00Z"
}
```

## 3. 指令接口

### 3.1 设备控制指令

平台向中继设备发送设备控制指令。

**请求格式**
```json
{
  "type": "command",
  "command": "control_device",
  "data": {
    "device_type": "fan",
    "device_id": "fan-001",
    "action": "on"
  },
  "timestamp": "2023-01-01T12:00:00Z"
}
```

**参数说明**
- `type`: 消息类型，固定为"command"
- `command`: 指令名称，固定为"control_device"
- `data`: 指令数据
  - `device_type`: 设备类型 (如: fan, water_curtain)
  - `device_id`: 设备唯一标识符
  - `action`: 执行动作 (如: on, off)
- `timestamp`: 指令发送时间

### 3.2 查询设备状态指令

平台向中继设备发送查询设备状态指令。

**请求格式**
```json
{
  "type": "command",
  "command": "query_device_status",
  "data": {
    "device_id": "fan-001"
  },
  "timestamp": "2023-01-01T12:00:00Z"
}
```

**参数说明**
- `type`: 消息类型，固定为"command"
- `command`: 指令名称，固定为"query_device_status"
- `data`: 指令数据
  - `device_id`: 设备唯一标识符
- `timestamp`: 指令发送时间

### 3.3 查询所有设备状态指令

平台向中继设备发送查询所有设备状态指令。

**请求格式**
```json
{
  "type": "command",
  "command": "query_all_device_status",
  "timestamp": "2023-01-01T12:00:00Z"
}
```

**参数说明**
- `type`: 消息类型，固定为"command"
- `command`: 指令名称，固定为"query_all_device_status"
- `timestamp`: 指令发送时间

### 3.4 心跳包指令

平台向中继设备发送心跳包指令，用于检测设备连接状态并获取下级设备状态信息。

**请求格式**
```json
{
  "type": "command",
  "command": "heartbeat",
  "data": {
    "timestamp": 1672545600
  },
  "timestamp": "2023-01-01T12:00:00Z"
}
```

**参数说明**
- `type`: 消息类型，固定为"command"
- `command`: 指令名称，固定为"heartbeat"
- `data`: 指令数据
  - `timestamp`: 时间戳（Unix时间戳格式）
- `timestamp`: 指令发送时间

## 4. 响应接口

### 4.1 设备控制响应

中继设备执行控制指令后，向平台发送响应。

**响应格式**
```json
{
  "type": "response",
  "command": "control_device",
  "data": {
    "device_id": "fan-001",
    "status": "success",
    "message": "设备控制成功"
  },
  "timestamp": "2023-01-01T12:00:05Z"
}
```

### 4.2 设备状态响应

中继设备响应设备状态查询指令。

**响应格式**
```json
{
  "type": "response",
  "command": "query_device_status",
  "data": {
    "device_id": "fan-001",
    "status": "running",
    "power": 220,
    "current": 5.2
  },
  "timestamp": "2023-01-01T12:00:05Z"
}
```

### 4.3 所有设备状态响应

中继设备响应所有设备状态查询指令。

**响应格式**
```json
{
  "type": "response",
  "command": "query_all_device_status",
  "data": [
    {
      "device_id": "fan-001",
      "device_type": "fan",
      "status": "running"
    },
    {
      "device_id": "curtain-001",
      "device_type": "water_curtain",
      "status": "stopped"
    }
  ],
  "timestamp": "2023-01-01T12:00:05Z"
}
```

### 4.4 心跳包响应

中继设备响应心跳包指令，返回自身及下级设备的状态信息。

**响应格式**
```json
{
  "type": "response",
  "command": "heartbeat",
  "data": {
    "devices": [
      {
        "device_id": "relay-001",
        "device_type": "relay",
        "status": "running"
      },
      {
        "device_id": "fan-001",
        "device_type": "fan",
        "status": "running"
      },
      {
        "device_id": "curtain-001",
        "device_type": "water_curtain",
        "status": "stopped"
      }
    ]
  },
  "timestamp": "2023-01-01T12:00:05Z"
}
```

**参数说明**
- `type`: 消息类型，固定为"response"
- `command`: 指令名称，固定为"heartbeat"
- `data`: 响应数据
  - `devices`: 设备列表
    - `device_id`: 设备唯一标识符
    - `device_type`: 设备类型
    - `status`: 设备状态（如: running, stopped, online, offline等）
- `timestamp`: 平台发送的时间戳, 需要原封不动的返回

## 5. 请求-响应机制

平台在发送指令后会等待中继设备的响应，超时时间由配置文件决定，默认为5秒。

### 5.1 同步等待响应

平台发送指令后会阻塞等待中继设备返回响应，直到：
1. 收到中继设备的响应消息
2. 超时（由配置文件决定，默认5秒）

### 5.2 响应处理

平台接收到响应后会：
1. 解析响应数据
2. 根据响应结果更新设备控制记录
3. 向前端返回操作结果

### 5.3 超时处理

如果在指定时间内未收到中继设备的响应，平台会：
1. 记录超时错误日志
2. 向前端返回超时错误信息
3. 设备控制记录中标记为失败状态

## 6. 配置说明

WebSocket请求超时时间可以通过配置文件进行设置：

```yaml
# WebSocket配置
websocket:
  # WebSocket请求超时时间(秒)
  timeout: 5
```

如果没有配置或配置值无效，系统将使用默认的5秒超时时间。

## 7. 响应结构定义

平台提供统一的响应结构定义，用于处理中继设备返回的响应：

### 7.1 CommandResponse 结构体

```go
type CommandResponse struct {
    // DeviceID 设备ID
    DeviceID string
    
    // Command 命令名称
    Command string
    
    // Data 响应数据
    Data interface{}
    
    // Status 响应状态
    Status string
    
    // Message 响应消息
    Message string
    
    // Timestamp 时间戳
    Timestamp time.Time
}
```

### 7.2 ParseData 方法

CommandResponse结构体提供了ParseData方法，用于将响应数据解析到指定的结构体中：

```go
func (cr *CommandResponse) ParseData(target interface{}) error
```

使用示例：
```go
// 定义目标结构体
type DeviceStatus struct {
    DeviceID string `json:"device_id"`
    Status   string `json:"status"`
    Message  string `json:"message"`
}

// 解析响应数据
var status DeviceStatus
if err := response.ParseData(&status); err != nil {
    // 处理错误
}
```

### 7.3 响应处理规则

1. `Status` 字段：表示操作的整体状态，如 "success"、"failed" 等
2. `Message` 字段：提供人类可读的操作结果描述
3. `Data` 字段：包含具体的操作结果数据
4. 如果响应中的 `Data` 是一个对象且包含 `status` 和 `message` 字段，系统会自动提取并填充到对应的结构体字段中

## 8. 消息类型说明

| 类型 | 说明 |
|------|------|
| command | 平台向中继设备发送的指令 |
| response | 中继设备向平台发送的响应 |
| heartbeat | 心跳消息 |

## 9. 设备类型说明

| 类型 | 说明 |
|------|------|
| fan | 风机设备 |
| water_curtain | 水帘设备 |
| relay | 中继设备 |

## 10. 动作说明

| 动作 | 说明 |
|------|------|
| on | 开启设备 |
| off | 关闭设备 |

## 11. 状态说明

| 状态 | 说明 |
|------|------|
| success | 操作成功 |
| failed | 操作失败 |
| running | 设备运行中 |
| stopped | 设备已停止 |
| online | 设备在线 |
| offline | 设备离线 |
| active | 设备激活 |