skip to Main Content

I have an IoT Edge Module filtermodule which sends telemetry using send_message (docs) with IoTHubModuleClient every minute.

When I run this module, the IoT Hub message counter in the portal is incrementing. Also, I used this route in the IoT Edge Hub configuration for deployment:

"routes": {
  "filtermoduleToIoTHub": "FROM /messages/modules/filtermodule/outputs/* INTO $upstream"
}

Furthermore, I created a custom route and endpoint in IoT Hub which routes messages to a storage account (key based authentication). The route query is true and I tested the same telemetry data with the route and all tests pass in the sense that it matches the query.

Somehow the data is not ending up in the storage account and there is not really a straight forward way to debug why that is the case. Before I was using IoTHubDeviceClient with send_message (no IoT Edge) with the same route and storage account and data did actually show up in the storage account. What is missing here? I find the docs on IoT Edge and IoT Hub and how they work together quite confusing sometimes.

EDIT:

The telemetry data I send has the following format (the same format as when it worked previously):

{"Measurements": [{"Temperature": 20.5}, {"Temperature": 20.5}]}

I am using Terraform for deployment and this endpoint and route used to work:

# IoT Hub endpoint for bronze ingestion storage container
resource "azurerm_iothub_endpoint_storage_container" "bronze_ingestion_endpoint" {
  resource_group_name = azurerm_resource_group.this.name
  iothub_id           = azurerm_iothub.this.id
  name                = "bronze-ingestion"

  container_name = azurerm_storage_container.bronze_ingestion_avro.name
  connection_string = azurerm_storage_account.bronze.primary_connection_string

  file_name_format           = "{iothub}/{YYYY}/{MM}/{DD}/{HH}/{mm}_{partition}.avro"
  batch_frequency_in_seconds = 600
  max_chunk_size_in_bytes    = 10485760
  encoding                   = "Avro"
}

# IoT Hub route for bronze ingestion storage container
resource "azurerm_iothub_route" "bronze_ingestion_route" {
  resource_group_name = azurerm_resource_group.this.name
  iothub_name         = azurerm_iothub.this.name
  name                = "bronze-ingestion-route"

  source         = "DeviceMessages"
  condition      = "true"
  endpoint_names = [azurerm_iothub_endpoint_storage_container.bronze_ingestion_endpoint.name]
  enabled        = true
}

EDIT 2:

I can confirm that if I use IoTHubModuleClient.create_from_connection_string(conn_string) on my local machine, the route works and data shows up in the storage account. When I use IoTHubModuleClient.create_from_edge_environment() on the IoT device within the edge environment, the route does not work (but the message counter in the portal increments).

The same is true for Azure IoT Explorer. I can monitor incoming events from if I use IoTHubModuleClient.create_from_connection_string(conn_string) on my local machine, but nothing shows up If I use IoTHubModuleClient.create_from_edge_environment() on the IoT device.

2

Answers


  1. Chosen as BEST ANSWER

    Apparently when you use /messages/modules/filtermodule/outputs/* you have to use send_message_to_output instead of send_message (documentation). I assumed that using send_message would send to any output, but that is not the case (documentation). send_message does work if you use /messages/modules/*, /messages/modules/<moduleId>/*, /messages/* or /*.


  2. Below are the steps to send device data to Azure Storage using IoT Hub message routing:
    From edge environment:

    Use iotedge logs <module_name> to inspect the logs for a specific module .(0r) Use sudo iotedge logs <ModuleName> -f to view the messages being sent from the module. Refer to this link to learn how to develop Azure IoT Edge modules using Visual Studio Code.

    Create a azure Storage and Container . Connect Endpoint for an IoT Hub Using a Connection String.

    az iot hub message-endpoint create storage-container -n {iothub_name} --en {endpoint_name} -c {connection_string} --container {container_name}
    

    az iot hub

    Create a route using the following command:

    az iot hub message-route create --route-name $routeName --hub-name $hubName --resource-group $resourceGroup --source-type devicemessages --endpoint-name $endpointName --enabled true --condition true
    
    

    enter image description here

    Run the send message code. Refer to this link for the send message code.

    Refer to this link and this So tread for using Azure CLI commands in Terraform.

    enter image description here

    Now, you can send device data to Azure Storage using IoT Hub message routing.Output

    Output

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search