Open engemil opened 1 year ago
I was able to successfully implement the twin document request by extending the example Azure_IoT_Central_ESP32 based on the sample ino that you've provided above. So thank you for that.
I noticed you are not subscribing to the topic '$iothub/twin/GET/?$rid=get_twin'. The response to the GET request will be posted there. Have you tried adding an additional subscription to that topic?
For what it's worth here's an extract from my log output which shows all topics I'm using
[ 17910][I] esp_mqtt_event_handler(): MQTT client connected (session_present=0x00000000).
[ 17914][I] mqtt_client_subscribe_function(): MQTT client subscribing to '$iothub/methods/POST/#'
[ 18015][I] esp_mqtt_event_handler(): MQTT topic subscribed (message id=0x00009e5c).
[ 18024][I] mqtt_client_subscribe_function(): MQTT client subscribing to '$iothub/twin/res/#'
[ 18099][I] esp_mqtt_event_handler(): MQTT topic subscribed (message id=0x0000569f).
[ 18104][I] mqtt_client_subscribe_function(): MQTT client subscribing to '$iothub/twin/PATCH/properties/desired/#'
[ 18174][I] esp_mqtt_event_handler(): MQTT topic subscribed (message id=0x0000c7b9).
[ 18184][I] azure_iot_do_work(): ******************* REQUESTING TWIN DOCUMENT *********************
[ 18206][I] mqtt_client_publish_function(): MQTT client publishing to '$iothub/twin/GET/?$rid=get_twin'
[ 18220][I] mqtt_client_subscribe_function(): MQTT client subscribing to '$iothub/twin/GET/?$rid=get_twin'
[ 18290][I] esp_mqtt_event_handler(): MQTT message received.
[ 18290][I] on_device_twin_received(): Device Twin received: {"desired":{"state":"on","temp":55,"deviceName":"foo" ....
[ 18425][I] esp_mqtt_event_handler(): MQTT topic subscribed (message id=0x00009019).
[ 18430][I] (): ******************* TWIN DOCUMENT GOTTEN *************************
Hope this helps
@meta-space Interesting to see that it works for you with ESP32.
When it comes to $iothub/twin/GET/?$rid=get_twin
, from the official examples, you are not supposed to subscribe to it. You only need to publish to it. I gave it a try to see if subscribing to it worked aswell. However, the same result.
...
[INFO] MQTT client initialized.
[INFO] Connecting to Azure IoT Hub.
[INFO] Connected to your Azure IoT Hub!
[INFO] Subscribed to MQTT topic: devices/+/messages/devicebound/#
[INFO] Subscribed to MQTT topic: $iothub/methods/POST/#
[INFO] Subscribed to MQTT topic: $iothub/twin/res/#
[INFO] Subscribed to MQTT topic: $iothub/twin/PATCH/properties/desired/#
[INFO] Subscribed to MQTT topic: $iothub/twin/GET/?$rid=get_twin
[INFO] Requesting device twin document . . .
[INFO] MQTT Client publishing to $iothub/twin/GET/?$rid=get_twin
And no reply.
And as mentioned, the odd part is that I can't receive any C2D Messages nor publish with D2C messages,
after I tried to publish to $iothub/twin/GET/?$rid=get_twin
.
@engemil , first, to confirm everything is set up correctly on the Hub side, please use the same device identity with the sample within this repository: https://github.com/Azure/azure-sdk-for-c/blob/main/sdk/samples/iot/paho_iot_hub_twin_sample.c I'm able to run the sample and use Azure IoT Explorer to modify twin's desired properties and receive updates on the device side.
The two topics you must subscribe to are: AZ_IOT_HUB_CLIENT_TWIN_PATCH_SUBSCRIBE_TOPIC
and AZ_IOT_HUB_CLIENT_TWIN_RESPONSE_SUBSCRIBE_TOPIC
.
Then, you must use the az_iot_hub_client_twin_document_get_publish_topic
and az_iot_hub_client_twin_patch_get_publish_topic
APIs to obtain the correct publish topics. This is described in the diagram here: https://github.com/Azure/azure-sdk-for-c/blob/main/sdk/docs/iot/mqtt_state_machine.md#iot-hub We do not recommend hardcoding any of the topics when using the SDK (they are subject to change in future versions).
Also, please keep in mind that Twin is not available on all IoT Hub SKUs: https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-scaling?branch=release-iotbasic (since you mentioned C2D works, I assume this is not a Basic hub).
Based on the logs above, the topics seem to be correct and Hub should have responded to the request. Since the logs though do not show MQTT acknowledgements, we don't know if the connection was terminated or if the subscriptions were successful.
To further investigate this issue, we need service-side logs. Please follow https://learn.microsoft.com/en-us/azure/azure-portal/supportability/how-to-create-azure-support-request to open a ticket.
@engemil You are correct. I removed the subscription call and the twin document still arrived.
I think I had accidentally messed up the state in the state machine which resulted in the response not being processed previously
@CIPop The IoT Hub (free tier) seem to be set up correctly. I managed to run the paho_iot_hub_twin_sample.c
from Windows, and I got the following result (Iot hub name sensured with XXXXXXXXX):
AZ_IOT_HUB_HOSTNAME = XXXXXXXXX.azure-devices.net
AZ_IOT_HUB_DEVICE_ID = paho-sample-device1
AZ_IOT_DEVICE_X509_CERT_PEM_FILE_PATH = C:\azure-sdk-for-c\sdk\samples\iot\device_cert_store.pem
AZ_IOT_DEVICE_X509_TRUST_PEM_FILE_PATH = C:\azure-sdk-for-c\sdk\samples\iot\BaltimoreCyberTrustRoot.crt.pem
SUCCESS: MQTT endpoint created at "ssl://XXXXXXXXX.azure-devices.net:8883".
SUCCESS: Client created and configured.
MQTT client username: XXXXXXXXX.azure-devices.net/paho-sample-device1/?api-version=2020-09-30&DeviceClientType=azsdk-c%2F1.6.0-beta.1
SUCCESS: Client connected to IoT Hub.
SUCCESS: Client subscribed to IoT Hub topics.
Client requesting device twin document from service.
Waiting for device twin message.
SUCCESS: Client received a device twin message from the service.
SUCCESS: Client received a valid topic response.
Topic: $iothub/twin/res/200/?$rid=get_twin
Payload: {"desired":{"$version":1},"reported":{"$version":1}}
Status: 200
SUCCESS: Client parsed device twin message.
Message Type: GET
Client sending reported property to service.
SUCCESS: Client published the Twin Patch reported property message.
Payload: {"device_count":0}
Waiting for device twin message.
SUCCESS: Client received a device twin message from the service.
SUCCESS: Client received a valid topic response.
Topic: $iothub/twin/res/204/?$rid=reported_prop&$version=2
Payload:
Status: 204
SUCCESS: Client parsed device twin message.
Message Type: Reported Properties
Waiting for device twin message.
Receive message timeout expired.
SUCCESS: Client disconnected from IoT Hub.
C:\azure-sdk-for-c\build\sdk\samples\iot\Debug\paho_iot_hub_twin_sample.exe (process 21612) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .
I tried to open a ticket with the instructions given in the link you gave, however, the "New support request"-interface sent me to a Diagnostics summary, summarizing that nothing seems to be wrong and recommended steps given where "no action should be needed".
I suspect the issue is in the arduino ported version of Azure SDK for C (https://github.com/Azure/azure-sdk-for-c-arduino), or in my own code. I'm available for further troubleshooting if you have more ideas for what should be tested.
Thank you @engemil for the test and logs!
We'll try to repro on our side with the Arduino port.
Describe the bug
I'm working on a code sample to utilize the IoT Hub device twin, where the first step is to request the device twin from cloud to device. After the request is sent, there is no message received and there is no telling if the cloud (IoT Hub) received the request.
The code is based on the Azure IoT Hub Arduino Nano RP2040 Connect example from https://github.com/Azure/azure-sdk-for-c-arduino/tree/main/examples/Azure_IoT_Hub_Arduino_Nano_RP2040_Connect . I built the example with PlatformIO, which worked. However, the device twin request doesn't seem execute properly. The device twin code is based on:
Exception or Stack Trace
Serial reading from the microcontroller
(Sensitive information sensured out with XXXXX) ``` [INFO] Attempting to connect to WIFI SSID: XXXXX [INFO] WiFi connected, IP address: XXXXX, Strength (dBm): -48 [INFO] Syncing time. ......... [INFO] Time synced! [INFO] Initializing Azure IoT Hub client. [INFO] Azure IoT Hub hostname: XXXXX.azure-devices.net [INFO] Azure IoT Hub client initialized. [INFO] Initializing MQTT client. [INFO] UTC Current time: 2023-03-17 12:31:57 (epoch: 1679056317 secs) [INFO] UTC Expiry time: 2023-03-17 13:31:57 (epoch: 1679059917 secs) [INFO] Local Current time: 2023-03-17 14:31:57 [INFO] Local Expiry time: 2023-03-17 15:31:57 [INFO] Client ID: XXXXX [INFO] Username: XXXXX.azure-devices.net/XXXXX/?api-version=2020-09-30&DeviceClientType=c/1.5.0-beta.1(ard;nanorp2040connect) [INFO] MQTT client initialized. [INFO] Connecting to Azure IoT Hub. [INFO] Connected to your Azure IoT Hub! [INFO] Subscribed to MQTT topic: devices/+/messages/devicebound/# [INFO] Subscribed to MQTT topic: $iothub/twin/res/# [INFO] Subscribed to MQTT topic: $iothub/twin/PATCH/properties/desired/# [INFO] Arduino Nano RP2040 Connect requesting device twin document . . . [INFO] MQTT Client publishing to $iothub/twin/GET/?$rid=get_twin [INFO] Request for Device Twin Document sent. ```To Reproduce
Code Snippet
The .ino-file (main.cpp file for PlatformIO projects)
``` /*--- Libraries ---*/ // Arduino #includeExpected behavior The expected behavior of the code is to receive a "message" which includes the device twin Json document. However, this code only checks if there is any message received, and prints the message-topic and message length. The code has not yet implemented code to read the message. It ONLY verifies if the device twin was sent to device.
Setup:
Additional context
Note1: If the problem does not relate to Azure SDK for C, I suspect limitations/problems with ArduinoMQTT. I would like to give an request for adding a device twin example in the Azure SDK for C Arduino repository.
Note 2: (Update 20.03.2023) I made another test with two functionaliteis implemented, twin get request and D2C message in the same code. The code first sends a D2C message, which I detect in Azure Portal (with
az iot hub montir-events --hub-name ...
). The second step is to send a twin get request over MQTT connection. After the request is sent, I can no longer recieve D2C messages in the cloud (IoT Hub). Not able to see this happen. Will try to replace theArduinoMqttClient
with SubPubClient.Note 3: (Update 20.03.2023) Tested
PubSubClient
library, same result. Suspect problem with the arduino porting repository (https://github.com/Azure/azure-sdk-for-c-arduino). NB! Im posting this issue here, as the arduino-ported repo does not have a issue tab.Note 4: (Update 21.03.2023) In the arduinoMqttClient library there is a macro (
MQTT_CLIENT_DEBUG
), commented out by default. With it enabled, it confirmed that the topics where subscripted to correctly (MQTT received data for each subscription). And, as suspected only sends and does NOT receive data when sending a "get_twin" request.Note 5: (Update 21.03.2023) In D2C / Telemetry messages, the Azure SDK for C (for arduino) seem to treat the payload section as non-JSON syntax. Due to the backslashes for each quotation mark, as shown here:
Is this as expected? or is the code in the Arduino framework affecting the handling of Strings/characters, such that the payload behaves wierd? And could this possible affect the "get_twin" request aswell?
Information Checklist Please make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report