2024年4月24日 星期三

2024年4月24日 星期三 Node-Red Dashboard UI Template + AngularJS 參考 AngularJS教學 --2

 2024年4月24日 星期三 Node-Red Dashboard UI Template + AngularJS 參考 AngularJS教學 --2


AngularJS 實例

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.staticfile.net/angular.js/1.4.6/angular.min.js"></script> 
</head>
<body>

<div ng-app="">
  <p>我的第一个表达式: {{ 5 + 5 }}</p>
</div>

</body>
</html>



node-red Dashboard UI Template

 

<script src="https://cdn.babylonjs.com/babylon.js"></script>

<style>

.main

{

    height:600px;

    width:200px;

    background:lightblue;

        

}

</style>


<body>


<div ng-app="">

  <p>我的第一个表达式: {{ 5 + 5 }}</p>

</div>


</body>

</html>



Node-Red Dashboard UI Template + AngularJS 參考 AngularJS教學 --1

 Node-Red Dashboard UI Template + AngularJS 參考 AngularJS教學 --1

參考來源 https://www.runoob.com/angularjs/angularjs-tutorial.html


AngularJS 實例


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.staticfile.net/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>

<div ng-app="">
  <p>名字 : <input type="text" ng-model="name"></p>
  <h1>Hello {{name}}</h1>
  <p ng-bind="name"></p>
</div>

</body>
</html>




node-red Dashboard UI Template

<script src="https://cdn.babylonjs.com/babylon.js"></script>
<style>
.main
{
    height:600px;
    width:200px;
    background:lightblue;
        
}
</style>

<div ng-app="">
  <p>名字 : <input type="text" ng-model="name"></p>
  <h1>Hello {{name}}</h1>
  <p ng-bind="name"></p>
</div>

</body>
</html>






Wokwi ESP32 Simulator : ESP32 + LED +MQTT+ Node-RED Dashboard

 Wokwi ESP32 Simulator : ESP32 +  LED +MQTT+ Node-RED Dashboard 









WOKWI ESP32程式

// Create an MQTT Connection
// TCP Connection
// import the WiFi and PubSubClient libraries
//The WiFi library allows ESP32 to establish connections with Wi-Fi networks
//The PubSubClient library enables ESP32 to connect to an MQTT broker for publishing messages and subscribing to topics.
#include <WiFi.h>
#include "PubSubClient.h"
// WiFi
char ssid[]="Wokwi-GUEST";
char pass[]="";
// MQTT Broker
const char *mqtt_broker = "broker.mqtt-dashboard.com";//"broker.emqx.io";//Public Broker
const char *mqtt_username = "hivemqtt";
const char *mqtt_password = "public";
const int mqtt_port = 1883;
// App Protcol ---> Port
const char *topic_publish = "alex9ufo/esp32/p1";//Topic ESP32 Pusblish
const char *topic_subsrcibe = "alex9ufo/esp32/s1";//Topic ESp32 Subs
const char *topic_subsrcibe2 = "alex9ufo/esp32/s2";//Topic ESp32 Subs

WiFiClient hamada;//WIFI Opject
PubSubClient client(hamada);//OOP
//int y ;
//void function(int x);
//call_function(y);
void callback(char *topic, byte *payload, unsigned int length);
#define LED 2
bool ledState=false;

void setup(){
   // Setting LED pin as output
    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);  // Turn off the LED initially
    //Open a serial connection to display program results and establish a connection to the Wi-Fi network.
    // Set software serial baud to 115200;
    Serial.begin(115200);
    // Connecting to a Wi-Fi network
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Connecting to WiFi..");
    }
        Serial.println("Connected to the Wi-Fi network");
    // Utilize PubSubClient to establish a connection with the MQTT broker.
    //connecting to a mqtt broker
    Serial.println("Before Connect MQTT");
    //Broker Configuration
    client.setServer(mqtt_broker, mqtt_port);
   
   while (!client.connected()) {
        String client_id = "esp32-client-";
        client_id =client_id+ String(WiFi.macAddress());
        //consloe.log("x"+"y");//xy

        //ESP32-ID -----> esp32-client-macaddress
        //variable.c_str()--->char [] , String
        Serial.printf("The client %s connects to the public MQTT broker\n", client_id.c_str());
        if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("Public MQTT broker connected");
        } else {
            Serial.print("failed with state ");
            Serial.print(client.state());//1 , 2 , 5
            delay(2000);
        }
    }
    Serial.println("After Connect MQTT");
    client.publish(topic_publish, "Hi, I'm ESP32 ^^");
    client.subscribe(topic_subsrcibe);
    client.subscribe(topic_subsrcibe2);
    client.setCallback(callback);
}

void loop() {
    client.loop();
}



void callback(char* topic, byte* message, unsigned int length) {
  printPayload(topic, message, length);  
}

