Raspberry pi MQTT Home Automation with NodeMcu|Chat with covid - Black keyhole

welcome to our keyhole, we provide you various knowledge from various sources such as Electric&Electronic, Health, Arduino, IOT, Diy projects, A/l past paper and model paper, Even though you can keep in touch with current technology

Raspberry pi MQTT Home Automation with NodeMcu|Chat with covid

Share This

Today we are going to take look at how to Automate home automation things using Raspberry pi. here we will be going to use Raspberry pi as a web server using a Python microframework called Flask. that can toggle LEDs  or Relay from ESP8266 using MQTT protocol. This tutorial is one of the parts of the Chat with Covid project. In my previous tutorial, I had shown you how to interface the mic and speaker with the Raspberry pi. You can check it out my previous tutorial here.

Hardware you need in this tutorial

1. Relay module 

     Here I have used relay module for controlling lights and fan. In this case I have used light. you can use multiple channels of the relay to control multiple things.

2. Raspberry pi 

3. Nodemcu


The Raspberry pi is going to interact with the ESP8266 with the MQTT protocol. If you want to get much more knowledge with the MQTT protocol that how it is working, you can check out scibot YouTube channel they were covered all the basics of MQTT protocol and how it is working.

Now let we move into the installation part of MQTT protocol.

give the following command to install  MQTT mosquito broker 


   pi@raspberry:~ $ sudo apt update

   pi@raspberry:~ $ sudo apt install -y mosquitto mosquitto-clients

To make Mosquitto auto start on boot up enter:

      pi@raspberry:~ $ sudo systemctl enable mosquitto.service

To make testing installation give the following command :

              pi@raspberry:~ $ mosquitto -v

To use your Mosquitto broker later in your project You need to have your Raspberry pi IP address you. To retrieve your pi address give the following command in your terminal window:

           pi@raspberry:~ $ hostname -I

 After installing the MQTT broker you should have to test your installation. In order to do that give the following command in your terminal window:

      pi@raspberry:~ $ sudo apt-get install mosquitto-clients

 Run Mosquitto on the background as a daemon:

          pi@raspberry:~ $ mosquitto -d

 we are going to use Microframework called flask to turn the Raspberry pi into web server. To install flask give the following command

    pi@raspberrypi ~ $ sudo apt-get update

pi@raspberrypi ~ $ sudo apt-get upgrade

pi@raspberrypi ~ $ sudo apt-get install python-pip python-flask

Then you have to install Flask and its dependencies:

       pi@raspberrypi ~ $ sudo pip install flask

The Paho-MQTT package provides a client class that enables applications to connect to an MQTT broker to publish messages and to subscribe to topics and receive published messages. In this example, the Python web server is going to publish messages to the ESP8266 to turn the GPIOs on and off.

          pi@raspberrypi ~ $ sudo pip install paho-mqtt


Create the python Script 

      It sets up the webserver and when these buttons are pressed it publishes an MQTT message to the ESP8266. To keep everything organized, start by creating a new folder.

pi@raspberrypi ~ $ mkdir web-server

pi@raspberrypi ~ $ cd web-server

pi@raspberrypi:~/web-server $

then create a new file called app.py 

     pi@raspberrypi:~/web-server $ nano app.py

then copy and paste the following script into your Raspberry pi

 import paho.mqtt.client as mqtt

from flask import Flask, render_template, request

app = Flask(__name__)




# Create a dictionary called pins to store the pin number, name, and pin state:

