1

i have followed this link To write custom modules. In this tutorial A module named tempSensor sending data to another Module CSharpModule. As far as tutorial is concerned, I successfully implemented it.

What i want to do is: Receiving telemetry data from IoTDevice to IoTEdge Device.

Architecture: Azure IoTHub connected with IoT devices and an IoTEdge device

What i have tried: I tried to send telemetry data from a simulated device connected to ioTEdge with connectionString.

The code to send data is here

        //DeviceClient connected to IoTEdge     
        s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionString);

        private static async void SendDeviceToCloudMessagesAsync()
        {
            // Initial telemetry values
            double minTemperature = 20;
            double minHumidity = 60;
            Random rand = new Random();

            while (true)
            {
                double currentTemperature = minTemperature + rand.NextDouble() * 15;
                double currentHumidity = minHumidity + rand.NextDouble() * 20;

                // Create JSON message
                var telemetryDataPoint = new
                {
                    temperature = currentTemperature,
                    humidity = currentHumidity
                };
                var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
                var message = new Message(Encoding.ASCII.GetBytes(messageString));

                // Add a custom application property to the message.                    
                message.Properties.Add("temperatureAlert", (currentTemperature > 30) ? "true" : "false");

                // Send the tlemetry message to endpoint output1
                await s_deviceClient.SendEventAsync("ouput1",message);

                //await s_deviceClient.SendEventAsync(message);
                Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);

                await Task.Delay(s_telemetryInterval * 10000);
            }
        }

IoTEdge custom module code's receiving end is here...

        static async Task Init()
        {
            AmqpTransportSettings amqpSetting = new AmqpTransportSettings(TransportType.Amqp_Tcp_Only);
            ITransportSettings[] settings = { amqpSetting };

            // Open a connection to the Edge runtime
            ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);
            await ioTHubModuleClient.OpenAsync();
            Console.WriteLine("IoT Hub module client initialized.");

        // Register a callback for messages that are received by the module.
            // await ioTHubModuleClient.SetImputMessageHandlerAsync("input1", PipeMessage, iotHubModuleClient);

            // Read the TemperatureThreshold value from the module twin's desired properties
            var moduleTwin = await ioTHubModuleClient.GetTwinAsync();
            var moduleTwinCollection = moduleTwin.Properties.Desired;
            try {
                temperatureThreshold = moduleTwinCollection["iothub-connection-device-id"];
            } catch(ArgumentOutOfRangeException e) {
                Console.WriteLine($"Property TemperatureThreshold not exist: {e.Message}"); 
            }

            // Attach a callback for updates to the module twin's desired properties.
            await ioTHubModuleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdate, null);

            // Register a callback for messages that are received by the module
            await ioTHubModuleClient.SetInputMessageHandlerAsync("input1", PipeMessage, ioTHubModuleClient);
        }

The route information from deployment.template.json file of custom module is as following.

 "routes": {
      "aggregationModuleToIoTHub": "FROM /messages/modules/aggregationModule/outputs/* INTO $upstream"           
    }

But the problem is the callback PipeMessage never called. My understanding is no message is coming at IoTEdge endpoint messages/input1.

Danny Ruijters
  • 3,411
  • 2
  • 18
  • 21
Bilal
  • 1,034
  • 11
  • 23

1 Answers1

0

To make sure I understand your question, you are trying to send code from an IoT Device outside of IoT Edge into IoT Edge, and then route that data through a module in IoT Edge up to IoT Hub? is that correct? If that's the case, we call the IoT Device a downstream or "leaf" device. IoT Edge needs to be set up as a 'transparent gateway' like this documentation. Once you do that, you need to add ;GatewayHostName= to the end of your connection string where is the name you used as the 'hostname' parameter in your config.yaml file.

  • yeah you understood it correctly. i will give it a try then, will let you know. just want to confirm one thing: should the data sending device connect to IotEdge? with connection string? or with IOT Hub? – Bilal Sep 14 '18 at 10:39
  • 1
    The data sending device uses the normal IoT Hub-based connection string... to the end of it, you just append ";GatewayHostName=" where is the name of your edge device from the hostname parameter in config.yaml… you need to make sure your "leaf" device (as we call it) can resolve that name (so you may need to add a hosts file entry if you don't have DNS). Also, as the documentation I referred to above, you need to make sure that the leaf device trusts the root ca certificate of your Edge device or the connection between leaf and edge will fail – Steve Busby - MSFT Sep 14 '18 at 18:17