plc_control/docs/api-feeder.md

11 KiB
Raw Permalink Blame History

PLC Control API

本文档基于当前后端代码整理,覆盖 HTTP API、SSE 日志流和 WebSocket 实时消息。

基本信息

  • UI: /ui
  • HTTP API 前缀: /api
  • 公共 WebSocket: /ws/public
  • 客户端专属 WebSocket: /ws/client/{client_id}
  • 日志 SSE: /api/logs/stream

通用错误响应

失败时通常返回:

{
  "err_code": 400,
  "err_msg": "Invalid JSON format",
  "err_detail": null
}

常见状态码:

  • 400 Bad Request: 参数非法或业务前置条件不满足
  • 403 Forbidden: 控制条件不满足或无写入权限
  • 404 Not Found: 资源不存在
  • 500 Internal Server Error: 服务端内部错误

Source

GET /api/source

获取数据源列表及连接状态。

POST /api/source

创建数据源。

请求示例:

{
  "name": "PLC-1",
  "protocol": "opcua",
  "endpoint": "opc.tcp://127.0.0.1:4840",
  "enabled": true
}

PUT /api/source/{source_id}

更新数据源,字段均可选。

DELETE /api/source/{source_id}

删除数据源。成功返回 204 No Content

POST /api/source/{source_id}/reconnect

手动重连数据源。

POST /api/source/{source_id}/browse

从 OPC UA 数据源浏览节点并写入本地 node 表。

GET /api/source/{source_id}/node-tree

获取数据源节点树。

Point

GET /api/point

分页获取点位列表,同时返回实时监测值。

查询参数:

  • source_id
  • equipment_id
  • page
  • page_size

GET /api/point/{point_id}

获取单个点位。

GET /api/point/{point_id}/history

获取最近历史样本。历史数据保存在进程内环形缓冲区,服务重启后清空。

查询参数:

  • limit: 默认 120,最大 1000

PUT /api/point/{point_id}

更新点位元数据。

可更新字段:

{
  "name": "Temperature",
  "description": "Room temperature",
  "unit": "C",
  "tag_id": "uuid",
  "equipment_id": "uuid",
  "signal_role": "run"
}

说明:

  • 点位变更设备绑定或信号角色后,会唤醒相关控制单元任务,使控制引擎尽快使用最新映射。

DELETE /api/point/{point_id}

删除单个点位。

说明:

  • 删除后会同步通知相关控制单元刷新配置。

POST /api/point/batch

根据节点批量创建点位。

DELETE /api/point/batch

批量删除点位。

说明:

  • 删除后会同步通知相关控制单元刷新配置。

PUT /api/point/batch/set-equipment

批量设置点位设备绑定和信号角色。

{
  "point_ids": ["uuid1", "uuid2"],
  "equipment_id": "uuid",
  "signal_role": "run"
}

说明:

  • 更新前后关联到的控制单元都会被唤醒,避免控制引擎继续使用旧映射。

PUT /api/point/batch/set-tags

批量设置点位标签。

POST /api/point/value/batch

批量写点。

请求头:

  • X-Write-Key: <key>

请求示例:

{
  "items": [
    { "point_id": "uuid", "value": 12.3 }
  ]
}

Equipment

GET /api/equipment

分页获取设备列表,包含点位数量和已绑定信号角色点。

GET /api/equipment/{equipment_id}

获取单个设备。

GET /api/equipment/{equipment_id}/points

获取设备下所有点位。

POST /api/equipment

创建设备。

说明:

  • 如果设备绑定了控制单元,创建成功后会唤醒对应控制单元。

PUT /api/equipment/{equipment_id}

更新设备。

说明:

  • 如果设备更换了 unit_idkind 或其他控制相关配置,旧单元和新单元都会被唤醒。

PUT /api/equipment/batch/set-unit

批量调整设备所属控制单元。

说明:

  • 批量更新前关联到的旧单元,以及更新后关联到的新单元,都会收到唤醒通知。

DELETE /api/equipment/{equipment_id}

删除设备。成功返回 204 No Content

说明:

  • 删除后会唤醒原所属控制单元。

Unit

GET /api/unit

分页获取控制单元列表,返回单元基础信息、运行时快照和设备摘要。

POST /api/unit

创建控制单元。

请求示例:

{
  "code": "U01",
  "name": "1号机组",
  "description": null,
  "enabled": true,
  "run_time_sec": 60,
  "stop_time_sec": 30,
  "acc_time_sec": 3600,
  "bl_time_sec": 10,
  "require_manual_ack_after_fault": true
}

约束:

  • run_time_sec > 0
  • stop_time_sec > 0
  • acc_time_sec > 0
  • bl_time_sec > 0
  • acc_time_sec > run_time_sec

PUT /api/unit/{unit_id}

更新控制单元,字段均可选。

约束:

  • 如果更新后涉及时长字段,仍然必须满足上面的全部约束。

DELETE /api/unit/{unit_id}

删除控制单元。成功返回 204 No Content

GET /api/unit/{unit_id}

获取单个控制单元及其设备摘要。

GET /api/unit/{unit_id}/detail

获取控制单元完整详情,包括设备和点位列表。

GET /api/unit/{unit_id}/runtime

获取控制单元当前运行时状态。

响应字段:

{
  "unit_id": "uuid",
  "state": "running",
  "auto_enabled": true,
  "accumulated_run_sec": 3600000,
  "display_acc_sec": 3600000,
  "fault_locked": false,
  "flt_active": false,
  "comm_locked": false,
  "manual_ack_required": false,
  "rem_local": false
}

