Skip to content

LC2000 Control 外部开发者对接指南 ​

适用服务版本:1.0.14
文档依据:当前版本公开接口行为
最后更新:2026-09-10

本文面向需要接入 lc2000-control 的平台、应用和设备侧开发者,说明当前版本实际开放的能力、接口选择、报文格式和使用边界。

1. 服务定位 ​

lc2000-control 部署在 LC2000 设备侧。一个服务实例管理一台 LC2000,并向客户系统提供 HTTP、WebSocket 和 MQTT 接口。

text
客户 Web/桌面应用 ---- HTTP / WebSocket ----+
                                            |
客户业务平台 --------------- MQTT ----------+---- lc2000-control ---- LC2000 设备

本文只描述对外开放的接口。未列出的设备能力不属于当前客户对接范围。

2. 可对接能力 ​

功能域当前能力推荐接口
服务与设备状态查询服务存活、设备连接、设备身份、CPU、内存、在线状态HTTP、WebSocket、MQTT
DI/DO查询缓存状态、接收 DI/DO 变化、控制 DO、设置 DO 常开/常闭模式、获取全量 IO 快照HTTP、WebSocket、MQTT
传感器查询温度、湿度、照度、电量等当前值,接收周期状态HTTP、WebSocket、MQTT
HPLC 白名单查询、新增或更新、删除、刷新白名单HTTP
HPLC 控制器与子设备查询控制器状态,查询、新增或更新、删除灯具子设备HTTP
单灯接入单灯、批量异步接入、查询/刷新状态、开关、调光HTTP、MQTT;状态也可通过 WebSocket 获取
灯具分组查询、创建、完整替换、删除分组,分组调光HTTP、MQTT
全网灯控全网广播调光MQTT
系统配置查询/设置时间,查询/设置 ETH0/ETH1 静态网络,上传升级包并启动升级HTTP
本地控制台浏览器查看状态、控制 DO/灯具、导入单灯、管理分组和系统配置Web UI

客户系统应以本表和后续接口清单为能力边界。当前接口不提供通用命令透传、HTTP 全网灯控、传感器告警事件或场景控制。

3. 如何选择接口 ​

场景接口特点
同一局域网内查询或配置单台设备HTTP请求/响应简单,适合管理页面和运维工具
浏览器或本地应用持续展示实时状态WebSocket连接后先收到最新快照,再收到增量事件
中心平台管理多台 LC2000、触发业务联动MQTT异步、QoS 1,支持命令回执和动态 topic

4. 接入前准备 ​

4.1 启动与地址 ​

服务部署和设备绑定由交付人员完成,默认 HTTP 端口为 19898。客户侧只需确认设备地址、开放端口,以及需要使用的 HTTP、WebSocket 或 MQTT 接口。

服务地址示例:

text
HTTP API:  http://192.168.1.10:19898/lc2000/api/v1
WebSocket: ws://192.168.1.10:19898/lc2000/api/v1/ws/status
Web UI:    http://192.168.1.10:19898/lc2000-control/
配置 API:  http://192.168.1.10:19898/lc2000/config-api

最小配置示例:

json
{
  "port": 19898,
  "cors": true,
  "data_source_id": "lc2000-datasource-id",
  "mqtt": {
    "report": {
      "broker": "mqtt://127.0.0.1:11883",
      "client_id": "lc2000-reporter",
      "username": "",
      "password": "",
      "di_topic": "lc2000/event/{lc2000_id}/di/{channel}",
      "do_topic": "lc2000/event/{lc2000_id}/do/{channel}",
      "sensor_topic": "lc2000/event/{lc2000_id}/sensor/{sensor_id}",
      "status_topic": "lc2000/status/{lc2000_id}",
      "full_topic": "lc2000/event/{lc2000_id}/io_status",
      "command_topic": "lc2000/control/{lc2000_id}/command",
      "ack_topic": "lc2000/ack/{lc2000_id}/{request_id}"
    }
  }
}

