使用 Azure IoT Edge,通过模拟设备发送设备到云消息 (Windows)

模拟设备云上传示例这一演练介绍如何使用 Azure IoT Edge 从模拟设备将设备到云遥测发送到 IoT 中心。

本文介绍的内容包括:

体系结构

模拟设备云上传示例介绍如何创建将遥测从模拟设备发送到 IoT 中心的网关。 设备可能无法直接连接到 IoT 中心,因为:

  • IoT 中心无法理解设备使用的通信协议。
  • 设备不够智能,无法记住 IoT 中心分配给它的标识。

IoT Edge 网关可通过以下方式解决这些问题:

  • 网关理解设备所使用的协议,因此接收到来自该设备的设备到云遥测后,使用 IoT 中心理解的协议将这些消息转发到 IoT 中心。

  • 网关将 IoT 中心标识映射到设备,并在设备向 IoT 中心发送消息时充当代理。

下图显示了示例的主要组件,包括 IoT Edge 模块:

关系图 - 模拟设备消息通过网关转到 IoT 中心

此示例包含三个模块,它们构成可网关:

  1. 协议引入模块
  2. MAC <-> IoT 中心 ID 模块
  3. IoT 中心通信模块

模块彼此之间不直接传递消息。 模块将消息发布到内部中转站,该中转站通过订阅机制将消息传递给其他模块。 有关详细信息,请参阅 Azure IoT Edge 入门

关系图 - 网关模块与中转站通信

协议引入模块

在从设备获取数据,通过网关将数据传递到云中的过程中,将协议引入模块作为起点。

示例中,此模块:

  1. 创建模拟温度数据。 如果使用物理设备,该模块会从这些物理设备读取数据。
  2. 创建消息。
  3. 将模拟温度数据置于消息内容中。
  4. 将 MAC 地址为虚构的属性添加到消息中。
  5. 向链中的下一模块提供该消息。

协议引入模块是源代码中的 simulated_device.c。

MAC <-> IoT 中心 ID 模块

MAC <-> IoT中心 ID 模块充当转换器。 此示例使用 MAC 地址作为唯一的设备标识符,将其与 IoT 中心设备标识相关联。 不过,可以编写自己的模块,让其使用其他的唯一标识符。 例如,设备可能具有唯一序列号或者遥测数据可能包括唯一的嵌入式设备名。

示例中,此模块:

  1. 扫描具有 MAC 地址属性的消息。
  2. 如果存在 MAC 地址,它会向消息添加另一个具有 IoT 中心设备密钥的属性。
  3. 向链中的下一模块提供该消息。

开发人员在 MAC 地址和 IoT 中心标识之间设置映射,将模拟设备与 IoT 中心设备标识相关联。 开发人员手动将映射添加到模块配置中。

MAC <-> IoT 中心 ID 模块是源代码中的 identitymap.c。

IoT 中心通信模块

IoT 中心通信模块开放从网关到 IoT 中心的单个 HTTPS 连接。 HTTPS 是 IoT 中心理解的三大协议之一。 此模块通过在一个连接上多路复用来自所有设备的连接,使你可以不必开放每个设备的连接。 此方法使单个网关能够连接多个设备。

示例中,此模块:

  1. 采用具有 IoT 中心设备密钥属性(由前一模块分配)的消息。
  2. 使用 HTTPS 协议将消息内容发送到 IoT 中心。

IoT 中心通信模块是源代码中的 iothub.c。

准备工作

开始之前,必须:

  • 创建 IoT 中心 。 在此示例演练中,需要 IoT 中心的名称。 如果没有帐户,只需几分钟即可创建一个试用帐户
  • 将两个设备添加到 IoT 中心,并记下其 ID 和设备密钥。 可使用设备资源管理器iothub-explorer 工具将设备添加到 IoT 中心,并检索其密钥。

