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__)
mqttc=mqtt.Client()
mqttc.connect("localhost",1883,60)
mqttc.loop_start()
# 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
}
@app.route("/")
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:
@app.route("/<board>/<changePin>/<action>")
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':
mqttc.publish(pins[changePin]['topic'],"1")
pins[changePin]['state'] = 'True'
if action == "0" and board == 'esp8266':
mqttc.publish(pins[changePin]['topic'],"0")
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='0.0.0.0', 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>
<head>
<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">
</head>
<body>
<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 %}
</body>
</html>
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 = "192.168.1.7";
// 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() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi connected - ESP IP address: ");
Serial.println(WiFi.localIP());
}
// 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(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// 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
if(topic=="esp8266/4"){
Serial.print("Changing GPIO 4 to ");
if(messageTemp == "1"){
digitalWrite(ledGPIO4, HIGH);
Serial.print("On");
}
else if(messageTemp == "0"){
digitalWrite(ledGPIO4, LOW);
Serial.print("Off");
}
}
if(topic=="esp8266/5"){
Serial.print("Changing GPIO 5 to ");
if(messageTemp == "1"){
digitalWrite(ledGPIO5, HIGH);
Serial.print("On");
}
else if(messageTemp == "0"){
digitalWrite(ledGPIO5, LOW);
Serial.print("Off");
}
}
Serial.println();
}
// 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
/*
YOU NEED TO CHANGE THIS NEXT LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
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")) {
Serial.println("connected");
// Subscribe or resubscribe to a topic
// You can subscribe to more topics (to control more LEDs in this example)
client.subscribe("esp8266/4");
client.subscribe("esp8266/5");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
// 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);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// 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()) {
reconnect();
}
if(!client.loop())
/*
YOU NEED TO CHANGE THIS NEXT LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
To change the ESP device ID, you will have to give a unique name to the ESP8266.
Here's how it looks like now:
client.connect("ESP8266Client");
If you want more devices connected to the MQTT broker, you can do it like this:
client.connect("ESPOffice");
Then, for the other ESP:
client.connect("ESPGarage");
That should solve your MQTT multiple connections problem
THE SECTION IN recionnect() function should match your device name
*/
client.connect("ESP8266Client");
}
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: http://192.168.1.7:8181
Hardware connection part
No comments:
Post a Comment