void printPayload(char* topic, byte* message, unsigned int length) {
  // Printing Received Message
  Serial.print("Message received on topic: ");
  Serial.println(topic);

  String messageTemp;
  for(int i=0; i<length; i+=1) {
    messageTemp += (char)message[i];
  }
  if(String(topic) == "alex9ufo/esp32/s1"){
      Serial.println("OK1-ON,OFF");
      if(messageTemp=="ON"){
        //Serial.println("Led ON");
        digitalWrite(2,HIGH);
      }  
      else{
        digitalWrite(2,LOW);
      }
  }
  else if(String(topic) == "alex9ufo/esp32/s2"){
    Serial.print("OK2-test messsage ");  
  }
  else{
    Serial.print("Any Thing");  
  }
  Serial.println(messageTemp);
}

WOKWI diagram.json 程式

{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-esp32-devkit-v1", "id": "esp", "top": -321.7, "left": 14.2, "attrs": {} },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": -236.79,
      "left": 182.53,
      "rotate": 90,
      "attrs": { "value": "1000" }
    },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": -310.28,
      "left": 155.35,
      "attrs": { "color": "red" }
    }
  ],
  "connections": [
    [ "esp:TX0", "$serialMonitor:RX", "", [] ],
    [ "esp:RX0", "$serialMonitor:TX", "", [] ],
    [ "led1:C", "esp:GND.1", "black", [ "v0" ] ],
    [ "r1:1", "led1:A", "red", [ "h0" ] ],
    [ "esp:D2", "r1:2", "red", [ "h0" ] ]
  ],
  "dependencies": {}
}

NODE-RED 程式

[
    {
        "id": "8ad0b62ca9d0f3bd",
        "type": "mqtt in",
        "z": "2ded2ffb8cb68caa",
        "name": "WOKWI--out",
        "topic": "alex9ufo/esp32/p1",
        "qos": "1",
        "datatype": "auto-detect",
        "broker": "841df58d.ee5e98",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 710,
        "y": 340,
        "wires": [
            [
                "274dced93fde72ef",
                "3d40f264b73266ac"
            ]
        ]
    },
    {
        "id": "dc2407b3a8a088eb",
        "type": "ui_button",
        "z": "2ded2ffb8cb68caa",
        "name": "",
        "group": "a717a00c22deda21",
        "order": 3,
        "width": 3,
        "height": 1,
        "passthru": false,
        "label": "ON",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "ON",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 690,
        "y": 120,
        "wires": [
            [
                "af354a115bab8bb7",
                "a53f8fca6ea739e5"
            ]
        ]
    },
    {
        "id": "ad4d88a419f60961",
        "type": "ui_button",
        "z": "2ded2ffb8cb68caa",
        "name": "",
        "group": "a717a00c22deda21",
        "order": 5,
        "width": 3,
        "height": 1,
        "passthru": false,
        "label": "OFF",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "OFF",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 690,
        "y": 160,
        "wires": [
            [
                "a53f8fca6ea739e5",
                "af354a115bab8bb7"
            ]
        ]
    },
    {
        "id": "8956f4dd3a6211e1",
        "type": "mqtt out",
        "z": "2ded2ffb8cb68caa",
        "name": "Test",
        "topic": "alex9ufo/esp32/s2",
        "qos": "1",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "841df58d.ee5e98",
        "x": 950,
        "y": 200,
        "wires": []
    },
    {
        "id": "3d40f264b73266ac",
        "type": "ui_text",
        "z": "2ded2ffb8cb68caa",
        "group": "a717a00c22deda21",
        "order": 9,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "訂閱主題 : ",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "x": 930,
        "y": 300,
        "wires": []
    },
    {
        "id": "274dced93fde72ef",
        "type": "ui_audio",
        "z": "2ded2ffb8cb68caa",
        "name": "",
        "group": "a717a00c22deda21",
        "voice": "Microsoft Yating - Chinese (Traditional, Taiwan)",
        "always": "",
        "x": 920,
        "y": 340,
        "wires": []
    },
    {
        "id": "af354a115bab8bb7",
        "type": "mqtt out",
        "z": "2ded2ffb8cb68caa",
        "name": "ON/OFF",
        "topic": "alex9ufo/esp32/s1",
        "qos": "1",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "841df58d.ee5e98",
        "x": 960,
        "y": 140,
        "wires": []
    },
    {
        "id": "a53f8fca6ea739e5",
        "type": "debug",
        "z": "2ded2ffb8cb68caa",
        "name": "debug 298",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 990,
        "y": 100,
        "wires": []
    },
    {
        "id": "3b366f277e55e09d",
        "type": "ui_button",
        "z": "2ded2ffb8cb68caa",
        "name": "",
        "group": "a717a00c22deda21",
        "order": 5,
        "width": 3,
        "height": 1,
        "passthru": false,
        "label": "Test ",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "Test....",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 690,
        "y": 200,
        "wires": [
            [
                "8956f4dd3a6211e1"
            ]
        ]
    },
    {
        "id": "84d4cce17c19fe1d",
        "type": "ui_button",
        "z": "2ded2ffb8cb68caa",
        "name": "",
        "group": "a717a00c22deda21",
        "order": 5,
        "width": 3,
        "height": 1,
        "passthru": false,
        "label": "Any Thing",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "Any Thing",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "x": 700,
        "y": 240,
        "wires": [
            [
                "638c9840c086dedd"
            ]
        ]
    },
    {
        "id": "638c9840c086dedd",
        "type": "mqtt out",
        "z": "2ded2ffb8cb68caa",
        "name": "Any Thing",
        "topic": "alex9ufo/esp32/s3",
        "qos": "1",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "841df58d.ee5e98",
        "x": 960,
        "y": 240,
        "wires": []
    },
    {
        "id": "841df58d.ee5e98",
        "type": "mqtt-broker",
        "name": "",
        "broker": "broker.hivemq.com",
        "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": "a717a00c22deda21",
        "type": "ui_group",
        "name": "LED",
        "tab": "b83c5c221c74411b",
        "order": 3,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "b83c5c221c74411b",
        "type": "ui_tab",
        "name": "Wokwi",
        "icon": "dashboard",
        "order": 121,
        "disabled": false,
        "hidden": false
    }
]


