Skip to content

技术架构与 API 接口

本文档详细介绍系统的技术架构、数据模型和 API 接口定义。

一、整体架构

系统分层

┌─────────────────────────────────────────────────────┐
│           前端应用层(Vue 3 + Vite)               │
│  Dashboard | Monitor | Data | Control | Settings   │
└─────────────────────────────────────────────────────┘
                    │ HTTP/REST
                    │ WebSocket

┌─────────────────────────────────────────────────────┐
│        后端应用层(FastAPI + SQLAlchemy)          │
│  ├─ API 路由层                                      │
│  ├─ 业务逻辑层(Service)                          │
│  └─ 数据访问层(DAO)                              │
└─────────────────────────────────────────────────────┘
         │                          │
    ┌────▼────┐              ┌──────▼──────┐
    │  MQTT   │              │  Broker &   │
    │ Publisher│              │  Message    │
    └────┬────┘              │  Queue      │
         │                   └──────┬──────┘
         │                          │
    ┌────▼──────────────────────────▼────┐
    │   消息队列(MQTT Broker)          │
    │   订阅/发布核心数据主题            │
    └────┬───────────────────────────────┘

    ┌────▼──────────┬──────────────────┐
    │               │                  │
┌───▼──┐      ┌─────▼──┐      ┌──────▼──┐
│Influx│      │SQLite  │      │缓存层   │
│DB    │      │(配置)│      │(Redis)  │
└──────┘      └────────┘      └─────────┘

数据流向

  1. 传感器数据流

    物理传感器 → MQTT Topic: greenhouse/sensors/* 
    → 后端 MQTT 订阅器接收
    → 数据校验与处理
    → 写入 InfluxDB(时序数据)
    → 缓存最新值到 Redis
    → 前端通过 API 查询或 WebSocket 推送
  2. 设备控制流

    前端 POST /api/devices/{id}/control
    → 后端收到控制指令
    → 校验权限与参数
    → 发布 MQTT 消息: greenhouse/devices/*/command
    → 设备接收指令并执行
    → 设备反馈状态到 MQTT
    → 后端更新 SQLite 中的设备状态
    → 前端收到反馈显示结果

技术栈详解

层级技术版本用途
前端Vue3.5.24UI 框架
TypeScript5.0+类型检查
Vite5.0+构建工具
Naive UI2.34+组件库
Pinia2.1+状态管理
Axios1.6+HTTP 客户端
MQTT.js4.3+MQTT 客户端
后端FastAPI0.104+框架
Python3.8+语言
SQLAlchemy2.0+ORM
Pydantic2.0+数据验证
MQTT3.1.1消息协议
数据库SQLite3.0+配置存储
InfluxDB2.0+时序数据库
Redis6.0+缓存
部署Docker20.10+容器化
docker-compose2.0+编排

二、数据模型

1. 传感器数据模型

InfluxDB 时序数据:

measurement: sensor_data
tags:
  - greenhouse_id (温室ID)
  - sensor_type (温度/湿度/土壤/光照/CO2)
fields:
  - value (数值)
  - unit (单位)
  - status (正常/异常/失连)
timestamp: UTC 时间戳

示例数据点:

greenhouse,greenhouse_id=gh001,sensor_type=temperature value=25.3,unit="°C",status="normal" 1705315200000000000
greenhouse,greenhouse_id=gh001,sensor_type=humidity value=65.2,unit="%",status="normal" 1705315200000000000

2. 设备数据模型(SQLite)

表结构:

sql
-- 设备表
CREATE TABLE device (
    id INTEGER PRIMARY KEY,
    name VARCHAR(100) NOT NULL,          -- 设备名称
    device_type VARCHAR(50) NOT NULL,    -- 类型: fan/pump/light/heater
    mqtt_topic VARCHAR(200) NOT NULL,    -- MQTT 主题
    status BOOLEAN DEFAULT FALSE,         -- 当前状态
    auto_mode BOOLEAN DEFAULT FALSE,      -- 自动模式
    last_updated TIMESTAMP,               -- 最后更新时间
    created_at TIMESTAMP
);

-- 设备日志表
CREATE TABLE device_log (
    id INTEGER PRIMARY KEY,
    device_id INTEGER,
    action VARCHAR(50),                   -- open/close/toggle
    triggered_by VARCHAR(100),            -- manual/auto/system
    result VARCHAR(50),                   -- success/failed/timeout
    timestamp TIMESTAMP,
    FOREIGN KEY (device_id) REFERENCES device(id)
);

3. 配置和阈值模型

