2023年6月9日 星期五

實驗1-2 2023 RFID (ESP32 + MQTT+ Node-Red + Line Notify +MQTT Client)

ESP32 + MQTT+ Node-Red + Line Notify +MQTT Client


安裝PubSubClient Library  (將原有C:\Users\User\OneDrive\文件\Arduino\libraries\pubsubclient 更名  然後依照下方的下載)

Installing the PubSubClient Library

The PubSubClient library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT (basically allows your ESP32 to talk with Node-RED).

  1. Click here to download the PubSubClient library. You should have a .zip folder in your Downloads folder
  2. Unzip the .zip folder and you should get pubsubclient-master folder
  3. Rename your folder from pubsubclient-master to pubsubclient
  4. Move the pubsubclient folder to your Arduino IDE installation libraries folder
  5. Then, re-open your Arduino IDE

The library comes with a number of example sketches. See File >Examples > PubSubClient within the Arduino IDE software.

Important: PubSubClient is not fully compatible with the ESP32, but the example provided in this tutorial is working very reliably during our tests.

Arduino 程式

#include <WiFi.h>
#include <PubSubClient.h>
#include <SPI.h>
#define BUILTIN_LED 2
// Update these with values suitable for your network.
//const char *ssid = "PTS-2F";
//const char *pass = "PTS6662594";
//const char *ssid = "alex9ufo";
//const char *pass = "alex9981";

//const char *ssid = "WBR-2200";
//const char *pass = "0226452362";
const char *ssid = "TOTOLINK_A3002MU";
const char *pass = "24063173";
//const char *ssid =  "yourSSID";     // change according to your Network - cannot be longer than 32 characters!
//const char *pass =  "yourPASSWORD"; // change according to your Network

#define MQTTid              ""                           //id of this mqtt client
#define MQTTip              "broker.mqtt-dashboard.com"  //ip address or hostname of the mqtt broker
#define MQTTport            1883                         //port of the mqtt broker
#define MQTTuser            "alex9ufo"                   //username of this mqtt client
#define MQTTpsw             "alex1234"                   //password of this mqtt client
//#define MQTTuser          "your_username"              //username of this mqtt client
//#define MQTTpsw           "your_password"              //password of this mqtt client
#define MQTTpubQos          2                            //qos of publish (see README)
#define MQTTsubQos          1                            //qos of subscribe

//Variables
long lastMsg = 0;
char jsonChar[100];
String Json_buf="";
String json="";

bool Flash = false;  //true
bool Timer = false;  //true
int Count= 0;

//=============================================================================
boolean pendingDisconnect = false;
void mqttConnectedCb(); // on connect callback
void mqttDisconnectedCb(); // on disconnect callback
void mqttDataCb(char* topic, byte* payload, unsigned int length); // on new message callback

WiFiClient wclient;
PubSubClient client(MQTTip, MQTTport, mqttDataCb, wclient);
//=============================================================================
void mqttConnectedCb() {
  Serial.println("connected");
 
  // Once connected, publish an announcement...
  client.publish("alex9ufo/outTopic/led/led_event", jsonChar, MQTTpubQos); // true means retain
  // ... and resubscribe
  client.subscribe("alex9ufo/inTopic/led/led_event", MQTTsubQos);
}
//=============================================================================
void mqttDisconnectedCb() {
  Serial.println("disconnected");
}
//=============================================================================
void mqttDataCb(char* topic, byte* payload, unsigned int length) {

  /*
  you can convert payload to a C string appending a null terminator to it;
  this is possible when the message (including protocol overhead) doesn't
  exceeds the MQTT_MAX_PACKET_SIZE defined in the library header.
  you can consider safe to do so when the length of topic plus the length of
  message doesn't exceeds 115 characters
  */
  char* message = (char *) payload;
  message[length] = 0;

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  Serial.println(message);
  String s = message;
  s.trim();

  Json_buf=s;
  // Switch on the LED if an 1 was received as first character
  if (s == "OFF") {
     digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
     // but actually the LED is on; this is because
     Serial.println("Received OFF , Send LOW TO BuildIn_LED");
     Flash = false;
     Timer = false;
    }
   if (s == "ON") {
     digitalWrite(BUILTIN_LED, HIGH);   // Turn the LED off (Note that HIGH is the voltage level
     // but actually the LED is on; this is because
     Serial.println("Received ON , Send HIGH TO BuildIn_LED");
     Flash = false;
     Timer = false;
   }
    if (s == "FLASH") {
     digitalWrite(BUILTIN_LED, HIGH);   // Turn the LED off (Note that HIGH is the voltage level
     // but actually the LED is on; this is because
     Serial.println("Received FLASH , Flashing BuildIn_LED ");
     Flash = true;
     Timer = false;
   } //if (message[0] == '2')
   
    if (s == "TIMER") {
     digitalWrite(BUILTIN_LED, HIGH);   // Turn the LED off (Note that HIGH is the voltage level
     // but actually the LED is on; this is because
     Serial.println("Received TIMER ,  BuildIn_LED ON 5 SEC");
     Flash = false;
     Timer = true;
     Count= 10;
   }
    if (s == "TOGGLE") {
     int currState = digitalRead(BUILTIN_LED);
     digitalWrite(BUILTIN_LED, !currState);  // sets the LED to the Toggle value
     // but actually the LED is on; this is because
     Serial.println("Received TOGGLE ,  BuildIn_LED TOGGLE");
     Flash = false;
     Timer = false;
   }  
}
//======================================================
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, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
}
//======================================================
void setup() {
  Serial.begin(115200);
  setup_wifi();
  pinMode(BUILTIN_LED, OUTPUT);
  Serial.println(F("Booting...."));
 }
//======================================================
void process_mqtt() {
  if (WiFi.status() == WL_CONNECTED) {
    if (client.connected()) {
      client.loop();
    } else {
    // client id, client username, client password, last will topic, last will qos, last will retain, last will message
      if (client.connect(MQTTid, MQTTuser, MQTTpsw, MQTTid "/status", 2, true, "0")) {
          pendingDisconnect = false;
          mqttConnectedCb();
      }
    }
  } else {
    if (client.connected())
      client.disconnect();
  }
  if (!client.connected() && !pendingDisconnect) {
    pendingDisconnect = true;
    mqttDisconnectedCb();
  }
}
//======================================================
void loop() {
  process_mqtt();
 
  if (Flash)
  {
    digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED));
    delay(500);
  }
  if (Timer)
  {
    digitalWrite(BUILTIN_LED, HIGH);
    delay(500);
    Count=Count-1;
    if (Count == 0 ){
       Timer=false;
       digitalWrite(BUILTIN_LED, LOW);
    }
     
  }

  // Convert data to JSON string
  if (json != Json_buf) {
    json = Json_buf ;
    json.toCharArray(jsonChar, json.length()+1);
 
    if  (client.connected()) {
          Serial.print("Publish message: alex9ufo/outTopic/led/led_event ");
          Serial.println(json);
          // Publish JSON character array to MQTT topic
          client.publish("alex9ufo/outTopic/led/led_event",jsonChar);
        }
  }

}   //Loop
//======================================================



Node-Red 程式

[

    {

        "id": "abeb9ac07c0f42bf",

        "type": "tab",

        "label": "2023_RFID_2-1",

        "disabled": false,

        "info": "",

        "env": []

    },

    {

        "id": "1d043f992e594832",

        "type": "mqtt in",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "topic": "alex9ufo/outTopic/led/led_event",

        "qos": "1",

        "datatype": "auto",

        "broker": "841df58d.ee5e98",

        "nl": false,

        "rap": false,

        "inputs": 0,

        "x": 230,

        "y": 80,

        "wires": [

            [

                "9f5ab78624a00a9c",

                "21f8d8c05955cf9b",

                "1e137239477d0f8a"

            ]

        ]

    },

    {

        "id": "d096f1714e74a828",

        "type": "ui_text",

        "z": "abeb9ac07c0f42bf",

        "group": "6c9116b.b62d4e8",

        "order": 0,

        "width": 0,

        "height": 0,

        "name": "",

        "label": "ESP32發行到MQTT的資料",

        "format": "{{msg.payload}}",

        "layout": "col-center",

        "x": 600,

        "y": 120,

        "wires": []

    },

    {

        "id": "4efd05adca200baa",

        "type": "ui_button",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "group": "6c9116b.b62d4e8",

        "order": 0,

        "width": 0,

        "height": 0,

        "passthru": false,

        "label": "LED 開",

        "tooltip": "",

        "color": "white",

        "bgcolor": "",

        "icon": "fa-circle",

        "payload": "ON",

        "payloadType": "str",

        "topic": "",

        "x": 160,

        "y": 360,

        "wires": [

            [

                "6865b15d3b8b9e2b",

                "ae99c1672227ca4b",

                "84196883d2018e01"

            ]

        ]

    },

    {

        "id": "795e06d959339717",

        "type": "ui_button",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "group": "6c9116b.b62d4e8",

        "order": 0,

        "width": 0,

        "height": 0,

        "passthru": false,

        "label": "LED 關",

        "tooltip": "",

        "color": "black",

        "bgcolor": "",

        "className": "",

        "icon": "fa-circle-o",

        "payload": "OFF",

        "payloadType": "str",

        "topic": "",

        "topicType": "str",

        "x": 160,

        "y": 400,

        "wires": [

            [

                "6865b15d3b8b9e2b",

                "ae99c1672227ca4b",

                "84196883d2018e01"

            ]

        ]

    },

    {

        "id": "6865b15d3b8b9e2b",

        "type": "mqtt out",

        "z": "abeb9ac07c0f42bf",

        "name": "Control LED",

        "topic": "alex9ufo/inTopic/led/led_event",

        "qos": "1",

        "retain": "true",

        "broker": "841df58d.ee5e98",

        "x": 410,

        "y": 460,

        "wires": []

    },

    {

        "id": "9f5ab78624a00a9c",

        "type": "debug",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "active": true,

        "tosidebar": true,

        "console": false,

        "tostatus": false,

        "complete": "false",

        "x": 450,

        "y": 80,

        "wires": []

    },

    {

        "id": "bcefc879d1be48a2",

        "type": "ui_audio",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "group": "6c9116b.b62d4e8",

        "voice": "zh-TW",

        "always": true,

        "x": 540,

        "y": 160,

        "wires": []

    },

    {

        "id": "70576e3fca5ec868",

        "type": "ui_button",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "group": "6c9116b.b62d4e8",

        "order": 0,

        "width": 0,

        "height": 0,

        "passthru": false,

        "label": "LED 開關反向",

        "tooltip": "",

        "color": "blue",

        "bgcolor": "",

        "className": "",

        "icon": "fa-circle-o",

        "payload": "TOGGLE",

        "payloadType": "str",

        "topic": "",

        "topicType": "str",

        "x": 180,

        "y": 440,

        "wires": [

            [

                "6865b15d3b8b9e2b",

                "ae99c1672227ca4b",

                "84196883d2018e01"

            ]

        ]

    },

    {

        "id": "21f8d8c05955cf9b",

        "type": "function",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "func": "var st1;\nif (msg.payload === \"ON\") {\n   st1=\"LED開\"; \n} \nelse if (msg.payload === \"OFF\") {\n  st1=\"LED關\";\n}\nelse if (msg.payload === \"FLASH\") {\n  st1=\"LED閃爍\";\n}\nelse if (msg.payload === \"TIMER\") {\n  st1=\"LED開五秒鐘\";\n}\nelse if (msg.payload === \"TOGGLE\") {\n  st1=\"LED ON OFF 交換\";\n}\n\nmsg.payload=st1;\nreturn msg;",

        "outputs": 1,

        "noerr": 0,

        "initialize": "",

        "finalize": "",

        "x": 370,

        "y": 160,

        "wires": [

            [

                "bcefc879d1be48a2",

                "0b6fb90165b3a6ec",

                "d096f1714e74a828"

            ]

        ]

    },

    {

        "id": "6118254f24394b62",

        "type": "ui_button",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "group": "6c9116b.b62d4e8",

        "order": 0,

        "width": 0,

        "height": 0,

        "passthru": false,

        "label": "LED 開5秒鐘",

        "tooltip": "",

        "color": "purple",

        "bgcolor": "",

        "icon": "fa-circle-o",

        "payload": "TIMER",

        "payloadType": "str",

        "topic": "",

        "x": 170,

        "y": 520,

        "wires": [

            [

                "6865b15d3b8b9e2b",

                "ae99c1672227ca4b",

                "84196883d2018e01"

            ]

        ]

    },

    {

        "id": "0b6fb90165b3a6ec",

        "type": "function",

        "z": "abeb9ac07c0f42bf",

        "name": "INSERT",

        "func": "msg.topic = \"INSERT INTO LED (time_led, led_status) VALUES (?,?)\";\n//msg.topic = \"INSERT INTO LED (id, time_led, led_status) VALUES (?,?,?)\";\n\n\nvar Today = new Date();\nvar yyyy = Today.getFullYear(); //年\nvar MM = Today.getMonth()+1;    //月\nvar dd = Today.getDate();       //日\nvar h = Today.getHours();       //時\nvar m = Today.getMinutes();     //分\nvar s = Today.getSeconds();     //秒\n\nif(MM<10)\n{\n   MM = '0'+MM;\n}\n\nif(dd<10)\n{\n   dd = '0'+dd;\n}\n\nif(h<10)\n{\n   h = '0'+h;\n}\n\nif(m<10)\n{\n  m = '0' + m;\n}\n\nif(s<10)\n{\n  s = '0' + s;\n}\n\nvar hms= yyyy + '/'+ MM + '/'+ dd + ' ' + h + ':' + m + ':' + s ;\n//var id= Date.now() ;\n//msg.payload = [id ,hms, msg.payload];\nmsg.payload = [hms, msg.payload];\n\nreturn msg;\n",

        "outputs": 1,

        "noerr": 0,

        "initialize": "",

        "finalize": "",

        "x": 400,

        "y": 200,

        "wires": [

            [

                "44eed8f37bc8fd17"

            ]

        ]

    },

    {

        "id": "44eed8f37bc8fd17",

        "type": "sqlite",

        "z": "abeb9ac07c0f42bf",

        "mydb": "19f59ce9.3edc23",

        "sqlquery": "msg.topic",

        "sql": "",

        "name": "LED Status",

        "x": 550,

        "y": 200,

        "wires": [

            [

                "da411cea3a40b17d"

            ]

        ]

    },

    {

        "id": "da411cea3a40b17d",

        "type": "debug",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "active": true,

        "tosidebar": true,

        "console": false,

        "tostatus": false,

        "complete": "false",

        "statusVal": "",

        "statusType": "auto",

        "x": 710,

        "y": 200,

        "wires": []

    },

    {

        "id": "d80c61b5bf8278a5",

        "type": "comment",

        "z": "abeb9ac07c0f42bf",

        "name": "Node-Red publish 到 HiveMQ Broker  , ESP32訂閱",

        "info": "將 alex9ufo/inTopic 到(publish)HiveMQ Broker \n給 Arduino 訂閱(Subscribe)",

        "x": 290,

        "y": 560,

        "wires": []

    },

    {

        "id": "12da4e5307be0c00",

        "type": "comment",

        "z": "abeb9ac07c0f42bf",

        "name": "ESP32向 HiveMQ Broker發行 Node-Red 訂閱subscribe",

        "info": "將  Arduino 發行到(publish)HiveMQ Broker alex9ufo/led/led_status \n給 Node-red 或 MQTTB-Box 訂閱(Subscribe)",

        "x": 300,

        "y": 40,

        "wires": []

    },

    {

        "id": "392701ef3a2dfdf8",

        "type": "ui_button",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "group": "6c9116b.b62d4e8",

        "order": 0,

        "width": 0,

        "height": 0,

        "passthru": false,

        "label": "LED 閃爍",

        "tooltip": "",

        "color": "yellow",

        "bgcolor": "",

        "icon": "fa-circle-o",

        "payload": "FLASH",

        "payloadType": "str",

        "topic": "",

        "x": 160,

        "y": 480,

        "wires": [

            [

                "6865b15d3b8b9e2b",

                "ae99c1672227ca4b",

                "84196883d2018e01"

            ]

        ]

    },

    {

        "id": "ae99c1672227ca4b",

        "type": "ui_audio",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "group": "6c9116b.b62d4e8",

        "voice": "zh-TW",

        "always": true,

        "x": 420,

        "y": 520,

        "wires": []

    },

    {

        "id": "84196883d2018e01",

        "type": "ui_text",

        "z": "abeb9ac07c0f42bf",

        "group": "6c9116b.b62d4e8",

        "order": 0,

        "width": 0,

        "height": 0,

        "name": "",

        "label": "Node-RED發行到MQTT的資料",

        "format": "{{msg.payload}}",

        "layout": "row-center",

        "x": 470,

        "y": 400,

        "wires": []

    },

    {

        "id": "1faac91f7a51160e",

        "type": "function",

        "z": "abeb9ac07c0f42bf",

        "name": "Set Line API ",

        "func": "msg.headers = {'content-type':'application/x-www-form-urlencoded','Authorization':'Bearer cEI4hx24xyopKGAArgZcKJNHE1V7KeeIi4Lzny3dDNO'};\nmsg.payload = {\"message\":msg.payload};\nreturn msg;",

        "outputs": 1,

        "noerr": 0,

        "x": 470,

        "y": 300,

        "wires": [

            [

                "dd5171fe4158b3fe"

            ]

        ]

    },

    {

        "id": "1e137239477d0f8a",

        "type": "function",

        "z": "abeb9ac07c0f42bf",

        "name": "Format timestamp",

        "func": "var date = new Date();\nvar h = date.getHours();\nvar m = date.getMinutes();\nvar s = date.getSeconds();\nif(h<10){\n    h = '0'+h;\n}\nif(m<10){\n    m = '0' + m;\n}\nif(s<10){\n    s = '0' + s;\n}\nmsg.payload = msg.payload + ' --> Time:(' + h + ':' + m + ':' + s + ')' ;\n\nreturn msg;",

        "outputs": 1,

        "noerr": 0,

        "initialize": "",

        "finalize": "",

        "x": 290,

        "y": 300,

        "wires": [

            [

                "1faac91f7a51160e"

            ]

        ]

    },

    {

        "id": "dd5171fe4158b3fe",

        "type": "http request",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "method": "POST",

        "ret": "txt",

        "url": "https://notify-api.line.me/api/notify",

        "tls": "",

        "x": 620,

        "y": 300,

        "wires": [

            [

                "bb5995536de3a60c"

            ]

        ]

    },

    {

        "id": "bb5995536de3a60c",

        "type": "debug",

        "z": "abeb9ac07c0f42bf",

        "name": "",

        "active": true,

        "tosidebar": true,

        "console": false,

        "tostatus": false,

        "complete": "false",

        "x": 770,

        "y": 300,

        "wires": []

    },

    {

        "id": "841df58d.ee5e98",

        "type": "mqtt-broker",

        "name": "",

        "broker": "broker.mqtt-dashboard.com",

        "port": "1883",

        "clientid": "",

        "usetls": false,

        "compatmode": false,

        "keepalive": "15",

        "cleansession": true,

        "birthTopic": "",

        "birthQos": "0",

        "birthPayload": "",

        "closeTopic": "",

        "closePayload": "",

        "willTopic": "",

        "willQos": "0",

        "willPayload": ""

    },

    {

        "id": "6c9116b.b62d4e8",

        "type": "ui_group",

        "name": "Storing IOT Data ",

        "tab": "eeb8e179.a47a4",

        "order": 1,

        "disp": true,

        "width": "6",

        "collapse": true

    },

    {

        "id": "19f59ce9.3edc23",

        "type": "sqlitedb",

        "db": "eWeLink-1.db",

        "mode": "RWC"

    },

    {

        "id": "eeb8e179.a47a4",

        "type": "ui_tab",

        "name": "eWeLink",

        "icon": "dashboard",

        "disabled": false,

        "hidden": false

    }

]




https://mqtt-explorer.com/





沒有留言:

張貼留言

Messaging API作為替代方案

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