Skip to content

网关 MQTT 接入 ​

网关设备通过 MQTT 接入 ZhiLian.Yun 后,可以代无法直接联网的子设备上报数据、接收平台下发消息,并维护子设备在线状态。

网关自身仍然使用设备证书连接平台,连接参数、接入点和身份认证方式与 设备 MQTT 接入 一致。区别在于:网关代子设备通信时,协议报文使用 gw 表示子设备数据,gw 的键通常是子设备地址。

TIP

直连设备报文使用 data;网关代子设备报文使用 gw。不要把子设备数据放到直连设备的 data 中。

子设备地址 ​

子设备地址由网关侧定义,用于在同一个网关下唯一标识子设备。常见取值包括:

  • Modbus 从站地址。
  • RS485/LoRa 子设备地址。
  • 子设备 SN、MAC、IMEI 或业务编号。
  • 网关内部维护的唯一逻辑地址。

示例中使用 SUB_DEVICE_ADDR1 和 SUB_DEVICE_ADDR2 表示子设备地址。

TIP

. 是网关层级的保留分隔符:7.8 表示「地址为 7 的(下级)网关下、地址为 8 的设备」。 子设备地址本身不要包含 .,否则会被当成多级路径解析,导致上报数据无法归属。 多级网关的用法见 多级网关(级联)。

多级网关(级联) ​

网关下面还可以再挂网关,形成多级网关,例如「集中网关 → 区域网关 → RS485 子设备」。 中间层网关在协议上只作为子设备地址中的一段出现,它自己不需要再连云平台,也不占用额外连接。

拓扑与地址 ​

层级之间用 . 分隔,从最上层网关往下依次拼接:

text
集中网关(连云平台)
└── 区域网关        子设备地址 "7"
    └── 温度子设备   子设备地址 "7.8"
  • 区域网关在集中网关下的子设备地址是 7。
  • 温度子设备在区域网关下的子设备地址是 8;上报给平台时用完整路径 7.8。
  • 服务端按 . 从最上层开始逐级解析;相邻两级的 msgProtocol 必须一致,层级深度受子设备地址长度限制。

控制台配置顺序:先在「设备类型」里准备网关类型与最下层设备的类型,建好设备,然后

  1. 打开集中网关的「子设备」页,关联区域网关,并设置子设备地址 7;
  2. 打开区域网关的「子设备」页,关联温度子设备,并设置子设备地址 8。

两条关联都要求父子 msgProtocol 一致,且不能把设备关联到自己的下级(平台会拒绝成环的拓扑)。

上报 ​

中间层网关自己的数据用它的地址,它下面设备的数据用完整路径。网关始终只用一条连接:

json
{
  "id": 1,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "7": { "temp": 30 },
    "7.8": { "temperature": 26.5, "humidity": 62 }
  }
}

7 的数据归属到区域网关,7.8 的数据归属到温度子设备,不会互相串扰。

下发 ​

平台把下行报文发到最上层网关那一条连接,gw 的键是完整路径:

json
{
  "id": 3,
  "time": 1626197189638,
  "method": "attributes/set",
  "data": {},
  "gw": { "7.8": { "temperature": 27 } }
}

属性下发、属性采集、命令下发都是这个形态。目标不是最上层网关自身时,data 会是空对象(命令下发时 data.key 为空字符串),按 gw 处理即可。

在线状态 ​

最上层网关要为每一个层级的设备上报 gateway/connect,地址同样用完整路径:

json
{ "id": 101, "ack": 1, "gw": { "device": "7", "typeKey": "区域网关类型KEY" } }
{ "id": 102, "ack": 1, "gw": { "device": "7.8", "typeKey": "温度子设备类型KEY" } }

WARNING

中间层网关与最下层设备一样,不上报连接状态平台就不会向它下发消息。

网关 MQTT 主题一览 ​

以下主题中的 网关设备码 是网关设备在平台中的 deviceCode。

发布主题 ​

网关向平台发布消息。

