9

I am working on a home automation project. The basic objective of my project is to control relays and other sensors located at different locations. I have set up my Raspberry Pi as an MQTT broker. Mosquitto is running fine. For now, what I am trying to do is trigger a relay wired up with esp8266 (GPIO2). Here is my Python web server code:

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 = {
   2 : {'name' : 'GPIO 2', 'board' : 'esp8266', 'topic' : 'esp8266/2', '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)

Here is my HTML code:

<!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>

Here is my ESP8266 code:

#include <ESP8266WiFi.h>
#include <PubSubClient.h

const char* ssid = "Godfather";
const char* password = "idontknow";

const char* mqtt_server = "192.168.137.100";

WiFiClient espClient;
PubSubClient client(espClient);

const int ledGPIO2 = 2;

void setup_wifi() {
  delay(10);

  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());
}

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();

  if(topic=="esp8266/2"){
      Serial.print("Changing GPIO 2 to ");
      if(messageTemp == "1"){
        digitalWrite(ledGPIO2, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "0"){
        digitalWrite(ledGPIO4, LOW);
        Serial.print("Off");
      }
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");  

      client.subscribe("esp8266/2");

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
  // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(ledGPIO2, OUTPUT);

  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);    
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
    client.connect("ESP8266Client");
}

Results: everything seems to be working fine but still the relay is not triggered when I hit the button at web server. I believe the ESP is not subscribed properly. When I run the Python script on the terminal, for the first click I receive HTTP/1.1" 404 at the terminal, and on every other click I receive HTTP/1.1" 200

My Pi is working on dynamic IP right now. But I've made sure the ESP8266 is configured with the current Pi IP address.

migrated from raspberrypi.stackexchange.com Sep 23 '17 at 12:47

This question came from our site for users and developers of hardware and software for Raspberry Pi.

  • 1
    This comment chain is getting quite long now; this conversation has been moved to chat. You can continue your discussion there in an environment that's more friendly to extended conversations. Also consider editing your question with updates or asking new questions if you encounter problems that you're not able to solve. – Aurora0001 Sep 26 '17 at 18:56
  • 1
    what should i add in my code if i have multiple clients? – Rohit Mathur Oct 6 '17 at 14:32
3

I suggest you to decompose the problem.

Try to test relay by publishing messages straight to MQTT broker (i.e. using mosquito_pub client).

Try to check if web app is publishing correct topics and messages to the broker (i.e. using mosquito_sub client).

You can also monitor your devices behaviour by subscribing to the SYS topic (i.e. total number of connected clients or subscriptions).

  • 1
    And add a ping (publish) from the ESP8266 so you can confirm that it is working and can reach the MQTT server. – MatsK Jan 13 '18 at 16:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.