mqtt.report.broker 为空时 MQTT 上报和控制关闭;HTTP 的 DO 控制和接点模式设置也会因此不可用。需要调整部署参数时,请向交付人员提供 HTTP 端口、数据源标识和 MQTT Broker 信息。

4.2 健康检查 ​

bash
curl http://192.168.1.10:19898/lc2000/api/v1/healthz
json
{
  "ok": true,
  "lc2000": {
    "address": "127.0.0.1:18081",
    "ip": "127.0.0.1",
    "port": "18081",
    "connected": true,
    "cpu_load": 0.11,
    "mem_used_mb": 1308,
    "mem_total_mb": 4096
  }
}

ok=true 只表示 HTTP 服务正常响应。设备通信是否已经就绪必须检查 lc2000.connected;业务调用应在该值为 true 后进行。

4.3 标识约定 ​

字段含义示例
lc2000_idLC2000 的序列号 sn,也是默认 MQTT topic 中的设备标识LC2000GATEWAY0001
device_id服务按 SN 分配并持久化的 32 位无横杠 UUID24391328e616431197dca8f675c3aa2c
controller_id / 控制器 dev_idHPLC 单灯控制器标识0000E0B72E02C72A
asset_id / 灯具 dev_id灯具子设备标识0000E0B72E02C72A_0000001
group_id灯具分组业务标识road-east
group_noLC2000 分组号,范围 1..641

不要混用网关 device_id、控制器 dev_id 和灯具 asset_id。

4.4 安全边界 ​

当前 HTTP 和 WebSocket 接口没有内置用户鉴权,也没有内置 HTTPS/WSS。服务默认监听所有网卡。生产部署应放在可信设备网或反向代理之后,并由网关提供访问控制、TLS、限流和审计。

HTTP 在 cors=true 时允许任意 Origin,但 WebSocket 仍校验同源:浏览器页面的 Origin 必须与请求 Host 一致。跨域网页应通过同源反向代理接入;没有 Origin 头的后端 WebSocket 客户端可以连接。

5. HTTP API ​

5.1 通用约定 ​

  • 业务 API 前缀:/lc2000/api/v1
  • JSON 请求头:Content-Type: application/json
  • 普通查询或写入成功:{"data": ...}
  • 删除成功:HTTP 204 No Content
  • 参数错误:{"error":"..."}
  • LC2000 协议错误:{"error":"...","lc2000_code":500}
  • 除批量导入外,JSON 请求体上限为 64 KiB;业务 API 会拒绝未知 JSON 字段和连续多个 JSON 对象
  • timestamp 使用 Unix 秒;timestamp_ms、updated_ms、updated_at 使用 Unix 毫秒

常见状态码:

状态码含义
200查询或更新完成
201资源创建完成
202命令、刷新或异步任务已接受,不一定代表设备最终状态已确认
204删除完成
400请求字段、取值或 JSON 格式错误
404服务侧资源或异步任务不存在
409已有升级任务正在执行
413升级文件超过 512 MiB
502LC2000 返回协议错误、拒绝操作或发生其他下游错误
503设备连接、状态存储或 MQTT 控制通道不可用
504等待 LC2000 响应超时

5.2 接口清单 ​

设备、IO 与传感器 ​

方法路径功能状态说明
GET/healthzHTTP 存活和设备连接快照不触发设备重连
GET/devices?sn={text}&device_id={id}查询设备及缓存的 DI/DO 状态;sn 模糊匹配,device_id 精确匹配返回最近持久化状态
GET/system/info查询设备身份、资源、时间和网络摘要实时查询
GET/sensors/{sensor_id}查询一个传感器;传空路径不可用,调用方应提供实际 ID实时查询
PUT/dido/do/{channel}/control设置 DO 值,请求体 {"value":0|1}MQTT 命令链路
PUT/dido/do/{channel}/contact-mode设置接点模式,请求体见下文MQTT 命令链路

