摩尔信使EdgeWeb:HTTP API 接口开发与调用指南
摩尔信使EdgeWeb:HTTP API 接口开发与调用指南
本文档描述 EdgeWeb 对外提供的 HTTP 接口。默认服务地址为:
http://<设备地址>:8080
实际监听地址、端口、令牌和 TLS 配置由 EdgeWeb 配置决定。
1. 通用约定
1.1 API 前缀
业务接口统一使用:
/api/v1
EdgeWeb 控制台静态页面不使用该前缀。
1.2 JSON 响应结构
REST 接口统一返回 JSON:
{
"code":0,
"message":"ok",
"data":{}
}
code = 0表示请求成功。 code != 0表示请求失败。 客户端应同时检查 HTTP 状态码和 code。HTTP 200 不应作为唯一的业务成功判断依据。
1.3 认证
除健康检查和静态页面外,接口需要只读令牌或控制令牌。
推荐使用 Bearer Token:
Authorization: Bearer <token>
也可以使用:
X-API-Token: <token>
权限说明:
未配置任何令牌时,仅静态页面和健康检查可用。
1.4 POST 请求
POST 接口必须指定:
Content-Type: application/json
控制类请求建议携带唯一的幂等键:
Idempotency-Key: <unique-printable-ascii-key>
要求:
最大长度为 128 个字符。 只能包含可打印 ASCII 字符。 相同幂等键和相同请求体会返回已有操作结果。 相同幂等键用于不同请求体时返回 HTTP 409。
1.5 分页
告警和历史接口采用从 1 开始的页码:
page=1&pageSize=30
page最小值为 1。 pageSize允许范围为 1~100。
1.6 CORS
需要跨域访问时,应配置一个精确的可信来源。不支持使用 *。同源访问 EdgeWeb 控制台时不需要配置 CORS。
2. 接口总览
/ | |||
/styles.css | |||
/app.js | |||
/pages/* | |||
/api/v1/health | |||
/api/v1/reports/stream | |||
/api/v1/devices | |||
/api/v1/device/points | |||
/api/v1/device/datas | |||
/api/v1/device/state | |||
/api/v1/device/cycle-self | |||
/api/v1/device/data | |||
/api/v1/device/data/query | |||
/api/v1/device/read | |||
/api/v1/device/write | |||
/api/v1/device/write-multi | |||
/api/v1/device/control | |||
/api/v1/operations/status | |||
/api/v1/alarms | |||
/api/v1/alarms/confirm | |||
/api/v1/history/devices | |||
/api/v1/history | |||
/api/v1/channels/control |
3. 健康检查
GET /api/v1/health
无需认证。
成功响应:
{
"code":0,
"message":"ok",
"data":{
"service":"edgeweb",
"version":"v1",
"readAccessConfigured":true,
"controlAccessConfigured":true,
"tlsConfigured":false
}
}
4. 设备接口
4.1 设备列表
GET /api/v1/devices
返回当前配置的设备快照及设备状态。
响应数据中的设备对象包含以下常用字段:
deviceId | ||
name | ||
address | ||
deviceType | ||
type | deviceType 相同 | |
ports | ||
protocols | ||
channelStates | ||
linkModes | ||
bindMasterMode | ||
bindMasterId | ||
pollInterval | ||
cmdBufferTime | ||
batchReadBegin | ||
state | ||
dataCount |
响应示例:
{
"code":0,
"message":"ok",
"data":{
"updatedAt":1784196000000,
"items":[
{
"deviceId":1,
"name":"NET001-001",
"address":"1",
"deviceType":10,
"type":10,
"ports":["NET001"],
"protocols":[1],
"channelStates":[1],
"linkModes":[0],
"state":1,
"dataCount":5
}
],
"devices":[
{
"deviceId":1,
"name":"NET001-001",
"address":"1",
"deviceType":10,
"type":10,
"ports":["NET001"],
"protocols":[1],
"channelStates":[1],
"linkModes":[0],
"state":1,
"dataCount":5
}
]
}
}
devices 是兼容字段,内容与 items 相同。客户端新接入时应优先使用 items。
设备状态值:
4.2 设备点位列表
GET /api/v1/device/points?deviceId=1
返回指定设备的全部配置点位和当前缓存值。/api/v1/device/datas 是兼容路径,响应相同。
参数:
deviceId |
点位对象包含以下常用字段:
dataId | ||
name | ||
value | ||
unit | ||
range | ||
showType | ||
tagColor | ||
cmdValue | ||
enumOptions | value 和 name |
响应示例:
{
"code":0,
"message":"ok",
"data":{
"deviceId":1,
"items":[
{
"dataId":1,
"name":"温度",
"value":"25.6",
"unit":"℃",
"range":"0~100",
"showType":0,
"enumOptions":[]
}
],
"datas":[
{
"dataId":1,
"name":"温度",
"value":"25.6",
"unit":"℃",
"range":"0~100",
"showType":0,
"enumOptions":[]
}
]
}
}
datas 是兼容字段,内容与 items 相同。客户端新接入时应优先使用 items。
4.3 设备状态
GET /api/v1/device/state?deviceId=1
参数:
deviceId |
{
"code":0,
"message":"ok",
"data":{
"deviceId":1,
"state":1
}
}
4.4 自循环状态
GET /api/v1/device/cycle-self?deviceId=1
参数:
deviceId |
{
"code":0,
"message":"ok",
"data":{
"deviceId":1,
"cycling":true
}
}
4.5 单点当前值
GET /api/v1/device/data?deviceId=1&dataId=10
参数:
deviceId | |||
dataId |
{
"code":0,
"message":"ok",
"data":{
"deviceId":1,
"dataId":10,
"value":"25.6"
}
}
4.6 批量查询当前值
POST /api/v1/device/data/query
该接口只读取缓存值,使用 Read 权限。
请求体:
{
"items":[
{"deviceId":1,"dataId":10},
{"deviceId":2,"dataId":20}
]
}
响应:
{
"code":0,
"message":"ok",
"data":{
"items":[
{"deviceId":1,"dataId":10,"value":"25.6"},
{"deviceId":2,"dataId":20,"value":"100"}
]
}
}
批量数量不能超过服务端配置的上限。
4.7 请求设备读取
POST /api/v1/device/read
该接口会向设备下发读取请求,需要 Control 权限。
请求体:
{
"deviceId":1,
"dataIds":[10,11,12]
}
成功响应:
{
"code":0,
"message":"ok",
"data":{
"operationId":"123",
"status":"succeeded",
"result":"OK"
}
}
4.8 写入单点
POST /api/v1/device/write
请求体:
{
"deviceId":1,
"dataId":10,
"value":"30"
}
浏览器示例:
const response = awaitfetch("/api/v1/device/write", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Token": controlToken,
"Idempotency-Key": crypto.randomUUID()
},
body: JSON.stringify({ deviceId: 1, dataId: 10, value: "30" })
});
const result = await response.json();
if (!response.ok || result.code !== 0) {
thrownewError(result.message);
}
4.9 单设备批量写入
POST /api/v1/device/write
请求体:
{
"deviceId":1,
"datas":[
{"dataId":10,"value":"30"},
{"dataId":11,"value":"1"}
]
}
4.10 跨设备批量写入
POST /api/v1/device/write-multi
请求体:
{
"datas":[
{"deviceId":1,"dataId":10,"value":"30"},
{"deviceId":2,"dataId":20,"value":"100"}
]
}
响应会包含每个设备的执行结果:
{
"code":0,
"message":"ok",
"data":{
"operationId":"123",
"status":"succeeded",
"results":[
{"deviceId":1,"succeeded":true,"result":"OK"},
{"deviceId":2,"succeeded":true,"result":"OK"}
]
}
}
4.11 设备控制
POST /api/v1/device/control
请求体:
{
"deviceId":1,
"cmdType":1
}
cmdType 为当前 MThings 版本定义的设备控制命令编号。外部客户端应以目标版本公开的命令编号为准,不要跨版本假设编号含义。
成功响应:
{
"code":0,
"message":"accepted",
"data":{
"operationId":"123",
"status":"succeeded",
"accepted":true
}
}
5. 操作状态
设备读取、写入、控制、告警确认和通道控制由服务端串行执行。响应数据会包含:
{
"operationId":"123",
"status":"succeeded"
}
可能的状态:
pending | |
accepted | |
succeeded | |
failed | |
cancelled |
GET /api/v1/operations/status?operationId=123
该接口需要 Control 权限。
请求超时时,如果响应中包含:
{
"operationId":"123",
"outcomeUnknown":true
}
不要直接重试控制类请求,应先查询操作状态,避免重复控制设备或通道。
6. 实时事件流
GET /api/v1/reports/stream
使用 Server-Sent Events(SSE)持续推送设备和通道变化。
可选过滤参数可以重复出现:
/api/v1/reports/stream?deviceId=1&deviceId=2&event=device-data&event=device-state
支持的事件:
device-data | |
device-state | |
curve-data | |
self-data | |
multi-device-data | |
device-list | /api/v1/devices |
channel-state | |
stream-reset |
device-data 示例:
id: 101
event: device-data
data: {"code":0,"message":"ok","data":{"deviceId":1,"datas":[{"dataId":10,"offset":0,"value":"25.6"}]}}
channel-state 示例:
id: 102
event: channel-state
data: {"code":0,"message":"ok","data":{"channel":"NET001","state":1,"time":1784196000000}}
浏览器原生 EventSource 不能设置认证请求头,因此应使用 fetch 流式读取:
const response = awaitfetch("/api/v1/reports/stream", {
headers: { "X-API-Token": readToken }
});
const reader = response.body.getReader();
const decoder = newTextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const text = decoder.decode(value, { stream: true });
// 按空行拆分 SSE 消息,并解析 event/data 字段。
}
服务端会定期发送心跳注释。客户端重连时可以发送:
Last-Event-ID: 101
服务端会尝试从有限的事件缓存中重放后续事件。
7. 告警接口
7.1 查询告警
GET /api/v1/alarms
查询当前告警或历史告警。
参数:
scope | active | activehistory | |
page | 1 | ||
pageSize | 30 |
响应:
{
"code":0,
"message":"ok",
"data":{
"page":1,
"pageSize":30,
"total":1,
"pageCount":1,
"items":[
{
"alarmId":1,
"name":"温度过高",
"type":"温度",
"level":0,
"triggered":true,
"confirmed":false,
"triggerTime":"2026-07-16 10:00:00",
"confirmTime":"",
"recoverTime":"",
"snapshot":"温度=86.4"
}
]
}
}
告警级别:
7.2 确认告警
POST /api/v1/alarms/confirm
该接口需要 Control 权限。
请求体:
{
"alarmId":1
}
成功响应:
{
"code":0,
"message":"ok",
"data":{
"operationId":"123",
"status":"succeeded",
"alarmId":1,
"confirmed":true
}
}
8. 历史数据接口
8.1 历史设备列表
GET /api/v1/history/devices
仅返回已配置历史记录点位的设备。
{
"code":0,
"message":"ok",
"data":{
"items":[
{
"deviceId":1,
"name":"NET001-001",
"pointCount":5
}
]
}
}
8.2 查询历史数据
GET /api/v1/history
参数:
deviceId | |||
date | yyyyMMdd | ||
startTime | HH:mm:ss | ||
endTime | HH:mm:ss | ||
page | 1 | ||
pageSize | 30 |
startTime 和 endTime 必须同时提供。
响应中的列由设备当日历史数据动态决定:
{
"code":0,
"message":"ok",
"data":{
"page":1,
"pageSize":30,
"total":2,
"pageCount":1,
"columns":[
{"field":"id","name":"ID"},
{"field":"dtime","name":"Date Time"},
{"field":"D_10","dataId":10,"name":"温度"}
],
"rows":[
["2","2026-07-16 10:00:10","25.7"],
["1","2026-07-16 10:00:00","25.6"]
],
"summary":[
{
"dataId":10,
"name":"温度",
"max":"25.7",
"min":"25.6",
"average":"25.65"
}
]
}
}
注意:
rows中的值与 columns位置一一对应。summary按全部筛选结果计算,不只统计当前页。 指定日期没有历史数据时返回失败,不会创建空数据。
9. 通道接口
POST /api/v1/channels/control
启动或停止通信通道。该接口需要 Control 权限。
请求体:
{
"channel":"NET001",
"action":"launch"
}
action 允许值:
launch | |
stop |
成功响应:
{
"code":0,
"message":"ok",
"data":{
"operationId":"123",
"status":"succeeded",
"channel":"NET001",
"action":"launch"
}
}
10. 静态页面
GET /
返回 EdgeWeb 控制台首页。
同时支持:
GET /styles.css
GET /app.js
GET /pages/<relative-path>
静态资源使用 Cache-Control: no-cache,并设置 Content Security Policy。
11. 常见错误
常见业务错误码:
12. 推荐调用流程
EdgeWeb 或移动客户端推荐按以下顺序接入:
调用 /api/v1/health检查服务和权限配置。使用只读令牌调用 /api/v1/devices获取设备完整快照。选择设备后调用 /api/v1/device/points获取点位结构和初值。连接 /api/v1/reports/stream,增量更新设备状态、通道状态和实时值。收到 device-list时重新获取设备和当前点位快照。控制类操作使用控制令牌和唯一 Idempotency-Key。控制类操作超时且结果未知时,先通过 /api/v1/operations/status查询。告警和历史数据使用服务端分页,避免一次请求大量记录。