0

I am trying to play with Azure IoT Edge and creating a custom C# module like below.

Module is up and running and logs suggest till here "IoT Hub module client initialized.".

how to send messages to module? how to call "input1"?

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Client.Transport.Mqtt;
using System.Text;

namespace SampleModule;

internal class ModuleBackgroundService : BackgroundService
{
    private int _counter;
    private ModuleClient? _moduleClient;
    private CancellationToken _cancellationToken;
    private readonly ILogger<ModuleBackgroundService> _logger;

    public ModuleBackgroundService(ILogger<ModuleBackgroundService> logger) => _logger = logger;

    protected override async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        _cancellationToken = cancellationToken;
        MqttTransportSettings mqttSetting = new(TransportType.Mqtt_Tcp_Only);
        ITransportSettings[] settings = { mqttSetting };

        // Open a connection to the Edge runtime
        _moduleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);

        // Reconnect is not implented because we'll let docker restart the process when the connection is lost
        _moduleClient.SetConnectionStatusChangesHandler((status, reason) => 
            _logger.LogWarning("Connection changed: Status: {status} Reason: {reason}", status, reason));

        await _moduleClient.OpenAsync(cancellationToken);

        _logger.LogInformation("IoT Hub module client initialized.");

        // Register callback to be called when a message is received by the module
        await _moduleClient.SetInputMessageHandlerAsync("input1", ProcessMessageAsync, null, cancellationToken);
    }

    async Task<MessageResponse> ProcessMessageAsync(Message message, object userContext)
    {
        int counterValue = Interlocked.Increment(ref _counter);

        byte[] messageBytes = message.GetBytes();
        string messageString = Encoding.UTF8.GetString(messageBytes);
        _logger.LogInformation("Received message: {counterValue}, Body: [{messageString}]", counterValue, messageString);

        if (!string.IsNullOrEmpty(messageString))
        {
            using var pipeMessage = new Message(messageBytes);
            foreach (var prop in message.Properties)
            {
                pipeMessage.Properties.Add(prop.Key, prop.Value);
            }
            await _moduleClient!.SendEventAsync("output1", pipeMessage, _cancellationToken);

            _logger.LogInformation("Received message sent");
        }
        return MessageResponse.Completed;
    }
}
James Z
  • 12,209
  • 10
  • 24
  • 44
user584018
  • 10,186
  • 15
  • 74
  • 160
  • hope this helps [you](https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/iot-develop/tutorial-migrate-device-to-module.md) – Sampath May 31 '23 at 09:28

2 Answers2

0

To send a message to an Edge module's input1 you need to set up a route in the Edge deployment. Typically, this is used to send a message from one module to another, but it also could be used to route messages from external devices connected to the Edge gateway.

See this webpage for information on declaring routes: https://learn.microsoft.com/en-us/azure/iot-edge/module-composition?view=iotedge-1.4#declare-routes

Mark Radbourne
  • 528
  • 3
  • 12
0

On the configuration of the module you need to add a route. Your route should look something like FROM /messages/modules/<module-name>/outputs/output1 INTO $upstream

In the code snippet you have above you need to route and send a message to the module at "input1" then route "output1" to upstream.

Iot edge doesn't support cloud to device messages, but they do support direct methods. You could try that instead of trying to route a message into the module, and you can invoke the method directly from the azure portal. Otherwise you need to route a message into your module in the same way the you route the message out.

Will
  • 26
  • 1
  • 4