LC2000 Control 外部开发者对接指南
适用服务版本:
1.0.14
文档依据:当前版本公开接口行为
最后更新:2026-09-10
本文面向需要接入 lc2000-control 的平台、应用和设备侧开发者,说明当前版本实际开放的能力、接口选择、报文格式和使用边界。
1. 服务定位
lc2000-control 部署在 LC2000 设备侧。一个服务实例管理一台 LC2000,并向客户系统提供 HTTP、WebSocket 和 MQTT 接口。
客户 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 接口。
服务地址示例:
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最小配置示例:
{
"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 健康检查
curl http://192.168.1.10:19898/lc2000/api/v1/healthz{
"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_id | LC2000 的序列号 sn,也是默认 MQTT topic 中的设备标识 | LC2000GATEWAY0001 |
device_id | 服务按 SN 分配并持久化的 32 位无横杠 UUID | 24391328e616431197dca8f675c3aa2c |
controller_id / 控制器 dev_id | HPLC 单灯控制器标识 | 0000E0B72E02C72A |
asset_id / 灯具 dev_id | 灯具子设备标识 | 0000E0B72E02C72A_0000001 |
group_id | 灯具分组业务标识 | road-east |
group_no | LC2000 分组号,范围 1..64 | 1 |
不要混用网关 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 |
502 | LC2000 返回协议错误、拒绝操作或发生其他下游错误 |
503 | 设备连接、状态存储或 MQTT 控制通道不可用 |
504 | 等待 LC2000 响应超时 |
5.2 接口清单
设备、IO 与传感器
| 方法 | 路径 | 功能 | 状态说明 |
|---|---|---|---|
GET | /healthz | HTTP 存活和设备连接快照 | 不触发设备重连 |
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 状态
curl 'http://192.168.1.10:19898/lc2000/api/v1/devices?sn=GATEWAY'{
"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 控制与接点模式
curl -X PUT http://192.168.1.10:19898/lc2000/api/v1/dido/do/1/control \
-H 'Content-Type: application/json' \
-d '{"value":1}'{"data":{"kind":"DO","channel":1,"value":1}}HTTP 202 只表示命令已提交到 MQTT 控制通道。此接口当前不返回服务生成的 request_id,因此需要关联最终回执的业务系统应直接使用 MQTT 控制接口。
设置 DO 接点模式:
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 传感器和系统信息
curl http://192.168.1.10:19898/lc2000/api/v1/sensors/TH1{
"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 白名单与子设备
新增白名单项并刷新:
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登记灯具子设备:
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 单灯接入与控制
推荐使用聚合接入接口:
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。流程已完成的步骤不会在后续失败时回滚,重复请求应按幂等更新思路处理。
单灯控制:
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 已接受控制,不代表灯具物理状态已经确认。需要闭环时再调用:
POST /lamps/{asset_id}/refresh
GET /lamps/{asset_id}灯具状态字段包括 online、switch、dim、source 和 updated_ms。source=stale 表示返回的是陈旧缓存,不应视为控制确认。
5.8 批量单灯接入
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 只取汇总,完成后再分页读取明细:
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 灯具分组
创建分组:
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} 不是局部补丁:服务会先校验完整请求,再删除原分组并按请求中的组号和全部成员重建。
分组调光:
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,但由本服务直接处理,不再反向代理到其他服务。它使用不同的响应格式:
{"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_file | multipart/form-data,推荐字段名 file | 保存升级包为 upgrade.pkg,最大 512 MiB |
POST | /hardware/upgrade | 无 | 异步启动 upgrade_tool |
修改正在使用的网口可能立即中断当前 HTTP/WebSocket 连接,应从本机或具备备用链路的管理端调用。启动升级只表示进程已经拉起;当前版本没有升级进度查询接口,执行结果记录在服务日志中。
7. WebSocket 实时状态
连接地址:
GET /lc2000/api/v1/ws/status浏览器示例:
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);
};统一事件信封:
{
"type": "io_event",
"sequence": 12,
"timestamp_ms": 1789000000123,
"data": {}
}type | data 内容 |
|---|---|
device_snapshot | 设备身份、版本、系统时间、连接地址、CPU/内存、DI/DO 全量状态 |
device_status | 与 MQTT 设备状态报文相同 |
io_status | 与 MQTT 全量 IO 快照相同 |
io_event | 与 MQTT DI/DO 单点变化报文相同 |
sensor_state | HTTP 传感器原始状态结构 |
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_status | DI/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 示例:
{
"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 使用相同基础结构,差异字段如下:
{
"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 传感器、设备和全量状态
传感器上报:
{
"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 格式完全一致。
设备状态:
{
"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 快照:
{
"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 控制命令
所有命令发布到:
lc2000/control/{lc2000_id}/commandaction | 必填业务字段 | 约束 | 成功判定 |
|---|---|---|---|
set_do | channel、value | channel 为字符串,推荐 DO1,也接受 1;value 为 0/1;ttl >= 0 | LC2000 写入成功 |
set_do_contact_mode | channel 或 do_no、contact_mode | 模式支持 no/nc 或完整名称 | LC2000 配置成功 |
set_lamp | asset_id,以及 switch / dim 至少一个 | switch=0/1,dim=0..100 | 等待 1 秒后刷新、读取并匹配实际状态 |
set_lamp_group | group_id、level | level=0..100 | LC2000 协议请求成功,不做灯具状态闭环 |
set_lamp_broadcast | level | level=0..100 | LC2000 协议请求成功,不做灯具状态闭环 |
query_lc2000_status | 无额外必填字段 | 可提供 response_topic | IO 快照和传感器读取/发布完成 |
每条命令都必须包含非空且全局唯一的 request_id。建议同时提供 data_source_id、lc2000_id 和 device_id。非空 lc2000_id 或 device_id 与本机不匹配时,服务拒绝执行并发布失败回执。data_source_id 当前只作为元数据,不参与目标校验,回执中的值取自服务本地配置。
DO 控制示例:
{
"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 表示关闭后自动打开。自动复位没有单独回执。
单灯控制示例:
{
"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。
状态查询示例:
{
"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:
lc2000/ack/{lc2000_id}/{request_id}{
"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_mismatchduplicate_request_iddo_set_failed、do_contact_mode_set_failedlamp_set_failed、lamp_set_not_acceptedlamp_state_refresh_failed、lamp_state_get_failed、lamp_state_unconfirmedquery_lc2000_status_failed
幂等记录只保存在当前进程内存中,服务重启后会清空。同一个 device_id + request_id 在进程生命周期内重复到达时不会再次执行,而是返回 duplicate_request_id。调用方必须为每一次业务意图生成新的 ID,并将失败回执、超时和重试策略纳入设计。
无法解析或不符合 action 字段约束的 MQTT 消息会在边界被丢弃,不保证有 ACK。调用方应设置回执超时,并结合服务日志排查格式错误。
8.7 外部 DI 输入
启用 mqtt.listen 后,外部系统可以向配置的 topic 发布 DI 状态:
{
"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 本地管理应用
- 调用
/healthz,同时检查 HTTP 可用和lc2000.connected=true。 - 调用
/devices、/children?kind=lamp获取目录和缓存状态。 - 建立
/ws/status,以初始快照覆盖本地状态,再持续应用增量事件。 - 使用 HTTP 执行白名单、单灯、分组和系统配置操作。
- DO 控制如需最终回执,改用 MQTT;只需尽力下发时可使用 HTTP。
9.2 中心平台或联动引擎
- 为每台 LC2000 配置唯一 SN 和唯一 MQTT client ID 前缀。
- 订阅
lc2000/event/#、lc2000/status/#和lc2000/ack/#。 - 启动后发送
query_lc2000_status,或通过 HTTP 读取初始快照。 - 每次控制生成新的
request_id,发布到目标 SN 的 command topic。 - 以 ACK 作为命令结果,以后续状态事件作为状态真相;为二者分别设置超时。
9.3 HPLC 单灯接入
- 优先调用
POST /single-lamps,不要在客户端重复编排白名单和刷新顺序。 - 批量数据使用异步导入接口,先轮询汇总,再分页读取失败明细。
- 控制后需要确认时执行“控制 -> 刷新 -> 查询”,并检查
online和source。 - 创建分组前确认灯具已经登记且控制器仍在白名单中。
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 状态和异步命令上下文