2021年12月27日 星期一

ESP32 Web Server & MQTT &Node-RED

 ESP32 Web Server & MQTT &Node-RED











#include <WiFi.h>

//================MQTT=====================

#include <PubSubClient.h>  //MQTT


// Replace with your network credentials

//const char* ssid = "REPLACE_WITH_YOUR_SSID";

//const char* password = "REPLACE_WITH_YOUR_PASSWORD";

const char* ssid     = "TOTOLINK_A3002MU";

const char* password = "24063173";


//================MQTT=====================

const char* mqtt_server = "broker.mqtt-dashboard.com" ; //MQTT

// Set web server port number to 80

WiFiServer server(80);


// Variable to store the HTTP request

String header;


//================MQTT=====================

WiFiClient espClient;

PubSubClient client(espClient);

long lastMsg = 0;

char msg[50];


// Auxiliar variables to store the current output state

String output26State = "off";

String output27State = "off";


// Assign output variables to GPIO pins

const int output26 = 26;

const int output27 = 27;


// Current time

unsigned long currentTime = millis();

// Previous time

unsigned long previousTime = 0; 

// Define timeout time in milliseconds (example: 2000ms = 2s)

const long timeoutTime = 2000;


//================MQTT=====================

void callback(char* 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 esp32/output, you check if the message is either "on" or "off". 

  // Changes the output state according to the message

  if (String(topic) == "alex96ufo/esp32/input/26") {

    Serial.print("Changing output to ");

    if(messageTemp == "on"){

      Serial.println("on");

      output26State = "on";

      digitalWrite(output26, HIGH);

    }

    else if(messageTemp == "off"){

      Serial.println("off");

      output26State = "off";

      digitalWrite(output26, LOW);

    }

  }

  if (String(topic) == "alex96ufo/esp32/input/27") {

    Serial.print("Changing output to ");

    if(messageTemp == "on"){

      Serial.println("on");

      output27State = "on";

      digitalWrite(output27, HIGH);

    }

    else if(messageTemp == "off"){

      Serial.println("off");

      output27State = "off";

      digitalWrite(output27, LOW);

    }

  }  


  loop_mqtt();

  

}

//================MQTT=====================


void reconnect() {

  // Loop until we're reconnected

  while (!client.connected()) {

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

    // Attempt to connect

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

      Serial.println("connected");

      // Subscribe

      client.subscribe("alex9ufo/esp32/input/26");

    client.subscribe("alex9ufo/esp32/input/27");

  

    } else {

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

      Serial.print(client.state());

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

      // Wait 5 seconds before retrying

      delay(5000);

    }

  }

}

//================MQTT===================== 

void loop_mqtt(){

  if (!client.connected()) {

    reconnect();

  }

  client.loop();

  long now = millis();

  if (now - lastMsg > 5000) {

    lastMsg = now;

    char tempString26[4];

    char tempString27[4];

    output26State.toCharArray(tempString26, 4);

    output27State.toCharArray(tempString27, 4);    

    // Convert the value to a char array

    client.publish("alex96ufo/esp32/output/26", tempString26);

    client.publish("alex96ufo/esp32/output/27", tempString27);

  }  

}

   

//=========================================


void setup() {

  Serial.begin(115200);

  // Initialize the output variables as outputs

  pinMode(output26, OUTPUT);

  pinMode(output27, OUTPUT);

  // Set outputs to LOW

  digitalWrite(output26, LOW);

  digitalWrite(output27, LOW);


  // Connect to Wi-Fi network with SSID and password

  Serial.print("Connecting to ");

  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

    delay(500);

    Serial.print(".");

  }

  // Print local IP address and start web server

  Serial.println("");

  Serial.println("WiFi connected.");

  Serial.println("IP address: ");

  Serial.println(WiFi.localIP());

  server.begin();

  

  //================MQTT===================== 

  client.setServer(mqtt_server, 1883);

  client.setCallback(callback);

  

}