消息类型主题
子设备上报属性值up/网关设备码/attributes/post
子设备获取属性值up/网关设备码/attributes/get
子设备获取期望属性up/网关设备码/attributes/desired_get
子设备清除期望属性up/网关设备码/attributes/desired_delete
子设备回复下发属性up/网关设备码/attributes/set_reply
子设备回复属性采集up/网关设备码/attributes/acquisition_reply
子设备上报事件up/网关设备码/event/post
子设备批量上报或历史上报up/网关设备码/batch/post
子设备回复命令up/网关设备码/command/send_reply
子设备已连接up/网关设备码/gateway/connect
子设备已断开up/网关设备码/gateway/disconnect
获取子设备列表up/网关设备码/gateway/device_list

订阅主题 ​

网关订阅平台下发给子设备的消息。

消息类型主题
子设备属性上报响应down/网关设备码/attributes/post_reply
子设备属性获取响应down/网关设备码/attributes/get_reply
子设备期望属性响应down/网关设备码/attributes/desired_get_reply
子设备清除期望属性响应down/网关设备码/attributes/desired_delete_reply
子设备接收下发属性down/网关设备码/attributes/set
子设备接收属性采集down/网关设备码/attributes/acquisition
子设备事件上报响应down/网关设备码/event/post_reply
子设备批量上报响应down/网关设备码/batch/post_reply
子设备接收下发命令down/网关设备码/command/send
子设备已连接响应down/网关设备码/gateway/connect_reply
子设备已断开响应down/网关设备码/gateway/disconnect_reply
获取子设备列表响应down/网关设备码/gateway/device_list_reply

子设备已连接 ​

当网关确认子设备已连接时,向平台上报子设备连接状态。平台可根据 typeKey 或 productKey 自动创建子设备。

这是平台向子设备下发消息的前提

网关必须为每个子设备上报一次连接状态,否则平台不会向该子设备下发任何消息: 属性下发、命令下发、属性采集都会直接返回「设备离线」。子设备的在线状态不会因为网关在线而自动置位。

发布主题:

text
up/网关设备码/gateway/connect

网关发送消息:

json
{
  "id": 101,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "device": "SUB_DEVICE_ADDR1",
    "typeKey": "TYPE_KEY",
    "productKey": "PRODUCT_KEY"
  }
}

字段说明:

字段说明
id消息序号,用于匹配请求和响应。
ack是否需要平台应答,1 表示需要,0 或不填表示不需要。
time设备采集时间戳,毫秒级,可选。
gw网关数据。
gw.device子设备地址,必须。
gw.typeKey设备类型 KEY,可选。自动创建时与 productKey 至少传一个。
gw.productKey产品识别码,可选。自动创建时与 typeKey 至少传一个。

TIP

自动创建子设备 在一些面向终端用户的场景中,用户可根据自己的实际需要,将不同子设备连接到网关。当网关识别到新的子设备后,平台可自动创建并关联该子设备。 使用 typeKey 时,需事先创建好对应设备类型,并开启允许自动创建设备;使用 productKey 时,平台会按产品识别码匹配或创建设备类型。二者至少上传一个。

平台响应主题:

text
down/网关设备码/gateway/connect_reply

平台回复消息:

json
{
  "id": 101,
  "time": 1626197189640,
  "code": 200,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "id": 122,
      "deviceCode": "10000003",
      "typeKey": "TYPE_KEY",
      "productKey": "PRODUCT_KEY"
    }
  }
}

字段说明:

字段说明
id消息序号,与请求中的 id 一致。
time平台时间戳,毫秒级。
code业务状态码,200 表示成功。
gw子设备信息,键为子设备地址。
gw.<addr>.id子设备 ID(平台侧设备 ID,不是消息序号)。
gw.<addr>.deviceCode子设备设备码。
gw.<addr>.typeKey设备类型 KEY。
gw.<addr>.productKey产品识别码。

子设备已断开 ​

当网关确认子设备已断开时,向平台上报断开状态。

