My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more
Building an IoT Environment Simulation: Building Smart Device

Building an IoT Environment Simulation: Building Smart Device

Simulating an IoT Environment using NodeJs and Javascript

Bhaskar's photo
Bhaskar
·Jan 28, 2022·

7 min read

This blog is a continuation of my previous blog here where we built a mock IoT Sensor (DTH11 Sensor) that generates random values for temperature and humidity and publishes that value to an MQTT Broker. Carrying forward, now we are going to build a Smart Device that will subscribe to the published data along with a mock LED that will be controlled by the smart device.

Target for this project

In this blog, we are going to build Smart Device that will subscribe to the temperature and humidity data published by the sensor. It then calculates the dew point based on the received data. We also build a mock LED that will be turned ON when the dew is comfortable for human habitation and will be turned OFF if the dew point is uncomfortable. The following flowchart shows the working of the smart device:

WorkingOfSmartDevice.drawio.png

Building the LED Simulation

We will start by building our LED simulator. It will also have REST APIs to turn it ON/OFF that will be called by the smart device. We start by creating a new file in our project directory called led.js. The code for the LED Simulator is:

const express = require('express')
const app = express()
const PORT = 8000

var ledStatus = false

// Crated API to turn on the LED
app.post("/turnon", function() {
    console.log("Turning on the lights")
    ledStatus = true
})

// Created API to turn off the LED
app.post("/turnoff", function() {
    console.log("Turning off the lights")
    ledStatus = false
})

// Created API to get the LED status
app.get("/status", function(req, res) {
    console.log("Getting the status")
    res.send({
        "status": ledStatus
    })
})

app.listen(PORT)

Here we have defined a ledStatus variable that is used to store the ON/OFF state of the led. We have 2 POST REST APIs /turnon and /turnoff that are used to change the state to ON and OFF respectively. We also have a GET REST API /status that is used to find whether the LED is in an ON or OFF state by returning the value of the ledStatus variable.

Testing the LED

Now, let's test our LED simulator before moving on to the next phase. We start our LED by using the following command

node led.js

To get the status of the LED, using the following command

curl -X GET http://localhost:8000/status

By default the status returned will be false. To turn on the LED we use

curl -X POST http://localhost:8000/turnon

If we check our status again, it will return true signifying that our LED is on. Finally, we can turn it off again using

curl -X POST http://localhost:8000/turnoff

We can check the status again to ensure that our LED has successfully turned off. WhatsApp Image 2022-01-29 at 1.28.47 AM.jpeg

Building the smart device simulator

Now let's start building our smart device simulator. We start by creating a new file called smartDevice.js. We start our code similar to our previous blog, by importing the libraries and defining the datamodel. We also define a variable called dewPoint that will used to calculate the dew point.

var mqtt = require('mqtt')
const express = require('express')
const fetch = require('node-fetch')
require('dotenv').config()

var app = express()
var PORT = 6000

var sensorData = {
  temperature: 0,
  humidity: 0,
}

var dewPoint = 0

Now we establish the connection with the MQTT broker using the following code:

//initialize the MQTT client
var client = mqtt.connect(options)

Now we define the functions that will be called when the connection is established, an error is generated and a message is received respectively

client.on('connect', function () {
  console.log('Connected')
})

client.on('error', function (error) {
  console.log(error)
})

client.on('message', function (topic, message) {
})

The client.on('message', function(topic, message){}) is used to define the function that will be called whenever a new data is published to the broker. topic contains the topic under which the data is published and message will be the main payload or data that was published.
Inside this function, we write the following code:

client.on('message', function (topic, message) {
  //Called each time a message is received
  //   console.log('Received message:', topic, message.toString())
  sensorData = JSON.parse(message)

  // Processing the Sensor data
  dewPoint = sensorData.temperature - (100 - sensorData.humidity) / 5

  console.log(dewPoint)

  if (dewPoint <= 55) {
    console.log('COMFORTABLE')
    // Calling the LED ON API
    fetch('http://localhost:8000/turnon', {
      method: 'POST',
    })
  } else {
    // Calling the LED OFF API
    fetch('http://localhost:8000/turnoff', {
      method: 'POST',
    })
    console.log('UNCOMFORTABLE')
  }
})

