# MQTT Forward－云端转发功能说明

### 订阅其他网关的数据

`MQTT Forward`云端转发应用的主要功能是订阅其他网关发给简捷平台的服务数据，并转发到网关自身的`IPC`消息总线上。代码路径为`lnxall_package/mqtt_forward`，由应用使用`python`脚本编写（支持`python2`和`python3`），主要依赖为`paho-mqtt-py`（同样的，该MQTT模块支持两个版本的`python`）。其订阅其他网关的`topic`主题为：

```
/sys/[TENANT]/[GW_SN]/service
```

其中，`TENANT`为网关所在的平台租户。该云端转发服务在启动时，会读取`/app/node/nodes_cfg.json`，要求`app_key`字段固定为`mqttforward`。其订阅的其他网关由扩展字段指定，例如：

```json
    {
      "app_key": "mqttforward",
      "connect_port": "VINTF_MQTT",
      "depth": 0,
      "ext_data": "{\"tenant\":\"RMBOnUo3\",\"gwsn\":\"218812000029\",\"service_post\":false,\"property_post\":true}",
      "product_key": "2112565838",
      "sn": "218812000029",
      "template_id": "2112565838"
    },
```

以上配置文件的扩展字段为：

```json
{"tenant":"RMBOnUo3","gwsn":"218812000029","service_post":false,"property_post":true}
```

`service_post`指定是否转发给内部的服务，`property_post`指定是否转发给内部的属性；二者不能同时为`false`（否则`MQTT Forward`应用会忽略该配置项）。

### 转发给内部服务

当`service_post`为`true`时，`MQTT Forward`会将接收到的外部网关消息转发到内部`IPC`的服务，新的`topic`主题为：

```
ipc/[GW_SN]/cloud/device/forward/data_filtered/service/post
```

其中，`GW_SN`为网关自身的序列号，而非外部网关的序列号。转发的消息`payload`负载不会被修改。

### 转发给内部属性

当`property_post`为`true`时，`MQTT Forward`会将接收到外部网关消息转发到内部`IPC`的属性，新的`topic`主题为：

```
ipc/[GW_SN0]/mqttforward/device/[GW_SN1]/data/property/post
```

其中`GW_SN0`为网关自身的序列号，`GW_SN1`为外部网关的序列号。此外，在转发之前，消息的`payload`负载会被被修改。举个例子，网关收到来自云端的消息为（由处部网关产生的数据）：

```json
{
    "sn":"94XgRmZs",
    "mi":0,
    "time":1649224527,
    "identifier":"read",
    "tags":{"stat":1},
    "gw_sn":"218812000029",
    "data_type":"service"
}
```

会被修改为：

```json
{
    "sn":"218812000029",
    "mi":0,
    "time":1649224527,
    "identifier":"read",
    "tag_node":{"stat":1},
    "data_type":"service"
}
```

即：

1.  把负载中的`tags`替换为`tag_node`
2.  删除负载中的`gw_sn`
3.  将原负载的中`gw_sn`赋值为`sn`的值