2024年4月23日 星期二

Wokwi ESP32 Simulator : ESP32 + NTP+MQTT+ Node-RED Dashboard

Wokwi ESP32 Simulator : ESP32 + NTP+MQTT+ Node-RED Dashboard 








Wokwi ESP32程式

// Learn about the ESP32 WiFi simulation in

// https://docs.wokwi.com/guides/esp32-wifi
/*
  Definition of struct tm:
  Member  Type  Meaning Range
  tm_sec  int seconds after the minute  0-61*
  tm_min  int minutes after the hour  0-59
  tm_hour int hours since midnight  0-23
  tm_mday int day of the month  1-31
  tm_mon  int months since January  0-11
  tm_year int years since 1900
  tm_wday int days since Sunday 0-6
  tm_yday int days since January 1  0-365
  tm_isdst  int Daylight Saving Time flag
*/
#include "time.h"
#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <PubSubClient.h>

LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);

#define NTP_SERVER     "pool.ntp.org"
#define UTC_OFFSET     28800  // 3600*8 = 28800
#define UTC_OFFSET_DST 0

unsigned long lastMsg = 0;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "broker.mqtt-dashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);

String Time1="";
char jsonChar1[50];
char jsonChar2[50];

void spinner() {
  static int8_t counter = 0;
  const char* glyphs = "\xa1\xa5\xdb";
  LCD.setCursor(15, 1);
  LCD.print(glyphs[counter++]);
  if (counter == strlen(glyphs)) {
    counter = 0;
  }
}

void printLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    LCD.setCursor(0, 1);
    LCD.println("Connection Err");
    return;
  }

  LCD.setCursor(8, 0);
  LCD.println(&timeinfo, "%H:%M:%S");

  LCD.setCursor(0, 1);
  LCD.println(&timeinfo, "%d/%m/%Y   %Z");
}

void printLocalTime2(){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");

  int current_hour = timeinfo.tm_hour;
  int current_min = timeinfo.tm_min;
  int current_sec = timeinfo.tm_sec;
  Time1 = String (current_hour)+":"+ String (current_min)+":"+ String (current_sec);
  Serial.println(Time1);
  int current_year = 1900+ timeinfo.tm_year;
  int current_mon = timeinfo.tm_mon;
  int current_mday = timeinfo.tm_mday;
  Time1 = Time1 + " " + String (current_year)+"/"+ String (current_mon)+"/"+ String (current_mday);
  Serial.println(Time1);
 

  Serial.print("Day of week: ");
  Serial.println(&timeinfo, "%A");
  Serial.print("Month: ");
  Serial.println(&timeinfo, "%B");
  Serial.print("Day of Month: ");
  Serial.println(&timeinfo, "%d");
  Serial.print("Year: ");
  Serial.println(&timeinfo, "%Y");
  Serial.print("Hour: ");
  Serial.println(&timeinfo, "%H");
  Serial.print("Hour (12 hour format): ");
  Serial.println(&timeinfo, "%I");
  Serial.print("Minute: ");
  Serial.println(&timeinfo, "%M");
  Serial.print("Second: ");
  Serial.println(&timeinfo, "%S");

  Serial.println("Time variables");
  char timeHour[3];
  strftime(timeHour,3, "%H", &timeinfo);
  Serial.println(timeHour);
  char timeWeekDay[10];
  strftime(timeWeekDay,10, "%A", &timeinfo);
  Serial.println(timeWeekDay);
  Serial.println();
}