安装必备组件

  1. 安装 Visual Studio 2015 或 2017。 如果满足授权要求,可以使用免费的社区版。 请务必包含 Visual C++ 和 NuGet 包管理器。

  2. 安装 git 并确保可从命令行运行 git.exe。

  3. 安装 CMake 并确保可从命令行运行 cmake.exe。 建议使用 CMake 版本 3.7.2 或更高版本。 .msi 安装程序是 Windows 上最简单的选项。 安装程序提示时,至少为当前用户将 CMake 添加到 PATH。

  4. 安装 Python 2.7。 请确保将 Python 添加到 PATH 环境变量。 转到“控制面板” > “系统和安全” > “系统” > “高级系统设置” > “环境变量”。 将 C:\Python27 添加到路径。

  5. 在命令提示符中,运行以下命令,将 Azure IoT Edge GitHub 存储库克隆到本地计算机上:

    git clone https://github.com/Azure/iot-edge.git
    

如何生成示例

现可在本地计算机上生成 IoT Edge 运行时和示例:

  1. 打开“VS 2015 开发人员命令提示”或“VS 2017 开发人员命令提示”,具体要取决于你的版本。

  2. 浏览到 iot-edge 存储库本地副本中的根文件夹。

  3. 如下所示运行生成脚本:

    tools\build.cmd --disable-native-remote-modules
    

此脚本创建 Visual Studio 解决方案文件并生成解决方案。 可以在 iot-edge 存储库本地副本的 build 文件夹中找到 Visual Studio 解决方案。 如果想要生成并运行单元测试,请添加 --run-unittests 参数。 如果想要生成并运行端到端测试,请添加 --run-e2e-tests

Note

每次运行 build.cmd 脚本时,都会删除 iot-edge 存储库本地副本的根文件夹中的 build 文件夹并重新生成。

运行示例

build.cmd 脚本在 iot-edge 存储库本地副本的 build 文件夹中生成输出。 该输出包括此示例中使用的四个 IoT Edge 模块。

生成脚本会创建以下文件:

  • logger.dll 放入 build\modules\logger\Debug 文件夹。
  • iothub.dll 放入 build\modules\iothub\Debug 文件夹。
  • identity_map.dll 放入 build\modules\identitymap\Debug 文件夹。
  • simulated_device.dll 放入 build\modules\simulated_device\Debug 文件夹。

将这些路径用于 module path 值,如 simulated_device_cloud_upload_win JSON 设置文件中所示。

simulated_device_cloud_upload 示例过程使用 JSON 配置文件的路径作为命令行参数。 以下示例 JSON 文件位于 SDK 存储库的以下路径:samples\simulated_device_cloud_upload_sample\src\simulated_device_cloud_upload_win.json。 除非修改了生成脚本,将 IoT Edge 模块或示例可执行文件放置在非默认位置,否则,此配置文件可按原样工作。

Note

模块路径相对于 simulated_device_cloud_upload_sample.exe 所在的目录。 示例 JSON 配置文件默认写入到当前工作目录中的“deviceCloudUploadGatewaylog.log”。

