欢迎使用 Inteagle 设备 API 文档。
快速导航
平台端 API
适用于通过 Inteagle 结构健康监测平台获取设备数据的场景。开始对接 →
设备直连
适用于客户搭建自有 MQTT Broker 平台,由设备直接上报数据的场景。查看设备类型 →
本文档介绍如何对接 Inteagle 监测设备。
Inteagle 提供两种数据对接方式,客户可根据业务需求和开发能力选择不同的接入方式。
说明:
- 建议不熟悉设备的客户前期采用平台对接方式获取数据和控制设备,接入更简单便捷,成本更低。
- 对设备的使用已经比较熟悉或者有更高需求的客户请联系鹰腾工作人员开通设备直连权限。
- 有数据保密要求的客户请联系鹰腾工作人员开通设备直连权限。
| 方式 | 适用场景 | 协议 |
|---|---|---|
| 平台对接 | 通过 Inteagle 结构健康监测平台 | SDK + MQTT |
| 设备直连 | 设备连接客户自有 MQTT Broker 平台,数据直接上报到客户系统 | MQTT |
适用于通过 Inteagle 结构健康监测平台获取设备数据的场景。
适用于客户搭建自有 MQTT Broker 平台,由设备直接上报数据的场景。
| 类型 | 说明 | 文档 |
|---|---|---|
| 视觉位移计(VDM) | 非接触式位移监测设备 | 查看详情 → |
更多设备类型持续更新中…
本章节介绍如何将您的系统与 Inteagle 结构健康监测平台对接。
强烈推荐使用官方 Java SDK 进行开发,SDK 封装了认证、API 调用、数据解析等功能,简化开发流程。
// Maven 依赖
<dependency>
<groupId>com.inteagle</groupId>
<artifactId>shm-sdk</artifactId>
<version>0.3.1</version>
</dependency>
// 快速使用
InteagleClient client = InteagleClient.builder()
.apiEndpoint("https://api.shm.inteagle.com")
.credentials(accessKey, secretKey)
.build();
// 查询项目
List<Project> projects = client.projects().list();
Go SDK 即将推出,敬请期待。
| 方式 | 用途 | 协议 |
|---|---|---|
| SDK(推荐) | 项目/设备/数据查询 | HTTP |
| MQTT 订阅 | 实时数据推送 | MQTT |
| 文档 | 说明 |
|---|---|
| 核心概念 | 数据模型与业务流程 |
| 快速入门 | SDK 使用教程 |
| MQTT 订阅 | 实时数据推送 |
| 数据字典 | 字段与枚举定义 |
理解平台的核心概念有助于更高效地使用SDK和API。
Inteagle 结构健康监测平台采用三层数据模型:
graph TD
subgraph L1["第一层 - 租户层"]
A[客户 Customer]
end
subgraph L2["第二层 - 项目层"]
B[项目 Project]
end
subgraph L3["第三层 - 数据采集层"]
C1[监测点<br/>Monitoring Point<br/>业务视角]
C2[设备<br/>Device<br/>物理设备]
end
subgraph DATA["数据层"]
D1[监测点数据<br/>dx dy tilt]
D2[设备原始数据<br/>标靶坐标]
end
A -->|1:N 包含| B
B -->|1:N 包含| C1
B -->|1:N 包含| C2
C1 -->|1:N 产生| D1
C2 -->|1:N 上报| D2
C1 <-.->|N:M 多对多映射| C2
style A fill:#e1f5ff,stroke:#01579b,stroke-width:3px
style B fill:#fff4e1,stroke:#e65100,stroke-width:3px
style C1 fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
style C2 fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
style D1 fill:#e8f5e9,stroke:#1b5e20,stroke-width:1px
style D2 fill:#e8f5e9,stroke:#1b5e20,stroke-width:1px核心特点:
| 层级 | 说明 | 用途 | ID |
|---|---|---|---|
| 客户 | 租户隔离 | 数据权限控制 | cust_abc123 |
| 项目 | 监测工程 | 业务组织单元 | proj_abc123 |
| 监测点 | 业务测点 | 展示监测指标(如位移、倾斜) | pt_xyz789 |
| 设备 | 物理设备 | 采集原始数据 | dev_001 |
监测工程的顶层容器,对应一个实际的工程项目(如桥梁监测、边坡监测)。
属性:
包含:
典型项目场景:
场景 1:桥梁监测项目
graph TD
P1[桥梁监测项目]
P1 --> PT1["位移监测点 x10"]
P1 --> PT2["倾斜监测点 x4"]
P1 --> PT3["应变监测点 x8"]
P1 --> PT4["环境监测点 x2"]
P1 --> D1["设备: V2K x6, X1 x4, O1 x8"]
style P1 fill:#fff4e1
style PT1 fill:#f3e5f5
style PT2 fill:#f3e5f5
style PT3 fill:#f3e5f5
style PT4 fill:#f3e5f5
style D1 fill:#e1f5ff场景 2:隧道监测项目
graph TD
P2[隧道监测项目]
P2 --> PT1["收敛监测点 x15"]
P2 --> PT2["沉降监测点 x20"]
P2 --> D2["设备: V2K x10, X1 x5"]
style P2 fill:#e3f2fd
style PT1 fill:#f3e5f5
style PT2 fill:#f3e5f5
style D2 fill:#e1f5ff场景 3:环境监测项目
graph TD
P3[环境监测项目]
P3 --> PT1["环境监测点 x5"]
P3 --> D3["环境传感器 x5"]
style P3 fill:#e8f5e9
style PT1 fill:#f3e5f5
style D3 fill:#e1f5ff业务视角的测量点,聚合了来自设备的监测指标。
特点:
监测点类型与场景:
| 监测场景 | 监测点类型 | 典型指标 | 应用示例 |
|---|---|---|---|
| 桥梁/结构监测 | 位移监测点 | dx, dy, dz, settlement | 桥墩位移、梁体沉降 |
| 倾斜监测点 | tilt | 桥塔倾斜、墩台倾角 | |
| 应变监测点 | strain, stress | 主梁应变、关键截面应力 | |
| 裂缝监测点 | crack, crackRate | 混凝土裂缝宽度 | |
| 隧道/基坑监测 | 收敛监测点 | dx, dy | 隧道净空收敛 |
| 沉降监测点 | dz, settlement | 地表沉降、周边建筑沉降 | |
| 边坡/地质监测 | 深层位移监测点 | dz (分层) | 深层土体位移 |
| 裂缝监测点 | crack | 边坡裂缝发展 | |
| 环境监测 | 环境监测点 | temperature, humidity, pressure | 施工环境、设备工作环境 |
详细监测点类型参见 数据字典 - 监测点类型
示例 1:多设备融合 → 一个监测点(3D 空间位移)
典型应用:通过两台视觉位移计的三角测量,融合计算出 3D 空间位移。
graph TD
PT[监测点<br/>桥墩A-3D位移监测点<br/>输出: dx, dy, dz]
D1[设备1 V2W<br/>标靶1]
D2[设备2 V2W<br/>标靶1]
L1[local坐标<br/>dx1, dy1]
L2[local坐标<br/>dx2, dy2]
FUSION[三维融合算法]
D1 -->|测量| L1
D2 -->|测量| L2
L1 --> FUSION
L2 --> FUSION
FUSION -->|计算| PT
style PT fill:#fff4e1,stroke:#e65100,stroke-width:3px
style D1 fill:#e1f5ff
style D2 fill:#e1f5ff
style FUSION fill:#ffe0b2,stroke:#f57c00,stroke-width:2px两台设备各自测量标靶在自己 local 坐标系下的 dx, dy,通过三维融合算法(空间几何计算)得到 global 坐标系下的完整 3D 位移(dx, dy, dz)。
示例 2:一个设备 → 多个监测点
graph TD
D[设备 dev_001<br/>V2K 2靶位移计]
T1[标靶1]
T2[标靶2]
PT1[监测点A<br/>桥墩A位移]
PT2[监测点B<br/>桥墩B位移]
D --> T1
D --> T2
T1 --> PT1
T2 --> PT2
style D fill:#e1f5ff
style PT1 fill:#fff4e1
style PT2 fill:#fff4e1物理传感器/采集设备,上报原始测量数据。
VDM 视觉位移计系列:
所有 视觉位移计设备均基于视觉测量原理,可测量多个标靶。不同型号在视觉传感器数量(单目/双目)、云台功能(固定式/旋转式)、连接方式(有线/无线)上有所差异。
型号分类:
详细型号规格参见 数据字典 - 设备类型
遥测数据是设备上报的时序监测数据,是平台的核心数据类型。
通过 HTTP API 查询历史遥测数据时,返回按指标分组的时间序列:
| 字段 | 类型 | 说明 |
|---|---|---|
ts | Long | 时间戳(毫秒级 Unix 时间戳) |
value | Number | 测量值 |
示例:
{
"dx": [
{ "ts": 1735560000000, "value": 0.05 },
{ "ts": 1735563600000, "value": 0.06 }
],
"dy": [
{ "ts": 1735560000000, "value": 0.02 },
{ "ts": 1735563600000, "value": 0.03 }
]
}
注意:MQTT 实时推送格式不同,详见 MQTT 数据订阅。
| 约定 | 说明 |
|---|---|
| 单位 | 毫秒(milliseconds) |
| 时区 | UTC(接口返回的时间戳均为 UTC) |
| 格式 | Unix 时间戳,如 1735560000000 |
时间转换示例:
UTC 时间戳: 1735560000000
UTC 时间: 2024-12-30T12:00:00Z
北京时间: 2024-12-30 20:00:00 (UTC+8)
告警系统采用四态状态模型,支持完整的告警生命周期管理。
stateDiagram-v2
[*] --> ACTIVE_UNACK: 触发告警
ACTIVE_UNACK --> ACTIVE_ACK: 确认
ACTIVE_UNACK --> CLEARED_UNACK: 自动清除
ACTIVE_ACK --> CLEARED_ACK: 自动清除
CLEARED_UNACK --> CLEARED_ACK: 确认
CLEARED_ACK --> [*]: 归档| 状态 | 活跃 | 已确认 | 说明 |
|---|---|---|---|
ACTIVE_UNACK | ✅ | ❌ | 新告警,待处理 |
ACTIVE_ACK | ✅ | ✅ | 已确认,处理中 |
CLEARED_UNACK | ❌ | ❌ | 已恢复,未确认 |
CLEARED_ACK | ❌ | ✅ | 已恢复,已确认 |
平台采用 3A 告警级别体系:
| 级别 | 颜色 | 说明 | 典型响应 |
|---|---|---|---|
ALERT | 🟡 黄色 | 预警 | 关注,无需立即处理 |
ALARM | 🟠 橙色 | 报警 | 需要处理 |
ACTION | 🔴 红色 | 紧急 | 立即行动 |
详细告警定义参见 数据字典 - 告警级别
sequenceDiagram
participant D as 设备
participant I as Inteagle平台
participant C as 第三方云平台
D->>I: 上报遥测数据
I->>I: 检查告警规则
alt 超过阈值
I->>I: 创建告警 (ACTIVE_UNACK)
I-->>C: MQTT 推送告警
end
alt 恢复正常
I->>I: 清除告警 (CLEARED_*)
I-->>C: MQTT 推送清除
endInteagle 提供 SDK,集成了 HTTP 和 MQTT 两种通道,配合使用获取完整的数据能力。
| 通道 | 协议 | 用途 | SDK 方法 |
|---|---|---|---|
| 查询通道 | HTTP | 查询项目、监测点、设备、历史数据 | client.projects(), client.telemetry() |
| 订阅通道 | MQTT | 接收实时遥测、告警推送 | client.subscribe() |
根据您的需求选择阅读路径:
| 目标 | 推荐阅读 |
|---|---|
| 快速体验对接 | 快速入门 - SDK 使用教程 |
| 实时监控 | MQTT 订阅 - 实时数据订阅指南 |
| 了解字段含义 | 数据字典 - 完整的字段定义 |
本指南帮助您快速使用 SDK 对接 Inteagle 结构健康监测平台。
<dependency>
<groupId>com.inteagle</groupId>
<artifactId>shm-sdk</artifactId>
<version>0.3.1</version>
</dependency>dependencies {
implementation 'com.inteagle:shm-sdk:0.3.1'
}Go SDK 即将推出,敬请期待。
import com.inteagle.shm.InteagleClient;
InteagleClient client = InteagleClient.builder()
.apiEndpoint("https://api.shm.inteagle.com")
.credentials("your-access-key", "your-secret-key")
.build();
// 查询项目列表
List<Project> projects = client.projects().list();
for (Project project : projects) {
System.out.println("项目: " + project.getName());
System.out.println("ID: " + project.getId());
}
// 查询项目详情
Project project = client.projects().get("project-id");
// 查询项目下的监测点
List<MonitoringPoint> points = client.points().listByProject("project-id");
for (MonitoringPoint point : points) {
System.out.println("监测点: " + point.getName());
}
// 查询监测点详情
MonitoringPoint point = client.points().get("point-id");
// 查询项目下的设备
List<Device> devices = client.devices().listByProject("project-id");
// 查询设备详情
Device device = client.devices().get("device-id");
System.out.println("设备状态: " + (device.isOnline() ? "在线" : "离线"));
// 查询监测点最新数据
TelemetryResult latest = client.telemetry()
.entity("POINT", "point-id")
.latest();
System.out.println("dx: " + latest.getValue("dx"));
System.out.println("dy: " + latest.getValue("dy"));
// 查询历史数据
long endTs = System.currentTimeMillis();
long startTs = endTs - 24 * 60 * 60 * 1000; // 最近24小时
TelemetryResult history = client.telemetry()
.entity("POINT", "point-id")
.timeRange(startTs, endTs)
.metrics("dx", "dy")
.query();
// 查询活动告警
List<Alarm> alarms = client.alarms()
.projectId("project-id")
.status("ACTIVE")
.list();
for (Alarm alarm : alarms) {
System.out.println("告警: " + alarm.getType());
System.out.println("级别: " + alarm.getSeverity());
}
// 查询项目的告警规则
List<AlarmRule> rules = client.alarmRules()
.projectId("project-id")
.list();
for (AlarmRule rule : rules) {
System.out.println("规则: " + rule.getName());
System.out.println("启用: " + rule.isEnabled());
}
SDK 提供命令行工具 shm-cli,方便调试和测试:
# 配置凭证
shm-cli config --access-key YOUR_KEY --secret-key YOUR_SECRET
# 查询项目
shm-cli projects list
# 查询监测点
shm-cli points list --project PROJECT_ID
# 查询遥测数据
shm-cli telemetry latest --entity-type POINT --entity-id POINT_ID
# 查询告警规则
shm-cli alarm-rules list --project PROJECT_ID
Inteagle 结构健康监测平台提供 MQTT 实时数据推送服务。
| 参数 | 值 |
|---|---|
| 服务器 | broker.shm.inteagle.com |
| 端口 | 8883 (TLS) |
| 协议 | MQTT 3.1.1 / 5.0 |
| 参数 | 值 |
|---|---|
| 用户名 | 客户 ID |
| 密码 | Access Token |
| Client ID | 自定义(建议:{customerId}_{appName}) |
inteagle/{customerId}/p/{projectId} # 项目所有数据
inteagle/{customerId}/p/{projectId}/mp/{pointId} # 监测点数据
inteagle/{customerId}/p/{projectId}/d/{deviceId} # 设备数据
订阅示例:
# 项目所有数据
inteagle/cust_abc123/p/proj_abc/#
# 所有监测点
inteagle/cust_abc123/p/proj_abc/mp/+
# 单个设备
inteagle/cust_abc123/p/proj_abc/d/dev_001
所有消息包含 type 字段区分数据类型:
{
"type": "telemetry",
"ts": 1735560000000,
"payload": {
"pointId": "point_001",
"data": {"dx": 0.05, "dy": 0.02}
}
}
{
"type": "3A",
"ts": 1735560000000,
"payload": {
"id": "alm_001",
"severity": "alert",
"status": "ACTIVE_UNACK",
"originator": {"entityType": "POINT", "id": "point_001"},
"detail": {"metric": "dx", "value": 12.5, "threshold": 10.0}
}
}
import paho.mqtt.client as mqtt
import json
def on_connect(client, userdata, flags, rc):
print(f"Connected: {rc}")
client.subscribe("inteagle/cust_abc123/p/proj_abc/#")
def on_message(client, userdata, msg):
data = json.loads(msg.payload.decode())
if data['type'] == 'telemetry':
print(f"遥测: {data['payload']}")
elif data['type'] == '3A':
print(f"告警: {data['payload']['severity']}")
client = mqtt.Client()
client.username_pw_set("cust_abc123", "your_token")
client.tls_set()
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.shm.inteagle.com", 8883)
client.loop_forever()
| 数据类型 | QoS | 说明 |
|---|---|---|
| 遥测 | 0 | 允许少量丢失 |
| 告警 | 1 | 确保送达 |
项目和监测点数据是面向业务的数据视图。
inteagle/{customerId}/p/{projectId} # 项目所有数据
inteagle/{customerId}/p/{projectId}/mp/{pointId} # 监测点数据
| 参数 | 说明 | 示例 |
|---|---|---|
{customerId} | 客户 ID | cust_abc123 |
{projectId} | 监测项目 ID | proj_abc |
{pointId} | 监测点 ID | point_001 |
# 某项目所有数据
inteagle/cust_abc123/p/proj_abc/#
# 某监测点所有数据
inteagle/cust_abc123/p/proj_abc/mp/point_001
# 项目下所有监测点数据
inteagle/cust_abc123/p/proj_abc/mp/+
Topic: inteagle/{customerId}/p/{projectId}/mp/{pointId}
{
"type": "telemetry",
"ts": 1735560000000,
"payload": {
"entity": {
"type": "POINT",
"id": "point_001"
},
"disp": {
"dx": 0.05,
"dy": 0.02,
"dz": 0.01
},
"tilt": 0.5
}
}
payload 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
entity | EntityRef | 实体引用(类型 + ID) |
disp, tilt, … | Object/Number | 指标数据(按需配置) |
注意:监测点名称、项目名称等元数据通过 HTTP API 获取。
常见指标
| 指标 | 说明 | 单位 |
|---|---|---|
dx | X 方向累积位移变化 | mm |
dy | Y 方向累积位移变化 | mm |
dz | Z 方向累积位移变化 | mm |
tilt | 倾斜角 | ″(角秒) |
strain | 应变 | με |
注意:监测点指标是按需配置的,不同监测点可能包含不同的指标组合。有些数据需要从 设备实体 订阅(如视觉位移计的图片)。
告警格式参见 告警消息。
监测点告警示例:
{
"type": "3A",
"ts": 1735560000000,
"payload": {
"id": "alm_20251230_001",
"alarmType": "DISPLACEMENT_EXCEEDED",
"severity": "alert",
"status": "ACTIVE_UNACK",
"originator": {
"type": "POINT",
"id": "point_001"
},
"detail": {
"metric": "dx",
"value": 12.5,
"threshold": 10.0,
"message": "X方向位移超限"
}
}
}
如需订阅设备原始数据(环境、图像等),请参见 设备数据格式。
设备数据通过 Topic inteagle/{customerId}/p/{projectId}/d/{deviceId} 推送。
所有 MQTT 消息采用统一的包装结构:
{
"type": "telemetry | 3A | event | image | attributes",
"ts": 1735560000000,
"payload": {
...
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
type | String | 消息类型 |
ts | Long | Unix 毫秒时间戳 |
payload | Object | 具体数据内容 |
开发者可以统一解析:
const { type, ts, payload } = message;
switch(type) {
case 'telemetry': handleTelemetry(payload); break;
case '3A': handleAlarm(payload); break;
case 'event': handleEvent(payload); break;
case 'image': handleImage(payload); break;
case 'attributes': handleAttributes(payload); break;
}
| type | 说明 | payload 内容 |
|---|---|---|
telemetry | 遥测数据 | 位移、环境、状态 |
3A | 告警 | 告警详情 |
event | 事件 | 事件类型和数据 |
image | 图像 | 图片 URL 和元数据 |
attributes | 属性变更 | 变更的属性 |
{
"type": "3A",
"ts": 1735560000000,
"payload": {
"id": "alm_20251230_001",
"alarmType": "LOW_BATTERY",
"severity": "alarm",
"status": "ACTIVE_UNACK",
"originator": {
"entityType": "DEVICE",
"id": "dev_001"
},
"detail": {
"metric": "pwr.battery",
"value": 3.2,
"threshold": 3.5,
"message": "电池电压低"
}
}
}
payload 字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | String | 是 | 告警唯一标识 |
alarmType | String | 是 | 告警类型(见数据字典) |
severity | String | 是 | 告警级别 |
status | String | 是 | 告警状态 |
originator.entityType | String | 是 | 实体类型:DEVICE、POINT |
originator.id | String | 是 | 实体 ID |
detail.metric | String | 是 | 触发告警的指标 |
detail.value | Number | 否 | 触发时的实际值 |
detail.threshold | Number | 否 | 阈值 |
detail.message | String | 是 | 告警描述 |
告警级别 (severity)
| 值 | 说明 |
|---|---|
ALERT | 预警 |
ALARM | 报警 |
ACTION | 紧急 |
告警状态 (status)
| 值 | 说明 |
|---|---|
ACTIVE_UNACK | 触发未确认 |
ACTIVE_ACK | 触发已确认 |
CLEARED_UNACK | 恢复未确认 |
CLEARED_ACK | 恢复已确认 |
事件分为通用事件(所有设备)和设备事件(取决于设备能力)。
{
"type": "event",
"ts": 1735560000000,
"payload": {
"deviceId": "dev_001",
"eventType": "DEVICE_ONLINE",
"data": {}
}
}
payload 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
deviceId | String | 设备 ID |
eventType | String | 事件类型 |
data | Object | 事件相关数据 |
通用事件类型
通用事件由平台根据设备连接状态生成,不是设备主动上报的事件。
| eventType | 说明 |
|---|---|
DEVICE_ONLINE | 设备上线(平台判定) |
DEVICE_OFFLINE | 设备离线(平台判定) |
设备特有事件参见各设备文档。
{
"type": "attributes",
"ts": 1735560000000,
"payload": {
"deviceId": "dev_001",
"data": {
"firmwareVersion": "2.1.0"
}
}
}
VDM(Visual Displacement Meter)视觉位移计是 Inteagle 核心监测设备,支持多标靶位移测量。
视觉位移计设备遥测数据包含位移、环境、状态信息:
{
"type": "telemetry",
"ts": 1735560000000,
"payload": {
"entity": {
"type": "DEVICE",
"id": "dev_001"
},
"disp": {
"1": {
"dx": 0.05,
"dy": 0.02,
"dz": 0.01,
"tilt": 0.05
},
"2": {
"dx": 0.03,
"dy": 0.01
}
},
"env": {
"t": 1781686005,
"temperature": 38.57,
"humidity": 25.86,
"pressure": 1002.8
},
"status": {
"signal": {
"type": "4G",
"rssi": -75
},
"pwr": {
"battery": 3.7,
"inputDC": 12.1
},
"storage": {
"percent": 45
}
}
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
disp | Object | 按标靶 ID 组织的位移数据 |
dx, dy, dz | Number | 累积位移变化 (mm) |
tilt | Number | 倾斜变化角度(″ 角秒) |
部分 VDM 型号支持环境数据采集:
| 字段 | 类型 | 单位 | 说明 |
|---|---|---|---|
t | Integer | s | Unix 时间戳(秒) |
temperature | Number | °C | 温度 |
humidity | Number | %RH | 相对湿度 |
pressure | Number | hPa | 大气压 |
| 字段 | 类型 | 说明 |
|---|---|---|
signal.type | String | 网络类型:4G, Ethernet |
signal.rssi | Integer | 信号强度 (dBm) |
pwr.battery | Number | 电池电压 (V) |
pwr.inputDC | Number | DC 输入电压 (V) |
storage.percent | Integer | 存储使用率 (%) |
设备告警格式参见 告警消息。
视觉位移计设备告警示例
{
"type": "3A",
"ts": 1735560000000,
"payload": {
"id": "alm_20251230_001",
"alarmType": "TARGET_LOST",
"severity": "alarm",
"status": "ACTIVE_UNACK",
"originator": {
"type": "DEVICE",
"id": "dev_001"
},
"detail": {
"metric": "target_1_status",
"message": "标靶1丢失"
}
}
}
VDM 常见告警类型
| alarmType | 说明 | metric |
|---|---|---|
TARGET_LOST | 标靶丢失 | target_{n}_status |
LOW_BATTERY | 电池电压低 | pwr.battery |
LOW_VOLTAGE | DC输入电压低 | pwr.inputDC |
STORAGE_FULL | 存储空间不足 | storage.percent |
事件分为通用事件(所有设备)和设备事件(取决于设备能力)。
平台根据设备连接状态为所有设备生成在线/离线状态推送。该事件不是 VDM 设备通过设备直连 MQTT 协议主动上报的消息。
{
"type": "event",
"ts": 1735560000000,
"payload": {
"entity": {
"type": "DEVICE",
"id": "dev_001"
},
"eventType": "DEVICE_ONLINE",
"data": {}
}
}
| eventType | 说明 |
|---|---|
DEVICE_ONLINE | 设备上线(平台判定) |
DEVICE_OFFLINE | 设备离线(平台判定) |
VDM 特有的事件类型:
{
"type": "event",
"ts": 1735560000000,
"payload": {
"entity": {
"type": "DEVICE",
"id": "dev_001"
},
"eventType": "TARGET_LOST",
"data": {
"targetId": "1"
}
}
}
| eventType | 说明 | data |
|---|---|---|
TARGET_LOST | 标靶丢失 | {"targetId": "1"} |
TARGET_RECOVERED | 标靶恢复 | {"targetId": "1"} |
CALIBRATION_COMPLETE | 标定完成 | {"targetId": "1"} |
STORAGE_FULL | 存储空间已满 | {} |
VDM 支持图像采集,图片分辨率为 640x480:
{
"type": "image",
"ts": 1735560000000,
"payload": {
"entity": {
"type": "DEVICE",
"id": "dev_001"
},
"sensorId": 0,
"trigger": "snapshot",
"url": "https://storage.inteagle.com/images/...",
"ttl": 86400
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
entity | EntityRef | 实体引用 |
sensorId | Integer | 视觉传感器 ID(0 或 1) |
trigger | String | 触发类型 |
url | String | 图片下载 URL |
ttl | Integer | URL 有效期(秒) |
触发类型
| trigger | 说明 |
|---|---|
snapshot | 手动快照 |
3A | 告警触发 |
periodic | 定时拍照 |
{
"type": "attributes",
"ts": 1735560000000,
"payload": {
"entity": {
"type": "DEVICE",
"id": "dev_001"
},
"measureFrequency": 10,
"irLightEnabled": true
}
}
VDM 常见属性
| 属性 | 类型 | 说明 |
|---|---|---|
measureFrequency | Integer | 测量频率 (Hz) |
irLightEnabled | Boolean | 红外补光灯开关 |
targetCount | Integer | 标靶数量 |
firmwareVersion | String | 固件版本 |
| 指标 | 名称 | 单位 | 说明 |
|---|---|---|---|
dx | X方向位移 | mm | 水平位移 |
dy | Y方向位移 | mm | 水平位移 |
dz | Z方向位移 | mm | 竖向位移 |
settlement | 沉降量 | mm | 竖向沉降(负值) |
| 指标 | 名称 | 单位 |
|---|---|---|
tilt | 倾斜角 | ″ (角秒) |
| 指标 | 名称 | 单位 |
|---|---|---|
temperature | 温度 | °C |
humidity | 湿度 | % |
| 类型 | 说明 |
|---|---|
PROJECT | 项目 |
POINT | 监测点 |
DEVICE | 设备 |
| 级别 | 说明 | 颜色 |
|---|---|---|
ALERT | 预警 | 黄色 |
ALARM | 报警 | 橙色 |
ACTION | 紧急 | 红色 |
| 状态 | 活跃 | 已确认 |
|---|---|---|
ACTIVE_UNACK | ✅ | ❌ |
ACTIVE_ACK | ✅ | ✅ |
CLEARED_UNACK | ❌ | ❌ |
CLEARED_ACK | ❌ | ✅ |
| 类型 | 说明 |
|---|---|
DISPLACEMENT_EXCEEDED | 位移超限 |
TILT_EXCEEDED | 倾斜超限 |
SETTLEMENT_EXCEEDED | 沉降超限 |
| 类型 | 说明 |
|---|---|
DEVICE_OFFLINE | 设备离线(平台判定) |
LOW_BATTERY | 电池电量低 |
TARGET_LOST | 标靶丢失 |
| 运算符 | 说明 |
|---|---|
GT | 大于 (>) |
GTE | 大于等于 (≥) |
LT | 小于 (<) |
LTE | 小于等于 (≤) |
EQ | 等于 (=) |
| 场景 | 格式 | 示例 |
|---|---|---|
| 时间戳 | Unix 毫秒 | 1735560000000 |
| 日期 | ISO 8601 | 2025-01-08T10:30:00Z |
可能原因:
解决: 确认凭证正确,联系管理员重新获取。
诊断:
// 使用 CLI 验证资源是否存在
shm-cli projects list
shm-cli points list --project PROJECT_ID
解决:
try {
client.telemetry().query(query);
} catch (RateLimitException e) {
Thread.sleep(e.getRetryAfterMs());
// 重试
}
| 错误码 | 含义 | 解决 |
|---|---|---|
| 4 | 用户名密码错误 | 检查客户 ID 和凭证 |
| 5 | 未授权 | 确认账号有 MQTT 权限 |
诊断:
# 测试端口连通性
openssl s_client -connect broker.shm.inteagle.com:8883
检查:
inteagle/{customerId}/p/{projectId}/## 测试是否有任何消息解决:
API 返回毫秒时间戳,转换时需除以 1000:
Instant instant = Instant.ofEpochMilli(ts);
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
检查:
endTs > startTs请联系技术支持。
本章节介绍 Inteagle 支持的设备类型及其技术参数。
| 类型 | 说明 | 文档 |
|---|---|---|
| 视觉位移计(VDM) | 非接触式位移监测设备 | 查看详情 → |
| 应变读数仪 | 高频应变监测设备 | 查看详情 → |
| 倾角振动传感器 | 倾角、振动和环境状态监测设备 | 查看详情 → |
视觉位移计是 Inteagle 研发的非接触式位移监测设备,可以实时监测目标结构物的位移变化。
设备连接系统集成商 MQTT Broker,支持 Protobuf(推荐)和 JSON。
| 文档 | 说明 |
|---|---|
| 快速入门 | 配置连接、接收位移数据、调用设备接口 |
| API 参考 | Protobuf / JSON 字段、API 支持矩阵与错误码 |
| 告警定义 | 3A 等级、告警类型、生命周期、规则参数与消息示例 |
| GitHub MQTT 示例 | 位移接收、RPC、告警抓拍示例及各语言 SDK |
| 型号 | 视觉传感器 | 云台类型 | 说明 |
|---|---|---|---|
| V1 | 单目 | 无 | 固定式,基础款 |
| V1 Pro | 单目 | 无 | 固定式,高性能款 |
| V1 Lite | 单目 | 无 | 固定式,轻量款 |
| V2-H | 双目 | 无 | 固定式,双目配置 |
| V2-W | 双目 | 无 | 固定式,视野加倍 |
| V2-K | 双目 | 无 | 固定式,安装时可自由选择视野角度 |
| O1 | 单目 | 单轴 | 旋转式,仅水平方向可旋转 |
| O2-H | 双目 | 单轴 | 旋转式,仅水平方向可旋转 |
| X1 | 单目 | 双轴 | 旋转式,水平和竖向方向均可旋转 |
| X2-H | 双目 | 双轴 | 旋转式,水平和竖向方向均可旋转 |
说明:
- 旋转式型号具有巡航监测功能
- 双目型号有
sensorId参数
本页按“准备设备 → 启动接收端 → 配置设备连接 → 验证数据 → 调用 RPC → 接收告警抓拍”的顺序完成一次接入。
设备和接收端连接的是同一个系统集成商 MQTT Broker。接收端只负责订阅和调用;Broker 地址、端口及认证信息由系统集成商提供。
在 App 中完成设备的标靶配置和初始化,记下设备 ID。验证位移前,设备必须处于测量状态并能看到有效标靶。
在能够访问 Broker 的电脑或服务器上安装 Git、Docker 和 Docker Compose v2。以下命令在 Bash 终端执行。
先在接收端所在的电脑或服务器上下载示例,并填写系统集成商提供的 Broker 域名或 IP、端口,以及设备 ID:
git clone https://github.com/inteagle-vision/inteagle-vdm-mqtt-examples.git
cd inteagle-vdm-mqtt-examples
export VDM_DEVICE_ID=YOUR_DEVICE_ID
export MQTT_HOST=YOUR_BROKER_HOST
export MQTT_PORT=1883 # 替换为 Broker 的实际端口
是否需要认证及认证信息由系统集成商指定。需要用户名、密码时,填写分配给接收程序的账号:
export MQTT_USERNAME=YOUR_USERNAME
export MQTT_PASSWORD=YOUR_PASSWORD
选择数据格式并启动:
export VDM_PAYLOAD_FORMAT=protobuf
./run_demo.sh protobuf
export VDM_PAYLOAD_FORMAT=json
./run_demo.sh json
脚本在后台启动接收程序并连接上述 Broker。保持这些服务运行,再配置设备端连接;以下命令均在仓库根目录执行。
在 App 中添加系统集成商 MQTT 连接:
| 配置 | 填写内容 |
|---|---|
| Broker 地址 | 系统集成商提供的域名或 IP,公网、内网均可 |
| 端口 | 系统集成商指定的 MQTT 端口 |
| 用户名、密码 | 按系统集成商为设备分配的认证信息填写;是否需要认证以接入要求为准 |
| Payload | 第 2 步选择的 Protobuf 或 JSON |
保存并启用连接。设备连接成功后,向 vdm/{deviceId}/telemetry 发布位移,接收程序订阅同一设备的主题。设备端 Payload 必须与接收程序选择的格式一致。
查看接收程序的输出:
docker compose logs -f python-data go-data java-data javascript-data
READY 只表示订阅已建立,不代表设备已经上报数据。看到包含标靶 ID 和非空位移数组的 telemetry 行,才表示位移链路已打通。例如:
{
"schemaVersion": 1,
"displacement": {
"sampleFrequencyHz": 2,
"firstSampleTimestampMs": "1734567890000",
"targets": [{"targetId": "T01", "dx": [0.01, 0.02], "dy": [0.0, 0.01]}]
}
}
{
"disp": {
"t": 1734567890,
"f": 2,
"d": {"T01": {"dx": [0.01, 0.02], "dy": [0.0, 0.01]}}
}
}
T01 是示例标靶 ID,X / Y 位移单位为 mm;2 Hz 表示数组中相邻样本相隔 0.5 秒。Protobuf 的首个样本时间使用 Unix 毫秒,JSON 使用 Unix 秒。
确认接收程序收到包含标靶 ID 和位移数组的消息。telemetry 还可能包含环境和设备状态,完整字段见 遥测数据。按 Ctrl+C 只退出日志查看,后台接收程序仍会运行。
位移数据正常后,任选一种语言发送一次 RPC(远程调用),查询设备 ID、型号、固件版本和测量状态:
| 语言 | 在当前终端执行 |
|---|---|
| Java | docker compose run --rm --no-deps java-data --query-attributes |
| Go | docker compose run --rm --no-deps go-data --query-attributes |
| Python | docker compose run --rm --no-deps python-data --query-attributes |
| JavaScript | docker compose run --rm --no-deps javascript-data --query-attributes |
看到 RESPONSE 且 code=0,说明请求已到达设备并收到成功响应。程序随后继续接收数据;按 Ctrl+C 退出本次运行。
请求发送到 vdm/{deviceId}/rpc/req,响应来自 vdm/{deviceId}/rpc/resp。后续可调用标靶管理接口和测量控制接口,完整格式见 RPC 格式。
位移和 RPC 接通后,再配置告警。按 告警配置示例查询能力、创建规则,并订阅 vdm/{deviceId}/3A。等级和参数见 告警参考。
需要抓拍时,为规则配置 SNAPSHOT 动作。仅配置一个已启用的系统集成商 MQTT 连接,且未另行指定或关闭抓拍上传时,设备默认向该连接发送;多个连接时需指定接收目标。
启动抓拍接收程序:
./run_demo.sh "$VDM_PAYLOAD_FORMAT" --evidence
docker compose logs -f python-evidence go-evidence java-evidence javascript-evidence
各接收程序独立保存图像包,校验通过后调用 ackEvidencePackage。VERIFIED 表示完整包校验通过,ACKED 表示设备已接受确认。完整代码、保存位置与补传方法见 抓拍接入说明。
| 现象 | 检查项 |
|---|---|
| 设备无法连接 Broker | 设备端填写的 Broker 域名或 IP、端口、认证信息及网络连通性 |
| 程序就绪但没有消息 | App 中连接是否在线、设备 ID 和 Payload 格式是否正确 |
| 有环境数据但没有位移 | 设备是否正在测量,标靶是否已初始化并有有效观测 |
| 消息解析失败 | 设备与接收程序所选格式是否一致 |
| RPC 超时 | 设备是否在线,是否允许请求 Topic 发布和响应 Topic 订阅 |
测试结束后执行 docker compose --profile evidence down 停止服务。抓拍文件保留在 Docker 数据卷中。
在本机运行单一语言时,参见 GitHub SDK 与运行步骤。
需要自行搭建联调 Broker 时,参见 NanoMQ 联调环境。
本文按“连接与消息格式 → 主题 → RPC → 遥测 → 告警与抓拍 → 错误码”的顺序组织。接入时先阅读连接参数、RPC 格式和主题结构,再按需要查阅具体接口。
| 参数 | 说明 |
|---|---|
| 协议 | MQTT v3.1.1 |
| Payload | Protobuf(推荐)/ JSON |
RPC 请求发布到 vdm/{deviceId}/rpc/req,响应从 vdm/{deviceId}/rpc/resp 接收。
请求结构:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=1)
request.get_targets.SetInParent()
payload = request.SerializeToString(deterministic=True)
{"reqId": 1, "method": "getTargets", "params": {}}
| Protobuf 字段 | JSON 字段 | 必填 | 说明 |
|---|---|---|---|
req_id | reqId | 是 | 请求 ID。必须是非零 32-bit signed integer;设备会在响应中原样返回 |
request oneof | method | 是 | RPC 方法;每条请求只设置一个 oneof 字段 |
| oneof 中的方法消息 | params | 否 | RPC 参数;无参数的方法使用 Empty |
调用限制:
4 时,应退避重试,不要立即循环重发。响应结构:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
response = pb.RpcResponse()
response.ParseFromString(response_payload) # rpc/resp 收到的 Payload
assert response.schema_version == 1
assert response.req_id == 1
assert response.code == 0
targets = response.get_targets.targets
{"reqId": 1, "code": 0, "data": {"targets": []}}
| Protobuf 字段 | JSON 字段 | 说明 |
|---|---|---|
req_id | reqId | 请求 ID,和请求中的 ID 一致 |
code | code | 结果码,0 表示成功,非 0 表示失败 |
response oneof | data | 方法对应的响应数据;成功时必须与请求方法一致 |
失败响应不携带方法数据;成功且无返回数据时,JSON 省略 data。错误说明见错误码。
请求和响应通过 req_id 关联。同一连接中,尚未收到响应的请求不得复用 req_id;重复 ID 会被拒绝。
| 主题 | 方向 | 说明 | Protobuf 消息类型 |
|---|---|---|---|
vdm/{deviceId}/rpc/req | 下行 | RPC 指令 | inteagle.vdm.mqtt.v1.RpcRequest |
vdm/{deviceId}/rpc/resp | 上行 | RPC 响应 | inteagle.vdm.mqtt.v1.RpcResponse |
vdm/{deviceId}/telemetry | 上行 | 遥测数据 | inteagle.vdm.mqtt.v1.Telemetry |
vdm/{deviceId}/attributes | 上行 | 属性上报 | inteagle.vdm.mqtt.v1.Attributes |
vdm/{deviceId}/event | 上行 | 事件上报 | inteagle.vdm.mqtt.v1.Event |
vdm/{deviceId}/3A | 上行 | 告警上报 | inteagle.vdm.mqtt.v1.Alarm |
vdm/{deviceId}/image | 上行 | 普通图片或告警抓拍图像包分块 | 不使用 Protobuf,按首字节区分类型 1/2 |
| 文件 | 用途 |
|---|---|
| inteagle_vdm_mqtt_v1.proto | VDM 遥测、属性、事件、告警和 RPC 定义 |
| inteagle_customer_mqtt_v1.desc | VDM descriptor set |
| inteagle_customer_mqtt_v1.proto.sha256 | .proto 文件校验值 |
| inteagle_customer_mqtt_v1.desc.sha256 | descriptor set 校验值 |
声明 schema_version 的 V1 根消息必须设置为 1。Python 项目可以直接使用已生成的 pb2 文件 和 package 文件。
完整代码见 GitHub SDK;告警配置运行步骤见 告警接入示例。
| Protobuf 字段 | JSON 字段 | 类型 | 约束 |
|---|---|---|---|
target_id | targetId | string | 标靶 ID,1-64 字节;去除前后空白后不能为空,不能包含控制字符,同一请求内不能重复 |
sensor_id | sensorId | uint32 | 视觉传感器 ID。单目设备通常为 0;双目设备为 0 或 1 |
roi.x / roi.y | 相同 | uint32 | ROI 左上角像素坐标;坐标基于原始相机画面 |
roi.width / roi.height | 相同 | uint32 | ROI 宽高,必须大于 0,且 ROI 应落在当前画面范围内 |
distance_m | distance | float | 标靶到设备的测量距离,单位 m,必须大于等于 0.1 |
role | role | enum | 标靶角色,枚举见下表;新建时默认 MP |
target_model | targetModel | enum | 标靶型号,枚举见下表 |
skip_measurement | skipMeasurement | bool | 是否跳过测量。false 或不传表示参与测量;true 表示保留配置但测量流程跳过该标靶 |
role 枚举含义:
| Protobuf 值 | JSON 值 | 名称 | 说明 |
|---|---|---|---|
TARGET_ROLE_RP | RP | Reference Point | 基准点,作为位移计算参考,通常布置在稳定区域 |
TARGET_ROLE_MP | MP | Measuring Point | 测点,普通待测标靶,默认角色 |
TARGET_ROLE_CP | CP | Control Point | 控制点,用于监测或补偿系统漂移,通常布置在稳定区域 |
role 使用建议:
MP 是默认和最常用角色。需要持续输出位移的被测位置,例如梁体、塔体、边坡或结构构件上的监测标靶,通常设置为 MP。RP 用作基准点。只有同一视野内存在相对稳定、不随被测体移动的标靶时,才建议设置为 RP;如果现场没有可靠稳定参考点,不要强行设置 RP。CP 用作控制点或校核点。通常布置在稳定位置,用来观察安装稳定性、温漂、整体漂移或测量质量;它不是默认的主测点。role,设备按 MP 处理。target_id 未设置时,支持自动生成 ID 的接口会由设备生成 UUID;JSON 对应字段为 targetId。
targetModel 枚举含义:
| Protobuf 值 | JSON 值 | 说明 |
|---|---|---|
TARGET_MODEL_T10 | T10 | T10 标靶型号 |
TARGET_MODEL_T20 | T20 | T20 标靶型号 |
TARGET_MODEL_T50 | T50 | T50 标靶型号 |
TARGET_MODEL_T100 | T100 | T100 标靶型号 |
TARGET_MODEL_T200 | T200 | T200 标靶型号 |
对指定标靶执行参考位置初始化/标定。设备会根据保存的标靶配置采集图像并计算初始参考位置;请求中也可以提供 ROI、测量距离、视觉传感器或标靶型号作为本次初始化的覆盖值。调用前应保证 ROI 已对准标靶,且设备没有正在进行其它测量或初始化流程。
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
targets | targets | repeated | 是 | 要初始化标靶参考位置的标靶数组,不能为空,最多 128 个 |
targets[].target_id | targets[].targetId | string | 是 | 标靶 ID,遵循公共字段约束;用于绑定初始化结果和后续位移数据 |
targets[].sensor_id | targets[].sensorId | optional uint32 | 否 | 视觉传感器 ID。不传时使用已保存配置;单目设备默认 0,双目设备建议显式传 0 或 1 |
targets[].roi | targets[].roi | Roi | 否 | 标靶 ROI;未保存标靶配置时必须提供 |
targets[].distance_m | targets[].distance | optional float | 否 | 测量距离,单位 m;未保存标靶配置时必须提供 |
targets[].target_model | targets[].targetModel | optional enum | 否 | 型号枚举见公共字段约束;未保存且未传入时默认 T100 |
标靶增删改请使用 addTargets、setTargets 或 deleteTargets。角色和跳过测量状态使用 addTargets 或 setTargets 配置。
最简请求与带覆盖值的请求:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
minimal = pb.RpcRequest(schema_version=1, req_id=1)
minimal.init_ref_targets.targets.add(target_id="1")
minimal_payload = minimal.SerializeToString(deterministic=True)
request = pb.RpcRequest(schema_version=1, req_id=2)
request.init_ref_targets.targets.add(
target_id="1",
sensor_id=0,
roi=pb.Roi(x=1000, y=500, width=400, height=400),
distance_m=5.0,
target_model=pb.TARGET_MODEL_T100,
)
payload = request.SerializeToString(deterministic=True)
{
"reqId": 1,
"method": "initRefTargets",
"params": {
"targets": [
{
"targetId": "1"
}
]
}
}
独立请求:
{
"reqId": 2,
"method": "initRefTargets",
"params": {
"targets": [
{
"targetId": "1",
"sensorId": 0,
"roi": {
"x": 1000,
"y": 500,
"width": 400,
"height": 400
},
"distance": 5.0,
"targetModel": "T100"
}
]
}
}
成功时,RpcResponse.code == 0 且 response.HasField("init_ref_targets")。
成功响应表示设备已启动参考位置初始化任务;最终结果通过 event 主题上报。若至少一个标靶初始化成功,设备会同时通过 attributes 主题上报当前 target_list 摘要,initialized_at_s 为 Unix 秒时间戳。
在已有标靶基础上添加新标靶。
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
targets | targets | repeated | 是 | 标靶配置数组,不能为空,最多 128 个 |
targets[].target_id | targets[].targetId | optional string | 否 | 不设置时由设备生成 UUID |
targets[].sensor_id | targets[].sensorId | optional uint32 | 双目设备必填 | 单目设备默认 0 |
targets[].roi | targets[].roi | Roi | 是 | 标靶 ROI 区域 |
targets[].distance_m | targets[].distance | float | 是 | 测量距离,单位 m |
targets[].role | targets[].role | optional enum | 否 | 角色枚举见公共字段约束;默认 MP |
targets[].target_model | targets[].targetModel | optional enum | 否 | 型号枚举见公共字段约束 |
targets[].skip_measurement | targets[].skipMeasurement | optional bool | 否 | 是否跳过测量,默认 false |
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=3)
request.add_targets.targets.add(
target_id="2",
sensor_id=0,
roi=pb.Roi(x=800, y=400, width=400, height=400),
distance_m=6.0,
role=pb.TARGET_ROLE_MP,
target_model=pb.TARGET_MODEL_T100,
skip_measurement=False,
)
payload = request.SerializeToString(deterministic=True)
# 解析成功响应后读取新增标靶 ID
response = pb.RpcResponse.FromString(response_payload)
added_ids = list(response.add_targets.added_target_ids)
{
"reqId": 3,
"method": "addTargets",
"params": {
"targets": [
{
"targetId": "2",
"sensorId": 0,
"roi": {
"x": 800,
"y": 400,
"width": 400,
"height": 400
},
"distance": 6.0,
"role": "MP",
"targetModel": "T100",
"skipMeasurement": false
}
]
}
}
获取当前标靶列表。请求使用 Empty,成功响应返回强类型 TargetInfo:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=4)
request.get_targets.SetInParent()
payload = request.SerializeToString(deterministic=True)
response = pb.RpcResponse.FromString(response_payload)
for target in response.get_targets.targets:
initialized_at = target.initialized_at_s if target.HasField("initialized_at_s") else None
print(target.target_id, target.distance_m, target.role, initialized_at)
{
"reqId": 4,
"method": "getTargets",
"params": {}
}
| Protobuf 字段 | JSON 字段 | 说明 |
|---|---|---|
targets[].target_id | targets[].targetId | 标靶 ID |
targets[].sensor_id | targets[].sensorId | 视觉传感器 ID |
targets[].roi | targets[].roi | 标靶 ROI |
targets[].distance_m | targets[].distance | 测量距离,单位 m |
targets[].role | targets[].role | 标靶角色枚举 |
targets[].target_model | targets[].targetModel | 标靶型号枚举 |
targets[].skip_measurement | targets[].skipMeasurement | 是否跳过测量 |
targets[].initialized | targets[].initialized | 是否已经初始化参考位置 |
targets[].initialized_at_s | targets[].initializedAt | optional Unix 秒时间戳 |
按 target_id 修改已有标靶。每个元素除 target_id 外,至少设置 sensor_id、roi、distance_m、role、target_model、skip_measurement 中的一个更新字段。
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
targets | targets | repeated | 是 | 标靶配置数组,不能为空,最多 128 个 |
targets[].target_id | targets[].targetId | string | 是 | 要更新的标靶 ID |
targets[].sensor_id | targets[].sensorId | optional uint32 | 否 | 更新视觉传感器 ID |
targets[].roi | targets[].roi | optional Roi | 否 | 更新 ROI 区域 |
targets[].distance_m | targets[].distance | optional float | 否 | 更新测量距离,单位 m |
targets[].role | targets[].role | optional enum | 否 | 更新 MP、RP 或 CP 角色 |
targets[].target_model | targets[].targetModel | optional enum | 否 | 更新 T10、T20、T50、T100 或 T200 型号 |
targets[].skip_measurement | targets[].skipMeasurement | optional bool | 否 | 更新是否跳过测量 |
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=5)
request.set_targets.targets.add(
target_id="2",
distance_m=6.5,
role=pb.TARGET_ROLE_CP,
target_model=pb.TARGET_MODEL_T200,
skip_measurement=True,
)
payload = request.SerializeToString(deterministic=True)
{
"reqId": 5,
"method": "setTargets",
"params": {
"targets": [
{
"targetId": "2",
"distance": 6.5,
"role": "CP",
"targetModel": "T200",
"skipMeasurement": true
}
]
}
}
成功响应必须设置 response.set_targets;未出现在请求中的 optional 字段不会被修改。
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
target_ids | targetIds | repeated string | 是 | 要删除的标靶 ID,不能为空,最多 128 个且不能重复 |
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=6)
request.delete_targets.target_ids.append("2")
payload = request.SerializeToString(deterministic=True)
{
"reqId": 6,
"method": "deleteTargets",
"params": {
"targetIds": [
"2"
]
}
}
成功响应必须设置 response.delete_targets。
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
keys | keys | repeated string | 否 | 最多 32 个且不能重复;空列表返回全部基础属性。key 名沿用公开属性名,例如 deviceId、deviceStatus、measureStatus、sampleFreq |
status 是 measureStatus 的兼容别名。
deviceStatus 是设备整体工作状态,独立于 measureStatus(测量状态)。设备进入低功耗前,JSON 属性上报 "deviceStatus":"Sleeping";Protobuf 使用 Attributes.device_status = DEVICE_STATUS_SLEEPING。设备唤醒启动后会上报 Idle。deviceStatus 只读,不能通过 setAttr 设置。
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=7)
request.get_attr.keys.extend([
"deviceId", "deviceStatus", "measureStatus", "sampleFreq", "showROI", "showTs", "showSensorId",
])
payload = request.SerializeToString(deterministic=True)
response = pb.RpcResponse.FromString(response_payload)
attrs = response.get_attr.attributes
print(attrs.device_id, attrs.device_status, attrs.measurement_status, attrs.sample_frequency_hz)
{
"reqId": 7,
"method": "getAttr",
"params": {
"keys": [
"deviceId",
"deviceStatus",
"measureStatus",
"sampleFreq",
"showROI",
"showTs",
"showSensorId"
]
}
}
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
sample_frequency_hz | sampleFreq | optional uint32 | 否 | 采样频率,单位 Hz,范围 1-60 |
report_metrics.values | reportMetrics | repeated enum | 否 | 当前只接受 REPORT_METRIC_DX 和 REPORT_METRIC_DY,不能为空且不能重复;缺省为两者都上报 |
show_roi | showROI | optional bool | 否 | 告警抓拍图像是否叠加 ROI |
show_timestamp | showTs | optional bool | 否 | 告警抓拍图像是否叠加时间戳 |
show_sensor_id | showSensorId | optional bool | 否 | 告警抓拍图像是否叠加视觉传感器 ID |
target_list 会在标靶配置变化时通过 attributes 主题上报,也可以通过 getTargets 查询;getAttr 不主动返回标靶列表。JSON 对应字段为 targets。
SetAttributesRequest 必须至少设置一个可写字段。设备 ID、型号、固件版本、分辨率、测量状态和标靶列表为只读字段,不能通过 setAttr 修改。
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=8)
request.set_attr.sample_frequency_hz = 5
request.set_attr.report_metrics.values.extend([pb.REPORT_METRIC_DX, pb.REPORT_METRIC_DY])
request.set_attr.show_roi = True
request.set_attr.show_timestamp = True
request.set_attr.show_sensor_id = True
payload = request.SerializeToString(deterministic=True)
{
"reqId": 8,
"method": "setAttr",
"params": {
"sampleFreq": 5,
"reportMetrics": [
"dx",
"dy"
],
"showROI": true,
"showTs": true,
"showSensorId": true
}
}
使用 NTP 同步设备系统时间。同步成功后,设备会保存本次使用的 NTP 服务器配置。
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
ntp_server | ntpServer | optional string | 否 | NTP 服务器;不传时使用 ntp.aliyun.com,最长 253 字节且不能包含空白 |
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
default_ntp = pb.RpcRequest(schema_version=1, req_id=9)
default_ntp.sync_time.SetInParent()
request = pb.RpcRequest(schema_version=1, req_id=10)
request.sync_time.ntp_server = "ntp.aliyun.com"
payload = request.SerializeToString(deterministic=True)
{
"reqId": 9,
"method": "syncTime",
"params": {}
}
独立请求:
{
"reqId": 10,
"method": "syncTime",
"params": {
"ntpServer": "ntp.aliyun.com"
}
}
如果 NTP 服务器不可达、地址格式不合法或同步失败,设备返回非 0 code。该接口会触发网络同步和本地配置保存,属于受限流保护的写操作。
这些接口使用 Empty 请求消息:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
start = pb.RpcRequest(schema_version=1, req_id=11)
start.start_measurement.SetInParent()
stop = pb.RpcRequest(schema_version=1, req_id=12)
stop.stop_measurement.SetInParent()
reboot = pb.RpcRequest(schema_version=1, req_id=13)
reboot.reboot.SetInParent()
{
"reqId": 11,
"method": "startMeasurement",
"params": {}
}
独立请求:
{
"reqId": 12,
"method": "stopMeasurement",
"params": {}
}
独立请求:
{
"reqId": 13,
"method": "reboot",
"params": {}
}
startMeasurement 和 stopMeasurement 会触发 attributes 主题上报 measurement_status;JSON 对应字段为 measureStatus。低功耗休眠前上报独立的 device_status;JSON 对应 deviceStatus。设备断电前的上报是有界尽力发送,没有逐条云端确认;设备离线并不单独证明其处于休眠。reboot 成功后设备会断开并重新连接 MQTT,调用方应等待设备重新上线。
单灯或所有灯使用统一亮度:
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
all_lights_level | level | uint32 | 是 | 所有补光灯统一亮度挡位,范围 0-8 |
双目设备需要分别设置多路补光灯时,也可以传 lights:
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
per_light.lights | lights | repeated | 是 | 补光灯配置数组,不能为空,最多 16 个 |
lights[].light_id | lights[].id | uint32 | 是 | 补光灯 ID |
lights[].level | lights[].level | uint32 | 是 | 亮度挡位,范围 0-8 |
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
all_lights = pb.RpcRequest(schema_version=1, req_id=14)
all_lights.set_light_level.all_lights_level = 4
per_light = pb.RpcRequest(schema_version=1, req_id=15)
per_light.set_light_level.per_light.lights.add(light_id=0, level=3)
per_light.set_light_level.per_light.lights.add(light_id=1, level=6)
{
"reqId": 14,
"method": "setLightLevel",
"params": {
"level": 4
}
}
独立请求:
{
"reqId": 15,
"method": "setLightLevel",
"params": {
"lights": [
{
"id": 0,
"level": 3
},
{
"id": 1,
"level": 6
}
]
}
}
getLightLevel 使用 Empty 请求;响应通过 WhichOneof("selection") 判断返回统一亮度还是逐灯数组:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=16)
request.get_light_level.SetInParent()
response = pb.RpcResponse.FromString(response_payload)
selection = response.get_light_level.WhichOneof("selection")
{
"reqId": 16,
"method": "getLightLevel",
"params": {}
}
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
sensor_id | sensorId | optional uint32 | 否 | 视觉传感器 ID,单目设备默认 0 |
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=17)
request.snapshot.sensor_id = 0
payload = request.SerializeToString(deterministic=True)
{
"reqId": 17,
"method": "snapshot",
"params": {
"sensorId": 0
}
}
snapshot RPC 成功响应只表示已触发抓图;JPEG 二进制图片通过 vdm/{deviceId}/image 主题上报。当前标准快照图片由设备侧处理为 640x480。
showROI、showTs 和 showSensorId 控制告警抓拍图像的叠加内容,不影响 snapshot 普通快照。
电机参数见 O1、O2-H、X1和 X2-H;ISP 参数见 X1。
支持 getStatus、setConfig 和 setExposurePreset 三个 action。
setConfig 的曝光时间、增益和旋转角度必须满足型号页面声明的范围;旋转角度只能为
0、90、180 或 270,单相机增益范围为 1024..16384。
ispCtl 成功时只由外层 code=0 表示成功,不重复返回 data.success。按 action 和设备能力,data 只可能包含
vdmModeEnabled、exposureLocked、exposureMode、nrLevel、enable3dnr、maxGain、
exposurePreset、exposureInfo、cameraCount、flip、mirror、rotation、frameWidth
和 frameHeight;exposureInfo 只包含 iso、expTime、aGain、dGain、ispDGain
和 aveLum。操作失败统一通过外层非零 code 返回,不携带 data。
getCruisePaths 成功时,JSON data 与 Protobuf get_cruise_paths.data 表示相同的数组结构:
[
{
"id": 1,
"enabled": true,
"order": 10,
"cruisePoints": [
{"id": 1, "targets": ["T01"], "xAngle": 45.0, "yAngle": -5.0}
]
}
]
路径只返回 id、enabled、order、cruisePoints;巡航点只返回 id、targets、
xAngle 和 yAngle。
仅配置一个已启用的系统集成商 MQTT 连接,且未另行指定或关闭抓拍上传时,设备默认向该连接发送告警抓拍。规则须配置 SNAPSHOT 动作;多个系统集成商 MQTT 连接时需指定接收目标。系统集成商平台校验并保存图像包后调用 ackEvidencePackage 确认。
告警抓拍图像操作使用对应告警的 eventId。
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
event_id | eventId | uint64 | 是 | 触发抓拍的告警状态变化 ID;JSON 建议用十进制字符串保持精度 |
kind | kind | optional EvidenceKind | 否 | 未设置时默认为 SNAPSHOT |
getEvidenceStatus 查询该次告警抓拍图像的处理结果;retryEvidence 请求设备重新发送对应图像包。两者都返回 EvidenceStatusResponse:found=false 表示未找到,found=true 时通过协议字段 evidence 返回 AlarmEvidence。
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
status_request = pb.RpcRequest(schema_version=1, req_id=80)
status_request.get_evidence_status.event_id = 9001
status_request.get_evidence_status.kind = pb.EVIDENCE_KIND_SNAPSHOT
retry_request = pb.RpcRequest(schema_version=1, req_id=81)
retry_request.retry_evidence.event_id = 9001
retry_request.retry_evidence.kind = pb.EVIDENCE_KIND_SNAPSHOT
{
"reqId": 80,
"method": "getEvidenceStatus",
"params": {
"eventId": "9001",
"kind": "SNAPSHOT"
}
}
独立请求:
{
"reqId": 81,
"method": "retryEvidence",
"params": {
"eventId": "9001",
"kind": "SNAPSHOT"
}
}
| Protobuf 字段 | JSON 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
event_id | eventId | uint64 | 是 | 触发抓拍的告警事件 ID |
kind | kind | EvidenceKind | 是 | 抓拍图片使用 SNAPSHOT |
package_sha256 | packageSha256 | string | 是 | 类型 2 Header 中 32 字节 packageSha256 的 64 位小写十六进制字符串 |
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
ack_request = pb.RpcRequest(schema_version=1, req_id=82)
ack_request.ack_evidence_package.event_id = 9001
ack_request.ack_evidence_package.kind = pb.EVIDENCE_KIND_SNAPSHOT
ack_request.ack_evidence_package.package_sha256 = "0" * 64 # 替换为 Header 中的实际值
{
"reqId": 82,
"method": "ackEvidencePackage",
"params": {
"eventId": "9001",
"kind": "SNAPSHOT",
"packageSha256": "0000000000000000000000000000000000000000000000000000000000000000"
}
}
只有完整 USTAR 图像包已持久化且通过长度、SHA-256 和成员安全校验时才能确认。设备只接受从原始接收该图像包的同一逻辑 MQTT 连接发出的 ACK。
先了解告警等级与生命周期,再查询能力、配置规则并接收告警。相关 RPC 如下:
| 方法 | RpcRequest/RpcResponse oneof 字段 | 字段号 |
|---|---|---|
getAlarmCaps | get_alarm_caps | 90 |
listAlarmRules | list_alarm_rules | 91 |
applyAlarmRules | apply_alarm_rules | 92 |
getAlarmState | get_alarm_state | 93 |
listAlarmHistory | list_alarm_history | 94 |
设备级电压规则不传 targetIds,详情包含电压和阈值。标靶级规则的选择范围以 getTargets 和 getAlarmCaps 为准。
get_alarm_caps.api_version / data.apiVersion 是告警管理接口版本,区别于 Protobuf 根消息的 schema_version=1。alarm_service_ready / alarmServiceReady 表示告警服务就绪,alarm_history_ready / alarmHistoryReady 表示历史查询可用;能力响应中的 levels、transitions 和 rule_types / ruleTypes 决定客户端可提供的选项。
| 方法 | 请求参数(Protobuf / JSON) | 响应与处理方式 |
|---|---|---|
getAlarmCaps | 空请求 | 返回服务就绪状态、规则类型、等级、动作及资源上限 |
listAlarmRules | 可选 cursor / cursor | items 为规则列表;返回 next_cursor / nextCursor 时继续分页,不自行解析游标;配置变化导致的分页冲突使用外层 code=6,此时从首页重查 |
getAlarmState | 空请求 | active 只包含当前活动告警;每项返回生命周期 ID、规则 ID、类型和当前等级;标靶 ID 对应 active[].target_id / active[].detail.targetId,设备级电压告警无此字段 |
listAlarmHistory | 可选 cursor、limit、alarm_id / cursor、limit、alarmId | items 按生命周期返回记录,包含该生命周期的最近一次转换;不是完整的逐事件列表。alarmId 在两种格式的查询请求中都使用十进制字符串;分页使用 next_cursor / nextCursor |
listAlarmHistory.limit 缺省为 20,设备将传入值限制在 1~50;alarmId 与 cursor 不能同时传入。
历史记录的 state 为 ALARM_INCIDENT_STATE_ACTIVE=1 / ACTIVE 或 ALARM_INCIDENT_STATE_CLEARED=2 / CLEARED。结束记录省略 level,通过 transition 区分恢复与取消。last_event_id / lastEventId 对应最近一次状态变化,可与 3A 的 eventId 关联;历史 ID 字段在两种格式中均为十进制字符串。
时间单位不能混用: 3A 的 ts 是 Unix 秒;历史中的 started_at / startedAt、updated_at / updatedAt、cleared_at / clearedAt 均为 Unix 毫秒。历史抓拍摘要的 captured_at / capturedAt、updated_at / updatedAt 也保持毫秒。
所有配置操作都调用 applyAlarmRules,请求发到 vdm/{deviceId}/rpc/req,响应从 vdm/{deviceId}/rpc/resp 接收。建议依次执行:getAlarmCaps 查询能力 → getTargets 确认标靶 → listAlarmRules 获取现有完整规则 → applyAlarmRules 提交 → listAlarmRules 回读。
| Protobuf 请求字段 | JSON params 字段 | 类型 | 说明 |
|---|---|---|---|
apply_alarm_rules.upsert | upsert | 规则数组 | 新增或完整替换指定规则;每项 Protobuf AlarmRuleDefinition 只设置一个规则分支 |
apply_alarm_rules.delete_ids | deleteIds | uint32 数组 | 删除指定已有规则,ID 必须非零且不重复 |
upsert 和 deleteIds 可同时提交,合计至少一项,当前每批最多 16 项,以 getAlarmCaps.limits.batchRules 为准。当前规则配置请求体上限为 16 KiB,区别于外层 RPC 的 64 KiB 上限。不要在同一批中重复更新同一个 ID,或同时更新和删除同一个 ID;更新和删除的 ID 必须已经存在。
提交按整批校验、编译、持久化并生效:任意一项失败,整批配置不生效。返回成功表示规则已保存,是否能产生告警还取决于规则是否启用、目标是否满足测量条件及有效观测是否达到阈值。
以下 Protobuf common 位于所选规则分支下,例如 displacement_limit.common;JSON 公共字段直接位于 upsert[] 对象内。
| Protobuf 字段 | JSON 规则字段 | 必填 | 说明 |
|---|---|---|---|
common.id | id | 更新时 | 新建必须省略,由设备分配;更新必须是已有非零 uint32,不能通过指定任意新 ID 创建规则 |
common.name | name | 否 | 规则名称,当前最多 64 UTF-8 字节,以能力上限为准 |
common.enabled | enabled | 否 | 缺省为 true;显式 false 保存禁用规则,仍会校验字段合法性 |
common.actions | actions | 否 | 默认无动作;动作类型及适用规则来自 getAlarmCaps.actions |
| 规则 oneof 分支 | type | 是 | 下表中的规则类型,不能在 Protobuf 的同一规则项设置多个分支 |
upsert 是完整规则替换,不是字段补丁。例如仅发送 {"id":12,"enabled":false} 不合法;必须带上 type 及该类型的全部必填字段。更新时省略可选字段会恢复其缺省含义,例如省略 enabled 会重新启用,省略 actions 会去掉原动作,省略数值规则的 recoverForMs 会使用默认恢复时间。
| Protobuf 分支 | JSON type | 必填业务字段(JSON 名称) | 可选业务字段 |
|---|---|---|---|
displacement_limit | DISP_LIMIT | targetIds、metric、direction、levels | recoverForMs |
displacement_rate | DISP_RATE | targetIds、metric、direction、windowMs、levels | recoverForMs |
target_lost | TARGET_LOST | targetIds、levels、recoverForMs | 无 |
voltage_low,并设置 alarm_type=ALARM_TYPE_INPUT_VOLTAGE_LOW | VIN_LOW | levels | recoverForMs |
voltage_low,并设置 alarm_type=ALARM_TYPE_BATTERY_VOLTAGE_LOW | VBAT_LOW | levels | recoverForMs |
Protobuf 对应字段名分别为 target_ids、metric、direction、window_ms、levels、recover_for_ms。TARGET_LOST 的等级使用 lost_for_ms / lostForMs,其余类型使用 enter 和 enter_for_ms / enterForMs。电压规则不接受 targetIds、metric、direction;速率规则通过窗口确定单位,不额外传 unit;未定义的字段会被拒绝。
| 场景 | Protobuf RpcResponse | JSON 响应 |
|---|---|---|
| 新增规则成功 | code=0,apply_alarm_rules.created_ids 返回新 ID | {"reqId":90,"code":0,"data":{"createdIds":[12]}} |
| 仅更新、禁用或删除成功 | code=0,选择 apply_alarm_rules 分支,created_ids 为空 | {"reqId":91,"code":0} |
| 失败 | 非零 code,不设置业务 response 分支 | 例如 {"reqId":91,"code":2},不含 data |
表中的 ID 仅为示例。createdIds 只包含本批新增规则的 ID,按新增项在 upsert 中出现的顺序返回,已有规则更新不会占位。reqId 只关联请求响应,不是配置事务 ID;若新增请求响应超时,先回读规则确认是否已创建,避免使用新 reqId 重发后产生重复规则。删除已经不存在的规则也会失败,不应当作无条件幂等操作。
公共错误码按错误码处理:2 表示参数错误,3 表示不支持,4 表示限流,5 表示超时,6 表示配置冲突;其他非零值作为失败处理。
先调用 getAlarmCaps 确认服务是否就绪,以及当前固件支持的规则类型、等级、动作和资源上限。三级含义见告警等级(3A)。规则的 levels 至少配置一级,未配置的等级不参与判定;JSON 使用 ALERT、ALARM、ACTION 作为 key,Protobuf 使用 levels.alert、levels.alarm、levels.action 消息字段。
| Protobuf 字段 | JSON 字段 | 说明 |
|---|---|---|
levels.<等级>.enter | levels.<等级>.enter | 数值类规则的临界阈值;位移单位 mm,电压单位 V,速率单位由窗口决定 |
levels.<等级>.enter_for_ms | levels.<等级>.enterForMs | 连续越限多少毫秒后进入该等级;缺省为 0,在有效观测越限时即可进入 |
levels.<等级>.lost_for_ms | levels.<等级>.lostForMs | 仅用于 TARGET_LOST,连续丢失时长,必须大于 0 |
recover_for_ms | recoverForMs | 整条规则共用的降级/恢复确认时长,必须大于 0;数值规则缺省为 2000 ms,可通过能力响应的 numeric_recover_for_ms / defaults.numericRecoverForMs 查询;丢失规则必须显式提供 |
window_ms | windowMs | 仅用于 DISP_RATE;1000~10000 ms、步长 100 ms 对应 mm/s,3600000 对应 mm/h,86400000 对应 mm/day;具体支持范围以能力响应为准 |
数值规则只有一个 enter 阈值,同时用于进入和退出判断,不接受另一个 exit 阈值。判定方式如下:
| 类型 | 进入条件 | 回到当前等级安全侧 | 已启用等级从 ALERT 到 ACTION 的配置顺序 |
|---|---|---|---|
DISP_LIMIT / DISP_RATE | 方向换算后的值 > enter,并满足 enterForMs | 值 <= enter | enter 严格递增,且均大于 0 |
VIN_LOW / VBAT_LOW | 电压 < enter,并满足 enterForMs | 电压 >= enter | enter 严格递减,电压越低等级越高 |
TARGET_LOST | 应当可见的标靶连续未检出,达到 lostForMs | 连续重新检出达到 recoverForMs 后恢复 | lostForMs 严格递增 |
数值告警回到安全侧后,还需连续满足 recoverForMs 才会降级或恢复;降到较低等级后仍是活动告警。丢失告警重新检出并满足恢复时间后直接恢复,不逐级降级。无效观测、乱序、观测超时或标靶当前不应可见等情况会中断未完成的计时,不能作为告警已经恢复的依据。
以下创建一个 X 方向双向位移规则,仅启用 ALERT 和 ACTION,只上报告警。阈值为说明协议用的示例值,实际值由项目监测要求确定;targetId="1" 必须是当前可见且允许配置位移规则的标靶。请求发布到 vdm/{deviceId}/rpc/req。
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
request = pb.RpcRequest(schema_version=1, req_id=90)
rule = request.apply_alarm_rules.upsert.add().displacement_limit
rule.common.name = "X 方向位移"
rule.common.enabled = True
rule.target_ids.append("1")
rule.metric = pb.ALARM_METRIC_DX
rule.direction = pb.DISPLACEMENT_DIRECTION_BIDIRECTIONAL
rule.levels.alert.enter = 5.0
rule.levels.alert.enter_for_ms = 1000
rule.levels.action.enter = 10.0
rule.levels.action.enter_for_ms = 1000
rule.recover_for_ms = 2000
payload = request.SerializeToString(deterministic=True)
{
"method": "applyAlarmRules",
"reqId": 90,
"params": {
"upsert": [{
"name": "X 方向位移",
"enabled": true,
"type": "DISP_LIMIT",
"targetIds": ["1"],
"metric": "DX",
"direction": "BIDIRECTIONAL",
"levels": {
"ALERT": {"enter": 5.0, "enterForMs": 1000},
"ACTION": {"enter": 10.0, "enterForMs": 1000}
},
"recoverForMs": 2000
}]
}
}
新建规则省略 id,从响应 created_ids / createdIds 获取设备分配的 ID;更新时使用该 ID 并提交完整规则。以上规则可直接从正常触发 ACTION,也可先触发 ALERT 后升级至 ACTION,不会产生未启用的 ALARM。
actions 省略或为空数组表示只告警、不抓拍。配置 SNAPSHOT 时可通过动作的 levels、transitions 选择触发时机;省略选择器时默认使用规则已启用的等级和 TRIGGERED。JSON 显式空选择器数组会被拒绝;Protobuf repeated 选择器为空等同于省略。动作失败不会回滚告警状态。速率告警抓拍仅支持 1000~10000 ms 短窗口;小时/日窗口仅上报告警。
同一规则绑定多个标靶时,每个标靶独立计时和维护告警生命周期。更新规则参数后,已有活动告警继续使用触发时的规则定义直到恢复;删除、禁用规则或解绑标靶会取消相应活动告警。
下例假设新增示例创建的规则 ID 为 12。禁用它时仍提交完整位移规则;若要更新阈值并启用,将 enabled 改为 true 并修改相应 enter。禁用活动规则会产生 CANCELLED,已有告警不会被标记成测量恢复。
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
update_request = pb.RpcRequest(schema_version=1, req_id=91)
rule = update_request.apply_alarm_rules.upsert.add().displacement_limit
rule.common.id = 12 # 替换成设备实际返回的 created_ids
rule.common.name = "X 方向位移"
rule.common.enabled = False
rule.target_ids.append("1")
rule.metric = pb.ALARM_METRIC_DX
rule.direction = pb.DISPLACEMENT_DIRECTION_BIDIRECTIONAL
rule.levels.alert.enter = 5.0
rule.levels.alert.enter_for_ms = 1000
rule.levels.action.enter = 10.0
rule.levels.action.enter_for_ms = 1000
rule.recover_for_ms = 2000
payload = update_request.SerializeToString(deterministic=True)
{
"reqId": 91,
"method": "applyAlarmRules",
"params": {
"upsert": [{
"id": 12,
"name": "X 方向位移",
"enabled": false,
"type": "DISP_LIMIT",
"targetIds": ["1"],
"metric": "DX",
"direction": "BIDIRECTIONAL",
"levels": {
"ALERT": {"enter": 5.0, "enterForMs": 1000},
"ACTION": {"enter": 10.0, "enterForMs": 1000}
},
"recoverForMs": 2000
}]
}
}
删除只需 ID,不需要重传规则。若规则正在告警,会终止其活动生命周期。
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
remove_request = pb.RpcRequest(schema_version=1, req_id=92)
remove_request.apply_alarm_rules.delete_ids.append(12)
payload = remove_request.SerializeToString(deterministic=True)
{"reqId":92,"method":"applyAlarmRules","params":{"deleteIds":[12]}}
listAlarmRules 不接受 limit 或 ID 过滤参数,页大小由设备控制。第一页不传 cursor,后续使用响应中的游标,直至响应不再携带游标。
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
list_request = pb.RpcRequest(schema_version=1, req_id=93)
list_request.list_alarm_rules.SetInParent()
# 后续页:list_request.list_alarm_rules.cursor = 上一页响应.next_cursor
payload = list_request.SerializeToString(deterministic=True)
{"reqId":93,"method":"listAlarmRules","params":{}}
JSON 后续请求将 params 替换为 {"cursor":"上一页返回的 nextCursor"},并使用新的 reqId。回读时默认值可能省略,例如缺省的 recoverForMs=2000、空动作数组和默认动作选择器;客户端应按默认语义补齐编辑表单。阈值使用浮点数,JSON 回读可能出现 0.20000000298023224 这样的二进制浮点展开;按数值及合理误差比较,不按小数字符串判断配置是否保存成功。
设备通过同一个 telemetry 主题上报位移数据、环境数据和设备状态数据。
主题: vdm/{deviceId}/telemetry
位移数据:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
message = pb.Telemetry(schema_version=1)
message.displacement.sample_frequency_hz = 3
message.displacement.first_sample_timestamp_ms = 1734567890123
target = message.displacement.targets.add(target_id="1")
target.dx.extend([0.01, 0.02, 0.03])
target.dy.extend([0.00, 0.01, 0.01])
payload = message.SerializeToString(deterministic=True)
{"disp":{"t":1734567890,"f":3,"d":{"1":{"dx":[0.01,0.02,0.03],"dy":[0.00,0.01,0.01]}}}}
| Protobuf 字段 | JSON 字段 | 说明 |
|---|---|---|
sample_frequency_hz | disp.f | 本次位移数组的采样频率,单位 Hz。例如 5 Hz 表示相邻样本约 200 ms |
first_sample_timestamp_ms | disp.t | 本批次首个样本的 Unix 毫秒时间戳;JSON 的 disp.t 保持既有 Unix 秒格式 |
targets[].target_id | disp.d 的 key | 标靶 ID |
targets[].dx | disp.d.{targetId}.dx | X 方向位移数组,单位 mm |
targets[].dy | disp.d.{targetId}.dy | Y 方向位移数组,单位 mm |
位移数据包含 X/Y 方向。reportMetrics=["dx"] 或 ["dy"] 时,JSON 省略未选择的方向 key,Protobuf 对应 repeated 字段为空;缺省值为 ["dx","dy"]。非空数组使用同一批次采样网格,云端按 first_sample_timestamp_ms + round(i × 1000 / sample_frequency_hz) 还原第 i 个样本时间。
环境数据:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
message = pb.Telemetry(schema_version=1)
message.environment.ts = 1781686005
message.environment.temperature_c = 38.57
message.environment.humidity_percent_rh = 25.86
message.environment.pressure_hpa = 1002.8
payload = message.SerializeToString(deterministic=True)
{"env":{"t":1781686005,"temperature":38.57,"humidity":25.86,"pressure":1002.8}}
| Protobuf 字段 | JSON 字段 | 说明 |
|---|---|---|
environment.ts | env.t | Unix 时间戳,单位秒 |
environment.temperature_c | env.temperature | 温度,单位 °C |
environment.humidity_percent_rh | env.humidity | 湿度,单位 %RH |
environment.pressure_hpa | env.pressure | 气压,单位 hPa |
设备状态数据:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
message = pb.Telemetry(schema_version=1)
message.device_status.ts = 1781686005
message.device_status.input_voltage_v = 12.11
message.device_status.lte_dbm = -71
payload = message.SerializeToString(deterministic=True)
{"device":{"t":1781686005,"vIn":12.11,"lteDbm":-71}}
| Protobuf 字段 | JSON 字段 | 说明 |
|---|---|---|
device_status.ts | device.t | Unix 时间戳,单位秒 |
device_status.input_voltage_v | device.vIn | 设备主电源输入电压,额定工作电压 12V,单位 V |
device_status.lte_dbm | device.lteDbm | LTE 接收信号强度,单位 dBm |
device_status 的公开状态字段以本表为准。除时间戳外,仅开放 vIn 和 lteDbm;二者均无有效采集值时不发送设备状态消息。
Protobuf 解析时使用 HasField("displacement")、HasField("environment") 或 HasField("device_status") 判断消息体。选择 JSON 时,对应判断 disp、env 或 device。
设备通过主题 vdm/{deviceId}/3A 上报告警生命周期事件。连接选择 Protobuf 时使用 inteagle.vdm.mqtt.v1.Alarm;选择 JSON 时使用本节的 JSON 字段。
严重程度从低到高为 ALERT < ALARM < ACTION。等级表示当前风险程度,是否触发抓拍等动作由规则的 actions 另行配置。
| Protobuf 枚举 | 数值 | JSON level | 含义 | 展示建议 |
|---|---|---|---|---|
ALARM_LEVEL_ALERT | 1 | ALERT | 预警,关注变化趋势 | 黄色 |
ALARM_LEVEL_ALARM | 2 | ALARM | 报警,需要处理 | 橙色 |
ALARM_LEVEL_ACTION | 3 | ACTION | 行动级/紧急,需要立即响应 | 红色 |
颜色是界面展示建议,不是设备传输字段。
level 为可选字段:TRIGGERED、ESCALATED、DEESCALATED 和活动状态的 SYNCED 携带当前等级;RECOVERED、CANCELLED 不设置 level。Python 应使用 HasField("level") 判断是否存在,不能把读取到的默认值 0 当成一个“正常等级”。JSON 结束事件直接省略 level,不要要求它为 "NORMAL" 或 null。
| Protobuf 枚举 | 数值 | JSON type | 含义与适用范围 | Protobuf detail 分支 |
|---|---|---|---|---|
ALARM_TYPE_DISPLACEMENT_LIMIT | 1 | DISP_LIMIT | 位移超限,真实标靶限 MP | displacement |
ALARM_TYPE_DISPLACEMENT_RATE_LIMIT | 2 | DISP_RATE | 位移变化速率超限,真实标靶限 MP | displacement_rate |
ALARM_TYPE_TARGET_LOST | 3 | TARGET_LOST | 应当可见的标靶持续丢失,适用 MP/RP/CP | target_lost |
ALARM_TYPE_INPUT_VOLTAGE_LOW | 4 | VIN_LOW | 设备输入电压过低 | voltage |
ALARM_TYPE_BATTERY_VOLTAGE_LOW | 5 | VBAT_LOW | 设备电池电压过低 | voltage |
实际可配置范围以 getAlarmCaps 为准。设备离线由云端根据连接或最后在线时间判定,不属于设备主动上报的上述五种类型。
| Protobuf 枚举 | 数值 | JSON transition | 含义 | alarmId 与 level |
|---|---|---|---|---|
ALARM_TRANSITION_TRIGGERED | 1 | TRIGGERED | 首次满足某个启用等级的条件 | 新 alarmId,携带进入的等级 |
ALARM_TRANSITION_ESCALATED | 2 | ESCALATED | 升至更高的启用等级,可跨级 | 原 alarmId,携带升级后的等级 |
ALARM_TRANSITION_DEESCALATED | 3 | DEESCALATED | 降至较低的启用等级,仍未恢复 | 原 alarmId,携带降级后的等级 |
ALARM_TRANSITION_RECOVERED | 4 | RECOVERED | 满足恢复条件,生命周期结束 | 原 alarmId,省略等级 |
ALARM_TRANSITION_CANCELLED | 5 | CANCELLED | 规则删除、禁用或标靶解绑等操作终止告警 | 原 alarmId,省略等级;不表示测量值已恢复 |
ALARM_TRANSITION_SYNCED | 6 | SYNCED | 显式同步已有活动状态 | 原 alarmId,携带当前等级;不算再次触发 |
设备状态不变化时不重复产生告警,也没有周期性告警心跳;重试使用原 eventId。云端不能因一段时间没有收到 3A 消息就自动判为恢复,重连后可用 getAlarmState 核对当前活动告警,用 listAlarmHistory 查询历史。
例如只启用 ALERT 和 ACTION 时,一个生命周期可以是:
stateDiagram-v2
[*] --> 正常
正常 --> ALERT: TRIGGERED
正常 --> ACTION: TRIGGERED,直接满足高等级
ALERT --> ACTION: ESCALATED
ACTION --> ALERT: DEESCALATED
ALERT --> 结束: RECOVERED 或 CANCELLED
ACTION --> 结束: RECOVERED 或 CANCELLED
结束 --> [*]图中的“正常”和“结束”用于说明生命周期,不是 AlarmLevel 枚举。下次重新触发会创建新的 alarmId。
| Protobuf 字段 | JSON 字段 | 类型与说明 |
|---|---|---|
schema_version | 无 | uint32,当前必须为 1 |
event_id | eventId | uint64 / 十进制字符串,一次状态变化的 ID |
alarm_id | alarmId | uint64 / 十进制字符串,一次完整生命周期的 ID |
rule_id | ruleId | uint32,对应触发告警的规则 ID |
alarm_type | type | AlarmType / 上表的业务类型字符串 |
level | level | optional AlarmLevel / 大写等级字符串,结束事件不设置 |
transition | transition | AlarmTransition / 上表的转换字符串 |
ts | ts | uint64 / Number,Unix 秒时间戳 |
detail(oneof) | detail | 与告警类型匹配的详情;Protobuf 只设置对应分支 |
各类型的详情如下,表中 Protobuf 字段相对于其分支列出:
| 类型 | Protobuf 字段 → JSON detail 字段 | 含义 |
|---|---|---|
DISP_LIMIT | target_id → targetId;metric → metric;direction → direction;value_mm → value;limit_mm → limit | 标靶、指标、方向、观测位移和阈值,数值单位为 mm;JSON 不额外上报 unit |
DISP_RATE | target_id → targetId;metric → metric;direction → direction;value → value;limit → limit;unit → unit;window_ms → windowMs | 观测速率、阈值、单位和窗口长度;单位为 mm/s、mm/h 或 mm/day |
TARGET_LOST | target_id → targetId | 只有标靶 ID,不携带 value、limit 或丢失时长 |
VIN_LOW / VBAT_LOW | value_v → value;limit_v → limit | 电压和阈值,单位 V;不携带 targetId 或 unit |
value、limit 及其 Protobuf 对应字段均可省略,缺失不等于 0;SYNCED 不携带这两个观测字段。详情是事件产生时冻结的数据,不能用当前规则配置反推历史事件的阈值。降级或恢复事件的 limit 表示离开等级的阈值。
当前位移和速率规则开放 ALARM_METRIC_DX=1 / DX、ALARM_METRIC_DY=2 / DY。方向枚举为:
| Protobuf 枚举 | 数值 | JSON direction | 用于比较的值 |
|---|---|---|---|
DISPLACEMENT_DIRECTION_POSITIVE | 1 | POSITIVE | 原始值 |
DISPLACEMENT_DIRECTION_NEGATIVE | 2 | NEGATIVE | 原始值取反 |
DISPLACEMENT_DIRECTION_BIDIRECTIONAL | 3 | BIDIRECTIONAL | 原始值的绝对值 |
事件中的 value 保留原始正负号,limit 使用正的阈值幅值。例如 DX + NEGATIVE 的 value=-5.2、limit=5.0 表示负 X 方向越限。
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
message = pb.Alarm(
schema_version=1,
event_id=7,
alarm_id=6,
rule_id=12,
alarm_type=pb.ALARM_TYPE_DISPLACEMENT_LIMIT,
level=pb.ALARM_LEVEL_ALERT,
transition=pb.ALARM_TRANSITION_TRIGGERED,
ts=1734567890,
)
message.displacement.target_id = "1"
message.displacement.metric = pb.ALARM_METRIC_DX
message.displacement.direction = pb.DISPLACEMENT_DIRECTION_BIDIRECTIONAL
message.displacement.value_mm = 5.2
message.displacement.limit_mm = 5.0
payload = message.SerializeToString(deterministic=True)
{
"eventId": "7",
"alarmId": "6",
"ruleId": 12,
"type": "DISP_LIMIT",
"level": "ALERT",
"transition": "TRIGGERED",
"ts": 1734567890,
"detail": {
"targetId": "1",
"metric": "DX",
"direction": "BIDIRECTIONAL",
"value": 5.2,
"limit": 5.0
}
}
alarmId 表示一次完整告警生命周期,eventId 表示该生命周期中的一次状态变化。RECOVERED 或 CANCELLED 表示该 alarmId 生命周期结束。系统集成商平台以 deviceId + alarmId 作为生命周期主键,以 deviceId + eventId 作为状态变化和抓拍图像去重键;不要根据 ID 位布局互相推导。
同一生命周期的恢复消息示例(新的 eventId,沿用 alarmId,省略 level):
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
recovered = pb.Alarm(
schema_version=1, event_id=8, alarm_id=6, rule_id=12,
alarm_type=pb.ALARM_TYPE_DISPLACEMENT_LIMIT,
transition=pb.ALARM_TRANSITION_RECOVERED, ts=1734567900,
)
recovered.displacement.CopyFrom(pb.DisplacementAlarmDetail(
target_id="1", metric=pb.ALARM_METRIC_DX,
direction=pb.DISPLACEMENT_DIRECTION_BIDIRECTIONAL,
value_mm=4.0, limit_mm=5.0,
))
payload = recovered.SerializeToString(deterministic=True)
{
"eventId": "8",
"alarmId": "6",
"ruleId": 12,
"type": "DISP_LIMIT",
"transition": "RECOVERED",
"ts": 1734567900,
"detail": {
"targetId": "1",
"metric": "DX",
"direction": "BIDIRECTIONAL",
"value": 4.0,
"limit": 5.0
}
}
ackEvidencePackage 仅确认抓拍图像包已完整接收,不会确认或清除告警;ACTION 等级也不代表抓拍已成功,应通过 event 中的图像状态或 getEvidenceStatus 查询结果。
设备通过 vdm/{deviceId}/event 上报事件。
标靶参考位置初始化结果:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
message = pb.Event(
schema_version=1,
ts=1781767001,
event_type=pb.EVENT_TYPE_REF_INIT_RESULT,
)
message.ref_init_result.successful_target_ids.append("1")
message.ref_init_result.failed_targets.add(
target_id="2",
code=102,
)
payload = message.SerializeToString(deterministic=True)
{
"type": "REF_INIT_RESULT",
"ts": 1781767001,
"detail": {
"ok": ["1"],
"fail": [
{"id": "2", "code": 102}
]
}
}
ref_init_result.successful_target_ids 为成功标靶 ID 列表,failed_targets 为失败标靶列表。
失败项携带数值错误码。JSON 对应字段为 detail.ok 和 detail.fail。
其他公共事件如下:
Protobuf EventType | JSON type | 明细 |
|---|---|---|
EVENT_TYPE_CRUISE_REACHED | CRUISE_REACHED | 只包含 pathId、pointId、pan、tilt 中已知字段 |
EVENT_TYPE_TARGET_TRACKING | TARGET_TRACKING | targetId 和稳定状态 LOST 或 TRACKING |
规则产生的标靶丢失通过 3A 上报。
初始化时间通过 Attributes.target_list.targets[].initialized_at_s 或 getTargets 获取;JSON 对应字段为 targets[].initializedAt。
设备通过 vdm/{deviceId}/attributes 上报属性。连接成功后会上报基础属性;属性变化时会上报增量属性。attributes 不是历史状态查询通道,订阅方需要当前标靶快照时应调用 getTargets。
基础属性示例:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
message = pb.Attributes(
schema_version=1,
device_id="XXXXXXXXXXXX",
device_model="V1",
firmware_version="1.2.3",
resolution="3840x2160",
measurement_status=pb.MEASUREMENT_STATUS_IDLE,
sample_frequency_hz=5,
show_roi=True,
show_timestamp=True,
show_sensor_id=True,
)
message.report_metrics.values.extend([
pb.REPORT_METRIC_DX,
pb.REPORT_METRIC_DY,
])
payload = message.SerializeToString(deterministic=True)
{
"deviceId": "XXXXXXXXXXXX",
"deviceModel": "V1",
"fwVer": "1.2.3",
"resolution": "3840x2160",
"measureStatus": "Idle",
"sampleFreq": 5,
"reportMetrics": ["dx", "dy"],
"showROI": true,
"showTs": true,
"showSensorId": true
}
标靶属性变化时,target_list 按精简摘要格式上报;单独调用 getTargets 只通过 RPC 响应返回,不额外触发 Attributes.target_list:
from generated import inteagle_vdm_mqtt_v1_pb2 as pb
message = pb.Attributes(schema_version=1)
target = message.target_list.targets.add(
target_id="1",
sensor_id=0,
roi=pb.Roi(x=1000, y=500, width=400, height=400),
distance_m=5.0,
role=pb.TARGET_ROLE_MP,
target_model=pb.TARGET_MODEL_T100,
skip_measurement=False,
initialized=True,
initialized_at_s=1781767000,
)
payload = message.SerializeToString(deterministic=True)
{
"targets": [
{
"targetId": "1",
"sensorId": 0,
"roi": {"x": 1000, "y": 500, "width": 400, "height": 400},
"distance": 5.0,
"role": "MP",
"targetModel": "T100",
"skipMeasurement": false,
"initialized": true,
"initializedAt": 1781767000
}
]
}
| Protobuf 字段 | JSON 字段 | 说明 |
|---|---|---|
target_list.targets[].target_id | targets[].targetId | 标靶 ID |
target_list.targets[].sensor_id | targets[].sensorId | 视觉传感器 ID |
target_list.targets[].roi | targets[].roi | 标靶 ROI |
target_list.targets[].distance_m | targets[].distance | 测量距离,单位 m |
target_list.targets[].role | targets[].role | 标靶角色枚举 |
target_list.targets[].target_model | targets[].targetModel | 标靶型号枚举 |
target_list.targets[].skip_measurement | targets[].skipMeasurement | 是否跳过测量 |
target_list.targets[].initialized | targets[].initialized | 是否已经初始化参考位置 |
target_list.targets[].initialized_at_s | targets[].initializedAt | optional Unix 秒时间戳 |
targets 属性只包含对外集成需要的摘要字段。
| API | V1 | V1 Pro | V1 Lite | V2-H | V2-W | V2-K | O1 | O2-H | X1 | X2-H |
|---|---|---|---|---|---|---|---|---|---|---|
| 基础 API | ||||||||||
| getAttr | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| setAttr | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| reboot | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| syncTime | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 标靶管理 | ||||||||||
| initRefTargets | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| addTargets | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| getTargets | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| setTargets | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| deleteTargets | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 测量控制 | ||||||||||
| startMeasurement | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| stopMeasurement | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| setLightLevel | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| getLightLevel | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| snapshot | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 告警抓拍图像(0.8.5+) | ||||||||||
| getEvidenceStatus | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| retryEvidence | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ackEvidencePackage | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 告警管理(JSON / Protobuf) | ||||||||||
| getAlarmCaps | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| listAlarmRules | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| device_status=pb.DEVICE_STATUS_IDLE, | ||||||||||
| applyAlarmRules | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| getAlarmState | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| listAlarmHistory | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ISP 控制 | ||||||||||
| ispCtl | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| 电机控制 | ||||||||||
| setMotorAngle | - | - | - | - | - | - | ✓ | ✓ | ✓ | ✓ |
| getMotorAngle | - | - | - | - | - | - | ✓ | ✓ | ✓ | ✓ |
| setMotorZero | - | - | - | - | - | - | ✓ | ✓ | ✓ | ✓ |
| enableMotor | - | - | - | - | - | - | ✓ | ✓ | ✓ | ✓ |
| disableMotor | - | - | - | - | - | - | ✓ | ✓ | ✓ | ✓ |
| 巡航控制 | ||||||||||
| getCruisePaths | - | - | - | - | - | - | ✓ | ✓ | ✓ | ✓ |
JSON code 与 Protobuf RpcResponse.code 含义一致:0 表示成功,其他值表示失败。
“deviceStatus”: “Idle”,
| 码 | 说明 | 适用型号 |
|---|---|---|
| 0 | 成功 | 全部 |
| 1 | 通用失败(无法进一步分类) | 全部 |
| 2 | 参数缺失、类型错误或取值无效 | 全部 |
| 3 | 方法、action 或 Payload 格式不支持 | 全部 |
| 4 | 请求被限流 | 全部 |
| 5 | 请求执行超时 | 全部 |
| 6 | 资源状态已变化,请刷新后重试 | 全部 |
| 100 | 标靶不存在,或对当前连接不可见 | 全部 |
| 102 | 标靶初始化失败 | 全部 |
| 104 | 标靶丢失 | 全部 |
| 200 | 测量未启动 | 全部 |
| 201 | 测量已在运行 | 全部 |
| 300 | 电机不可用 | O1, O2-H, X1, X2-H |
| 302 | 电机运动中 | O1, O2-H, X1, X2-H |
| 303 | 电机到达限位 | X1, X2-H |
| 310 | 垂直电机不可用 | O1, O2-H |
| 400 | 巡航功能不可用 | O1, O2-H, X1, X2-H |
| 403 | 巡航已在运行 | O1, O2-H, X1, X2-H |
RPC 失败仅通过外层数字 code 表示,不携带业务数据。
设备通过 image 主题上报普通图片和告警抓拍图像包分块。该 Topic 始终使用二进制 Payload,不使用 JSON 或 Protobuf 包装。
主题: vdm/{deviceId}/image
解析器必须先检查第 0 字节,不能把所有 image Payload 都按旧 8 字节 Header 解析:
| 第 0 字节 | 格式 | Payload |
|---|---|---|
1 | 普通图片 | 8 字节可扩展 Header + 完整 JPEG |
2 | 告警抓拍图像包分块 | 76 字节固定 Header + 一个 USTAR 分块 |
普通图片继续使用可扩展 Header:
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | version | 消息类型 / Header 版本,当前 0x01 |
| 1 | 1 | headerLen | Header 总长度(字节) |
| 2 | 1 | sensorId | 视觉传感器 ID(单目为 0,双目为 0 或 1) |
| 3 | 1 | type | 图片类型(见下表) |
| 4 | 4 | timestamp | Unix 秒时间戳(uint32,大端) |
headerLen | 剩余 | imageData | 完整 JPEG 二进制数据 |
图片类型 (type):
| 值 | 类型 | 说明 |
|---|---|---|
| 0 | snapshot | RPC 触发的快照 |
| 1 | 3A | 告警触发的抓图 |
| 2 | periodic | 定时抓图 |
01 08 00 01 67 72 B3 D6 FF D8 FF E0 ...
│ │ │ │ └──────────┴─ timestamp: 1735533526
│ │ │ └─ type: 1 (3A)
│ │ └─ sensorId: 0
│ └─ headerLen: 8
└─ version: 1
headerLen 可能在未来版本增加。解析时应从 headerLen 位置取 JPEG,不应将未识别的扩展字段当作图片字节。
类型 2 使用 76 字节固定 Header。除单字节字段和原始 SHA-256 外,所有整数均使用大端序:
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | messageType | 固定为 2 |
| 1 | 1 | headerLen | 固定为 76 |
| 2 | 1 | packageFormat | 固定为 1,表示确定性 USTAR |
| 3 | 1 | evidenceKind | 抓拍图像固定为 1(SNAPSHOT) |
| 4 | 8 | eventId | 触发抓拍的告警状态变化 ID,必须非 0 |
| 12 | 8 | packageLength | 完整 USTAR 包长度,范围 1..32 MiB |
| 20 | 32 | packageSha256 | 完整 USTAR 包的 SHA-256 原始字节 |
| 52 | 4 | chunkIndex | 当前分块索引,从 0 开始 |
| 56 | 4 | chunkCount | 完整抓拍图像包的分块数 |
| 60 | 8 | chunkOffset | 当前分块在完整抓拍图像包中的字节偏移 |
| 68 | 4 | chunkLength | Header 后当前分块的字节数 |
| 72 | 4 | flags | 当前必须为 0 |
| 76 | chunkLength | chunkData | USTAR 分块字节 |
分块大小固定为 128 KiB,只有最后一块可以更短。解析器必须检查:
chunkCount == ceil(packageLength / 128 KiB)。chunkOffset == chunkIndex × 128 KiB,chunkLength 等于该位置的预期长度。76 + chunkLength,flags == 0。ustar 标识。packageLength 相同,SHA-256 与 packageSha256 相同。manifest.json,所有成员必须是安全相对路径下的普通文件。MQTT QoS 1 允许重复投递,不保证业务消息与其他 Topic 的到达顺序。推荐使用磁盘优先、有界的重组流程:
deviceId + eventId + packageSha256 + chunkIndex 作为分块幂等键,相同键再次到达时必须比对字节内容。chunkOffset 写入临时文件,并限制同时未完成的事件数和磁盘占用。ackEvidencePackage。生产实现应持久化已收分块 bitmap,使接收服务重启后可以继续去重和重组。官方示例仓库的 python/evidence_receiver.py 提供可运行的落盘、校验和 ACK 参考实现。
官方 Python、Go、Java 和 JavaScript/TypeScript SDK 均提供一致的有界磁盘重组、完整性与安全 USTAR 校验和原子接收回执能力;Python 文件另外提供可直接运行的接收进程示例。
| 项目 | 规格 |
|---|---|
| 格式 | JPEG |
| 普通快照标准分辨率 | 640x480 |
| 普通图片典型大小 | 50KB - 200KB |
| 单个告警抓拍图像包上限 | 32 MiB |
| 单次告警抓拍图像数上限 | 64 |
型号: V1 Lite | 版本: 1.0 | 更新: 2026-09-11
V1 Lite 是 V1 系列的轻量款单目固定式视觉位移计,接口形态与 V1 保持一致。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 项目 | 说明 |
|---|---|
| 视觉传感器 | 单目 |
| 云台类型 | 无 |
sensorId | 不需要 |
| 电机控制 | 不支持 |
| 巡航控制 | 不支持 |
| 兼容手册 | V1 |
| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
V1 Lite 为单目设备,标靶配置不需要传入 sensorId。getTargets 请求、响应字段、ROI 和距离字段参考 V1。
型号: V1 | 版本: 1.0 | 更新: 2026-09-28
V1 是单目固定式视觉位移计。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
标靶管理 API 的完整字段约束参考 API参考。
获取设备属性。不带 keys 参数时返回全部属性。
属性列表:
| 属性 | 类型 | 读写 | 说明 |
|---|---|---|---|
deviceId | String | R | 设备 ID |
deviceModel | String | R | 型号 |
fwVer | String | R | 固件版本 |
resolution | String | R | 图像分辨率,通常为 3840x2160 |
deviceStatus | String | R | 设备整体工作状态:Initializing、Measuring、Idle、Testing、Calibrating、Sleeping。休眠前上报 Sleeping,唤醒启动后上报 Idle |
measureStatus | String | R | 测量状态 |
sampleFreq | Integer | RW | 采样频率 (整数 Hz,1-60) |
reportMetrics | Array | RW | 上报指标 |
showROI | Boolean | RW | 告警抓拍图像是否叠加 ROI 标注 |
showTs | Boolean | RW | 告警抓拍图像是否叠加时间戳 |
showSensorId | Boolean | RW | 告警抓拍图像是否叠加视觉传感器 ID |
标靶配置变化时,设备会通过 vdm/{deviceId}/attributes 上报只读 targets 摘要属性。单独调用 getTargets 只通过 RPC 响应返回;订阅方需要当前标靶快照时应调用 getTargets。targets 不是 setAttr 的可写字段,标靶配置请使用 addTargets、setTargets 或 deleteTargets,参考位置初始化使用 initRefTargets。
targets 摘要只包含 targetId、sensorId、roi、distance、role、targetModel、skipMeasurement、initialized、initializedAt 等对外字段。
设置设备属性。
对指定标靶执行参考位置初始化/标定。通常先通过 addTargets 或 setTargets 保存标靶配置;初始化时可只传 targetId。如需覆盖保存配置,可在本次请求中提供 roi、distance 或 targetModel。
参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
targets | Array | 是 | 要初始化标靶参考位置的标靶数组,不能为空 |
targets[].targetId | String | 是 | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].roi | Object | 否 | ROI 区域;不传时使用已保存标靶配置 |
targets[].distance | Float | 否 | 测量距离 (m);不传时使用已保存标靶配置 |
targets[].targetModel | String | 否 | 标靶型号,取值 T10、T20、T50、T100、T200 |
在已有标靶基础上添加新标靶。
获取当前标靶列表。
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
targets[].targetId | String | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 视觉传感器 ID,单目设备为 0 |
targets[].roi | Object | 标靶 ROI 区域 |
targets[].distance | Float | 测量距离,单位 m |
targets[].role | String | 标靶角色:MP 为被测点,RP 为稳定基准点,CP 为控制/校核点 |
targets[].targetModel | String | 标靶型号,取值 T10、T20、T50、T100、T200 |
targets[].skipMeasurement | Boolean | 是否跳过测量 |
targets[].initialized | Boolean | 是否已经初始化标靶参考位置 |
targets[].initializedAt | Integer | Null | 初始化标靶参考位置的 Unix 秒时间戳;未初始化或无记录时为 null |
更新已有标靶的配置。
删除指定标靶。
启动测量。
停止测量。
设置补光灯发光挡位。
获取补光灯发光挡位。
设备通过 vdm/{deviceId}/telemetry 上报位移和设备状态;环境字段按设备传感器能力提供。字段、单位及 Protobuf / JSON 示例见遥测数据。
code=0 成功,任意非零码均为失败,见 错误码。型号: V1 Pro | 版本: 1.0 | 更新: 2026-09-11
V1 Pro 是 V1 系列的高性能单目固定式视觉位移计,MQTT 接口与 V1 保持一致。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 项目 | 说明 |
|---|---|
| 视觉传感器 | 单目 |
| 云台类型 | 无 |
sensorId | 不需要 |
| 电机控制 | 不支持 |
| 巡航控制 | 不支持 |
| 兼容手册 | V1 |
完整的 RPC、属性、遥测和告警抓拍图像字段见 API 参考。
型号: V2-H | 版本: 1.0 | 更新: 2026-09-11
V2-H 是 V2 系列双目固定式视觉位移计。双目型号的标靶配置建议保存 sensorId,基础 API 与 V2-W 一致。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 项目 | 说明 |
|---|---|
| 视觉传感器 | 双目 |
| 云台类型 | 无 |
sensorId | 新增标靶时必填,取值为 0 或 1 |
| 电机控制 | 不支持 |
| 巡航控制 | 不支持 |
| 兼容手册 | V2-W |
| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
新增标靶时指定 sensor_id / sensorId 为 0 或 1;初始化已有标靶时可沿用保存的值。
更多字段说明参考 V2-W。
型号: V2-W | 版本: 1.0 | 更新: 2026-09-11
V2-W 系列是双目固定式视觉位移计,支持双视觉传感器同步测量。配合另一台设备可实现 3D 空间位移融合计算。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
标靶管理 API 的完整字段约束参考 API参考。
对指定标靶执行参考位置初始化/标定。通常先通过 addTargets 或 setTargets 保存标靶配置;初始化时可只传 targetId。双目设备可从已保存配置中读取 sensorId,如需覆盖保存配置,可在本次请求中提供 sensorId、roi、distance 或 targetModel。
参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
targets | Array | 是 | 要初始化标靶参考位置的标靶数组,不能为空 |
targets[].targetId | String | 是 | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 否 | 视觉传感器 ID (0 或 1);不传时使用已保存标靶配置 |
targets[].roi | Object | 否 | ROI 区域;不传时使用已保存标靶配置 |
targets[].distance | Float | 否 | 测量距离 (m);不传时使用已保存标靶配置 |
targets[].targetModel | String | 否 | 标靶型号,取值 T10、T20、T50、T100、T200 |
注意: V2-W 4M 分辨率为 2560×1440,ROI 坐标需相应调整。
在已有标靶基础上添加新标靶。
获取当前标靶列表。
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
targets[].targetId | String | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 视觉传感器 ID,双目设备为 0 或 1 |
targets[].roi | Object | 标靶 ROI 区域 |
targets[].distance | Float | 测量距离,单位 m |
targets[].role | String | 标靶角色:MP 为被测点,RP 为稳定基准点,CP 为控制/校核点 |
targets[].targetModel | String | 标靶型号,取值 T10、T20、T50、T100、T200 |
targets[].skipMeasurement | Boolean | 是否跳过测量 |
更新已有标靶的配置。
删除指定标靶。
设置补光灯发光挡位。V2-W 为双目设备,有两个补光灯。
reportMetrics 支持 dx、dy。
设备通过 vdm/{deviceId}/telemetry 上报位移和设备状态;环境字段按设备传感器能力提供。字段、单位及 Protobuf / JSON 示例见遥测数据。
code=0 成功,任意非零码均为失败,见 错误码。型号: V2-K | 版本: 1.0 | 更新: 2026-09-11
V2-K 是双目固定式视觉位移计,双视觉传感器可独立调整角度,适用于需要灵活监测角度的场景。
与 V2-W 的区别: V2-K 双视觉传感器可朝向不同方向,因此各标靶距离可能不同。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
标靶管理 API 的完整字段约束参考 API参考。
对指定标靶执行参考位置初始化/标定。通常先通过 addTargets 或 setTargets 保存标靶配置;初始化时可只传 targetId。双视觉传感器可从已保存配置中读取 sensorId 和距离,如需覆盖保存配置,可在本次请求中提供 sensorId、roi、distance 或 targetModel。
参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
targets | Array | 是 | 要初始化标靶参考位置的标靶数组,不能为空 |
targets[].targetId | String | 是 | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 否 | 视觉传感器 ID (0 或 1);不传时使用已保存标靶配置 |
targets[].roi | Object | 否 | ROI 区域;不传时使用已保存标靶配置 |
targets[].distance | Float | 否 | 测量距离 (m);不传时使用已保存标靶配置 |
targets[].targetModel | String | 否 | 标靶型号,取值 T10、T20、T50、T100、T200 |
V2-K 双视觉传感器可朝向不同方向,因此各标靶距离可能不同。
在已有标靶基础上添加新标靶。
获取当前标靶列表。
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
targets[].targetId | String | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 视觉传感器 ID,双目设备为 0 或 1 |
targets[].roi | Object | 标靶 ROI 区域 |
targets[].distance | Float | 测量距离,单位 m |
targets[].role | String | 标靶角色:MP 为被测点,RP 为稳定基准点,CP 为控制/校核点 |
targets[].targetModel | String | 标靶型号,取值 T10、T20、T50、T100、T200 |
targets[].skipMeasurement | Boolean | 是否跳过测量 |
更新已有标靶的配置。
删除指定标靶。
reportMetrics 支持 dx、dy。
| 指标 | 说明 |
|---|---|
dx, dy | X/Y 位移;可选择其一或全部 |
设备通过 vdm/{deviceId}/telemetry 上报位移和设备状态;环境字段按设备传感器能力提供。字段、单位及 Protobuf / JSON 示例见遥测数据。
code=0 成功,任意非零码均为失败,见 错误码。型号: O1 | 版本: 1.0 | 更新: 2026-09-11
O1 是单目单轴旋转式视觉位移计,支持水平方向云台控制和巡航。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
| 方法 | 说明 |
|---|---|
setMotorAngle | 设置电机角度(仅 pan) |
getMotorAngle | 获取电机角度 |
setMotorZero | 设置电机零点 |
enableMotor | 启用电机 |
disableMotor | 禁用电机 |
| 方法 | 说明 |
|---|---|
getCruisePaths | 获取巡航路径 |
标靶管理 API 的完整字段约束参考 API参考。
对指定标靶执行参考位置初始化/标定。通常先通过 addTargets 或 setTargets 保存标靶配置;初始化时可只传 targetId。如需覆盖保存配置,可在本次请求中提供 roi、distance 或 targetModel。
在已有标靶基础上添加新标靶。
获取当前标靶列表。
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
targets[].targetId | String | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 视觉传感器 ID,单目设备为 0 |
targets[].roi | Object | 标靶 ROI 区域 |
targets[].distance | Float | 测量距离,单位 m |
targets[].role | String | 标靶角色:MP 为被测点,RP 为稳定基准点,CP 为控制/校核点 |
targets[].targetModel | String | 标靶型号,取值 T10、T20、T50、T100、T200 |
targets[].skipMeasurement | Boolean | 是否跳过测量 |
更新已有标靶的配置。
删除指定标靶。
设置电机角度。
注意: O1 仅支持水平 (pan) 方向,不支持 tilt 参数。
参数:
| 字段 | 类型 | 范围 | 说明 |
|---|---|---|---|
pan | Float | -180 ~ 180 | 水平角度 (°) |
speed | Integer | 1-100 | 转动速度 (%) |
请求:
{"reqId": 1, "method": "setMotorAngle", "params": {"pan": 45.0, "speed": 50}}
获取当前电机角度。
请求:
{"reqId": 1, "method": "getMotorAngle", "params": {}}
响应:
{"reqId": 1, "code": 0, "data": {"pan": 45.0}}
设备通过 vdm/{deviceId}/telemetry 上报位移和设备状态;环境字段按设备传感器能力提供。字段、单位及 Protobuf / JSON 示例见遥测数据。
code=0 成功,任意非零码均为失败,见 错误码。型号: O2-H | 版本: 1.0 | 更新: 2026-09-11
O2-H 是双目单轴旋转式视觉位移计,支持水平方向云台控制和巡航。标靶管理使用双目设备的 sensorId 参数,电机控制方式与 O1 的单轴控制一致。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 项目 | 说明 |
|---|---|
| 视觉传感器 | 双目 |
| 云台类型 | 单轴 |
sensorId | 新增标靶时必填,取值为 0 或 1 |
| 电机控制 | 支持,仅支持 pan |
| 巡航路径查询 | 支持 |
| 兼容手册 | 电机和巡航参考 O1,双目标靶参考 V2-W |
| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
| 方法 | 说明 |
|---|---|
setMotorAngle | 设置电机角度(仅 pan) |
getMotorAngle | 获取电机角度 |
setMotorZero | 设置电机零点 |
enableMotor | 启用电机 |
disableMotor | 禁用电机 |
| 方法 | 说明 |
|---|---|
getCruisePaths | 获取巡航路径 |
新增标靶时指定 sensor_id / sensorId 为 0 或 1;初始化已有标靶时可沿用保存的值。
O2-H 仅支持水平转动:Protobuf 使用 pan_degrees、speed_percent;JSON 使用 pan、speed。参数范围与示例见 O1 电机控制。
型号: X1 | 版本: 1.0 | 更新: 2026-09-11
X1 是单目双轴旋转式视觉位移计,支持水平和垂直云台控制及自动巡航。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
| 方法 | 说明 |
|---|---|
setMotorAngle | 设置电机角度 |
getMotorAngle | 获取电机角度 |
setMotorZero | 设置电机零点 |
enableMotor | 启用电机 |
disableMotor | 禁用电机 |
| 方法 | 说明 |
|---|---|
ispCtl | ISP 图像参数控制(曝光、降噪、翻转/镜像等) |
| 方法 | 说明 |
|---|---|
getCruisePaths | 获取巡航路径 |
标靶管理 API 的完整字段约束参考 API参考。
对指定标靶执行参考位置初始化/标定。通常先通过 addTargets 或 setTargets 保存标靶配置;初始化时可只传 targetId。如需覆盖保存配置,可在本次请求中提供 roi、distance 或 targetModel。
在已有标靶基础上添加新标靶。
获取当前标靶列表。
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
targets[].targetId | String | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 视觉传感器 ID,单目设备为 0 |
targets[].roi | Object | 标靶 ROI 区域 |
targets[].distance | Float | 测量距离,单位 m |
targets[].role | String | 标靶角色:MP 为被测点,RP 为稳定基准点,CP 为控制/校核点 |
targets[].targetModel | String | 标靶型号,取值 T10、T20、T50、T100、T200 |
targets[].skipMeasurement | Boolean | 是否跳过测量 |
更新已有标靶的配置。
删除指定标靶。
设置电机角度。
参数:
| 字段 | 类型 | 范围 | 说明 |
|---|---|---|---|
pan | Float | -180 ~ 180 | 水平角度 (°) |
tilt | Float | -90 ~ 90 | 垂直角度 (°) |
speed | Integer | 1-100 | 转动速度 (%) |
请求:
{"reqId": 1, "method": "setMotorAngle", "params": {"pan": 45.0, "tilt": -10.0, "speed": 50}}
获取当前电机角度。
请求:
{"reqId": 1, "method": "getMotorAngle", "params": {}}
响应:
{"reqId": 1, "code": 0, "data": {"pan": 45.0, "tilt": -10.0}}
ISP 图像参数控制,支持曝光、降噪、画面翻转/镜像/旋转等设置。
请求:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "getStatus"
}}
响应:
{"reqId": 1, "code": 0, "data": {
"vdmModeEnabled": true,
"exposureLocked": false,
"exposureMode": "manual",
"nrLevel": "mediumNoise",
"enable3dnr": true,
"exposurePreset": "medium",
"cameraCount": 1,
"flip": false,
"mirror": false,
"rotation": 0,
"exposureInfo": {
"iso": 200,
"expTime": 20000,
"aGain": 1024,
"dGain": 1024,
"ispDGain": 256,
"aveLum": 128
}
}}
支持画面翻转、镜像和旋转。
注意:翻转/镜像/旋转设置需要重启设备后生效。 设置后配置会自动持久化,多相机设备(如双目型号)所有相机会同时生效。
参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
flip | Boolean | 否 | 画面垂直翻转 |
mirror | Boolean | 否 | 画面水平镜像 |
rotation | Integer | 否 | 画面旋转角度,仅支持 0/90/180/270 |
请求 - 启用垂直翻转:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"config": {
"flip": true
}
}}
请求 - 启用水平镜像:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"config": {
"mirror": true
}
}}
请求 - 同时启用翻转和镜像(等效 180° 旋转):
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"config": {
"flip": true,
"mirror": true
}
}}
请求 - 恢复默认(关闭翻转和镜像):
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"config": {
"flip": false,
"mirror": false
}
}}
请求 - 设置旋转 90°:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"config": {
"rotation": 90
}
}}
请求 - 设置旋转 270°:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"config": {
"rotation": 270
}
}}
请求 - 取消旋转:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"config": {
"rotation": 0
}
}}
响应:
{"reqId": 1, "code": 0}
参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
exposureMode | String | 否 | 曝光模式:auto, semiAuto, manual |
manualExpTime | Integer | 否 | 手动曝光时间 (微秒),范围 100-100000 |
manualAgain | Integer | 否 | 手动模拟增益,1024=1x, 4096=4x, 8192=8x |
nrLevel | String | 否 | 降噪等级:off, lowNoise, mediumNoise, highNoise, veryHighNoise |
enable3dnr | Boolean | 否 | 是否启用 3DNR 时域降噪 |
请求 - 手动曝光 20ms + 4x 增益:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"config": {
"exposureMode": "manual",
"manualExpTime": 20000,
"manualAgain": 4096
}
}}
通过 isp 数组对每个相机独立配置曝光参数。
参数(isp 数组项):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
cameraId | Integer | 是 | 相机索引 (0, 1, …) |
expTime | Integer | 否 | 曝光时间 (微秒),范围 1000-40000 |
gain | Integer | 否 | 增益,范围 1024-16384 |
flip | Boolean | 否 | 画面垂直翻转(重启后生效) |
mirror | Boolean | 否 | 画面水平镜像(重启后生效) |
rotation | Integer | 否 | 画面旋转角度 0/90/180/270(重启后生效) |
请求:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setConfig",
"isp": [
{"cameraId": 0, "expTime": 20000, "gain": 4096, "flip": true, "mirror": false}
]
}}
参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
exposurePreset | String | 是 | 档位:low, medium, high |
| 档位 | 曝光时间 | 增益 | 场景 |
|---|---|---|---|
low | 10ms | 1x | 近距离/强 IR 补光 |
medium | 20ms | 1x | 标准模式 |
high | 30ms | 10x | 远距离/弱 IR 补光 |
请求:
{"reqId": 1, "method": "ispCtl", "params": {
"action": "setExposurePreset",
"exposurePreset": "medium"
}}
设备通过 vdm/{deviceId}/telemetry 上报位移和设备状态;环境字段按设备传感器能力提供。字段、单位及 Protobuf / JSON 示例见遥测数据。
code=0 成功,任意非零码均为失败,见 错误码。型号: X2-H | 版本: 1.0 | 更新: 2026-09-11
X2-H 系列是双目双轴旋转式视觉位移计,支持双轴云台和自动巡航,适用于多点巡航监测场景。
连接与数据接收见快速入门。完整代码见 GitHub SDK 和告警接入示例。
setMotorAngle 移动到测量位置。initRefTargets 初始化该位置可见的标靶,等待 event 中的 REF_INIT_RESULT 成功结果。startMeasurement,从 telemetry Topic 接收位移数据。| 方法 | 说明 |
|---|---|
getAttr | 获取属性 |
setAttr | 设置属性 |
reboot | 重启设备 |
syncTime | 同步时间 |
| 方法 | 说明 |
|---|---|
initRefTargets | 初始化标靶参考位置 |
addTargets | 添加标靶 |
getTargets | 获取标靶列表 |
setTargets | 更新标靶配置 |
deleteTargets | 删除标靶 |
| 方法 | 说明 |
|---|---|
startMeasurement | 启动测量 |
stopMeasurement | 停止测量 |
setLightLevel | 设置补光灯发光挡位 |
getLightLevel | 获取补光灯发光挡位 |
snapshot | 获取快照 |
| 方法 | 说明 |
|---|---|
setMotorAngle | 设置电机角度 |
getMotorAngle | 获取电机角度 |
setMotorZero | 设置电机零点 |
enableMotor | 启用电机 |
disableMotor | 禁用电机 |
| 方法 | 说明 |
|---|---|
getCruisePaths | 获取巡航路径 |
标靶管理 API 的完整字段约束参考 API参考。
对指定标靶执行参考位置初始化/标定。通常先通过 addTargets 或 setTargets 保存标靶配置;初始化时可只传 targetId。双目设备可从已保存配置中读取 sensorId,如需覆盖保存配置,可在本次请求中提供 sensorId、roi、distance 或 targetModel。
参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
targets | Array | 是 | 要初始化标靶参考位置的标靶数组,不能为空 |
targets[].targetId | String | 是 | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 否 | 视觉传感器 ID (0 或 1);不传时使用已保存标靶配置 |
targets[].roi | Object | 否 | ROI 区域;不传时使用已保存标靶配置 |
targets[].distance | Float | 否 | 测量距离 (m);不传时使用已保存标靶配置 |
targets[].targetModel | String | 否 | 标靶型号,取值 T10、T20、T50、T100、T200 |
注意: X2-H 4M 分辨率为 2560×1440,ROI 坐标需相应调整。
在已有标靶基础上添加新标靶。
获取当前标靶列表。
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
targets[].targetId | String | 标靶 ID,1-64 字节,非空,不包含控制字符 |
targets[].sensorId | Integer | 视觉传感器 ID,双目设备为 0 或 1 |
targets[].roi | Object | 标靶 ROI 区域 |
targets[].distance | Float | 测量距离,单位 m |
targets[].role | String | 标靶角色:MP 为被测点,RP 为稳定基准点,CP 为控制/校核点 |
targets[].targetModel | String | 标靶型号,取值 T10、T20、T50、T100、T200 |
targets[].skipMeasurement | Boolean | 是否跳过测量 |
更新已有标靶的配置。
删除指定标靶。
设置电机角度。
参数:
| 字段 | 类型 | 范围 | 说明 |
|---|---|---|---|
pan | Float | -180 ~ 180 | 水平角度 (°) |
tilt | Float | -90 ~ 90 | 垂直角度 (°) |
speed | Integer | 1-100 | 转动速度 (%) |
请求:
{"reqId": 1, "method": "setMotorAngle", "params": {"pan": 45.0, "tilt": -10.0, "speed": 50}}
获取当前电机角度。
请求:
{"reqId": 1, "method": "getMotorAngle", "params": {}}
响应:
{"reqId": 1, "code": 0, "data": {"pan": 45.0, "tilt": -10.0}}
reportMetrics 支持 dx、dy。
| 指标 | 说明 |
|---|---|
dx | X方向累积位移变化 |
dy | Y方向累积位移变化 |
设备通过 vdm/{deviceId}/telemetry 上报位移和设备状态;环境字段按设备传感器能力提供。字段、单位及 Protobuf / JSON 示例见遥测数据。
code=0 成功,任意非零码均为失败,见 错误码。INT705 倾角振动传感器用于结构物姿态、振动和环境状态监测。设备通过 MQTT JSON 接入,设备侧只配置一个上行 Topic 和一个下行 Topic。
| 文档 | 说明 |
|---|---|
| 协议规格 | MQTT 主题配置、上报 JSON、下发 JSON 和字段说明 |
| 型号 | 网络 | 说明 |
|---|---|---|
| INT705 | 4G LTE Cat 1 | 高精度物联网倾角振动传感器 |
| 参数 | 值 |
|---|---|
| 协议 | MQTT v3.1.1 |
| Payload | JSON 字符串 |
| 编码 | UTF-8 |
| Client ID | 设备 IMEI(设备唯一标识) |
| Username | MQTT 用户名;服务器不要求认证时留空 |
| Password | MQTT 密码;服务器不要求认证时留空 |
该设备只支持配置一个上行 Topic 和一个下行 Topic。服务端应按设备配置的 Topic 接收和下发。
| 配置项 | 方向 | 说明 | 示例 |
|---|---|---|---|
| Pub Topic | 上行 | 设备向服务端发布数据、状态和告警 | inclinometer/{IMEI}/up |
| Sub Topic | 下行 | 服务端向设备下发参数配置或清零指令 | inclinometer/{IMEI}/down |
{IMEI} 为设备 IMEI,作为设备唯一标识。实际项目中 Topic 字符串可以按 MQTT 服务器要求配置,但设备侧仍只有一个上行 Topic 和一个下行 Topic。建议使用普通业务主题,不使用 /sys/ 或 $SYS/ 前缀,避免与服务器系统主题、平台预留主题或访问控制规则混淆。
设备通过 Pub Topic 上报 JSON 字符串。根对象必须包含 params,设备数据字段放在 params 对象内。
{
"params": {
"INDEX": 1,
"IMEI": "862177241709877",
"PID": 386025,
"XANG": 0.000,
"YANG": 0.000,
"ZANG": 0.000,
"XACC": 0.000,
"YACC": 0.000,
"ZACC": 0.000,
"ALARM_FLG": 0,
"ALARM_TYPE": 0,
"ANG": 0.000,
"ACC": 0.000,
"CLR_FLG": 0,
"FIX": 0,
"FREQ": 28800,
"RFAA": 600,
"ACTC": 0,
"CSQ": 0,
"EQC": 0,
"TEMP": 0.00,
"LNGTD": 0.00,
"LATTD": 0.00,
"SOFTVERSION": "205A220916"
}
}
上行报文为设备 JSON,不包含设备时间戳字段。服务端入库时可使用 MQTT 接收时间作为数据时间。
以下关键字均位于 params 对象内。
| 关键字 | 含义 | 格式 | 范围 | 备注 |
|---|---|---|---|---|
INDEX | 报文序号 | uint32 | 0 - 2^32 | 上报自增 |
IMEI | 国际移动设备识别码 | String | 15 - 17 位 | 设备唯一标识 |
PID | 产品 ID | int32 | 0 - 2^31 | 用户自分配 |
XANG | X 轴与水平面的夹角 | Float | -90 - 90° | 当前角度,超过角度阈值产生告警 |
YANG | Y 轴与水平面的夹角 | Float | -90 - 90° | 当前角度,超过角度阈值产生告警 |
ZANG | Z 轴与水平面的夹角 | Float | -90 - 90° | 不清零,不告警 |
XACC | X 轴加速度 | Float | -2 - 2g | 加速度变化量,超过加速度阈值产生告警 |
YACC | Y 轴加速度 | Float | -2 - 2g | 加速度变化量,超过加速度阈值产生告警 |
ZACC | Z 轴加速度 | Float | -2 - 2g | 加速度变化量,超过加速度阈值产生告警 |
ALARM_FLG | 告警标志 | int | 0 正常,1 告警 | 默认 0 |
ALARM_TYPE | 告警类型 | int | 0 正常,1 角度告警,2 加速度告警,3 角度和加速度同时告警 | 默认 0 |
ANG | 角度阈值 | Float | 0 - 90° | 默认 0° |
ACC | 加速度阈值 | Float | 0 - 1g | 默认 0g |
CLR_FLG | 清零标志 | int | 0 绝对零点,1 相对零点 | 默认 0 |
FIX | 安装方向 | int | 0 水平向上,1 垂直向上,2 垂直向左,3 垂直向右,4 水平向下 | 默认 0 |
FREQ | 休眠周期 | int | 600 - 259200s | 默认 86400 秒 |
RFAA | 告警周期 | int | 600 - 259200s | 默认 600 秒 |
ACTC | 告警确认 | int | 0 - 30min | 默认 0 分钟 |
CSQ | 信号强度 | int | 0 - 99 | <=10 信号差,11 - 18 信号一般,>18 信号好 |
EQC | 电量 | int | 0 - 100 | 百分比 |
TEMP | 温度 | Float | -128 - 127°C | 单位:摄氏度 |
LNGTD | 经度 | Float | -180 - 180° | 单位:度 |
LATTD | 纬度 | Float | -90 - 90° | 单位:度 |
SOFTVERSION | 软件版本 | String | 10 个字符 | - |
params,再解析其中的设备字段。INDEX 是报文序号,不是时间戳。上行报文不包含设备时间字段,数据时间建议使用服务端收到 MQTT 消息的时间。IMEI 是设备唯一标识,建议校验 Topic 中的 {IMEI} 与报文中的 params.IMEI 是否一致。ANG 和 ACC 是当前配置阈值,不是实时测量值。实时测量值分别为 XANG、YANG、ZANG 和 XACC、YACC、ZACC。XANG、YANG 与 ANG 判断;ZANG 只上报,不参与清零和告警。XACC、YACC、ZACC 与 ACC 判断。FIX 表示设备安装方向,服务端展示或计算角度时应保留该配置值。服务端通过 Sub Topic 下发 JSON 字符串。根对象必须包含 params,配置字段放在 params 对象内。字段名保持设备定义的大写格式。
{
"params": {
"ANG": 5,
"ACC": 0.082,
"FREQ": 43200,
"RFAA": 1200,
"ACTC": 3,
"CLR_FLG": 1
}
}
{"params":{"ANG":5}}
{"params":{"ACC":0.082}}
{"params":{"FREQ":43200}}
{"params":{"RFAA":1200}}
{"params":{"ACTC":3}}
{"params":{"CLR_FLG":1}}
| 字段 | 类型 | 范围 | 说明 |
|---|---|---|---|
params.ANG | Float | 0 - 90° | 倾角告警阈值 |
params.ACC | Float | 0 - 1g | 振动加速度告警阈值 |
params.FREQ | Integer | 600 - 259200s | 休眠周期 |
params.RFAA | Integer | 600 - 259200s | 告警周期 |
params.ACTC | Integer | 0 - 30min | 告警确认 |
params.CLR_FLG | Integer | 0 或 1 | 清零标志,0 表示绝对零点,1 表示相对零点 |
下发时直接发布完整 JSON 对象字符串,不要把整个 JSON 再作为字符串值封装;不要使用单引号、注释或尾逗号;所有下行参数必须放在 params 对象内,字段名区分大小写。
配置下发后,服务端可通过后续上行报文中的 ANG、ACC、FREQ、RFAA、ACTC 等字段确认设备当前配置值;清零动作可结合后续角度数据判断是否生效。
| 条件 | 字段 |
|---|---|
| 正常 | ALARM_FLG = 0,ALARM_TYPE = 0 |
| 倾角超过阈值 | ALARM_FLG = 1,ALARM_TYPE = 1 |
| 振动加速度超过阈值 | ALARM_FLG = 1,ALARM_TYPE = 2 |
| 倾角和振动加速度同时超过阈值 | ALARM_FLG = 1,ALARM_TYPE = 3 |
| 设置相对零点 | 服务端下发 {"params":{"CLR_FLG":1}} |
服务端解析上行数据时应优先判断 ALARM_FLG,再根据 ALARM_TYPE 区分告警类型。
应变读数仪用于结构健康监测中的应变数据采集,通过 MQTT + Protobuf 协议上报数据。
| 文档 | 说明 |
|---|---|
| 协议规格 | MQTT 主题、Protobuf 定义、字段说明 |
| 型号 | 通道数 | 最高采样频率 | 说明 |
|---|---|---|---|
| SGR-10 | 10 | 100Hz | 振玄 10 通道应变读数仪 |
| 参数 | 值 |
|---|---|
| 协议 | MQTT v3.1.1 |
| Broker | 由平台提供 |
| 端口 | 1883 |
| Payload | Protobuf |
支持两种 MQTT 认证方式:
| 方式 | clientId | username | password |
|---|---|---|---|
| Access Token | 任意 | Access Token | 留空 |
| Basic | deviceId | username | password |
认证凭据在平台创建设备后获取。clientId 建议使用 deviceId。
| 主题 | 方向 | QoS | 说明 |
|---|---|---|---|
strain/{deviceId}/telemetry | 上行 | 0 | 遥测数据(高频应变值) |
strain/{deviceId}/attributes | 上行 | 1 | 设备属性上报 |
strain/{deviceId}/attributes/subscribe | 下行 | 1 | 平台下发配置指令 |
设备端编译以下 .proto 文件生成对应语言的代码:
syntax = "proto3";
package shm.strain.v1;
// 遥测上报消息
message StrainTelemetry {
StrainBatch strainBatch = 1;
message StrainBatch {
uint64 timestamp = 1; // 首样本设备时间戳(毫秒)
uint32 ch_no = 2; // 通道编号(从 1 开始)
uint32 sample_interval_ms = 3; // 采样间隔(ms),100Hz=10, 50Hz=20, 20Hz=50
repeated sint32 values = 4; // 该通道的应变值数组(με)
optional float temperature = 5; // 该通道温度值(℃)
optional uint32 battery = 6; // 电池电量 0-100%
optional uint32 mode = 7; // 设备工作模式
optional uint32 status = 8; // 状态码,0=正常
}
}
// 属性上报消息
message StrainDeviceAttributes {
string firmware_version = 1; // 固件版本
string serial_number = 2; // 设备序列号
string device_model = 3; // 设备型号
uint32 channel_count = 4; // 通道数
uint32 sample_interval_ms = 5; // 采样间隔(ms),所有通道统一
}
遥测数据封装在 StrainTelemetry.strainBatch 中,每个通道独立一包。
| 字段 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
timestamp | uint64 | 是 | 本批次首样本的设备时间戳,毫秒 | 1776206400000 |
ch_no | uint32 | 是 | 通道编号,从 1 开始 | 1 |
sample_interval_ms | uint32 | 是 | 采样间隔,100Hz=10, 50Hz=20, 20Hz=50 | 10 |
values | repeated sint32 | 是 | 该通道应变值数组(με),长度 = 1000 / sample_interval_ms | [1500,1502,1498,...] |
temperature | float | 否 | 该通道温度值(℃) | 25.3 |
battery | uint32 | 否 | 电池电量百分比 | 60 |
mode | uint32 | 否 | 工作模式编码 | 0 |
status | uint32 | 否 | 0=正常,其他=异常码 | 0 |
设备启动、固件升级或配置变更时上报一次。
| 字段 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
firmware_version | string | 是 | 固件版本 | "1.0.3" |
serial_number | string | 是 | 设备序列号 | "ZX-0001" |
device_model | string | 是 | 设备型号 | "SGR-10" |
channel_count | uint32 | 是 | 通道数 | 10 |
sample_interval_ms | uint32 | 是 | 采样间隔(ms),所有通道统一 | 10 |
平台通过修改共享属性下发配置指令,设备订阅 strain/{deviceId}/attributes/subscribe 接收变更。
| 属性 | 类型 | 说明 | 示例 |
|---|---|---|---|
sample_interval_ms | uint32 | 修改采样间隔 | 20(50Hz) |
mode | uint32 | 切换工作模式 | 1 |
reboot | bool | 重启设备 | true |
sync_time | uint64 | 时间同步,平台当前时间(ms) | 1776206400000 |
设备收到属性变更后直接执行,无需回复。设备重连后可主动请求最新共享属性获取最新配置。
每个通道每秒上报一包,包内样本时间按以下公式推导:
第 n 个样本时间 = timestamp + n × sample_interval_ms
示例(通道 1,100Hz,timestamp = 1776206400000):
| 样本 | 时间戳 |
|---|---|
| 第 1 个(n=0) | 1776206400000 |
| 第 2 个(n=1) | 1776206400010 |
| 第 100 个(n=99) | 1776206400990 |
以 10 通道 100Hz 设备为例,每秒上报 10 个包:
每秒重复:
1. 获取当前设备时间戳 timestamp
2. 对每个通道 ch_no = 1..10:
a. 采集 100 个应变值
b. 构造 StrainTelemetry 消息
c. 序列化为 Protobuf 二进制
d. 发布到 strain/{deviceId}/telemetry,QoS 0
| 包 | ch_no | sample_interval_ms | values 长度 |
|---|---|---|---|
| 包1 | 1 | 10 | 100 |
| 包2 | 2 | 10 | 100 |
| … | … | … | … |
| 包10 | 10 | 10 | 100 |
同一秒的 10 个包共享同一个 timestamp。
pip install paho-mqtt protobuf
将上方 Protobuf 定义保存为 strain.proto,然后编译:
protoc --python_out=. strain.proto
#!/usr/bin/env python3
"""应变读数仪模拟器 - 10通道 100Hz"""
import math, random, time
import paho.mqtt.client as mqtt
import strain_pb2
BROKER = "gw.mqtt.inteagle.com"
PORT = 1883
TOKEN = "your_access_token" # 替换为平台分配的 Access Token
DEVICE_ID = "ZX-0001" # 替换为平台分配的设备编号
CHANNELS = 10
SAMPLE_INTERVAL_MS = 10 # 100Hz
def on_connect(client, userdata, flags, rc, properties=None):
print(f"连接{'成功' if rc == 0 else '失败: ' + str(rc)}")
def main():
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"strain-{DEVICE_ID}")
client.username_pw_set(TOKEN)
client.on_connect = on_connect
client.connect(BROKER, PORT, keepalive=60)
client.loop_start()
time.sleep(1)
# 上报设备属性(仅启动时一次)
attrs = strain_pb2.StrainDeviceAttributes()
attrs.firmware_version = "1.0.3"
attrs.serial_number = DEVICE_ID
attrs.device_model = "SGR-10"
attrs.channel_count = CHANNELS
attrs.sample_interval_ms = SAMPLE_INTERVAL_MS
client.publish(f"strain/{DEVICE_ID}/attributes", attrs.SerializeToString(), qos=1)
print("属性上报完成")
# 持续上报遥测
topic = f"strain/{DEVICE_ID}/telemetry"
num_samples = 1000 // SAMPLE_INTERVAL_MS # 100
for sec in range(10):
ts_ms = int(time.time() * 1000)
for ch in range(1, CHANNELS + 1):
msg = strain_pb2.StrainTelemetry()
batch = msg.strainBatch
batch.timestamp = ts_ms
batch.ch_no = ch
batch.sample_interval_ms = SAMPLE_INTERVAL_MS
# 模拟应变数据
base = 1500 + ch * 100
for i in range(num_samples):
t = i * SAMPLE_INTERVAL_MS / 1000.0
val = int(base + 200 * math.sin(2 * math.pi * 2.0 * t) + random.randint(-10, 10))
batch.values.append(val)
batch.temperature = 25.3
batch.battery = 85
batch.status = 0
client.publish(topic, msg.SerializeToString(), qos=0)
print(f"第{sec+1}秒: 发送 {CHANNELS} 包")
time.sleep(1)
client.loop_stop()
client.disconnect()
print("完成")
if __name__ == "__main__":
main()
python sim_strain.py
连接成功
属性上报完成
第1秒: 发送 10 包
第2秒: 发送 10 包
第3秒: 发送 10 包
...
完成
本章节对文档中使用的专业术语和概念进行解释。
| 术语 | 英文 | 说明 |
|---|---|---|
| VDM | Visual Displacement Meter | 视觉位移计 |
| 设备 ID | Device ID | 设备的唯一标识符 |
| 标靶 | Target | 视觉位移计通过监测标靶计算出结构物变形 |
| 基准点标靶 | Reference Target | 基准点用于纠正设备测量中的误差 |
| 感兴趣区域 | Region of Interest (ROI) | 用于框选标靶的位置,标识标靶的名字 |
| 累积位移变化 | Displacement | 标靶相对于初值位置的位移变化量 |
| 采样频率 | Sampling Frequency | 视觉位移计的测量频率 |
| 术语 | 英文 | 说明 |
|---|---|---|
| 巡航 | Cruise / Patrol | 视觉位移计旋转监测时,自动巡航监测不同视野范围内的标靶 |
| 巡航路径 | Cruise Path | 视觉位移计旋转监测时的指定路线 |
| 巡航点 | Cruise Point / Waypoint | 视觉位移计通过监测标靶计算出结构物变形 |
| 停留时间 | Dwell Time | 基准点用于纠正设备测量中的误差 |
| 自动巡航 | Auto Patrol | 设备的唯一标识符 |
| 术语 | 英文 | 说明 |
|---|---|---|
| 监测项目 | Project | 一组相关监测点和设备的集合,通常对应一个工程项目 |
| 监测点 | Monitoring Point | 具体的测量位置,可关联一个或多个设备传感器数据源 |
| 遥测数据 | Telemetry | 设备上报的测量数据,如位移、温度、湿度等 |
| 3A | Alert, Alarm and Action | 告警的等级:预警、报警和行动 |
| 术语 | 英文 | 说明 |
|---|---|---|
| MQTT | Message Queuing Telemetry Transport | 轻量级消息传输协议,用于物联网设备通信 |
| Topic | - | MQTT 消息主题,用于消息的分类和路由 |
| QoS | Quality of Service | 消息服务质量等级(0/1/2) |
| 术语 | 英文 | 说明 |
|---|---|---|
| JSON | JavaScript Object Notation | 轻量级数据交换格式 |
| 时间戳 | Timestamp | Unix 时间戳,单位为毫秒 |
| 术语 | 英文 | 说明 |
|---|---|---|
| 客户 ID | Customer ID | 客户身份的唯一标识符 |
| Token | - | 认证令牌,用于 API 调用身份验证 |
| 实体 | Entity | 平台中的对象,包括设备、监测点、项目等 |