发布主题:

text
up/网关设备码/gateway/disconnect

网关发送消息:

json
{
  "id": 102,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "device": "SUB_DEVICE_ADDR1"
  }
}

平台响应主题:

text
down/网关设备码/gateway/disconnect_reply

平台回复消息:

json
{
  "id": 102,
  "time": 1626197189640,
  "code": 200
}

子设备上报属性 ​

网关代子设备上报属性值。gw 的每个键是子设备地址,值是该子设备的属性键值。

发布主题:

text
up/网关设备码/attributes/post

网关发送消息:

json
{
  "id": 1,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "temperature": 26.5,
      "humidity": 62
    },
    "SUB_DEVICE_ADDR2": {
      "switch": true,
      "voltage": 220
    }
  }
}

平台响应主题:

text
down/网关设备码/attributes/post_reply

平台回复消息:

json
{
  "id": 1,
  "time": 1626197189640,
  "code": 200
}

子设备获取属性 ​

网关代子设备获取平台保存的属性当前值。

发布主题:

text
up/网关设备码/attributes/get

网关发送消息:

json
{
  "id": 2,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "keys": ["temperature", "humidity"]
    },
    "SUB_DEVICE_ADDR2": {
      "keys": []
    }
  }
}

平台响应主题:

text
down/网关设备码/attributes/get_reply

平台回复消息:

json
{
  "id": 2,
  "time": 1626197189640,
  "code": 200,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "temperature": {
        "value": 26.5,
        "time": 1626197189640
      },
      "humidity": {
        "value": 62,
        "time": 1626197189640
      }
    },
    "SUB_DEVICE_ADDR2": {
      "switch": {
        "value": true,
        "time": 1626197189640
      }
    }
  }
}

子设备获取期望属性 ​

网关代子设备获取平台暂存的期望属性。

发布主题:

text
up/网关设备码/attributes/desired_get

网关发送消息:

json
{
  "id": 3,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "id": 31,
      "keys": ["switch", "brightness"]
    },
    "SUB_DEVICE_ADDR2": {
      "id": 32,
      "keys": []
    }
  }
}

平台响应主题:

text
down/网关设备码/attributes/desired_get_reply

平台回复消息:

json
{
  "id": 3,
  "time": 1626197189640,
  "code": 200,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "switch": {
        "value": true,
        "time": 1626197189640,
        "version": 1
      },
      "brightness": {
        "value": 80,
        "time": 1626197189640,
        "version": 2
      }
    }
  }
}

子设备清除期望属性 ​

子设备成功执行期望属性后,网关代子设备清除对应期望值。

发布主题:

text
up/网关设备码/attributes/desired_delete

网关发送消息:

json
{
  "id": 4,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "switch": {
        "version": 1
      },
      "brightness": {
        "version": 2
      }
    }
  }
}

平台响应主题:

text
down/网关设备码/attributes/desired_delete_reply

平台回复消息:

json
{
  "id": 4,
  "time": 1626197189640,
  "code": 200
}

子设备事件上报 ​

网关代子设备上报事件。

发布主题:

text
up/网关设备码/event/post

网关发送消息:

json
{
  "id": 5,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "id": 51,
      "key": "alarmEvent",
      "value": {
        "temperature": -10
      }
    },
    "SUB_DEVICE_ADDR2": {
      "id": 52,
      "key": "doorEvent",
      "value": {
        "open": true
      }
    }
  }
}

平台响应主题:

text
down/网关设备码/event/post_reply

平台回复消息:

json
{
  "id": 5,
  "time": 1626197189640,
  "code": 200
}

子设备批量上报或历史上报 ​

网关可代多个子设备一次上报多条属性和事件数据。

发布主题:

text
up/网关设备码/batch/post

网关发送消息:

json
{
  "id": 6,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "attributes": [
        {
          "key": "temperature",
          "value": 26.5,
          "time": 1626197182640
        },
        {
          "key": "humidity",
          "value": 62,
          "time": 1626197189640
        }
      ],
      "events": [
        {
          "key": "alarmEvent",
          "time": 1626197189640,
          "value": {
            "temperature": -10
          }
        }
      ]
    }
  }
}

