
# 在线开发MQTT协议的模拟智慧路灯
#### 场景说明
本文以"智慧路灯"为示例，通过设备模拟器替代真实的设备，带您快速体验设备上报数据到物联网平台和远程下发控制命令到设备的全过程。您可以选择MQTT.fx工具或MQTT_Simulator两种设备模拟器，推荐使用MQTT.fx工具进行模拟。
假设：路灯设备上报一条光照强度（luminance）消息；支持远程控制路灯开关状态的命令（switch），上报数据的格式为JSON格式。
#### 前提条件
- 已注册华为云官方账号。未注册可单击[注册页面](https://reg.huaweicloud.com/registerui/public/custom/register.html#/register)完成注册。
- 已完成实名制认证。未完成可在华为云上单击[实名认证](https://account.huaweicloud.com/usercenter/#/accountindex/realNameAuth)完成认证，否则无法使用设备接入功能。
- 已开通设备接入服务。未开通则访问[设备接入服务](https://www.huaweicloud.com/product/iothub.html)，单击"立即使用"后开通该服务。
 
#### 业务流程
基于MQTT.fx体验平台功能是指使用MQTT.fx模拟器工具，进行数据上报、命令下发等业务的体验。
1. [创建产品]。创建一个MQTT协议的产品。
2. [开发产品模型]。通过定义产品模型，在物联网平台构建一款路灯设备，支持上报光照强度、下发路灯开关状态命令。
3. [注册设备]。注册一个MQTT协议的设备，体验数据上报业务。
4. [连接鉴权]。使用MQTT.fx激活在物联网平台上注册的设备。
5. [数据上报]。使用MQTT.fx向物联网平台上报数据。
6. [命令下发]。在管理控制台下发命令，远程控制设备。
 #### 创建产品
1. 登录[管理控制台](https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home)，选择您的实例，单击实例卡片进入。单击左侧导航栏"产品"，单击页面左侧的"创建产品"。
   
   图1产品-创建产品   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000002358714305.png "点击放大")
   
   
2. 创建一个协议类型为MQTT协议、自定义设备类型为StreetLamp的产品，参考页面提示填写参数后，单击"确定"。 
   图2创建产品-MQTT   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981306829.png "点击放大")
   
   
 
 #### 开发产品模型
1. 找到新增的产品，单击产品进入产品界面。
2. 在产品详情"基本信息"页面，单击"自定义模型"，配置产品的服务。 
   图3自定义模型-MQTT   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981309873.png "点击放大")
   
   
3. 新增服务类型"BasicData"。 
   1. 在"添加服务"页面，根据页面提示填写"服务ID"、"服务类型"和"服务描述"，单击"确定"。
      图4添加服务-BasicData   
      ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981469753.png "点击放大") 
   
   2. 在"BasicData"服务列表右侧区域，单击"新增属性"，填写相关信息后，单击"确定"。
      图5新增属性-luminance   
      ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981470853.png "点击放大") 
   
   
   
   
4. 新增服务类型"LightControl"。 
   1. 在"基本信息"下单击"添加服务"，根据页面提示填写后，单击"确定"。
      - "服务ID"：LightControl
      
      - "服务类型"：建议和服务ID保持一致
      
      - "服务描述"：路灯开关控制
       
   
   2. 在"LightControl"的下拉菜单下单击"新增命令"，输入命令名称"Switch"。
      图6新增命令-Switch   
      ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981311005.png "点击放大") 
   
   3. 在"新增命令"页面，单击"新增下发参数"，填写相关信息后，单击"确定"。
      图7新增命令参数-value   
      ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981469745.png "点击放大") 
   
   
   
   
 
 #### 注册设备
1. 在设备接入控制台页面，选择您的实例，选择左侧导航栏"设备 \> 所有设备"，单击"注册设备"。 
   图8所有设备-注册设备   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981487325.png "点击放大")
   
   