void loop(){

  loop_mqtt();

  WiFiClient client = server.available();   // Listen for incoming clients


  if (client) {                             // If a new client connects,

    currentTime = millis();

    previousTime = currentTime;

    Serial.println("New Client.");          // print a message out in the serial port

    String currentLine = "";                // make a String to hold incoming data from the client

    while (client.connected() && currentTime - previousTime <= timeoutTime) {  // loop while the client's connected

      currentTime = millis();

      if (client.available()) {             // if there's bytes to read from the client,

        char c = client.read();             // read a byte, then

        Serial.write(c);                    // print it out the serial monitor

        header += c;

        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.

          // that's the end of the client HTTP request, so send a response:

          if (currentLine.length() == 0) {

            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)

            // and a content-type so the client knows what's coming, then a blank line:

            client.println("HTTP/1.1 200 OK");

            client.println("Content-type:text/html");

            client.println("Connection: close");

            client.println();

            

            // turns the GPIOs on and off

            if (header.indexOf("GET /26/on") >= 0) {

              Serial.println("GPIO 26 on");

              output26State = "on";

              digitalWrite(output26, HIGH);

            } else if (header.indexOf("GET /26/off") >= 0) {

              Serial.println("GPIO 26 off");

              output26State = "off";

              digitalWrite(output26, LOW);

            } else if (header.indexOf("GET /27/on") >= 0) {

              Serial.println("GPIO 27 on");

              output27State = "on";

              digitalWrite(output27, HIGH);

            } else if (header.indexOf("GET /27/off") >= 0) {

              Serial.println("GPIO 27 off");

              output27State = "off";

              digitalWrite(output27, LOW);

            }

            

            // Display the HTML web page

            client.println("<!DOCTYPE html><html>");

            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");

            client.println("<link rel=\"icon\" href=\"data:,\">");

            // CSS to style the on/off buttons 

            // Feel free to change the background-color and font-size attributes to fit your preferences

            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");

            client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");

            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");

            client.println(".button2 {background-color: #555555;}</style></head>");

            

            // Web Page Heading

            client.println("<body><h1>ESP32 Web Server</h1>");

            

            // Display current state, and ON/OFF buttons for GPIO 26  

            client.println("<p>GPIO 26 - State " + output26State + "</p>");

            // If the output26State is off, it displays the ON button       

            if (output26State=="off") {

              client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");

            } else {

              client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");

            } 

               

            // Display current state, and ON/OFF buttons for GPIO 27  

            client.println("<p>GPIO 27 - State " + output27State + "</p>");

            // If the output27State is off, it displays the ON button       

            if (output27State=="off") {

              client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>");

            } else {

              client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>");

            }

            client.println("</body></html>");

            

            // The HTTP response ends with another blank line

            client.println();

            // Break out of the while loop

            break;

          } else { // if you got a newline, then clear currentLine

            currentLine = "";

          }

        } else if (c != '\r') {  // if you got anything else but a carriage return character,

          currentLine += c;      // add it to the end of the currentLine

        }

      }

    }

    // Clear the header variable

    header = "";

    // Close the connection

    client.stop();

    Serial.println("Client disconnected.");

    Serial.println("");

  }

  


}



