Reputation: 31
I'm trying to send a message to my device from the cloud, using Azure IoT Hub and REST api (not using the Azure IoT hub python SDK).
I can successfully send a message (POST request) to the hub from the device with uri https://<myiothub>.azure-devices.net/devices/<devid>/messages/events?api-version=2018-06-30
. In the documentation at https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-c2d it says there is a service-side endpoint at /messages/devicebound
. However, they don't show a complete example, so I'm not entirely sure what the full endpoint I should use is, and how/where to specify which device to send to.
I anyway tried the following:
curl -v POST \
https://<myhub>.azure-devices.net/messages/devicebound?api-version=2018-06-30 \
-H 'Authorization: SharedAccessSignature <sas>' \
-H 'Content-Type: application/json' \
-d '{
"payload": {
"key": "value"
}
}'
where is generated via Azure CLI az iot hub generate-sas-token -n <myhub>
. I get the error message
{"Message":"ErrorCode:ArgumentInvalid;Request must contain IoTHub custom 'To' header","ExceptionMessage":"Tracking ID:ec98ff8...
where I cut off the end. So I tried adding a "To" header, which regardless of what I put returns the same error message.
I also tried what's suggested here Cloud-to-device Azure IoT REST API, namely to send via endpoint https://main.iothub.ext.azure.com/api/Service/SendMessage/, but without luck.
Upvotes: 3
Views: 1812
Reputation: 109
Here's how to do it:
Using a text editor, create a SendCloudToDeviceMessage.py file.
Add the following import statements and variables at the start of the SendCloudToDeviceMessage.py file:
import random
import sys
import iothub_service_client
from iothub_service_client import IoTHubMessaging, IoTHubMessage, IoTHubError
OPEN_CONTEXT = 0
FEEDBACK_CONTEXT = 1
MESSAGE_COUNT = 1
AVG_WIND_SPEED = 10.0
MSG_TXT = "{\"service client sent a message\": %.2f}"
CONNECTION_STRING = "{IoTHubConnectionString}"
DEVICE_ID = "{deviceId}"
def open_complete_callback(context):
print ( 'open_complete_callback called with context: {0}'.format(context) )
def send_complete_callback(context, messaging_result):
context = 0
print ( 'send_complete_callback called with context : {0}'.format(context) )
print ( 'messagingResult : {0}'.format(messaging_result) )
def iothub_messaging_sample_run():
try:
iothub_messaging = IoTHubMessaging(CONNECTION_STRING)
iothub_messaging.open(open_complete_callback, OPEN_CONTEXT)
for i in range(0, MESSAGE_COUNT):
print ( 'Sending message: {0}'.format(i) )
msg_txt_formatted = MSG_TXT % (AVG_WIND_SPEED + (random.random() * 4 + 2))
message = IoTHubMessage(bytearray(msg_txt_formatted, 'utf8'))
# optional: assign ids
message.message_id = "message_%d" % i
message.correlation_id = "correlation_%d" % i
# optional: assign properties
prop_map = message.properties()
prop_text = "PropMsg_%d" % i
prop_map.add("Property", prop_text)
iothub_messaging.send_async(DEVICE_ID, message, send_complete_callback, i)
try:
# Try Python 2.xx first
raw_input("Press Enter to continue...\n")
except:
pass
# Use Python 3.xx in the case of exception
input("Press Enter to continue...\n")
iothub_messaging.close()
except IoTHubError as iothub_error:
print ( "Unexpected error {0}" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubMessaging sample stopped" )
if __name__ == '__main__':
print ( "Starting the IoT Hub Service Client Messaging Python sample..." )
print ( " Connection string = {0}".format(CONNECTION_STRING) )
print ( " Device ID = {0}".format(DEVICE_ID) )
iothub_messaging_sample_run()
Save and close SendCloudToDeviceMessage.py file.
Install dependency library: pip install azure-iothub-service-client
Run the Application: python SendCloudToDeviceMessage.py
Upvotes: 0
Reputation: 599
To receive a Cloud to Device message from the device end using IoT Hub API you will have to do the following request -
curl -X GET \
'https://{your hub}.azure-devices.net/devices/{your device id}/messages/deviceBound?api-version=2018-06-30' \
-H 'Authorization: {your sas token}'
Upvotes: 0