2. 根据页面提示信息填写参数，然后单击"确定"。 
   
   | 参数名称   | 说明                                                                         |
   |:---|:---|
   | 所属资源空间 | 确保和所属产品归属在同一个资源空间。                                                         |
   | 所属产品   | 选择对应产品。                                                                    |
   | 设备标识码  | 即nodeID，设备唯一物理标识。设备标识码长度为4至64个字符，只允许字母、数字、下划线（_）、连接符（-）的组合。可自定义由英文字母和数字组成。 |
   | 设备名称   | 即device_name，可自定义。                                                         |
   | 设备认证类型 | 选择"密钥"。                                                                    |
   | 密钥     | 此处如不填写，物联网平台会自动生成。                                                         |
      
   图9单设备注册-MQTT   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981327497.png "点击放大")
   
   
3. 成功注册设备后，平台会自动生成设备ID和密钥，请妥善保管好设备ID（deviceId）和密钥（deviceSecret），用于设备接入。 
   图10设备-注册设备成功   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981487333.png "点击放大")
   
   
 
 #### 连接鉴权
使用MQTT.fx工具激活在物联网平台上注册的设备。
1. 下载[MQTT.fx](https://iotda-document.obs.cn-north-4.myhuaweicloud.com/mqttfx-1.7.1-windows-x64.exe)（默认是64位操作系统，如果是32位操作系统，单击此处下载[MQTT.fx](https://iotda-document.obs.cn-north-4.myhuaweicloud.com/mqttfx-1.7.1-windows.exe)），安装MQTT.fx工具。
2. 访问[这里](https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/)，填写注册设备后生成的设备ID（DeviceId）和密钥（DeviceSecret），生成连接信息（ClientId、Username、Password）。
   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001084886471.png "点击放大")
   
   | 参数       | 必选/可选 | 类型          | 参数描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   |:---|:---|:---|:---|
   | ClientId | 必选    | String(256) | 一机一密的设备clientId由4个部分组成：设备ID、设备身份标识类型、密码签名类型、时间戳，通过下划线"_"分隔。 - **设备ID**：指设备在平台成功注册后生成的唯一设备标识，通常由设备的产品ID和设备的NodeId通过分隔符"_"拼装而来。  - **设备身份标识类型**：固定值为0，表示设备ID。  - **密码签名类型** ：长度1字节，当前支持2种类型： - "0"代表HMACSHA256不校验时间戳。  - "1"代表HMACSHA256校验时间戳。    - **时间戳**：为设备连接平台时的UTC时间，格式为YYYYMMDDHH，如UTC 时间2018/7/24 17:56:20 则应表示为2018072417。   |
   | Username | 必选    | String(256) | 设备ID。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | Password | 必选    | String(256) | 加密后的设备密钥。Password的值为使用"HMACSHA256"算法以时间戳为密钥，对secret进行加密后的值。 secret为注册设备时平台返回的secret。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
      
   设备通过MQTT协议的connect消息进行鉴权，对于构造clientId的各个部分信息都必须包括进去，平台收到connect消息时，会判断设备的鉴权类型和密码摘要算法。
   使用生成工具生成的clientId格式，默认不校验时间戳：设备ID_0_0_时间戳。
   - 当采用"HMACSHA256"校验时间戳方式时，会先校验消息时间戳与平台时间是否一致，再判断密码是否正确。
   
   - 当采用"HMACSHA256"不校验时间戳方式时，鉴权消息也必须带时间戳，但不检验时间是否准确，仅判断密码是否正确。
   
   
   connect消息鉴权失败时，平台会返回错误，并自动断开MQTT链路。
   
   