在文本编辑器中,打开 iot-edge 存储库本地副本中的文件 samples\simulated_device_cloud_upload\src\simulated_device_cloud_upload_win.json。 此文件配置示例网关中的 IoT Edge 模块:

  • IoTHub 模块连接到 IoT 中心。 将该模块配置为将数据发送到 IoT 中心。 具体而言,将 IoTHubName 值设置为 IoT 中心的名称,将 IoTHubSuffix 值设置为 azure-devices.cn。 将“传输”值设置为“HTTP”、“AMQP”或“MQTT”其中的一个。 目前只有“HTTP”会针对所有设备消息共享一个 TCP 连接。 如果将值设置为“AMQP”或“MQTT”,则网关将为每个设备维护与 IoT 中心的单独 TCP 连接。
  • mapping 模块将模拟设备的 MAC 地址映射到 IoT 中心设备 ID。 将 deviceId 值设置为添加到 IoT 中心的两个设备的 ID。 将 deviceKey 值设置为两个设备的密钥。
  • BLE1BLE2 模块是模拟设备。 注意模块 MAC 地址如何与“映射”模块中的地址匹配。
  • Logger 模块将网关活动记录到一个文件中。
  • 以下示例中所示的 module path 值相对于 simulated_device_cloud_upload_sample.exe 所在的目录。
  • JSON 文件底部的 links 数组将 BLE1BLE2 模块连接到 mapping 模块,并将 mapping 模块连接到 IoTHub 模块。 它还确保 Logger 模块记录所有消息。
{
    "modules" :
    [
      {
        "name": "IotHub",
        "loader": {
          "name": "native",
          "entrypoint": {
            "module.path": "..\\..\\..\\modules\\iothub\\Debug\\iothub.dll"
          }
          },
          "args": {
            "IoTHubName": "<<insert here IoTHubName>>",
            "IoTHubSuffix": "<<insert here IoTHubSuffix>>",
            "Transport": "HTTP"
          }
        },
      {
        "name": "mapping",
        "loader": {
          "name": "native",
          "entrypoint": {
            "module.path": "..\\..\\..\\modules\\identitymap\\Debug\\identity_map.dll"
          }
          },
          "args": [
            {
              "macAddress": "01:01:01:01:01:01",
              "deviceId": "<<insert here deviceId>>",
              "deviceKey": "<<insert here deviceKey>>"
            },
            {
              "macAddress": "02:02:02:02:02:02",
              "deviceId": "<<insert here deviceId>>",
              "deviceKey": "<<insert here deviceKey>>"
            }
          ]
        },
      {
        "name": "BLE1",
        "loader": {
          "name": "native",
          "entrypoint": {
            "module.path": "..\\..\\..\\modules\\simulated_device\\Debug\\simulated_device.dll"
          }
          },
          "args": {
            "macAddress": "01:01:01:01:01:01",
            "messagePeriod" : 2000
          }
        },
      {
        "name": "BLE2",
        "loader": {
          "name": "native",
          "entrypoint": {
            "module.path": "..\\..\\..\\modules\\simulated_device\\Debug\\simulated_device.dll"
          }
          },
          "args": {
            "macAddress": "02:02:02:02:02:02",
            "messagePeriod" : 2000
          }
        },
      {
        "name": "Logger",
        "loader": {
          "name": "native",
          "entrypoint": {
            "module.path": "..\\..\\..\\modules\\logger\\Debug\\logger.dll"
          }
        },
        "args": {
          "filename": "deviceCloudUploadGatewaylog.log"
        }
      }
    ],
    "links" : [
        { "source" : "*", "sink" : "Logger" },
        { "source" : "BLE1", "sink" : "mapping" },
        { "source" : "BLE2", "sink" : "mapping" },
        { "source" : "mapping", "sink" : "IotHub" }
    ]
}

保存对配置文件所做的更改。

运行示例:

  1. 在命令提示符下,导航到 iot-edge 存储库本地副本中的 build 文件夹。
  2. 运行以下命令:

    samples\simulated_device_cloud_upload\Debug\simulated_device_cloud_upload_sample.exe ..\samples\simulated_device_cloud_upload\src\simulated_device_cloud_upload_win.json
    
  3. 可使用设备资源管理器iothub-explorer 工具监视 IoT 中心从网关接收的消息。 例如,若使用 iothub-explorer,可通过以下命令监视设备到云的消息:

    iothub-explorer monitor-events --login "HostName={Your iot hub name}.azure-devices.cn;SharedAccessKeyName=iothubowner;SharedAccessKey={Your IoT Hub key}"
    

后续步骤

若要深入了解 IoT Edge 并尝试一些代码示例,请访问以下开发人员教程和资源:

若要进一步探索 IoT 中心的功能,请参阅: