Reputation: 1337
I am sending data through the path as below.
Android -> IoT Hub -> Stream Analytics -> SQL
I am calling machine learning function at the query of Stream Analytics. Now, I want to return the result of machine learning to the Android device. For receiving cloud-to-device message at Android device, I have done and tested with Device Explorer. I am looking at official tutorials, 1, 2 but still no clue on how to send cloud to device message using the Stream Analytics. He said using the service bus and function app but did not give the details. I am new to Azure. Hoping someone will give me some guidance or any link so I can understand more on how to implement it. Thanks in advance.
Upvotes: 1
Views: 1117
Reputation: 8265
You can use an Azure Function (Preview) to output an ASA job for sending a cloud-to-device message via the Azure IoT Hub service-facing endpoint.
The following is an example of this function.
run.csx:
#r "Newtonsoft.Json"
using System.Configuration;
using System.Text;
using System.Net;
using Microsoft.Azure.Devices;
using Newtonsoft.Json;
// create proxy
static Microsoft.Azure.Devices.ServiceClient client = ServiceClient.CreateFromConnectionString(ConfigurationManager.AppSettings["myIoTHub"]);
public static async Task<HttpResponseMessage> Run(string input, HttpRequestMessage req, TraceWriter log)
{
log.Info($"ASA Job: {input}");
var data = JsonConvert.DeserializeAnonymousType(input, new[] { new { xyz = "", IoTHub = new { ConnectionDeviceId = ""}}});
if(!string.IsNullOrEmpty(data[0]?.IoTHub?.ConnectionDeviceId))
{
string deviceId = data[0].IoTHub.ConnectionDeviceId;
log.Info($"Device: {deviceId}");
// cloud-to-device message
var msg = JsonConvert.SerializeObject(new { temp = 20.5 });
var c2dmsg = new Microsoft.Azure.Devices.Message(Encoding.ASCII.GetBytes(msg));
// send AMQP message
await client.SendAsync(deviceId, c2dmsg);
}
return req.CreateResponse(HttpStatusCode.NoContent);
}
function.json:
{
"bindings": [
{
"authLevel": "function",
"name": "input",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
project.json:
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.Azure.Devices": "1.3.2"
}
}
}
}
Appendix A
For the test purpose, make the following steps:
[ { "time": "2017-11-26T12:52:23.4292501Z", "counter": 57, "windSpeed": 8.7358, "temperature": 16.63, "humidity": 79.42, "EventProcessedUtcTime": "2017-11-26T12:52:21.3568252Z", "PartitionId": 2, "EventEnqueuedUtcTime": "2017-11-26T12:52:22.435Z", "IoTHub": { "MessageId": null, "CorrelationId": null, "ConnectionDeviceId": "Device1", "ConnectionDeviceGenerationId": "636189812948967054", "EnqueuedTime": "2017-11-26T12:52:21.562Z", "StreamId": null } } ]
Change the value Device1 for your actually deviceId.
You should see this function in the combobox when you selected your subscription in the Import option combobox. Once you done, press the Save button and watch the notification message on the screen. The ASA will send a validation message to your AF and its response status should be 20x code.
Note, the inpsim is my iothub input.
The ASA outputs payload for HttpTrigger Function in the following format, see my example:
[
{
"time": "2017-11-26T12:52:23.4292501Z",
"counter": 57,
"windSpeed": 8.7358,
"temperature": 16.63,
"humidity": 79.42,
"EventProcessedUtcTime": "2017-11-26T12:52:21.3568252Z",
"PartitionId": 2,
"EventEnqueuedUtcTime": "2017-11-26T12:52:22.435Z",
"IoTHub": {
"MessageId": null,
"CorrelationId": null,
"ConnectionDeviceId": "Device1",
"ConnectionDeviceGenerationId": "636189812948967054",
"EnqueuedTime": "2017-11-26T12:52:21.562Z",
"StreamId": null
}
}
]
Note, that my telemetry data (*) are counter, temperature, humidity and timestamp time, so the other properties are created implicitly by ASA job. Based on the query, you can create any business properties for C2D message.
Upvotes: 3