Debdeep Das
Debdeep Das

Reputation: 129

Azure function to send telemetry data to iotDevice

I am trying to develop a azure function that receives messages from one the built-in eventhub process it and send the result to another IoT Device configured in the Azure IoT Hub. Below is the code:

module.exports = function (context, IoTHubMessages) {

var Mqtt = require('azure-iot-device-mqtt').Mqtt;
var DeviceClient = require('azure-iot-device').Client
var Message = require('azure-iot-device').Message

var connectionString = '{connectionstring of the target device}';
var acRoom1 = DeviceClient.fromConnectionString(connectionString, Mqtt);


var totalPerson = 0;
var events = IoTHubMessages.length;

context.log(JSON.stringify(IoTHubMessages));
context.log(Array.isArray(IoTHubMessages));

context.log(`Number of entries: ${IoTHubMessages.length}`);
IoTHubMessages.forEach(message => {
    context.log(`Processed message: ${JSON.stringify(message)}`);
    totalPerson = totalPerson + message.personCount;
    context.log(`Total count: ${totalPerson}`);

});

var avgPersonCount = Math.round( totalPerson / events );
context.log(`Average person count: ${avgPersonCount}`);

var temp = 24;
if ( avgPersonCount > 5){
    temp = 20;
}
else if ((avgPersonCount>2) && (avgPersonCount <= 5)){
    temp = 22;
}
else {
    temp = 24;
} 
var msg = new Message(`Setting temperature to ${temp} C`);
context.log('Sending message: ' + msg.getData());
context.log(`Temeperature set to ${temp} C`);
acRoom1.sendEvent(msg);

context.done();

};

The issue I have is that the event that I am sending to device is coming back to this azure functions again. I believe, i need to do something in the Message Routing, but not sure what needs to be done.

The flow of the entire solution ( that I want to achieve ) is as below

Camera -- > Azure IOT Hub --> Azure Function --> AC

Upvotes: 0

Views: 549

Answers (3)

Debdeep Das
Debdeep Das

Reputation: 129

I figured out the answer. Thanks to @Matthijs van der Veer for the hint. 1. Firstly disable the fall back rule. Now I have a 2 route Messaging Routes

  1. Instead of azure-iot-device package, i shifted to azure-iothub package.

    module.exports = function (context, IoTHubMessages) {
    
        var Client = require('azure-iothub').Client;
        var Message = require('azure-iot-common').Message;
    
        var connectionString = '{connection-string-policy-service}';
        var targetDevice = '{destination-deviceid}';
    
        var serviceClient = Client.fromConnectionString(connectionString);
        serviceClient.open(function (err) {
        if (err) {
            context.log('Could not connect: ' + err.message);
            }
        });
    
        var totalPerson = 0;
        var events = IoTHubMessages.length;
    
        context.log(JSON.stringify(IoTHubMessages));
    
        context.log(`Number of entries: ${IoTHubMessages.length}`);
        IoTHubMessages.forEach(message => {
            context.log(`Processed message: ${JSON.stringify(message)}`);
            totalPerson = totalPerson + message.personCount;
            context.log(`Total count: ${totalPerson}`);
    
        });
    
        var avgPersonCount = Math.round( totalPerson / events );
        context.log(`Average person count: ${avgPersonCount}`);
    
        var temp = 24;
        if ( avgPersonCount > 5){
            temp = 20;
        }
        else if ((avgPersonCount>2) && (avgPersonCount <= 5)){
            temp = 22;
        }
        else {
            temp = 24;
        } 
        var msg = new Message(`Setting temperature to ${temp} C`);
        msg .properties.add('eventType', 'AC');
        context.log('Sending message: ' + msg.getData());
        context.log(`Temeperature set to ${temp} C`);
        serviceClient.send(targetDevice, msg);
    
        context.done();
    };
    

Upvotes: 0

SatishBoddu
SatishBoddu

Reputation: 800

So please follow as below example shows on Message routing.

Routing on Message Body If you are routing on $body.property You have to add the property in the body payload which is being sent by the device (device code is not shown here, only portal query is shown here). enter image description here

and you can test it out by...

enter image description here Routing on system property The Iot Hub will assign this property on every message , so simply do setting on Portal side.(just give device name in the query, for quick you can test by using it on portal side)

enter image description here

App Property as said by Matthijs in his response, below snap shows on device C# sample code. And then you have to write the query which matches the app property.

enter image description here

Verify on Destination side In my example the destination is Blob container.

enter image description here

Upvotes: 1

Matthijs van der Veer
Matthijs van der Veer

Reputation: 4085

You could filter events by device ID, but a more scalable way would be to add an appProperty. If you want to send all the AC events to a different endpoint, you can add an appProperty to the message the AC is sending. Example:

var msg = new Message(`Setting temperature to ${temp} C`);
msg .properties.add('eventType', 'AC');
context.log('Sending message: ' + msg.getData());
context.log(`Temeperature set to ${temp} C`);
acRoom1.sendEvent(msg);

After that, you can go to your IoT Hub and add a new route. You can route these events to a different endpoint like so: Adding a new route

Because your camera doesn't send this appProperty, it will rely on the fallback route and your Azure Function will still handle those events. Another, perhaps more reliant option is to send only the camera messages to a specific route. But either will work!

Upvotes: 0

Related Questions