pins = {

   4 : {'name' : 'GPIO 4', 'board' : 'esp8266', 'topic' : 'esp8266/4', 'state' : 'False'},

   5 : {'name' : 'GPIO 5', 'board' : 'esp8266', 'topic' : 'esp8266/5', 'state' : 'False'}


# Put the pin dictionary into the template data dictionary:

templateData = {

   'pins' : pins



def main():

   # Pass the template data into the template main.html and return it to the user

   return render_template('main.html', **templateData)

# The function below is executed when someone requests a URL with the pin number and action in it:


def action(board, changePin, action):

   # Convert the pin from the URL into an integer:

   changePin = int(changePin)

   # Get the device name for the pin being changed:

   devicePin = pins[changePin]['name']

   # If the action part of the URL is "on," execute the code indented below:

   if action == "1" and board == 'esp8266':


      pins[changePin]['state'] = 'True'

   if action == "0" and board == 'esp8266':


      pins[changePin]['state'] = 'False'

   # Along with the pin dictionary, put the message into the template data dictionary:

   templateData = {

      'pins' : pins


   return render_template('main.html', **templateData)

if __name__ == "__main__":

   app.run(host='', port=8181, debug=True)


Then Create the HTML file. To create that give the follwing command. you have to keep everyfile organized.

 pi@raspberrypi:~/web-server $ mkdir templates

pi@raspberrypi:~/web-server $ cd templates

pi@raspberrypi:~/web-server/templates $

then create the main file called tag.html

       pi@raspberrypi:~/web-server/templates $ nano tag.html


Copy and paste the following HTML code in your tag.html file

                 <!DOCTYPE html>


   <title>RPi Web Server</title>

   <!-- Latest compiled and minified CSS -->

   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

   <!-- Optional theme -->

   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">

   <!-- Latest compiled and minified JavaScript -->

   <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

   <meta name="viewport" content="width=device-width, initial-scale=1">



   <h1>RPi Web Server - ESP8266 MQTT</h1>

   {% for pin in pins %}

   <h2>{{ pins[pin].name }}

   {% if pins[pin].state == 'True' %}

      is currently <strong>on</strong></h2><div class="row"><div class="col-md-2">

      <a href="/esp8266/{{pin}}/0" class="btn btn-block btn-lg btn-default" role="button">Turn off</a></div></div>

   {% else %}

      is currently <strong>off</strong></h2><div class="row"><div class="col-md-2">

      <a href="/esp8266/{{pin}}/1" class="btn btn-block btn-lg btn-primary" role="button">Turn on</a></div></div>

   {% endif %}

   {% endfor %}



Programming the ESP8266

    For the Nodemcu to interect with the Raspberry pi web server, you need to install PubSubClient library. This library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT. Click here to download that library .

After Download that above library. add that library by going to your Arduino IDE and you can find the option that sketch> Include library>Add.Zip file option. throughout that you can find the downloaded zip file and select the file to add to your Arduino library collection. then copy and paste the following code in your Arduino code file. After that, upload the code by selecting Nodemcu as a board type and the correct port number for your board.

#include <ESP8266WiFi.h>

#include <PubSubClient.h>

// Change the credentials below, so your ESP8266 connects to your router

const char* ssid = "ZTE WIFI";

const char* password = "kl2229834";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker

const char* mqtt_server = "";

// Initializes the espClient

WiFiClient espClient;

PubSubClient client(espClient);

// Connect an LED to each GPIO of your ESP8266

const int ledGPIO5 = 5;

const int ledGPIO4 = 4;

// Don't change the function below. This functions connects your ESP8266 to your router

void setup_wifi() {


  // We start by connecting to a WiFi network


  Serial.print("Connecting to ");


  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {





  Serial.print("WiFi connected - ESP IP address: ");



// This functions is executed when some device publishes a message to a topic that your ESP8266 is subscribed to

// Change the function below to add logic to your program, so when a device publishes a message to a topic that 

// your ESP8266 is subscribed you can actually do something

void callback(String topic, byte* message, unsigned int length) {

  Serial.print("Message arrived on topic: ");


  Serial.print(". Message: ");

  String messageTemp;


  for (int i = 0; i < length; i++) {


    messageTemp += (char)message[i];



  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic home/office/esp1/gpio2, you check if the message is either 1 or 0. Turns the ESP GPIO according to the message


      Serial.print("Changing GPIO 4 to ");

      if(messageTemp == "1"){

        digitalWrite(ledGPIO4, HIGH);



      else if(messageTemp == "0"){

        digitalWrite(ledGPIO4, LOW);





      Serial.print("Changing GPIO 5 to ");

      if(messageTemp == "1"){

        digitalWrite(ledGPIO5, HIGH);



      else if(messageTemp == "0"){

        digitalWrite(ledGPIO5, LOW);






// This functions reconnects your ESP8266 to your MQTT broker

// Change the function below if you want to subscribe to more topics with your ESP8266 

void reconnect() {

  // Loop until we're reconnected

  while (!client.connected()) {

    Serial.print("Attempting MQTT connection...");

    // Attempt to connect



     To change the ESP device ID, you will have to give a unique name to the ESP8266.

     Here's how it looks like now:

       if (client.connect("ESP8266Client")) {

     If you want more devices connected to the MQTT broker, you can do it like this:

       if (client.connect("ESPOffice")) {

     Then, for the other ESP:

       if (client.connect("ESPGarage")) {

      That should solve your MQTT multiple connections problem

     THE SECTION IN loop() function should match your device name


    if (client.connect("ESP8266Client")) {


      // Subscribe or resubscribe to a topic

      // You can subscribe to more topics (to control more LEDs in this example)



    } else {

      Serial.print("failed, rc=");


      Serial.println(" try again in 5 seconds");

      // Wait 5 seconds before retrying





// The setup function sets your ESP GPIOs to Outputs, starts the serial communication at a baud rate of 115200

// Sets your mqtt broker and sets the callback function

// The callback function is what receives messages and actually controls the LEDs

void setup() {

  pinMode(ledGPIO4, OUTPUT);

  pinMode(ledGPIO5, OUTPUT);




  client.setServer(mqtt_server, 1883);



// For this project, you don't need to change anything in the loop function. 

// Basically it ensures that you ESP is connected to your broker

void loop() {

  if (!client.connected()) {






     To change the ESP device ID, you will have to give a unique name to the ESP8266.

     Here's how it looks like now:


     If you want more devices connected to the MQTT broker, you can do it like this:


     Then, for the other ESP:


      That should solve your MQTT multiple connections problem

     THE SECTION IN recionnect() function should match your device name




 Launch your web server by giving the following command. Move to the folder that contains the app.py

pi@raspberrypi:~/web-server/templates $ cd ..

pi@raspberrypi:~/web-server $ sudo python app.py

Open your Raspberry Pi address in your browser by entering its IP address, in my case:

Hardware connection part


No comments:

Post a Comment

business queries