本文介绍:

1. 利用Module Client 发送Module 到云的消息;

2. 如何在本地VS code中调试 Azure IoT Edge Module;

3. 使用路由 在多个模块之间控制消息流向;

 

本文代码请参考github:https://github.com/sean8544/azure-iot-edge-quickstart/tree/main/demo08

 

本文参考:

开发调试 edge module:https://docs.microsoft.com/zh-cn/azure/iot-edge/how-to-vs-code-develop-module

edge hub dev tool:https://github.com/Azure/iotedgehubdev

 

视频:

 

图文:

Azure IoT Edge 的Module 如果要发送模块到云的消息,需要使用Module Client 客户端,有关 ModuleClient 类及其通信方法的更多信息,请参阅首选 SDK 语言的 API 参考:C#CPythonJava 或 Node.js

本文在《Azure IoT Edge入门(7)体验Edge Module开发 》的基础上,将模版中的微软提前预置的“SimulatedTemperatureSensor”替换成自己写的“SensorModule”,在SensorModule中我们使用了Module Client 类发送数据,数据格式也比价简单,每5秒钟发送一次模拟的温湿度值。

1. 利用Module Client 发送Module 到云的消息;

ctrl+shift+p,输入Azure IoT Edge:Add IoT Edge Module,为解决方案创建一个新的module

 

选择一个部署模版,本例中选择debug,那么deployment.template.json则需要在项目调试结束后,手动修改

一个edge中的多个module可以采用不同的开发语言,本例中,我们继续使用C#语言。

输入一个Module的命成,本文设置为“SensorModule”。

 

可以在Azure portal找到 容器注册表的 登录服务器地址,拷贝到 vs code中

 

 

 

 

保留/sensormodule的路径

 

module创建完成后,可以在左侧列表中看到如下图所示的SensorModule,还有上一讲中创建好的MyFirstModule

 

修改Programs.cs中的源代码,源码可参照:

或直接将下文中的源码覆盖掉:

namespace SensorModule
{
    using System;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.Devices.Client.Transport.Mqtt;
    using Microsoft.Azure.Devices.Shared;
    using Microsoft.Extensions.Configuration;
    using Newtonsoft.Json;


    class Program
    {
        static readonly Random Rnd = new Random();
        static TimeSpan messageDelay;
               

        public static int Main() => MainAsync().Result;

        static async Task<int> MainAsync()
        {
            Console.WriteLine("Sensor Module Main() started.");

            IConfiguration configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("config/appsettings.json", optional: true)
                .AddEnvironmentVariables()
                .Build();

            messageDelay = configuration.GetValue("MessageDelay", TimeSpan.FromSeconds(5));
                            
            ModuleClient client =  await ModuleClient.CreateFromEnvironmentAsync(new ITransportSettings[] { new MqttTransportSettings(TransportType.Mqtt_Tcp_Only)});
            await client.OpenAsync();

            await SendCustomMsg(client,"Sensor Module Start");
            
            await SendEvents(client);
            Console.WriteLine("SimulatedSensor Main() finished.");
            return 0;
        }
  
        static async Task SendCustomMsg( ModuleClient moduleClient,string Msg)
        {                  
                    string sensorDtaBuffer = JsonConvert.SerializeObject(Msg);
                    var sensorEventMessage = new Message(Encoding.UTF8.GetBytes(sensorDtaBuffer));
                    sensorEventMessage.Properties.Add("MsgType", "CustomMsg");

                    await moduleClient.SendEventAsync("sensorOutput", sensorEventMessage);                 
                    
                    Console.WriteLine($"message sent:{sensorDtaBuffer}");              
           

        }
        
        static async Task SendEvents( ModuleClient moduleClient)
        {                   

            while (true)
            {       
                    var sensorData = new SensorData
                                        {
                                            Temperature=Rnd.Next(20,35),
                                            Humidity=Rnd.Next(55,80)
                                        };

                    string sensorDtaBuffer = JsonConvert.SerializeObject(sensorData);
                    var sensorEventMessage = new Message(Encoding.UTF8.GetBytes(sensorDtaBuffer));
                    sensorEventMessage.Properties.Add("MsgType", "Telemetry");
                    if(sensorData.Temperature>30)
                    {
                         sensorEventMessage.Properties.Add("Alert", "TemperatureAlert");
                    }

                    await moduleClient.SendEventAsync("sensorOutput", sensorEventMessage);                 
                    
                     Console.WriteLine($"message sent:{sensorDtaBuffer}");

                await Task.Delay(messageDelay);
            }

           
        }

      
     
     
        class SensorData
        {
            public double Temperature { get; set; }

            public double Humidity { get; set; }            
        }
    }
}

 

添加一个配置文件(此步骤仅针对本文案例,不是module开发的必备步骤):

 

修改 deployment.debug.template.json中模块的信息:

删除 默认的 SimulatedTemperatureSensor 模块。

修改路由:

对如下路由进行修改:

修改为:

"routes": {
          "MyFirstModuleToIoTHub": "FROM /messages/modules/MyFirstModule/outputs/* INTO $upstream",

          "SensorModuleToMyFirstModule": "FROM /messages/modules/SensorModule/outputs/sensorOutput INTO BrokeredEndpoint(\"/modules/MyFirstModule/inputs/input1\")"
        },

 

编译项目并推送到ACR:

 

 

 

 

 向单个iot edge设备发起远程部署:

 

选择config文件夹下生成的部署配置文件:

部署完成后,可以看到四个模块:

 

开始监控Edge Module发送到云端的消息:

温湿度值已经可以收到:

 

2. 如何在本地VS code中调试 Azure IoT Edge Module;

多个module在本地进行调试:

在Edge设备上创建本地调试用的模拟器,在IoTEdge设备上右键选择“Setup IoT Edge Simulator”

在VS Code中的TERMINAL窗口中,根据操作系统可能需要输入管理员密码,直到看到“Setup iot edge simulator successfully”

 

在deployment.debug.template.json文件上右键Build and run iot solution in simulator。

在VS Code中的TERMINAL窗口中可以看到 edgehubdev 工具已经开始运行。

同时在vs code docker扩展中可以看到本地的三个容器已经开始运行了,注意,三个容器中又一个 edge-hub是Azure IOT Edge系统module,且系统module中本地调试过程中,没有edge-agent module。

在要调试的代码出添加断点:

 

开始启动调试,注意,项目选则带有remote 字样的。

 

断点被中断,可以进行调试: