0

I'm using IoT Edge to connect Modbus devices to IoT Hub and I'm trying to implement protocol + identity translation modules.

I started with the example here

I have two modules:

  1. ModbusClient, for the protocol translation, in C#

  2. IdentityTranslation, in NodeJS

Here is how routes are defined in the deployment file:

"ModbusClientToIdentityTranslation": "FROM /messages/modules/ModbusClient/outputs/modbusOutput INTO BrokeredEndpoint(\"/modules/IdentityTranslation/inputs/input1\")",

"IdentityTranslationToIoTHub": "FROM /messages/modules/IdentityTranslation/outputs/* INTO $upstream"

I would like to add a property with the deviceId value in the message transformed by the ModbusClient and read this property in the IdentityTranslation module.

Here are the snippets of the code in the two modules:

  • ModbusClient
Message message = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(out_message)));
message.Properties.Add("content-type", "application/edge-modbus-json");
message.Properties.Add("deviceId", deviceId);

Console.WriteLine("deviceId " + message.Properties["deviceId"]);
await ioTHubModuleClient.SendEventAsync("modbusOutput", message);
  • IdentityTranslation
moduleClient.on('inputMessage', function (inputName, msg) {
  console.log("new message received", msg);
  if (modbusClient) {
    // Identity Translation configured, wrap message for IoT device
    const message = msg.getBytes().toString('utf8');
    const sensorMsg = new Message(message);
    console.log("sensorMsg ", sensorMsg);
    if(sensorMsg.Keys.Contains("deviceId")){
       console.log("deviceId ", sensorMsg.Properties["deviceId"]);
    }
    modbusClient.sendEvent(sensorMsg);
}

When the message arrives at the IdentityTranslation module, Properties are empty and I cannot get the deviceId value.

This is the content of the recevived message

new message received Message {
  data:
   <Buffer 7b 22 50 75 62 6c 69 73 68 54 69 6d 65 73 74 61 6d 70 22 3a 22 32 30 32 33 2d 30 36 2d 32 37 20 31 34 3a 34 39 3a 33 30 22 2c 22 43 6f 6e 74 65 6e 74 ... >,
  properties:
   Properties { propertyList: [ [Object], [Object], [Object] ] },
  messageId: '',
  to: '',
  expiryTimeUtc: undefined,
  lockToken: '',
  correlationId: '',
  userId: '',
  contentEncoding: 'utf-8',
  contentType: 'application/json' }

Can you please help me to undertsand where I'm wrong?

Thanks a lot in advance

ValeriaN
  • 3
  • 2

1 Answers1

0

The custom message properties added to the message in the ModbusClient module are not propagated to the IdentityTranslation module, is due to the message routes that you have defined does not specify that the message properties should be propagated.

For this, you have to update the message routes to include the $includeProperties option.

"ModbusClientToIdentityTranslation": "FROM /messages/modules/ModbusClient/outputs/modbusOutput INTO BrokeredEndpoint("/modules/IdentityTranslation/inputs/input1") WITH $includeProperties"

Once you updated the message routes, the custom message properties will be propagated to the IdentityTranslation module and able to access them in the Properties object of the message.

To access the deviceId property in the IdentityTranslation module.

var msg = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(out_message)));
msg.Properties.Add("content-type", "application/edge-modbus-json");
msg.Properties.Add("deviceId", deviceId);

await ioTHubModuleClient.SendEventAsync("modbusOutput", msg);

var route = new EdgeRouteSpecification.Builder()
    .WithSource("/messages/modules/ModbusClient/outputs/modbusOutput")
    .WithTarget(new EdgeModuleEndpoint.Builder()
        .WithModuleId("IdentityTranslation")
        .WithInputName("input")
        .Build())
    .WithPropagateProperties(true)
    .Build();

await ioTHubModuleClient.AddRouteAsync(route);

Reference taken from Azure Storage using IoT Hub message routing.

enter image description here

enter image description here

enter image description here

For tags updating check this SO and for more information, refer to the GitHub Code and MS Doc.

Rajesh Mopati
  • 1,329
  • 1
  • 2
  • 7
  • Thanks @Rajesh M for the answer. Simply adding the **$includeProperties** option in the route doesn't work for me. I have also an error if I try to use **EdgeRouteSpecification** , it is not recognized. Which SDK is part of? I haven't found any reference to EdgeRouteSpecification or includeProperties in the documentation. Are there specific examples for this case? – ValeriaN Jun 28 '23 at 09:08
  • Use the `Message.SystemProperties` property to access the system properties of the message, including the `iothub-connection-device-id` property which contains the device ID. – Rajesh Mopati Jun 28 '23 at 09:17
  • Use this example: moduleClient.on('inputMessage', function (inputName, msg) { console.log("new message received", msg); if (modbusClient) { // Identity Translation configured, wrap message for IoT device const message = msg.getBytes().toString('utf8'); const sensorMsg = new Message(message); console.log("sensorMsg ", sensorMsg); if(sensorMsg.systemProperties['iothub-connection-device-id']){ console.log("deviceId ", sensorMsg.systemProperties['iothub-connection-device-id']); } modbusClient.sendEvent(sensorMsg); } – Rajesh Mopati Jun 28 '23 at 09:18
  • It seems that SystemProperties property doesn't exist on The Message class [link](https://learn.microsoft.com/en-us/javascript/api/azure-iot-device/message?view=azure-node-latest#azure-iot-device-message-properties) This is the error that I have `/app/app.js:43 if(sensorMsg.systemProperties['iothub-connection-device-id']){ ^ TypeError: Cannot read property 'iothub-connection-device-id' of undefined` – ValeriaN Jun 28 '23 at 09:33