Reputation: 595
I'm receiving messages from IoT devices through IoT Hub, and storing them in a Cosmos database. Stream Analytics works fine, but I want to use Azure Functions.
I want to process the incoming message slightly before storing it in my Cosmos DB. The raw messages look something like this:
{
"id": "12345",
"time": "2019-12-05T07:21:37.000+0000",
"sensors": [
{
"type": "TEMPERATURE",
"value": 23.30286376953125,
"unit": "C"
},
{
"type": "HUMIDITY",
"value": 29.686492919921875,
"unit": "RH"
},
{
"type": "CELL_ID",
"value": 56789,
"unit": ""
},
{
"type": "RSSI_LEVEL",
"value": -86,
"unit": "dBm"
}
]
}
What I would like to store in Cosmos should look something like this:
{
id: "2019-12-05T07:21:37.000+0000",
{
"deviceId": "12345",
"time": "2019-12-05T07:21:37.000+0000",
"type": "TEMPERATURE",
"value": "23.30286376953125",
"unit": "C"
},
{
"deviceId": "12345",
"time": "2019-12-05T07:21:37.000+0000",
"type": "HUMIDITY",
"value": "29.686492919921875",
"unit": "RH"
},
...
}
The reason I'm setting id
to equal time
, is because I have not yet figured out how to replicate the Document Id
functionality from Azure Stream Analytics. I'm trying to ensure that the writing operation to Cosmos doesn't overwrite existing files.
At the moment, my JavaScript code looks like this (I don't know JavaScript, I'm just adapting code I find on the internet):
module.exports = function (context, IoTHubMessages) {
context.log(`JavaScript eventhub trigger function called for message array: ${IoTHubMessages}`);
var payload = "";
IoTHubMessages.forEach(message => {
context.log(`Processed message: ${message}`);
payload += { "id": message.time };
message.sensors.forEach(observation => {
if (observation.type != "CELL_ID" && observation.type != "RSSI_LEVEL") {
payload += {
"deviceId": message.id,
"time": message.time,
"type": observation.type,
"value": observation.value,
"unit": observation.unit
};
};
});
});
context.bindings.outputDocument = payload;
context.done();
};
Debugging the above code takes a long time because I'm not in control of the IoT device's sample rate. I was wondering if someone could help me get the above code-chunk to produce the desired results.
Upvotes: 0
Views: 230
Reputation: 15583
{
id: "2019-12-05T07:21:37.000+0000",
{
"deviceId": "12345",
"time": "2019-12-05T07:21:37.000+0000",
"type": "TEMPERATURE",
"value": "23.30286376953125",
"unit": "C"
},
{
"deviceId": "12345",
"time": "2019-12-05T07:21:37.000+0000",
"type": "HUMIDITY",
"value": "29.686492919921875",
"unit": "RH"
},
...
}
Is not valid JSON, you are missing the property name for the device information. This could be changed to:
{
id: "2019-12-05T07:21:37.000+0000",
"deviceInformation": [
{
"deviceId": "12345",
"time": "2019-12-05T07:21:37.000+0000",
"type": "TEMPERATURE",
"value": "23.30286376953125",
"unit": "C"
},
{
"deviceId": "12345",
"time": "2019-12-05T07:21:37.000+0000",
"type": "HUMIDITY",
"value": "29.686492919921875",
"unit": "RH"
},
...
]
}
As for the code, it might be easier if you create an object instead of concatenating strings, something like:
module.exports = function (context, IoTHubMessages) {
context.log(`JavaScript eventhub trigger function called for message array: ${IoTHubMessages}`);
var payload = [];
IoTHubMessages.forEach(message => {
context.log(`Processed message: ${message}`);
var messageToStore = { id: message.time, deviceInformation: [] };
message.sensors.forEach(observation => {
if (observation.type != "CELL_ID" && observation.type != "RSSI_LEVEL") {
messageToStore.deviceInformation.push({
"deviceId": message.id,
"time": message.time,
"type": observation.type,
"value": observation.value,
"unit": observation.unit
});
};
});
payload.push(messageToStore);
});
context.bindings.outputDocument = payload;
context.done();
};
Upvotes: 1