白名单、控制器与子设备 ​

方法路径功能
GET/whitelist查询白名单
POST / PUT/whitelist新增或覆盖白名单项
GET/whitelist/{dev_id}查询单个白名单项
PUT/whitelist/{dev_id}更新白名单项,路径 ID 为准
DELETE/whitelist/{dev_id}删除白名单项
POST/whitelist/refresh将白名单刷新到 HPLC CCO
GET/controllers/{dev_id}查询控制器在线状态和版本
GET/children?kind=lamp查询子设备,可按 kind 过滤
POST / PUT/children新增或覆盖子设备
GET/children/{dev_id}查询单个子设备
PUT/children/{dev_id}更新子设备,路径 ID 为准
DELETE/children/{dev_id}删除子设备

单灯、批量接入与分组 ​

方法路径功能
GET/lamps/{asset_id}查询灯具当前状态
POST/lamps/{asset_id}/refresh主动刷新灯具状态
PUT/lamps/{asset_id}/control单灯开关或调光
POST/single-lamps编排一盏灯的完整接入流程
POST/single-lamp-imports创建批量单灯异步接入任务
GET/single-lamp-imports/{task_id}?offset=0&limit=200查询任务汇总和分页明细
GET/groups查询所有分组及成员
POST / PUT/groups创建或覆盖分组
GET/groups/{group_id}查询一个分组
PUT/groups/{group_id}删除旧分组后完整重建
PUT/groups/{group_id}/control分组调光
DELETE/groups/{group_id}删除分组

5.3 查询设备与 IO 状态 ​

bash
curl 'http://192.168.1.10:19898/lc2000/api/v1/devices?sn=GATEWAY'
json
{
  "data": [
    {
      "device_id": "24391328e616431197dca8f675c3aa2c",
      "sn": "LC2000GATEWAY0001",
      "model": "LC2000",
      "sw_ver": "1.0.0",
      "oh_ver": "6.0",
      "online": true,
      "di_count": 8,
      "di": [{"kind":"DI","channel":1,"value":1,"duration_ms":12000,"updated_at":1789000000000}],
      "do_count": 8,
      "do": [{"kind":"DO","channel":1,"value":0,"duration_ms":9000,"updated_at":1789000000000}],
      "updated_at": 1789000000000
    }
  ]
}

该接口返回最近一次持久化的状态,适合设备目录和断线后的最后状态展示,不等同于实时采集。实时页面应使用 WebSocket,中心平台应使用 MQTT。

5.4 DO 控制与接点模式 ​

bash
curl -X PUT http://192.168.1.10:19898/lc2000/api/v1/dido/do/1/control \
  -H 'Content-Type: application/json' \
  -d '{"value":1}'
json
{"data":{"kind":"DO","channel":1,"value":1}}

HTTP 202 只表示命令已提交到 MQTT 控制通道。此接口当前不返回服务生成的 request_id,因此需要关联最终回执的业务系统应直接使用 MQTT 控制接口。

设置 DO 接点模式:

bash
curl -X PUT http://192.168.1.10:19898/lc2000/api/v1/dido/do/1/contact-mode \
  -H 'Content-Type: application/json' \
  -d '{"contact_mode":"normally_closed"}'

contact_mode 支持 normally_open / no 和 normally_closed / nc。返回值会规范化为 normally_open 或 normally_closed。

5.5 传感器和系统信息 ​

bash
curl http://192.168.1.10:19898/lc2000/api/v1/sensors/TH1
json
{
  "data": {
    "dev_id": "TH1",
    "online": true,
    "temperature_c": 26.5,
    "humidity_rh": 63.2,
    "illuminance_lx": 180.0,
    "battery_pct": 95.0
  }
}

未提供的测点字段会省略。系统摘要可通过 GET /system/info 获取,响应包括 device_name、model、serial_number、固件/硬件版本、运行时间、在线状态、CPU/内存和网络地址。

5.6 白名单与子设备 ​