3. 打开MQTT.fx软件，单击设置图标。 
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001084799925.png "点击放大")
   
   
4. 参考下表配置鉴权参数，然后单击"Apply"。 
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001084886473.png "点击放大")
   
   | 参数名称           | 说明                                                                                                                                                                                    |
   |:---|:---|
   | Broker Address | 填写从设备接入服务控制台获取的[平台对接信息](https://support.huaweicloud.com/devg-iothub/iot_02_1004.html#section0)，此接入地址为域名信息。不能通过域名接入的设备，通过在cmd命令框中执行"ping 域名"获取IP地址，用IP地址接入平台。由于IP地址不固定，您需要将IP地址做成可配置项。 |
   | Broker Port    | 默认为1883。                                                                                                                                                                              |
   | Client ID      | 设备clientID，请参考[2]中获取。                                                                                                                  |
   | User Name      | 即设备ID，请参考[2]中获取。                                                                                                                       |
   | Password       | 加密后的设备密钥，请参考[2]中获取。                                                                                                                    |
      
   
   
5. 单击"Connect"，设备鉴权成功后，在物联网平台可以看到设备处于在线状态。 
   图11设备在线   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981327513.png "点击放大")
   
   
 
 #### 数据上报
使用MQTT.fx工具向物联网平台上报数据。设备若通过MQTT通道上报数据，需要发给指定的topic，上报消息的topic格式为：$oc/devices/{device_id}/sys/properties/report，其中对于一机一密设备，使用deviceId接入时需填写为设备注册成功后返回的deviceId值。
1. 填写接口地址，此处以$oc/devices/{device_id}/sys/properties/report为例，如：$oc/devices/5e4e2e92ac-164aefa8fouquan1/sys/properties/report。 
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001769648470.png "点击放大")
   
   
2. 在工具中间的空白处填写上报的数据后，单击"Publish"。 
   表1设备服务数据列表 
   | 字段名      | 必选/可选 | 类型                      | 参数描述                                 |
   |:---|:---|:---|:---|
   | services | 必选    | List\<ServiceProperty\> | 设备服务数据列表（具体结构参考下表ServiceProperty定义表） |
      
   表2ServiceProperty定义表 
   | 字段名        | 必选/可选 | 类型     | 参数描述                                                                                                                                                               |
   |:---|:---|:---|:---|
   | service_id | 必选    | String | 设备服务的ID。                                                                                                                                                           |
   | properties | 必选    | Object | 设备服务的属性列表，具体字段在设备关联的产品模型中定义。                                                                                                                                       |
   | eventTime  | 可选    | String | 设备采集数据UTC时间（格式：yyyyMMddTHHmmssZ），如：20161219T114920Z。 设备上报数据不带该参数或参数格式错误时，则数据上报时间以平台时间为准。 |
      
   **请求示例**
   ```
   {
       "services": [{
               "service_id": "BasicData",
               "properties": {
                   "luminance": 30
           }
         }
      ]
   }
   ```
   
   
3. 可以在设备详情页中查看设备是否成功上报数据。 
   图12查看上报数据-MQTT   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981489749.png "点击放大")
   
   
 
 #### 命令下发