[{"id":"19e786ee6973478d","type":"mqtt in","z":"1c234d4ad776c8ec","name":"","topic":"alex9ufo/esp32/output/26","qos":"1","datatype":"auto","broker":"3d43a51a.c133a2","nl":false,"rap":true,"rh":0,"x":290,"y":100,"wires":[["bdd73930f1e50c3b","346b0d30d302b689"]]},{"id":"02ef7f91d529b1ee","type":"mqtt out","z":"1c234d4ad776c8ec","name":"","topic":"alex9ufo/esp32/input/26","qos":"1","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"2e162217.bc2456","x":650,"y":280,"wires":[]},{"id":"7ed34d6113cb7cd5","type":"ui_led","z":"1c234d4ad776c8ec","order":2,"group":"fc89dc38.347898","width":4,"height":4,"label":"LED26","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"#ff0000","value":"false","valueType":"bool"},{"color":"#008000","value":"true","valueType":"bool"}],"allowColorForValueInMessage":false,"shape":"circle","showGlow":true,"name":"","x":690,"y":100,"wires":[]},{"id":"43556ac91a1a45ed","type":"mqtt in","z":"1c234d4ad776c8ec","name":"","topic":"alex9ufo/esp32/output/27","qos":"1","datatype":"auto","broker":"3d43a51a.c133a2","nl":false,"rap":true,"rh":0,"x":290,"y":140,"wires":[["b3d5d81a8a2664d0"]]},{"id":"ef5083294f837232","type":"ui_led","z":"1c234d4ad776c8ec","order":4,"group":"fc89dc38.347898","width":4,"height":4,"label":"LED27","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"#ff0000","value":"false","valueType":"bool"},{"color":"#008000","value":"true","valueType":"bool"}],"allowColorForValueInMessage":false,"shape":"circle","showGlow":true,"name":"","x":690,"y":140,"wires":[]},{"id":"a9f6cb58bb14d00c","type":"mqtt out","z":"1c234d4ad776c8ec","name":"","topic":"alex9ufo/esp32/input/27","qos":"1","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"2e162217.bc2456","x":650,"y":340,"wires":[]},{"id":"bdd73930f1e50c3b","type":"function","z":"1c234d4ad776c8ec","name":"","func":"var onoff=msg.payload;\n\nif (onoff === \"on\") {\n\n//if (onoff === \"on\\n\") {    \n\tmsg.payload=true;\n} \nelse {\n    msg.payload=false;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":100,"wires":[["7ed34d6113cb7cd5","7835c6a54441f735"]]},{"id":"b3d5d81a8a2664d0","type":"function","z":"1c234d4ad776c8ec","name":"","func":"var onoff=msg.payload;\n\nif (onoff === 'on') {\n//if (onoff === 'on\\n') {\n\tmsg.payload=true;\n} \nelse {\n    msg.payload=false;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":140,"wires":[["ef5083294f837232","bf227fa4789ed536"]]},{"id":"f170f8739308b6fb","type":"ui_switch","z":"1c234d4ad776c8ec","name":"","label":"switch LED26","tooltip":"","group":"fc89dc38.347898","order":19,"width":4,"height":4,"passthru":true,"decouple":"false","topic":"topic","topicType":"msg","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","animate":false,"className":"","x":260,"y":280,"wires":[["17e893efc6d06e7d"]],"info":"<i class=\"fa fa-camera-retro fa-3x\"></i> fa-3x"},{"id":"65640a8134150229","type":"ui_switch","z":"1c234d4ad776c8ec","name":"","label":"switch LED27","tooltip":"","group":"fc89dc38.347898","order":21,"width":4,"height":4,"passthru":true,"decouple":"false","topic":"topic","topicType":"msg","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","animate":false,"className":"","x":260,"y":340,"wires":[["97563dbef69e66e6"]],"info":"<i class=\"fa fa-camera-retro fa-3x\"></i> fa-3x"},{"id":"17e893efc6d06e7d","type":"function","z":"1c234d4ad776c8ec","name":"","func":"var onoff=msg.payload;\n\nif (onoff === true) {\n\tmsg.payload='on';\n} \nelse {\n    msg.payload='off';\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":280,"wires":[["02ef7f91d529b1ee","8fe9679230897829","bdd73930f1e50c3b"]]},{"id":"7835c6a54441f735","type":"debug","z":"1c234d4ad776c8ec","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":710,"y":60,"wires":[]},{"id":"bf227fa4789ed536","type":"debug","z":"1c234d4ad776c8ec","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":710,"y":180,"wires":[]},{"id":"8fe9679230897829","type":"debug","z":"1c234d4ad776c8ec","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":220,"wires":[]},{"id":"b76b8efd4d10d806","type":"debug","z":"1c234d4ad776c8ec","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":630,"y":400,"wires":[]},{"id":"97563dbef69e66e6","type":"function","z":"1c234d4ad776c8ec","name":"","func":"var onoff=msg.payload;\n\nif (onoff === true) {\n\tmsg.payload='on';\n} \nelse {\n    msg.payload='off';\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":340,"wires":[["a9f6cb58bb14d00c","b76b8efd4d10d806","b3d5d81a8a2664d0"]]},{"id":"346b0d30d302b689","type":"debug","z":"1c234d4ad776c8ec","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":500,"y":60,"wires":[]},{"id":"3d43a51a.c133a2","type":"mqtt-broker","name":"broker.mqtt-dashboard.com","broker":"broker.mqtt-dashboard.com","port":"1883","clientid":"","usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"2e162217.bc2456","type":"mqtt-broker","name":"broker.mqtt-dashboard.com","broker":"broker.mqtt-dashboard.com","port":"1883","clientid":"","usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"fc89dc38.347898","type":"ui_group","name":"LED show","tab":"ec4c23e9246d7836","order":1,"disp":true,"width":16,"collapse":false,"className":""},{"id":"ec4c23e9246d7836","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...