新增白名单项并刷新:

bash
curl -X POST http://192.168.1.10:19898/lc2000/api/v1/whitelist \
  -H 'Content-Type: application/json' \
  -d '{"dev_id":"0000E0B72E02C72A","model":"LC601-HPLC","note":"road-a"}'

curl -X POST http://192.168.1.10:19898/lc2000/api/v1/whitelist/refresh

登记灯具子设备:

bash
curl -X POST http://192.168.1.10:19898/lc2000/api/v1/children \
  -H 'Content-Type: application/json' \
  -d '{"dev_id":"0000E0B72E02C72A_0000001","parent_id":"0000E0B72E02C72A","kind":"lamp","channel":1,"model":"sslamp","note":"pole-1"}'

白名单写入后不会自动刷新,调用方使用细粒度接口时必须显式调用 /whitelist/refresh。若希望服务完成整个顺序,应使用 /single-lamps。

5.7 单灯接入与控制 ​

推荐使用聚合接入接口:

bash
curl -X POST http://192.168.1.10:19898/lc2000/api/v1/single-lamps \
  -H 'Content-Type: application/json' \
  -d '{
    "controller_id":"0000E0B72E02C72A",
    "asset_id":"0000E0B72E02C72A_0000001",
    "channel":1,
    "model":"sslamp",
    "controller_model":"LC601-HPLC",
    "require_controller_online":true
  }'

服务依次执行:回读白名单、按需新增控制器、按需刷新白名单、查询控制器、登记子设备、刷新灯具、查询灯具状态。ensure_controller 默认 true;灯具型号默认 sslamp,控制器型号默认 LC601-HPLC。流程已完成的步骤不会在后续失败时回滚,重复请求应按幂等更新思路处理。

单灯控制:

bash
curl -X PUT http://192.168.1.10:19898/lc2000/api/v1/lamps/0000E0B72E02C72A_0000001/control \
  -H 'Content-Type: application/json' \
  -d '{"switch":1,"dim":60}'

switch 可选且只能为 0/1,dim 可选且范围为 0..100,至少提供一个。HTTP 202 表示 LC2000 已接受控制,不代表灯具物理状态已经确认。需要闭环时再调用:

text
POST /lamps/{asset_id}/refresh
GET  /lamps/{asset_id}

灯具状态字段包括 online、switch、dim、source 和 updated_ms。source=stale 表示返回的是陈旧缓存,不应视为控制确认。

5.8 批量单灯接入 ​

bash
curl -X POST http://192.168.1.10:19898/lc2000/api/v1/single-lamp-imports \
  -H 'Content-Type: application/json' \
  -d '{
    "require_controller_online":false,
    "items":[
      {"controller_id":"0000E0B72E02C72A","asset_id":"0000E0B72E02C72A_0000001","channel":1},
      {"controller_id":"0000E0B72E02C72A","asset_id":"0000E0B72E02C72A_0000002","channel":2}
    ]
  }'

接口返回 202 和任务 ID。轮询时先用 limit=0 只取汇总,完成后再分页读取明细:

bash
curl 'http://192.168.1.10:19898/lc2000/api/v1/single-lamp-imports/lamp-import-1789000000000-1?offset=0&limit=200'

限制和生命周期:

  • 请求体最大 8 MiB,单任务最多 10000 项
  • asset_id 在同一任务中重复时,仅重复行失败,不阻塞其他行
  • 查询页最大 500 项;limit=0 不返回 items
  • worker 数由 single_lamp_import_workers 配置,范围 1..32,默认 4
  • 任务仅保存在当前进程内存中,重启后不可恢复;服务只保留有限数量的已完成任务
  • 页面关闭不会取消任务,当前没有取消任务 API

任务状态为 queued、running、completed;明细阶段包括 validation、whitelist、sync、controller、child、lamp_refresh、lamp_state 和 completed。

5.9 灯具分组 ​

创建分组:

bash
curl -X POST http://192.168.1.10:19898/lc2000/api/v1/groups \
  -H 'Content-Type: application/json' \
  -d '{
    "group_id":"road-east",
    "group_no":1,
    "members":[
      {"asset_id":"0000E0B72E02C72A_0000001"},
      {"asset_id":"0000E0B72E02C72A_0000002"}
    ]
  }'

成员必须是已登记灯具,并且所属控制器必须在白名单中。重复成员会去重。更新 PUT /groups/{group_id} 不是局部补丁:服务会先校验完整请求,再删除原分组并按请求中的组号和全部成员重建。

分组调光:

bash
curl -X PUT http://192.168.1.10:19898/lc2000/api/v1/groups/road-east/control \
  -H 'Content-Type: application/json' \
  -d '{"level":40}'

level 范围为 0..100,0 表示关闭。

6. 系统配置 API ​

系统配置接口保留历史前缀 /lc2000/config-api,但由本服务直接处理,不再反向代理到其他服务。它使用不同的响应格式:

json
{"code":200,"msg":"Network config found","data":{}}
方法路径请求说明
GET/config/system_time无查询系统时间、时区和 NTP 配置
POST/config/system_time{"system_time":"2026-09-10 14:30:00"}设置 Linux、硬件和 LC2000 时钟;也接受 RFC3339
GET/config/network/{index}index 为 1 或 2查询 ETH0/ETH1 持久化配置和运行状态
POST/config/network/{index}{"ip":"192.168.1.10","netmask":"255.255.255.0","gateway":"192.168.1.1"}写入并应用静态 IPv4 配置
POST/hardware/upload_filemultipart/form-data,推荐字段名 file保存升级包为 upgrade.pkg,最大 512 MiB
POST/hardware/upgrade无异步启动 upgrade_tool

修改正在使用的网口可能立即中断当前 HTTP/WebSocket 连接,应从本机或具备备用链路的管理端调用。启动升级只表示进程已经拉起;当前版本没有升级进度查询接口,执行结果记录在服务日志中。

7. WebSocket 实时状态 ​

连接地址:

text
GET /lc2000/api/v1/ws/status

浏览器示例:

javascript
const socket = new WebSocket("ws://192.168.1.10:19898/lc2000/api/v1/ws/status");

socket.onmessage = ({ data }) => {
  const event = JSON.parse(data);
  console.log(event.type, event.sequence, event.data);
};

统一事件信封:

json
{
  "type": "io_event",
  "sequence": 12,
  "timestamp_ms": 1789000000123,
  "data": {}
}
typedata 内容
device_snapshot设备身份、版本、系统时间、连接地址、CPU/内存、DI/DO 全量状态
device_status与 MQTT 设备状态报文相同
io_status与 MQTT 全量 IO 快照相同
io_event与 MQTT DI/DO 单点变化报文相同
sensor_stateHTTP 传感器原始状态结构
sensor_status与 MQTT 传感器上报结构相同
lamp_status灯具 asset_id、在线、开关、亮度、来源和更新时间

连接建立后,服务先按 sequence 顺序发送进程内保存的各类最新快照,再发送增量事件。客户端应遵循以下规则:

  • sequence 只在当前进程生命周期内单调递增,服务重启后会重置
  • 首批快照的序号可能不连续,不要用缺号判断丢包
  • 按实体保存最后一个事件,并忽略比本地序号更旧的事件
  • 断线后指数退避重连;服务会再次发送最新快照
  • 慢客户端的发送队列满时,服务会主动断开,采集线程不会等待客户端
  • WebSocket 与 MQTT 是独立的客户接入通道;MQTT 中断时 WebSocket 实时状态仍可使用

8. MQTT 对接 ​

8.1 两组连接 ​

配置组方向用途
mqtt.listen外部系统 -> 服务接收兼容的 DI 输入事件并合并到本地状态
mqtt.report双向上报 DI/DO、传感器、设备和快照;接收控制命令;发布回执