void callback(char* topic, byte* payload, unsigned int length) {
 Serial.print("Message arrived [");
 Serial.print(topic);
 Serial.print("] ");
 for (int i = 0; i < length; i++) {
   Serial.print((char)payload[i]);
 }}

void reconnect() {
 while (!client.connected()) {
   Serial.print("Attempting MQTT connection...");
   String clientId = "ESP32Client-";
   clientId += String(random(0xffff), HEX);
   if (client.connect(clientId.c_str())) {
     Serial.println("Connected");
     client.publish("alex9ufo/ThinkIOT/Publish", "Welcome");
     client.subscribe("alex9ufo/ThinkIOT/Subscribe");
   } else {
     Serial.print("failed, rc=");
     Serial.print(client.state());
     Serial.println(" try again in 5 seconds");
     delay(5000);
   }}
}

void setup_wifi() {
 delay(10);
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);


 WiFi.mode(WIFI_STA);
 WiFi.begin(ssid, password);


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

 randomSeed(micros());

 Serial.println("");
 Serial.println("WiFi connected");
 Serial.println("IP address: ");
 Serial.println(WiFi.localIP());
}
void setup() {
  Serial.begin(115200);

  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
 
  LCD.init();
  LCD.backlight();
  LCD.setCursor(0, 0);
  LCD.print("Connecting to ");
  LCD.setCursor(0, 1);
  LCD.print("WiFi ");

  WiFi.begin("Wokwi-GUEST", "", 6);
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    spinner();
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  LCD.clear();
  LCD.setCursor(0, 0);
  LCD.println("Online");
  LCD.setCursor(0, 1);
  LCD.println("Updating time...");

  configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
}

void loop() {
  printLocalTime();
  delay(250);

 if (!client.connected()) {
   reconnect();
 }
 client.loop();

 unsigned long now = millis();
 if (now - lastMsg > 12000) {
   printLocalTime2();
   lastMsg = now;
   Time1.toCharArray(jsonChar1, Time1.length()+1);
 
   client.publish("alex9ufo/ThinkIOT/NTPTime1", jsonChar1);

 }

}

WOKWI diagram.json

{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "board-esp32-devkit-c-v4", "id": "esp", "top": -76.8, "left": 43.24, "attrs": {} },
    {
      "type": "wokwi-lcd1602",
      "id": "lcd1",
      "top": -70.4,
      "left": 236,
      "attrs": { "pins": "i2c" }
    }
  ],
  "connections": [
    [ "esp:TX", "$serialMonitor:RX", "", [] ],
    [ "esp:RX", "$serialMonitor:TX", "", [] ],
    [ "lcd1:SDA", "esp:21", "green", [ "v-4.49", "h-28.8", "v23.89" ] ],
    [ "lcd1:GND", "esp:GND.2", "black", [ "h-16.67", "v162.78" ] ],
    [ "lcd1:VCC", "esp:3V3", "red", [ "h-9.6", "v-57.5", "h-134.55" ] ],
    [ "lcd1:SCL", "esp:22", "purple", [ "h-19.2", "v-18.9" ] ]
  ],
  "dependencies": {}
}

Node-Red 程式

[ { "id": "9741629b8510891f", "type": "mqtt in", "z": "2ded2ffb8cb68caa", "name": "", "topic": "alex9ufo/ThinkIOT/NTPTime1", "qos": "1", "datatype": "auto-detect", "broker": "603bb104.d6134", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 200, "y": 300, "wires": [ [ "70f6524c6b60447d" ] ] }, { "id": "70f6524c6b60447d", "type": "ui_text", "z": "2ded2ffb8cb68caa", "group": "ed796d698b021723", "order": 2, "width": 0, "height": 0, "name": "", "label": "收到 NTP的訊息", "format": "{{msg.payload}}", "layout": "row-spread", "className": "", "x": 460, "y": 300, "wires": [] }, { "id": "603bb104.d6134", "type": "mqtt-broker", "name": "", "broker": "broker.mqtt-dashboard.com", "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": "ed796d698b021723", "type": "ui_group", "name": "NTP_Time", "tab": "b83c5c221c74411b", "order": 2, "disp": true, "width": "6", "collapse": false, "className": "" }, { "id": "b83c5c221c74411b", "type": "ui_tab", "name": "Wokwi", "icon": "dashboard", "order": 121, "disabled": false, "hidden": false } ]


2024年4月24日 星期三 Node-Red Dashboard UI Template + AngularJS 參考 AngularJS教學 --2

 2024年4月24日 星期三 Node-Red Dashboard UI Template + AngularJS 參考 AngularJS教學 --2 AngularJS 實例 <!DOCTYPE html> <html> <head> &...