rem_local 说明:

  • true: 单元下存在设备 REM 信号为本地模式REM=0信号质量正常
  • rem_local = true 时,自动控制会被强制停止,且禁止重新启动,直到所有 REM 恢复远程

state 枚举:

  • stopped
  • running
  • distributor_running
  • fault_locked
  • comm_locked

说明:

  • accumulated_run_secdisplay_acc_sec 单位都是毫秒。
  • 运行时状态保存在内存中,服务重启后重置。

Event

GET /api/event

分页获取系统事件。

查询参数:

  • unit_id
  • event_type
  • page
  • page_size

常见事件类型:

  • unit.auto_control_started
  • unit.auto_control_stopped
  • unit.fault_locked
  • unit.fault_acked
  • unit.comm_locked
  • unit.comm_recovered
  • unit.rem_local — 设备切换为本地模式自动控制已停止warn
  • unit.rem_recovered — 设备切换回远程模式自动控制需手动重新启动warn
  • equipment.start_command_sent
  • equipment.stop_command_sent

Control

所有控制命令在执行前都会校验:

  • 信号质量
  • REM 状态REM=0 时拒绝手动指令)
  • FLT 状态
  • 单元 auto_enabled
  • 单元 comm_locked
  • 单元 fault_locked
  • 单元 manual_ack_required
  • 单元 rem_local(自动控制启动时额外校验)

POST /api/control/equipment/{equipment_id}/start

发送设备启动脉冲命令。

POST /api/control/equipment/{equipment_id}/stop

发送设备停止脉冲命令。

POST /api/control/unit/{unit_id}/start-auto

启动单元自动控制。

前置条件:

  • 单元已启用
  • fault_locked = false
  • comm_locked = false
  • manual_ack_required = false
  • rem_local = false(有设备处于本地模式时不允许启动)

成功响应:

{ "ok_msg": "Auto control started", "unit_id": "uuid" }

POST /api/control/unit/{unit_id}/stop-auto

停止单元自动控制。

POST /api/control/unit/batch-start-auto

批量启动所有已启用单元的自动控制。

会跳过以下单元:

  • 已经 auto_enabled = true
  • fault_locked = true
  • comm_locked = true
  • manual_ack_required = true
  • rem_local = true

说明:

  • 单个启动和批量启动现在使用相同的阻断规则。

POST /api/control/unit/batch-stop-auto

批量停止自动控制。

POST /api/control/unit/{unit_id}/ack-fault

人工确认故障。

前置条件:

  • fault_locked = true
  • flt_active = false

Tag

GET /api/tag

分页获取标签列表。

POST /api/tag

创建标签。

GET /api/tag/{tag_id}

获取标签下已绑定点位。

PUT /api/tag/{tag_id}

更新标签。

DELETE /api/tag/{tag_id}

删除标签。成功返回 204 No Content

Page

GET /api/page

获取自定义页面列表。

POST /api/page

创建页面。

GET /api/page/{page_id}

获取单个页面。

PUT /api/page/{page_id}

更新页面。

DELETE /api/page/{page_id}

删除页面。成功返回 204 No Content

Log

GET /api/logs

读取日志文件内容。默认读取最新的 app.log* 文件。

查询参数:

  • file: 指定文件名,仅允许 app.log*
  • cursor: 增量读取位置
  • tail_lines: 默认 200,最大 2000
  • max_bytes: 默认 64KB,最大 512KB

响应示例:

{
  "file": "app.log",
  "cursor": 204800,
  "lines": ["2026-03-25 10:00:00 INFO ..."],
  "truncated": false,
  "reset": false
}

字段说明:

  • truncated = true: 当前还有未读完内容,可继续用新 cursor 拉取
  • reset = true: 文件被截断或读取起点被重置

GET /api/logs/stream

通过 SSE 推送日志增量。

查询参数:

  • file
  • cursor
  • max_bytes

默认行为:

  • 如果没有传 file,服务端会始终跟随最新的 app.log*
  • 如果日志轮转到了新文件,流会自动切换到新文件,并推送一条 reset = true 的日志事件

事件示例:

event: log
data: { "file": "app.log.1", "cursor": 1024, "lines": ["..."], "truncated": false, "reset": true }

event: error
data: log stream read failed

WebSocket

服务端推送消息

PointNewValue

点位实时值更新。

EventCreated

系统事件创建。

UnitRuntimeChanged

控制单元运行时状态更新。

{
  "type": "UnitRuntimeChanged",
  "data": {
    "unit_id": "uuid",
    "state": "running",
    "auto_enabled": true,
    "fault_locked": false,
    "flt_active": false,
    "comm_locked": false,
    "manual_ack_required": false,
    "rem_local": false,
    "accumulated_run_sec": 3600000,
    "display_acc_sec": 3600000
  }
}

PointSetValueBatchResult

批量写点结果回调。

客户端消息

auth_write

{
  "type": "auth_write",
  "data": { "key": "your-write-key" }
}

point_set_value_batch

{
  "type": "point_set_value_batch",
  "data": {
    "items": [
      { "point_id": "uuid", "value": 12.3 }
    ]
  }
}

备注

  • 控制引擎现在会在每轮单元循环中重新加载设备和角色映射,而不是只在任务启动时加载一次。
  • 设备和点位的控制相关配置变更后,会主动唤醒对应单元任务,使新配置尽快生效。
  • 日志流默认跟随最新日志文件,适配日志轮转场景。
  • REM 信号为本地模式REM=0手动控制指令start/stop和自动控制启动均被拒绝若自动控制正在运行引擎会立即停止并记录 unit.rem_local 事件。REM 恢复远程后记录 unit.rem_recoveredwarn自动控制需操作员手动重新启动。