两组连接相互独立。Broker 为空即关闭对应组。客户端使用 MQTT QoS 1、retain=false、clean session,并在断线后自动重连和恢复订阅。上报消息不会保留在 Broker;晚订阅方应通过 HTTP 或状态查询命令补齐初始状态。

mqtt.report 的 topic 模板支持以下占位符:{lc2000_id}、{device_id}、{channel}、{sensor_id}、{request_id}。默认 {lc2000_id} 为 LC2000 SN;mqtt.listen.topic 按配置原值订阅,不展开占位符。

8.2 Topic 清单 ​

方向默认 topic说明
发布lc2000/event/{lc2000_id}/di/{channel}DI 单点变化
发布lc2000/event/{lc2000_id}/do/{channel}DO 单点变化
发布lc2000/event/{lc2000_id}/sensor/{sensor_id}传感器数值
发布lc2000/status/{lc2000_id}网关在线和资源状态
发布lc2000/event/{lc2000_id}/io_statusDI/DO 全量快照
订阅lc2000/control/{lc2000_id}/command控制或状态查询命令
发布lc2000/ack/{lc2000_id}/{request_id}控制回执
订阅lc2000-di-event可选的外部 DI 输入

默认上报节奏:设备状态每 status_seconds 秒一次,全量 IO 每 full_seconds 秒一次,传感器在每次 sensor_poll_seconds 轮询完成后上报;DI/DO 只在状态变化时发布单点事件。

8.3 DI/DO 事件 ​

DI 示例:

json
{
  "event_id": "550e8400e29b41d4a716446655440000",
  "data_source_id": "lc2000-datasource-id",
  "lc2000_id": "LC2000GATEWAY0001",
  "device_id": "24391328e616431197dca8f675c3aa2c",
  "device_name": "ssslc-LC2000GATEWAY0001",
  "condition_name": "DIChange",
  "channel": "DI1",
  "status": 1,
  "value": 1,
  "edge": "rising",
  "quality": "good",
  "timestamp": 1789000000
}

DO 使用相同基础结构,差异字段如下:

json
{
  "condition_name": "DOStatus",
  "channel": "DO1",
  "status": 1,
  "value": 1,
  "edge": "rising",
  "quality": "good",
  "source": "lc2000",
  "contact_mode": "normally_open",
  "normally_closed": 0
}

status 与 value 当前保持相同,均为 0 或 1。edge 根据新值生成:1 为 rising,0 为 falling。

8.4 传感器、设备和全量状态 ​

传感器上报:

json
{
  "event_id": "550e8400e29b41d4a716446655440001",
  "data_source_id": "lc2000-datasource-id",
  "lc2000_id": "LC2000GATEWAY0001",
  "device_id": "LC2000GATEWAY0001",
  "device_name": "ssslc-LC2000GATEWAY0001",
  "condition_name": "SensorValue",
  "sensor_id": "TH1",
  "values": [
    {"key":"temperature","name":"Temperature","value":26.5,"unit":"celsius","quality":"good"},
    {"key":"humidity","name":"Humidity","value":63.2,"unit":"percent","quality":"good"}
  ],
  "timestamp": 1789000000
}

当前 1.0.14 接口中,传感器报文的 device_id 使用 LC2000 SN,而 DI/DO、设备状态和全量 IO 报文使用服务分配的 UUID。消费者应优先用 data_source_id + lc2000_id 识别网关,用 sensor_id 识别传感器,不要假设所有报文的 device_id 格式完全一致。

设备状态:

json
{
  "data_source_id": "lc2000-datasource-id",
  "lc2000_id": "LC2000GATEWAY0001",
  "device_id": "24391328e616431197dca8f675c3aa2c",
  "device_name": "ssslc-LC2000GATEWAY0001",
  "condition_name": "DeviceStatus",
  "status": "online",
  "cpu_load": 0.11,
  "mem_used_mb": 1308,
  "mem_total_mb": 4096,
  "reason": "",
  "timestamp": 1789000000
}