平台响应主题:

text
down/网关设备码/batch/post_reply

平台回复消息:

json
{
  "id": 6,
  "time": 1626197189640,
  "code": 200
}

子设备属性下发 ​

平台向子设备下发属性时,网关从订阅主题接收消息,并转发给对应子设备。

订阅主题:

text
down/网关设备码/attributes/set

网关接收消息:

json
{
  "id": 7,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "switch": true,
      "brightness": 80
    }
  }
}

网关回复主题:

text
up/网关设备码/attributes/set_reply

网关回复消息:

json
{
  "id": 7,
  "time": 1626197189640,
  "code": 200,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "code": 200
    }
  }
}

子设备属性采集 ​

平台向子设备发起属性采集时,网关负责采集子设备实时值并回复。

订阅主题:

text
down/网关设备码/attributes/acquisition

网关接收消息:

json
{
  "id": 8,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "keys": ["temperature", "humidity"]
    }
  }
}

网关回复主题:

text
up/网关设备码/attributes/acquisition_reply

网关回复消息:

json
{
  "id": 8,
  "time": 1626197189640,
  "code": 200,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "temperature": 26.5,
      "humidity": 62
    }
  }
}

子设备命令下发 ​

平台向子设备下发命令时,网关接收命令并转发给对应子设备,随后返回执行结果。

订阅主题:

text
down/网关设备码/command/send

网关接收消息:

json
{
  "id": 9,
  "time": 1626197189638,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "id": 91,
      "key": "set_param",
      "input": {
        "mode": "auto",
        "threshold": 30
      }
    }
  }
}

网关回复主题:

text
up/网关设备码/command/send_reply

网关回复消息:

json
{
  "id": 9,
  "time": 1626197189640,
  "code": 200,
  "gw": {
    "SUB_DEVICE_ADDR1": {
      "id": 91,
      "key": "set_param",
      "code": 200,
      "output": {
        "result": "ok"
      }
    }
  }
}

获取子设备列表 ​

网关向平台分页查询已关联的子设备列表。每次最多返回 100 条子设备;总数超过一页时,网关需按 page 继续拉取。

发布主题:

text
up/网关设备码/gateway/device_list

网关发送消息:

json
{
  "id": 10,
  "ack": 1,
  "time": 1626197189638,
  "gw": {
    "page": 1,
    "pageSize": 100
  }
}

字段说明:

字段说明
id消息序号,用于匹配请求和响应。
ack是否需要平台应答。本接口应传 1,否则平台不返回子设备列表。
time设备采集时间戳,毫秒级,可选。
gw.page页码,从 1 开始,可选,默认 1。
gw.pageSize每页数量,可选,默认 100,最大 100。超过最大值时按 100 处理。

平台响应主题:

text
down/网关设备码/gateway/device_list_reply

平台回复消息:

json
{
  "id": 10,
  "time": 1626197189638,
  "code": 200,
  "gw": {
    "page": 1,
    "pageSize": 100,
    "total": 2,
    "data": {
      "SUB_DEVICE_ADDR1": {
        "id": 122,
        "deviceCode": "10000003"
      },
      "SUB_DEVICE_ADDR2": {
        "id": 123,
        "deviceCode": "10000004"
      }
    }
  }
}

字段说明:

字段说明
id消息序号,与请求中的 id 一致。
time平台时间戳,毫秒级。
code业务状态码,200 表示成功。
gw.page当前页码。
gw.pageSize当前页请求的每页数量。
gw.total子设备总数。可根据 gw.total 与 gw.pageSize 判断是否还有下一页。
gw.data当前页子设备列表,键为子设备地址;本页最多 100 条。
gw.data.<addr>.id子设备 ID(平台侧设备 ID,不是消息序号)。
gw.data.<addr>.deviceCode子设备设备码。