sql
-- 环境阈值表
CREATE TABLE environment_threshold (
    id INTEGER PRIMARY KEY,
    metric VARCHAR(50),                   -- temperature/humidity/soil/light/co2
    upper_limit FLOAT,                    -- 上限
    lower_limit FLOAT,                    -- 下限
    unit VARCHAR(20),                     -- 单位
    alert_enabled BOOLEAN DEFAULT TRUE,   -- 是否启用告警
    severity VARCHAR(20),                 -- critical/warning/info
    updated_at TIMESTAMP
);

-- 自动策略表
CREATE TABLE automation_strategy (
    id INTEGER PRIMARY KEY,
    name VARCHAR(100),                    -- 策略名称
    trigger_condition VARCHAR(500),       -- 触发条件(JSON)
    action_command VARCHAR(500),          -- 执行动作(JSON)
    enabled BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

4. API 数据模型(Pydantic)

python
# 传感器数据模型
class SensorData(BaseModel):
    timestamp: datetime
    temperature: float      # °C
    humidity: float         # %
    soil_moisture: float    # %
    light_level: float      # Lux
    co2: Optional[float]    # ppm

class HistoryDataPoint(BaseModel):
    timestamp: datetime
    value: float
    unit: str
    status: str  # normal/abnormal

class DataQueryParams(BaseModel):
    start_time: datetime
    end_time: datetime
    metrics: List[str]      # 要查询的指标列表
    interval: str           # 聚合间隔: 1m/5m/15m/1h/1d

# 设备模型
class Device(BaseModel):
    id: int
    name: str
    device_type: str        # fan/pump/light/heater
    status: bool            # 开/关
    auto_mode: bool         # 自动模式
    online: bool            # 在线状态
    last_updated: datetime

class DeviceControlRequest(BaseModel):
    status: bool            # true=打开, false=关闭

class DeviceAutoModeRequest(BaseModel):
    auto_mode: bool

# 配置模型
class EnvironmentThreshold(BaseModel):
    temperature_high: float
    temperature_low: float
    humidity_high: float
    humidity_low: float
    soil_moisture_high: float
    soil_moisture_low: float
    light_high: float
    light_low: float
    co2_high: Optional[float]
    co2_low: Optional[float]

# 系统状态模型
class SystemHealth(BaseModel):
    mqtt_connected: bool
    mqtt_status: str        # connected/disconnected/error
    api_status: str         # healthy/degraded/error
    database_status: str    # connected/error
    devices_online: int
    devices_total: int
    last_check: datetime

三、REST API 接口

基础信息

  • 基础 URLhttp://localhost:8000/api
  • 响应格式:JSON
  • 认证:JWT(可选,后续版本添加)
  • 超时:10 秒

API 端点列表

传感器数据接口

1. 获取实时传感器数据

GET /sensors/current

请求参数:无

响应示例

json
{
  "timestamp": "2024-01-15T10:30:00Z",
  "temperature": 25.3,
  "humidity": 65.2,
  "soil_moisture": 45.8,
  "light_level": 550,
  "co2": 420,
  "status": "normal"
}

状态码

  • 200:成功
  • 503:MQTT 不可用

2. 查询历史数据

POST /sensors/history

请求体

json
{
  "start_time": "2024-01-15T00:00:00Z",
  "end_time": "2024-01-15T23:59:59Z",
  "metrics": ["temperature", "humidity", "soil_moisture"],
  "interval": "1h"
}

响应示例

json
{
  "data": [
    {
      "timestamp": "2024-01-15T00:00:00Z",
      "temperature": 22.1,
      "humidity": 58.5,
      "soil_moisture": 42.3
    },
    {
      "timestamp": "2024-01-15T01:00:00Z",
      "temperature": 21.8,
      "humidity": 59.2,
      "soil_moisture": 41.9
    }
  ],
  "total_points": 24,
  "query_time_ms": 145
}

聚合间隔说明

  • 1m:1分钟聚合(最多查询 7 天)
  • 5m:5分钟聚合(最多查询 30 天)
  • 1h:小时聚合(最多查询 90 天)
  • 1d:天聚合(最多查询 1 年)

设备管理接口

1. 获取设备列表

GET /devices

请求参数

  • type(可选):筛选设备类型 (fan/pump/light/heater)
  • online_only(可选):true = 仅显示在线设备

响应示例

json
{
  "devices": [
    {
      "id": 1,
      "name": "风机 A",
      "device_type": "fan",
      "status": true,
      "auto_mode": true,
      "online": true,
      "last_updated": "2024-01-15T10:30:00Z"
    },
    {
      "id": 2,
      "name": "灌溉泵",
      "device_type": "pump",
      "status": false,
      "auto_mode": false,
      "online": true,
      "last_updated": "2024-01-15T10:29:50Z"
    }
  ],
  "total": 2,
  "online_count": 2
}

2. 控制单个设备

POST /devices/{device_id}/control

请求参数

  • device_id(路径参数):设备 ID

请求体

json
{
  "status": true
}

响应示例

json
{
  "success": true,
  "message": "风机 A 已打开",
  "device_id": 1,
  "new_status": true,
  "executed_at": "2024-01-15T10:31:00Z"
}

错误响应

json
{
  "success": false,
  "error": "设备离线",
  "error_code": "DEVICE_OFFLINE",
  "device_id": 1
}

3. 切换设备自动模式

POST /devices/{device_id}/auto

请求体

json
{
  "auto_mode": true
}

响应示例

json
{
  "success": true,
  "device_id": 1,
  "auto_mode": true,
  "message": "已切换为自动模式"
}

4. 批量控制设备

POST /devices/batch/control

请求体

json
{
  "device_ids": [1, 2, 3],
  "action": "open"  // open/close/toggle
}

响应示例

json
{
  "success": true,
  "results": [
    {
      "device_id": 1,
      "status": "success",
      "new_state": true
    },
    {
      "device_id": 2,
      "status": "success",
      "new_state": true
    },
    {
      "device_id": 3,
      "status": "failed",
      "error": "设备离线"
    }
  ]
}

配置接口

1. 获取环境阈值

GET /config/thresholds

响应示例

json
{
  "temperature": {
    "high": 28.0,
    "low": 20.0,
    "unit": "°C"
  },
  "humidity": {
    "high": 75.0,
    "low": 45.0,
    "unit": "%"
  },
  "soil_moisture": {
    "high": 70.0,
    "low": 35.0,
    "unit": "%"
  },
  "light": {
    "high": 8000.0,
    "low": 200.0,
    "unit": "Lux"
  },
  "co2": {
    "high": 1000.0,
    "low": 350.0,
    "unit": "ppm"
  }
}

2. 更新环境阈值

POST /config/thresholds

请求体

json
{
  "temperature": {"high": 30.0, "low": 18.0},
  "humidity": {"high": 80.0, "low": 40.0},
  "soil_moisture": {"high": 75.0, "low": 30.0},
  "light": {"high": 9000.0, "low": 100.0},
  "co2": {"high": 1200.0, "low": 300.0}
}

响应示例

json
{
  "success": true,
  "message": "阈值已更新",
  "updated_at": "2024-01-15T10:32:00Z"
}

系统接口

1. 获取详细系统状态

GET /health/detailed

响应示例

json
{
  "status": "healthy",
  "timestamp": "2024-01-15T10:30:00Z",
  "components": {
    "mqtt": {
      "status": "connected",
      "message": "MQTT Broker 连接正常",
      "response_time_ms": 5
    },
    "api": {
      "status": "healthy",
      "message": "API 服务正常",
      "response_time_ms": 10
    },
    "database": {
      "status": "connected",
      "message": "SQLite 连接正常",
      "size_mb": 245.3
    },
    "influxdb": {
      "status": "connected",
      "message": "InfluxDB 连接正常",
      "latest_data_age_seconds": 15
    }
  },
  "devices": {
    "online": 8,
    "total": 10,
    "offline": ["device_05", "device_10"]
  }
}

四、WebSocket 接口(可选)

实时数据推送

连接ws://localhost:8000/ws/live

消息格式

json
{
  "type": "sensor_update",
  "data": {
    "timestamp": "2024-01-15T10:30:00Z",
    "temperature": 25.3,
    "humidity": 65.2
  }
}

事件类型

  • sensor_update:传感器数据更新
  • device_status_change:设备状态变化
  • alert_triggered:告警触发
  • system_status_change:系统状态变化

五、错误处理

标准错误响应

json
{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "请求参数错误",
    "details": {
      "field": "start_time",
      "reason": "时间格式不合法"
    }
  }
}

常见错误码

错误码HTTP 状态码描述
INVALID_REQUEST400请求参数错误
UNAUTHORIZED401未授权
FORBIDDEN403无权限
NOT_FOUND404资源不存在
CONFLICT409资源冲突
DEVICE_OFFLINE503设备离线
MQTT_UNAVAILABLE503MQTT 不可用
DATABASE_ERROR500数据库错误
INTERNAL_ERROR500服务器内部错误

六、认证与授权(后续版本)

计划在 M5 阶段添加

  • JWT Token 认证
  • 基于角色的访问控制(RBAC)
  • API Key 机制
  • 请求签名验证

七、性能优化建议

查询优化

  • 使用 InfluxDB 的聚合查询而非全量查询
  • 前端分页加载大数据集
  • 实时数据使用 WebSocket 推送替代轮询

缓存策略

  • 最新传感器数据缓存 Redis(TTL 1 分钟)
  • 设备状态缓存(TTL 5 分钟)
  • 配置缓存(TTL 10 分钟)

限流与熔断

  • API 限流:100 req/min per client
  • 超时时间:10 秒
  • 重试策略:指数退避

最后更新:2025年11月18日

温室智能管理系统