在管理控制台下发命令，远程控制设备。
1. 选择"设备 \> 所有设备"，找到新建的设备，单击"详情"进入设备详情页面。
2. 单击"云端下发"页签，下发同步命令。 
   图13命令下发-MQTT   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981577861.png "点击放大")
   ![](https://support.huaweicloud.com/bestpractice-iothub/public_sys-resources/note_3.0-zh-cn.png)
   MQTT协议设备仅支持同步命令下发，NB-IoT设备仅支持异步命令下发。
   
   
3. MQTT.fx模拟器中选择"Subscribe"，输入命令下发Topic，订阅后则可以查看到下发的命令参数。 
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001625175073.png "点击放大")
   ![](https://support.huaweicloud.com/bestpractice-iothub/public_sys-resources/note_3.0-zh-cn.png)
   - 通过MQTT.fx模拟器查看下发的命令参数，命令下发Topic格式为：$oc/devices/{device_id}/sys/commands/#，其中{device_id}为设备注册成功后返回的deviceId值。
   
   - 界面提示命令下发失败，是因为下发的同步命令需要设备侧及时回响应，响应内容请参考[平台命令下发](https://support.huaweicloud.com/api-iothub/iot_06_v5_3014.html)。
    
   
   
 
#### 使用MQTT_Simulator接入
1. 下载[MQTT_Simulator模拟器](https://obs-pipeline.obs.cn-north-4.myhuaweicloud.com/sdkDeploy/simulator/MQTT_Simulator.zip)（默认是64位操作系统），并启动模拟器，如下图：
   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001871167350.png)
   
   
2. 界面展示 
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001916886993.png "点击放大")
   1. 模拟器提供了界面显示，填写Server地址、设备ID、设备密钥。请根据实际创建的设备信息填写。
      - Server地址：即域名，参考[平台对接信息](https://support.huaweicloud.com/devg-iothub/iot_02_1004.html#section0)获取；
      
      - 设备ID和设备密钥：在[这里]获取。
       
   
   2. 不同的Server地址SSL加密接入时要与对应的[证书文件匹配使用](https://support.huaweicloud.com/devg-iothub/iot_02_1004.html#section3)，证书获取请参考[获取资源](https://support.huaweicloud.com/devg-iothub/iot_02_1004.html)，需要替换certificate文件夹下的证书，如下图：
      ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001871007506.png)
      
   
   3. 用户可以选择设备侧建链时是否为SSL加密，选择Qos方式是0还是1，当前不支持Qos2，可参考[使用限制](https://support.huaweicloud.com/devg-iothub/iot_02_2200.html#section2)。
   
   
   
   
3. 新建连接 
   设备或网关在接入物联网平台时首先需要和平台建立连接，从而将设备或网关与平台进行关联。开发者通过传入设备信息，将设备或网关连接到物联网平台。单击新建连接按钮，域名、设备ID和密钥正确的情况下，可以看到日志设备连接成功，可在平台查看设备状态，如下图：
   图14设备列表-设备在线   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001950367902.png "点击放大")
   
   
4. 订阅Topic 
   订阅某topic的设备才能接收broker发布的关于该topic的消息，关于平台预置topic可参考[Topic定义](https://support.huaweicloud.com/api-iothub/iot_06_v5_3004.html)。
   建链后，如果成功订阅Topic，主界面日志栏显示如下信息：
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001917006689.png "点击放大")
   
   
5. 发布Topic 
   发布Topic是指设备主动向平台上报自己的属性或消息，详细见[设备属性上报接口](https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html)文档。
   在模拟器中实现了上报Topic、属性上报功能。
   输入要上报的JSON message，上报luminance属性为30。发布Topic后，Demo界面显示如下：
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001871167354.png "点击放大")
   设备上报属性成功后可在"设备详情"页面查看到上报的属性：
   图15查看上报数据-MQTT   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981489749.png "点击放大")
   
   
6. 接收下发命令 
   模拟器支持接收平台下发命令的功能，在MQTT建链完成并成功订阅Topic后，可以在[控制台](https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home)设备详情中对该设备进行同步命令下发。下发成功后，在MQTT的回调函数中接收到平台下发给设备的命令。
   例如用户想远程开灯，下发参数名为LightControl: switch，参数值为ON的命令。
   图16命令下发-同步命令下发   
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001981553705.png "点击放大")
   同步命令下发成功后，Demo界面显示如下：
   ![](https://support.huaweicloud.com/bestpractice-iothub/figure/zh-cn_image_0000001916886997.png "点击放大")
   
   
 
#### 进阶体验
按照本页面的指导，模拟MQTT设备接入物联网平台后，您应该已经基本了解MQTT设备调用物联网平台开放的接口与平台交互。
若您想要进一步体验设备接入服务，可参考[开发指南](https://support.huaweicloud.com/devg-iothub/iot_02_9994.html)开发真实应用和真实设备，并接入物联网平台，体验更多功能。