全量 IO 快照:

json
{
  "data_source_id": "lc2000-datasource-id",
  "report_type": "io_status_snapshot",
  "lc2000_id": "LC2000GATEWAY0001",
  "device_id": "24391328e616431197dca8f675c3aa2c",
  "device_name": "ssslc-LC2000GATEWAY0001",
  "timestamp": 1789000000,
  "io_status": {
    "di": [{"channel":"DI1","value":1,"edge":"rising","quality":"good","name":""}],
    "do": [{"channel":"DO1","value":0,"source":"","quality":"good","name":"","contact_mode":"normally_open","normally_closed":0}]
  }
}

全量快照用于初始化和对账,不会替代 DI/DO 单点事件触发联动。

8.5 控制命令 ​

所有命令发布到:

text
lc2000/control/{lc2000_id}/command
action必填业务字段约束成功判定
set_dochannel、valuechannel 为字符串,推荐 DO1,也接受 1;value 为 0/1;ttl >= 0LC2000 写入成功
set_do_contact_modechannel 或 do_no、contact_mode模式支持 no/nc 或完整名称LC2000 配置成功
set_lampasset_id,以及 switch / dim 至少一个switch=0/1,dim=0..100等待 1 秒后刷新、读取并匹配实际状态
set_lamp_groupgroup_id、levellevel=0..100LC2000 协议请求成功,不做灯具状态闭环
set_lamp_broadcastlevellevel=0..100LC2000 协议请求成功,不做灯具状态闭环
query_lc2000_status无额外必填字段可提供 response_topicIO 快照和传感器读取/发布完成

每条命令都必须包含非空且全局唯一的 request_id。建议同时提供 data_source_id、lc2000_id 和 device_id。非空 lc2000_id 或 device_id 与本机不匹配时,服务拒绝执行并发布失败回执。data_source_id 当前只作为元数据,不参与目标校验,回执中的值取自服务本地配置。

DO 控制示例:

json
{
  "request_id": "order-20260910-0001",
  "data_source_id": "lc2000-datasource-id",
  "lc2000_id": "LC2000GATEWAY0001",
  "device_id": "24391328e616431197dca8f675c3aa2c",
  "action": "set_do",
  "channel": "DO1",
  "value": 1,
  "ttl": 30
}

ttl 单位为秒。大于 0 时,到期后服务写入本次值的反值;value=1 表示打开后自动关闭,value=0 表示关闭后自动打开。自动复位没有单独回执。

单灯控制示例:

json
{
  "request_id": "order-20260910-0002",
  "lc2000_id": "LC2000GATEWAY0001",
  "action": "set_lamp",
  "asset_id": "0000E0B72E02C72A_0000001",
  "switch": 1,
  "dim": 60
}

set_lamp 不接受旧字段 dev_id 和 level;set_lamp_group 只接受 level,不接受 dim。

状态查询示例:

json
{
  "request_id": "query-20260910-0001",
  "lc2000_id": "LC2000GATEWAY0001",
  "action": "query_lc2000_status",
  "response_topic": "client/demo/lc2000/status"
}

查询成功后,服务向 response_topic 发布 report_type=status_snapshot 的 IO 快照,并向正常的传感器 topic 另发一条传感器报文。当前快照不包含传感器数组、设备资源状态或 extra_status,成功时也不发布 ACK;任一步骤失败时会发布 query_lc2000_status_failed 回执。未指定 response_topic 时默认发布到 lc2000/event/{lc2000_id}/status_snapshot。

8.6 回执与幂等 ​

回执 topic:

text
lc2000/ack/{lc2000_id}/{request_id}
json
{
  "request_id": "order-20260910-0001",
  "data_source_id": "lc2000-datasource-id",
  "lc2000_id": "LC2000GATEWAY0001",
  "device_id": "24391328e616431197dca8f675c3aa2c",
  "status": "success",
  "error_code": "",
  "error": "",
  "message": "executed",
  "timestamp": 1789000001
}

