Saturday, May 26, 2018

Demo 42: How to build an IoT Dashboard using Node-Red dashboard and ESP

1. Introduction
In this post, we will learn how to build an IoT Dashboard using Node-Redand node-red-dashboard.
These set-up can be deployed on Raspberry Pi, Orange Pi, ... easily.
We will make a demo for this post, a simple smart home demo: a floor has 1 bulb and 1 temperature sensor. They will be control by a ESP32. This ESP32 send and receive data using MQTT protocol. A server with MQTT broker, Node-Red, NodeJS and a dashboard with a chart to monitor temperature and a switch to control the bulb.
Figure: Demo model
Note: This post will re-use the posts:
How to turn the Orange Pi/Raspberry Pi into an IoT node : To install Mosquito and use host name instead of remembering the IP address
Demo 8: How to use TCP/IP with Arduino ESP32 : part 1.2 - Introduction to Node-Red (installation and usage)
Demo 14: How to use MQTT and Arduino ESP32 to build a simple Smart home system : build a smart home using Mosquito MQTT, ESP32 MQTT.
2. node-red-dashboard
Figure: node-red-dashboard
2.1 Concepts
With this dashboard:
+ Layout will be considered as a grid. It is in Dashboard Tab.
+ A group element has a width - by default 6 'units'.
+ A unit is 48px wide by default with a 6px gap.
+ A widget in the group also has a default 'auto'. It means it will fill the width of the group contained it, or you can set it to a fixed number of units.
2.2 Features
+ Layout: Tab, Link to other web pages.
+ Theme: Light, Dark or Custom Theme.
+ Widgets include Button, Chart, Form, Gauge, Notification, Switch ...
Note: the node-red-dashboard will be deployed at: http://localhost:1880/ui (change localhost accordingly)
2.3 Installation
Note: I instaled all things on my localhost
I assume that you did install NodeJS
Then install Mosquito broker following How to turn the Orange Pi/Raspberry Pi into an IoT node
Figure: ensuare MQTT broker is running 
Then you need to install Node-Red following Demo 8: How to use TCP/IP with Arduino ESP32 - part 1.
Then install node-red-dashboard. It requires Node-RED version 0.14 or more recent. Open Terminal and typing commands:
cd ~/.node-red
npm i node-red-dashboard
Then run Node-Red from Terminal using command:
node-red
You will see:
Figure: Node-Red started
Now open your web browser and go to the link http://127.0.0.1:1880/
If you use MDNS as in How to turn the Oavahi-daemonrange Pi/Raspberry Pi into an IoT node.
You will see:
Figure: left side is widgets area, right side is layout area, middile is working space of node-red-dashboard
3. Hardware
2 modules ESP32, an Raspberry Pi or Orange Pi or PC. I will use a Led for testing and generate temperature randomly.
4. Software:
We define MQTT topics and values:
    + For Led: "floor1/led" with value false-off, true-on
    + For temerature: "floor1/temp" with value is an integer or string
4.1 Node-Red side
The steps to create our model on Node-Red:
Step 1: Create 2 tabs (when deploying real website, it becomes 1 menu - 2 categories) standing for 2 floors.
Step 2: Create Tab 1 - Floor 1 has 2 groups: Group 1 contains 1 switch, Group 2 contains 1 chart.
Step 3: Create Tab 2 - Floor 2 has 2 groups: Group 1 contains 1 switch, Group 2 contains 1 Gauge.
Just follow red boxes and steps in order number.
 Figure: Node-Red GUI

Figure: Create Tab 1 - Floor 1
Figure: create Floor 1-Group 1-Switch
Figure: create MQTT publish when switch is pressed
Figure: create MQTT subscribe temperature sensor floor1/temp"
Figure: create a chart

Figure: deploy our model
Open Web Browser and go to the url: http://localhost:1880/ui
Our first draft:
Figure: first draft
Do similar things for Floor 2.
Change the theme to dark:
Figure: Dark theme
Our final model:
Figure: final model
Or you can import Node-Red model from script below:
[{"id":"bc6c4c2e.077c5","type":"mqtt in","z":"d4b07266.f397","name":"","topic":"floor2/temp","qos":"2","broker":"fc2a1412.370a68","x":284.5,"y":478,"wires":[["b9eef4aa.a11648"]]},{"id":"fc2a1412.370a68","type":"mqtt-broker","z":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}] 

4.2 ESP32 side
ESP32 Arduino code:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <WiFi.h>
#include <PubSubClient.h>

/* change it with your ssid-password */
const char* ssid = "dd-wrt";
const char* password = "0000000000";
/* this is the IP of PC/raspberry where you installed MQTT Server 
on Wins use "ipconfig" 
on Linux use "ifconfig" to get its IP address */
const char* mqtt_server = "192.168.1.107";
float temperature = 0;

/* create an instance of PubSubClient client */
WiFiClient espClient;
PubSubClient client(espClient);

/*LED GPIO pin*/
const char led = 4;

/* topics */
#define TEMP_TOPIC    "floor1/temp"
#define LED_TOPIC     "floor1/led" /* true=on, false=off */

long lastMsg = 0;
char msg[20];

void receivedCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.println(topic);

  Serial.print("payload: ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  /* we got '1' -> on */
  if ((char)payload[0] == 't') {
    digitalWrite(led, HIGH); 
  } else {
    /* we got '0' -> on */
    digitalWrite(led, LOW);
  }

}

void mqttconnect() {
  /* Loop until reconnected */
  while (!client.connected()) {
    Serial.print("MQTT connecting ...");
    /* client ID */
    String clientId = "ESP32Client";
    /* connect now */
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      /* subscribe topic with default QoS 0*/
      client.subscribe(LED_TOPIC);
    } else {
      Serial.print("failed, status code =");
      Serial.print(client.state());
      Serial.println("try again in 5 seconds");
      /* Wait 5 seconds before retrying */
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  /* set led as output to control led on-off */
  pinMode(led, OUTPUT);

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

  /* configure the MQTT server with IPaddress and port */
  client.setServer(mqtt_server, 1883);
  /* this receivedCallback function will be invoked 
  when client received subscribed topic */
  client.setCallback(receivedCallback);
}
void loop() {
  /* if client was disconnected then try to reconnect again */
  if (!client.connected()) {
    mqttconnect();
  }
  /* this function will listen for incomming 
  subscribed topic-process-invoke receivedCallback */
  client.loop();
  /* we measure temperature every 3 secs
  we count until 3 secs reached to avoid blocking program if using delay()*/
  long now = millis();
  if (now - lastMsg > 3000) {
    lastMsg = now;
    temperature = random(0, 40);
    if (!isnan(temperature)) {
      snprintf (msg, 20, "%lf", temperature);
      /* publish the message */
      client.publish(TEMP_TOPIC, msg);
    }
  }
}
5. Result

0 comments: