2024年6月23日 星期日

WOKWI + IoT MQTT Panel+ Node-Red

 WOKWI + IoT MQTT Panel+ Node-Red





// Wifi 與 MQttClient 程式庫
#include <ArduinoMqttClient.h>
#include <WiFi.h>
//#include "arduino_secrets1.h"

//#define LED 13           //定義LED接腳
int LED = 13;

const char ssid[] = "Wokwi-GUEST"; // Enter your Wi-Fi name
const char pass[] = "";           // Enter Wi-Fi password

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

//const char broker[] = "test.mosquitto.org";
const char broker[] = "broker.emqx.io";
int        port     = 1883;
String json = "";

const char *SubTopic1 = "alex9ufo/sw1";
const char *PubTopic2 = "alex9ufo/led1";

const char willTopic[] = "alex9ufo/2024/RFID/Starting";
//==========================================================
//布林代數 LED狀態 是否連上網路ESP32 ready ?
bool ledState = false;
bool atwork = false;
bool Send = false;  //true
String LEDjson = "";
int Count= 0;
bool Flash = false;  //true
bool Timer = false;  //true

//===========================================================
void onMqttMessage(int messageSize) {
  // we received a message, print out the topic and contents
  Serial.print("Received a message with topic '");
  Serial.print(mqttClient.messageTopic());
  String Topic= mqttClient.messageTopic();
  Serial.print("', duplicate = ");
  Serial.print(mqttClient.messageDup() ? "true" : "false");
  Serial.print(", QoS = ");
  Serial.print(mqttClient.messageQoS());
  Serial.print(", retained = ");
  Serial.print(mqttClient.messageRetain() ? "true" : "false");
  Serial.print("', length ");
  Serial.print(messageSize);
  Serial.println(" bytes:");
  String message="";
  // use the Stream interface to print the contents
  while (mqttClient.available()) {
    //Serial.print((char)mqttClient.read());
    message += (char)mqttClient.read();
  }

  Serial.println(message);
  message.trim();
  Topic.trim();

  if (Topic=="alex9ufo/sw1") {
  if (message == "on") {
    digitalWrite(LED, LOW);  // Turn on the LED
    //ledState = true;  //ledState = ture HIGH
    //設定 各個 旗號
    LEDjson ="ON";
Flash = false;
    Send = true ;
    Serial.print("LED =");
    Serial.println(LEDjson);
  }

  if (message == "off" ) {
    digitalWrite(LED, HIGH); // Turn off the LED
    //ledState = false; //ledState = false LOW
    LEDjson ="OFF";
    Flash = false;
Send = true ;
    Serial.print("LED =");
    Serial.println(LEDjson);
  }
 
  if (message == "flash" ) {
    digitalWrite(LED, HIGH); // Turn off the LED
    Flash = true;
    Timer = false;
    LEDjson ="FLASH";
    Send = true ;  
    Serial.print("LED =");
    Serial.println(LEDjson);      
  }

  if (message == "timer" ) {
    digitalWrite(LED, LOW); // Turn off the LED
    Flash = false;
    Timer = true;
    LEDjson ="TIMER";
    Send = true ;
    Count= 11;
    Serial.print("LED =");
    Serial.println(LEDjson);  
  }
 
    Serial.println();
    Serial.println("-----------------------");
  }  

}

//===========================================================
//副程式  setup wifi
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);     //print ssid
  WiFi.begin(ssid, pass);  //初始化WiFi 函式庫並回傳目前的網路狀態
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }   //假設 wifi 未連接 show ………

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}  
//===========================================================
//判斷 旗號Flash , Timer 是否為真
void LED_Message() {
  //判斷 旗號 Flash / timer  是否為真 ? 閃爍 定時
 
  if (Flash){
    digitalWrite(LED, !digitalRead(LED));
    delay(500);
    if (digitalRead(LED))
      ledState = true;
    else
      ledState = false;

  } //(Flash)

  if (Timer) {
    digitalWrite(LED, LOW);
    delay(500);
    if (digitalRead(LED))
      ledState = true;
    else
      ledState = false;

  Count=Count-1;
  if (Count == 0 ){
    Timer=false;
    digitalWrite(LED, HIGH);
    ledState = false;
    }
  } //(Timer)
 
 
  ////判斷 旗號 Send 是否為真 回傳MQTT訊息到MQTT Broker 
  if (Send) {
    // Convert JSON string to character array
    Serial.print("Publish message: ");
    Serial.println(LEDjson);
    LEDjson.trim();

    bool retained = false;
    int qos = 1;
    bool dup = false;
   
    // Publish JSON character array to MQTT topic
    mqttClient.beginMessage(PubTopic2,  LEDjson.length(), retained, qos, dup);  //LED Status
    mqttClient.print(LEDjson);
    mqttClient.endMessage();
    Send = false;    //處理過後 旗號 Send為假
  }

}
//===========================================================
void setup() {
  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);  // Turn off the LED initially
  //Initialize serial and wait for port to open:
  Serial.begin(115200);   // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
 
  setup_wifi();
  Serial.println("You're connected to the network");
  Serial.println();
 
  String willPayload = "ESP32 Start working....!";
  bool willRetain = true;
  int willQos = 1;

  mqttClient.beginWill(willTopic, willPayload.length(), willRetain, willQos);
  mqttClient.print(willPayload);
  mqttClient.endWill();

  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());

    while (1);
  }

  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  // set the message receive callback
  mqttClient.onMessage(onMqttMessage);
  Serial.print("Subscribing to topic: ");
  Serial.println(SubTopic1);
  // subscribe to a topic
  // the second parameter sets the QoS of the subscription,
  // the the library supports subscribing at QoS 0, 1, or 2
  int subscribeQos = 1;
  mqttClient.subscribe(SubTopic1, subscribeQos);

}
//===========================================================
void loop() {
 
  // call poll() regularly to allow the library to receive MQTT messages and
  // send MQTT keep alives which avoids being disconnected by the broker
  mqttClient.poll();
 
  LED_Message();
}
////===========================================================


[ { "id": "c5aa76af923f7f58", "type": "sqlite", "z": "5ac0dcc9b2371c86", "mydb": "f5c97c74cc496505", "sqlquery": "msg.topic", "sql": "", "name": "LED_STATUS", "x": 540, "y": 380, "wires": [ [ "27efa6abf9cbb4ee" ] ] }, { "id": "b828b27417d30085", "type": "function", "z": "5ac0dcc9b2371c86", "name": "CREATE DATABASE", "func": "//CREATE TABLE LEDSTATUS (\n//id INTEGER,\n//STATUS TEXT,\n//Date DATE,\n//Time TIME,\n//PRIMARY KEY (id)\n//);\n//CREATE TABLE LEDSTATUS (id INTEGER,STATUS TEXT,Date DATE,Time TIME,PRIMARY KEY (id));\nmsg.topic = \"CREATE TABLE LEDSTATUS (id INTEGER,STATUS TEXT,Date DATE,Time TIME,PRIMARY KEY (id))\";\nreturn msg;\n", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 320, "y": 380, "wires": [ [ "c5aa76af923f7f58" ] ] }, { "id": "7c9ce84a58e9c7c6", "type": "ui_button", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "order": 7, "width": 2, "height": 1, "passthru": false, "label": "建立LED資料庫", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "建立資料庫", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 100, "y": 380, "wires": [ [ "b828b27417d30085", "8a34af6b3043f18b" ] ] }, { "id": "d600380920810b2c", "type": "ui_button", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "order": 1, "width": 2, "height": 1, "passthru": false, "label": "ON", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "on", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 70, "y": 20, "wires": [ [ "853f81265d7f417a", "c46e8dac6baed7b8", "b6406d3708209514" ] ] }, { "id": "8a81fcaa99d572b0", "type": "ui_button", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "order": 2, "width": 2, "height": 1, "passthru": false, "label": "OFF", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "off", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 70, "y": 60, "wires": [ [ "853f81265d7f417a", "c46e8dac6baed7b8", "b6406d3708209514" ] ] }, { "id": "184a7cf3f412a863", "type": "ui_button", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "order": 3, "width": 2, "height": 1, "passthru": false, "label": "TIMER", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "timer", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 80, "y": 100, "wires": [ [ "853f81265d7f417a", "c46e8dac6baed7b8", "b6406d3708209514" ] ] }, { "id": "9d0bd7688496f671", "type": "ui_button", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "order": 4, "width": 2, "height": 1, "passthru": false, "label": "FLASH", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "flash", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 80, "y": 140, "wires": [ [ "853f81265d7f417a", "c46e8dac6baed7b8", "b6406d3708209514" ] ] }, { "id": "eb51a0c1908bb83d", "type": "function", "z": "5ac0dcc9b2371c86", "name": "INSERT", "func": "var 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(); //秒\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}\nvar var_date = yyyy+'/'+MM+'/'+dd;\nvar var_time = h+':'+m+':'+s;\n\nvar myLED = msg.payload;\n\n\nmsg.topic = \"INSERT INTO LEDSTATUS ( STATUS , Date , Time ) VALUES ($myLED, $var_date , $var_time ) \" ;\nmsg.payload = [myLED, var_date , var_time ]\nreturn msg;\n\n\n//INSERT INTO LEDSTATUS (\n//id INTEGER,\n//STATUS TEXT,\n//Date DATE,\n//Time TIME,\n//PRIMARY KEY (id)\n//);\n", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 280, "y": 240, "wires": [ [ "c2294ca83046a6a8", "ed45bf6fa0449143" ] ] }, { "id": "853f81265d7f417a", "type": "ui_audio", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "voice": "Microsoft Hanhan - Chinese (Traditional, Taiwan)", "always": true, "x": 245, "y": 80, "wires": [], "l": false }, { "id": "c2294ca83046a6a8", "type": "sqlite", "z": "5ac0dcc9b2371c86", "mydb": "f5c97c74cc496505", "sqlquery": "msg.topic", "sql": "", "name": "LED_STATUS", "x": 440, "y": 240, "wires": [ [ "727a752dd0efde03", "8a83c8bbcfd46f16" ] ] }, { "id": "27efa6abf9cbb4ee", "type": "debug", "z": "5ac0dcc9b2371c86", "name": "debug ", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 690, "y": 380, "wires": [] }, { "id": "727a752dd0efde03", "type": "debug", "z": "5ac0dcc9b2371c86", "name": "debug ", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 630, "y": 240, "wires": [] }, { "id": "3c4ed0b0d50c313b", "type": "ui_button", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "order": 9, "width": 2, "height": 1, "passthru": false, "label": "檢視資料庫資料", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "檢視資料", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 100, "y": 320, "wires": [ [ "8a83c8bbcfd46f16", "8a34af6b3043f18b" ] ] }, { "id": "8a83c8bbcfd46f16", "type": "function", "z": "5ac0dcc9b2371c86", "name": "檢視資料", "func": "//INSERT INTO LEDSTATUS (\n//id INTEGER,\n//STATUS TEXT,\n//Date DATE,\n//Time TIME,\n//PRIMARY KEY (id)\n//);\n\n//SELECT * FROM LEDSTATUS ORDER BY id DESC LIMIT 50;\n\nmsg.topic = \"SELECT * FROM LEDSTATUS ORDER BY id DESC LIMIT 50\";\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 400, "y": 320, "wires": [ [ "063f373de357143f" ] ] }, { "id": "479ed14e926a7249", "type": "ui_table", "z": "5ac0dcc9b2371c86", "group": "a4f973bfe806b409", "name": "", "order": 10, "width": 8, "height": 7, "columns": [], "outputs": 0, "cts": false, "x": 730, "y": 320, "wires": [] }, { "id": "063f373de357143f", "type": "sqlite", "z": "5ac0dcc9b2371c86", "mydb": "f5c97c74cc496505", "sqlquery": "msg.topic", "sql": "", "name": "LED_STATUS", "x": 580, "y": 320, "wires": [ [ "479ed14e926a7249" ] ] }, { "id": "ab233348d9ada221", "type": "sqlite", "z": "5ac0dcc9b2371c86", "mydb": "f5c97c74cc496505", "sqlquery": "msg.topic", "sql": "", "name": "LED_STATUS", "x": 860, "y": 440, "wires": [ [ "c0418a0d5597ab8c" ] ] }, { "id": "6d75b939206467c1", "type": "ui_button", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "order": 5, "width": 2, "height": 1, "passthru": false, "label": "刪除所有資料 ", "tooltip": "", "color": "", "bgcolor": "", "className": "", "icon": "", "payload": "刪除所有資料 ", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 100, "y": 440, "wires": [ [ "4b5568863d72eab6", "2719587fe3d60360" ] ] }, { "id": "cd756cbe3e25a9ef", "type": "function", "z": "5ac0dcc9b2371c86", "name": "DELETE ALL DATA", "func": "//CREATE TABLE LEDSTATUS (\n//id INTEGER,\n//STATUS TEXT,\n//Date DATE,\n//Time TIME,\n//PRIMARY KEY (id)\n//);\n//CREATE TABLE LEDSTATUS (id INTEGER,STATUS TEXT,Date DATE,Time TIME,PRIMARY KEY (id));\nmsg.topic = \"DELETE from LEDSTATUS\";\nreturn msg;\n", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 670, "y": 440, "wires": [ [ "ab233348d9ada221" ] ] }, { "id": "4b5568863d72eab6", "type": "ui_audio", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "voice": "Microsoft Hanhan - Chinese (Traditional, Taiwan)", "always": true, "x": 225, "y": 500, "wires": [], "l": false }, { "id": "2719587fe3d60360", "type": "ui_toast", "z": "5ac0dcc9b2371c86", "position": "prompt", "displayTime": "3", "highlight": "", "sendall": true, "outputs": 1, "ok": "OK", "cancel": "Cancel", "raw": true, "className": "", "topic": "", "name": "", "x": 290, "y": 440, "wires": [ [ "a83b6434dccb201a" ] ] }, { "id": "a83b6434dccb201a", "type": "function", "z": "5ac0dcc9b2371c86", "name": "OK or Cancel", "func": "var topic=msg.payload;\nif (topic==\"\"){\n return [msg,null];\n \n}\nif (topic==\"Cancel\"){\n return [null,msg];\n \n}\nreturn msg;", "outputs": 2, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 460, "y": 440, "wires": [ [ "cd756cbe3e25a9ef" ], [] ] }, { "id": "8a34af6b3043f18b", "type": "ui_audio", "z": "5ac0dcc9b2371c86", "name": "", "group": "a4f973bfe806b409", "voice": "Microsoft Hanhan - Chinese (Traditional, Taiwan)", "always": true, "x": 245, "y": 340, "wires": [], "l": false }, { "id": "c0418a0d5597ab8c", "type": "link out", "z": "5ac0dcc9b2371c86", "name": "link out 57", "mode": "link", "links": [ "8159eed66b810c64" ], "x": 845, "y": 380, "wires": [] }, { "id": "8159eed66b810c64", "type": "link in", "z": "5ac0dcc9b2371c86", "name": "link in 55", "links": [ "c0418a0d5597ab8c" ], "x": 915, "y": 380, "wires": [ [ "8a83c8bbcfd46f16" ] ] }, { "id": "c46e8dac6baed7b8", "type": "mqtt out", "z": "5ac0dcc9b2371c86", "name": "Control LED out", "topic": "alex9ufo/sw1", "qos": "1", "retain": "true", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "603bb104.d6134", "x": 280, "y": 20, "wires": [] }, { "id": "1e1d4be0b371f61e", "type": "mqtt in", "z": "5ac0dcc9b2371c86", "name": "Control LED in", "topic": "alex9ufo/led1", "qos": "1", "datatype": "auto-detect", "broker": "603bb104.d6134", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 100, "y": 240, "wires": [ [ "eb51a0c1908bb83d" ] ] }, { "id": "ed45bf6fa0449143", "type": "function", "z": "5ac0dcc9b2371c86", "name": "增加 日期 時間", "func": "var ms1=msg.payload[0];\nvar ms2=msg.payload[1];\nvar ms3=msg.payload[2];\n\nmsg.payload=\"新增一筆:\"+ms1+\", 日期: \"+ms2+\", 時間:\"+ms3;\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 440, "y": 560, "wires": [ [ "0d83415fea7049d4" ] ] }, { "id": "0d83415fea7049d4", "type": "function", "z": "5ac0dcc9b2371c86", "name": "Set Line API ", "func": "msg.headers = {'content-type':'application/x-www-form-urlencoded','Authorization':'Bearer A4wwPNh2WqB7dlfeQyyIAwtggn1kfZSI5LkkCdia1gB'};\nmsg.payload = {\"message\":msg.payload};\nreturn msg;\n\n//oR7KdXvK1eobRr2sRRgsl4PMq23DjDlhfUs96SyUBZu", "outputs": 1, "noerr": 0, "x": 610, "y": 560, "wires": [ [ "efb7573d4730829c" ] ] }, { "id": "efb7573d4730829c", "type": "http request", "z": "5ac0dcc9b2371c86", "name": "", "method": "POST", "ret": "txt", "paytoqs": false, "url": "https://notify-api.line.me/api/notify", "tls": "", "persist": false, "proxy": "", "authType": "", "x": 760, "y": 560, "wires": [ [ "cbb012945f38ffa1" ] ] }, { "id": "cbb012945f38ffa1", "type": "debug", "z": "5ac0dcc9b2371c86", "name": "debug ", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 890, "y": 560, "wires": [] }, { "id": "485a0a5eba40e7a6", "type": "comment", "z": "5ac0dcc9b2371c86", "name": "Line Notify Message ", "info": "", "x": 510, "y": 500, "wires": [] }, { "id": "b6406d3708209514", "type": "debug", "z": "5ac0dcc9b2371c86", "name": "debug ", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 310, "y": 140, "wires": [] }, { "id": "f5c97c74cc496505", "type": "sqlitedb", "db": "C:\\Users\\User\\.node-red\\2024EX_LED2.db", "mode": "RWC" }, { "id": "a4f973bfe806b409", "type": "ui_group", "name": "LED", "tab": "3469785e1c4b892d", "order": 1, "disp": true, "width": 8, "collapse": false, "className": "" }, { "id": "603bb104.d6134", "type": "mqtt-broker", "name": "", "broker": "broker.emqx.io", "port": "1883", "clientid": "", "autoConnect": true, "usetls": false, "compatmode": false, "protocolVersion": "4", "keepalive": "15", "cleansession": true, "birthTopic": "", "birthQos": "0", "birthPayload": "", "birthMsg": {}, "closeTopic": "", "closePayload": "", "closeMsg": {}, "willTopic": "", "willQos": "0", "willPayload": "", "willMsg": {}, "userProps": "", "sessionExpiry": "" }, { "id": "3469785e1c4b892d", "type": "ui_tab", "name": "2024勤益2", "icon": "dashboard", "order": 126, "disabled": false, "hidden": false } ]



























沒有留言:

張貼留言

WOKWI DHT22 & LED , Node-Red + SQLite database

 WOKWI DHT22 & LED , Node-Red + SQLite database Node-Red程式 [{"id":"6f0240353e534bbd","type":"comment&...