status 为 success 或 failed。单灯闭环成功时 message=confirmed 且带 lamp_state。常见 error_code 包括:

  • device_id_mismatch、lc2000_id_mismatch
  • duplicate_request_id
  • do_set_failed、do_contact_mode_set_failed
  • lamp_set_failed、lamp_set_not_accepted
  • lamp_state_refresh_failed、lamp_state_get_failed、lamp_state_unconfirmed
  • query_lc2000_status_failed

幂等记录只保存在当前进程内存中,服务重启后会清空。同一个 device_id + request_id 在进程生命周期内重复到达时不会再次执行,而是返回 duplicate_request_id。调用方必须为每一次业务意图生成新的 ID,并将失败回执、超时和重试策略纳入设计。

无法解析或不符合 action 字段约束的 MQTT 消息会在边界被丢弃,不保证有 ACK。调用方应设置回执超时,并结合服务日志排查格式错误。

8.7 外部 DI 输入 ​

启用 mqtt.listen 后,外部系统可以向配置的 topic 发布 DI 状态:

json
{
  "device_id": "24391328e616431197dca8f675c3aa2c",
  "sn": "LC2000GATEWAY0001",
  "kind": "DI",
  "di_no": 1,
  "value": 1
}

di_no 和 channel 二选一,范围从 1 开始;value 为 0/1;kind 可省略或为 DI。device_id、sn 可省略,但提供时必须与本机身份匹配。合法事件会更新持久化状态和 WebSocket 状态,并在发生变化时通过 mqtt.report 的标准 DI topic 再上报。

9. 推荐对接流程 ​

9.1 本地管理应用 ​

  1. 调用 /healthz,同时检查 HTTP 可用和 lc2000.connected=true。
  2. 调用 /devices、/children?kind=lamp 获取目录和缓存状态。
  3. 建立 /ws/status,以初始快照覆盖本地状态,再持续应用增量事件。
  4. 使用 HTTP 执行白名单、单灯、分组和系统配置操作。
  5. DO 控制如需最终回执,改用 MQTT;只需尽力下发时可使用 HTTP。

9.2 中心平台或联动引擎 ​

  1. 为每台 LC2000 配置唯一 SN 和唯一 MQTT client ID 前缀。
  2. 订阅 lc2000/event/#、lc2000/status/# 和 lc2000/ack/#。
  3. 启动后发送 query_lc2000_status,或通过 HTTP 读取初始快照。
  4. 每次控制生成新的 request_id,发布到目标 SN 的 command topic。
  5. 以 ACK 作为命令结果,以后续状态事件作为状态真相;为二者分别设置超时。

9.3 HPLC 单灯接入 ​

  1. 优先调用 POST /single-lamps,不要在客户端重复编排白名单和刷新顺序。
  2. 批量数据使用异步导入接口,先轮询汇总,再分页读取失败明细。
  3. 控制后需要确认时执行“控制 -> 刷新 -> 查询”,并检查 online 和 source。
  4. 创建分组前确认灯具已经登记且控制器仍在白名单中。

10. 联调验收清单 ​

  • /healthz 返回 200,且 lc2000.connected=true
  • /system/info 能返回正确 SN、型号和版本
  • /devices 的 DI/DO 通道数与现场硬件一致
  • WebSocket 首次连接能收到 device_snapshot 或其他最新快照,断线后能重连
  • DI/DO 变化 topic、payload、时间单位与平台解析一致
  • 传感器消费者已处理 values 数组和当前 device_id 兼容性
  • MQTT 命令使用唯一 request_id,错误和超时均有处理策略
  • 单灯控制区分“命令已接受”和“实际状态已确认”
  • 网络配置变更具备备用管理链路
  • HTTP/WebSocket 已由可信网络或网关保护
  • 服务重启后,调用方能够重建 WebSocket 状态和异步命令上下文