This project is a quick demonstration of a demo about plant observation system. The system should gain valuable information about plants from diverse sensors such as photoresistors, moisture sensors, temperature/humidity sensors. These sensors are connected to the device, which communicates events to the back-end application for later processing and analysis.
Here we will use Azure IoT Hub to let the device to communicate with our back-end app. In that device we will randomly generate telemetry, so it's make possible to test the system without a real hardware parts and sensors.
Let's go into details!
ArchitectureWe came up with the architecture shown below.
As you can see, the core of the system is IoT hub which allows transferring telemetry from sensors to the back-end application. Collected data is supposed to be indexed in Elasticsearch for later visual analysis in Kibana.
Device applicationWe wrote a node.js application for device using SDK provided by IoT hub. The target is to read telemetry (temperature, moisture...) and send it to the back-end application through IoT hub for processing. In order to let application to connect to hub you need to register it right there and obtain a connection string. The steps to achieve it are explained here.
To create a client instance we specify a communication protocol and the connection string:
const client = DeviceClient.fromConnectionString(connectionString, Mqtt);
Communicated messages are created using a Message
constructor. The body is specified as a JSON string as shown below:
const message = new Message(JSON.stringify({
temperature: 20 + (Math.random() * 15),
moisture: 30 + Math.random() * 50,
humidity: 20 + (Math.random() * (10 + i)),
illumination: 18000 + Math.random() * 2000,
id: DEVICE_ID }));
Here we are randomly generating message for testing purpose, but it could be a real data from sensors as well.
Then we can send created messages to the IoT hub using client instance:
client.sendEvent(message, (err) => {
if (err) {
console.error('send error: ' + err.toString());
return;
}
console.log('message sent');
});
Back-end applicationBack-end is also a node.js application, nothing special :) The purpose of which is to read data from IoT hub and index it into elastic. Here we also need a connection string (look at this guide for further details).
Let's try to read from the hub:
let ehClient;
EventHubClient.createFromIotHubConnectionString(connectionString).then((client) => {
console.log("Successfully created the EventHub Client.");
ehClient = client;
return ehClient.getPartitionIds();
}).then((ids) => {
console.log("The partition ids are: ", ids);
return ids.map((id) => {
return ehClient.receive(
id,
processMessage, // function for processing incoming messages
printError,
{ eventPosition: EventPosition.fromEnqueuedTime(Date.now()) }
);
});
}).catch(printError);
Here we are creating a communication with hub and receiving a client instance. Then we can read messages from available partitions and process it in the processMessage
function.
Received message we need to index. This can be done by using @elastic/elasticsearch
which provides us with a client instance for communicating with elastic.
The index part is done basically through the call to the index
method of the elastic client as shown below:
try {
result = await client.index(document);
} catch (err) {
console.log(err);
}
Document
is a data entity we want to index.
Comments