Forum Discussion
Help understanding IoTHubDeviceClient in distributed modules
Hi,
I have a hard time wrapping my head around how to work with custom developed modules and connection strings. To make things easy, I've taken one of the Python scripts from the SDK examples on GitHub (the one that sends simulated temperature and humidity values).
The example mentioned uses IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING) and the send_message(message) to deliver it's values. This works fine and the data keeps coming in. However when I build a module from this and don't want to include a static connection string I can't seem to understand how this is done. Surely there's a corresponding way to get this dynamically populated or handled by the edge device. I just can't find any info on it.
My guess is that you are suppose to use IoTHubModuleClient.create_from_edge_environment() instead and use that but I can't seem to get that to work. Any input to what achieves this? The aim is to be able to push the same module to multiple edge devices connected to different IoT Hubs and to do this I don't want to include a connection string.
8 Replies
- OlivierBlochFormer Employee
petersaverman the modules in IoT Edge do not need to authenticate with IoT Hub directly and you shouldn't use a device connection string nor the IoT HubDeviceClient client in a module. As you have seen you need to use the IoTHubModule client.
The IoTEdge runtime is the one that will have to authenticate using the IoT Edge Device credentials created when provisioning in your IoT Hub(s). BTW I recommend using the Device Provisioning Service rather than connection strings when going to production. See some doc about this https://docs.microsoft.com/en-us/azure/iot-edge/how-to-auto-provision-x509-certs.
Once your IoT Edge devices connect and authenticate to the IoT Hub they were configured for, you can deploy the same module to multiple IoT Edge devices through IoT Hub using the https://docs.microsoft.com/en-us/azure/iot-edge/how-to-deploy-at-scale, the https://docs.microsoft.com/en-us/azure/iot-edge/how-to-deploy-cli-at-scale or your own code using the IoT Hub APIs.
Let me know if that puts you on the right track
- petersavermanCopper Contributor
Thanks for responding and excuse my late reply. I've actually set up provisioning of my devices and that works fine. I did find a discussion regarding the IoTHubModuleClient not receiving a connection as well as not throwing an error under certain circumstances which I sadly can't remember now but this was my issue as well.
I'm trying to find out just how to use the IoTHubModuleClient to send a message to the Hub right now. Is that where the output comes in (via send_message_to_output) or do I still use the
or should I still use the send_message method?
- OlivierBlochFormer Employee
The modules communication is enabled by the Edge Hub module which is part of the IoT Edge runtime. The idea is that you configure routes between modules and up to the IoT Hub service at the IoT Edge runtime level and then in your module you can send messages to the output of the module defined in the routing configuration. You can learn more about the IoT Edge runtime concepts in https://docs.microsoft.com/en-us/azure/iot-edge/iot-edge-runtime#module-communication and more on the routing setup in https://docs.microsoft.com/en-us/azure/iot-edge/module-composition.
If you want to send messages to IoT Hub directly from a module then you need to setup a route that takes all outputs from the module and sends to "upstream".
For sending all messages from a specific module to IoT Hub, you would setup the route like this:
"$edgeHub": { "properties.desired": { "routes": { "route1": "FROM /messages/modules/<moduleId>/* INTO $upstream" }, } }