We start by converting our received message into JSON format using the JSON.parse() function and then store it in the sensorData variable defined. Then we calculate the dew point based on the temperature and humidity data using the formula dew point = temperature - (100 - humidity) / 5. If the dew point is less than 55, it signifies that it is comfortable for living and hence turns the LED On by calling the API defined earlier. Otherwise, it turns off the LED. Based on the value of the dew point it also prints COMFORTABLE or UNCOMFORTABLE to the console respectively.
Finally, we subscribe to the topic under which our mock sensor publishes the data so that whenever new data is published the above function can be called. Please note that this topic should be exactly the same as the one used in the previous blog.

// subscribe to topic 'my/test/topic'
client.subscribe('my/test/topic')

The complete code

The final code for the smartDevice.js is as follows:

var mqtt = require('mqtt')
const express = require('express')
const fetch = require('node-fetch')
require('dotenv').config()

var app = express()
var PORT = 6000

var sensorData = {
  temperature: 0,
  humidity: 0,
}

var options = {
  host: process.env.MQTT_HOST,
  port: process.env.MQTT_PORT,
  protocol: 'mqtts',
  username: process.env.MQTT_USERNAME,
  password: process.env.MQTT_PASSWORD,
}

//initialize the MQTT client
var client = mqtt.connect(options)
var dewPoint = 0
//setup the callbacks
client.on('connect', function () {
  console.log('Connected')
})

client.on('error', function (error) {
  console.log(error)
})

client.on('message', function (topic, message) {
  //Called each time a message is received
  //   console.log('Received message:', topic, message.toString())
  sensorData = JSON.parse(message)

  // Processing the Sensor data
  dewPoint = sensorData.temperature - (100 - sensorData.humidity) / 5

  console.log(dewPoint)

  if (dewPoint <= 55) {
    console.log('COMFORTABLE')
    // Calling the LED ON API
    fetch('http://localhost:8000/turnon', {
      method: 'POST',
    })
  } else {
    // Calling the LED OFF API
    fetch('http://localhost:8000/turnoff', {
      method: 'POST',
    })
    console.log('UNCOMFORTABLE')
  }
})

// subscribe to topic 'my/test/topic'
client.subscribe('my/test/topic')

app.listen(PORT)

Both the above codes can be found here and here respectively.

Running the simulation

We can run the entire simulation by opening three terminal instances and running the following commands

node dth11.js // Starts the mock sensor
node led.js // Starts the mock led
node smartDevice.js // Starts the mock smart device

Finally, to start the system, we use the following command to start our mock sensor

curl -X POST http://localhost:4000/start

Now you can see all the 3 components working together.

Screenshot 2022-01-29 at 02.41.46.png The mock sensor generates the data and published it to the MQTT broker. The smart device simulator has subscribed to the topic and hence receives the data from the broker. The sensor then calculates the dew point and sends the appropriate signal to the LED showing whether the environment is suitable for living or not.

Conclusion

We have built an IoT environment where there is a sensor that senses data and publishes it through MQTT. There is also a smart device that subscribes to this broker, receives the published data, processes it, and finally displays an output using other IoT devices. This system can also be extended to the real world using actual sensors and LEDs instead of simulation.

About Authors

We are a group of four students, Bhaskar Dutta (writer of this blog), Amartya Bhattacharya, Hrithik Anand and Rupam Kumar Roy working under the guidance of Dr. Atanu Roy Chowdhury. This blog encapsulates our project for IoT class CSEL 711.

Next Step

As the final add-on to our system, we have built a frontend using react that enables us to interact with our device and sensor. You can continue to the next section here.