â˜€ī¸Siang
Dashboard & Visualisasi

Dashboard Monitoring Real-time: Node-RED + Grafana + MQTT

TOKEN

Bangun sistem monitoring IoT real-time dari nol — dari MQTT broker hingga dashboard Grafana yang interaktif, lengkap dengan alerting otomatis

Artikel: Dashboard Monitoring Artikel: Dashboard Monitoring


1. Mengapa Dashboard Monitoring?

Di era IoT, ribuan data dihasilkan setiap detik dari sensor suhu, kelembaban, tekanan, arus listrik, dan banyak lagi. Tanpa visualisasi yang tepat, data mentah ini hanyalah angka-angka yang sulit dipahami. Dashboard monitoring real-time mengubah data mentah menjadi informasi visual yang bisa langsung ditindaklanjuti.

Bayangkan sebuah gudang penyimpanan farmasi yang membutuhkan pemantauan suhu 24/7. Jika suhu melewati batas aman, obat-obatan bisa rusak dan menimbulkan kerugian ratusan juta rupiah. Dengan dashboard monitoring real-time, petugas bisa langsung melihat perubahan suhu dari layar mana pun dan menerima notifikasi otomatis saat terjadi anomali.

Diagram: Alur Data Monitoring IoT
Alur Data Monitoring IoT

Alert (Telegram / Email)

Sensor (Edge) â–ļ

Gateway (MQTT) â–ļ

Server (InfluxDB +NR) â–ļ Dashboard (Grafana)

Manfaat Utama Dashboard Monitoring

Manfaat Penjelasan
Visibilitas Real-timeLihat kondisi sistem kapan saja dari browser mana pun tanpa akses fisik ke perangkat
Detect Anomali DiniPola grafik membantu mengidentifikasi masalah sebelum menjadi kritis
Historical AnalysisAnalisis tren data historis untuk pengambilan keputusan jangka panjang
Alerting OtomatisSistem notifikasi otomatis via Telegram, Email, atau Webhook saat threshold terlewati
SkalabilitasMenambah sensor baru tanpa mengubah arsitektur dashboard
Remote AccessPantau dari mana saja selama ada koneksi internet
💡 Mengapa Bukan Spreadsheet?

Google Sheets atau Excel memang bisa menyimpan data, tetapi tidak dirancang untuk pemantauan real-time. Spreadsheet tidak memiliki fitur alerting otomatis, refresh data otomatis, atau kemampuan menampilkan ratusan panel grafik secara bersamaan. Tool dedicated seperti Grafana dirancang khusus untuk use case ini.



2. Arsitektur Sistem

Sistem dashboard monitoring yang kita bangun terdiri dari empat komponen utama yang saling terhubung: MQTT Broker sebagai pusat komunikasi, Node-RED sebagai middleware pemrosesan data, InfluxDB sebagai database time-series, dan Grafana sebagai platform visualisasi.

Diagram: Arsitektur Lengkap Dashboard Monitoring

SERVER / RASPBERRY PI

InfluxDB 2.x ("Port: 8086") Database: iot_sensors...

Mosquitto MQTT Broker ("Port: 1883 / 8883 TLS")

Node-RED (Port 1880) Flow: - Parse JSON - Valid...

Grafana (Port 3000) Datasources: - InfluxDB - MQTT

Peran Setiap Komponen

Komponen Peran Port Default Bahasa
MosquittoMQTT Broker — menerima & meneruskan pesan antara publisher dan subscriber1883 (TCP), 8883 (TLS)C
Node-REDMiddleware visual — menerima data MQTT, memproses, dan menyimpan ke database1880JavaScript (Node.js)
InfluxDBDatabase time-series — menyimpan data sensor dengan timestamp presisi tinggi8086Go
GrafanaPlatform visualisasi — menampilkan grafik, gauge, table, dan alert3000Go + JavaScript
â„šī¸ Mengapa InfluxDB, bukan MySQL/PostgreSQL?

InfluxDB adalah database yang dioptimalkan untuk data time-series — data yang memiliki timestamp. Query seperti "ambil rata-rata suhu selama 1 jam terakhir" jauh lebih cepat di InfluxDB dibanding relational database. Selain itu, fitur retention policy memudahkan otomatisasi penghapusan data lama.



3. Setup MQTT Broker (Mosquitto)

Eclipse Mosquitto adalah broker MQTT open-source yang ringan dan populer. Mosquitto mendukung MQTT 3.1.1 dan 5.0, menjadikannya pilihan standar untuk proyek-proyek IoT. Kita akan menginstalnya di Raspberry Pi atau server Linux.

Instalasi Mosquitto di Ubuntu/Debian

Flow: MQTT → Parse → InfluxDB
Diagram

JSON Parse msg. payload → object

Range Check Validate data

InfluxDB Out Bucket: iot_data

Konfigurasi Node-RED Flow (JSON)

Copy kode JSON berikut dan import ke Node-RED via menu Import → Clipboard:

Diagram: Alur Alert Grafana
Alur Alert Grafana

InfluxDB Query suhu 35? â–ļ

Grafana Rule Eval Every 1m â–ļ Alert Notif. - Ema...

Telegram Bot Msg 'âš ī¸ Suhu 37.2°C!'



7. Proyek: Dashboard Suhu & Kelembaban Real-time

Sekarang kita akan menggabungkan seluruh komponen ke dalam satu proyek utuh. Pastikan Mosquitto, Node-RED, InfluxDB, dan Grafana sudah terinstal dan berjalan di server yang sama (atau Raspberry Pi).

Step 1: Kode ESP32 untuk Proyek

ESP32 akan membaca sensor DHT22 dan mengirim data ke MQTT broker setiap 10 detik:

C++ — esp32_monitoring.ino
#include "WiFi.h"
#include "PubSubClient.h"
#include "DHT.h"

#define DHT_PIN 4
#define DHT_TYPE DHT22

const char* WIFI_SSID = "NamaWiFi";
const char* WIFI_PASS = "PasswordWiFi";
const char* MQTT_SERVER = "192.168.1.100";
const int   MQTT_PORT = 1883;
const char* MQTT_TOPIC = "iot/sensor/esp32_01";

DHT dht(DHT_PIN, DHT_TYPE);
WiFiClient espClient;
PubSubClient mqtt(espClient);

void setup() {
  Serial.begin(115200);
  dht.begin();
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  mqtt.setServer(MQTT_SERVER, MQTT_PORT);
}

void loop() {
  if (!mqtt.connected()) {
    mqtt.connect("esp32_01", "iotuser", "iotpass");
  }
  mqtt.loop();

  float suhu = dht.readTemperature();
  float rh = dht.readHumidity();
  if (!isnan(suhu) && !isnan(rh)) {
    char payload[128];
    snprintf(payload, sizeof(payload),
      "{\"suhu\":%.1f,\"kelembaban\":%.1f,\"rssi\":%d}",
      suhu, rh, WiFi.RSSI());
    mqtt.publish(MQTT_TOPIC, payload);
    Serial.println(payload);
  }
  delay(10000);
}

Step 2: Import Flow Node-RED

Buka Node-RED di http://<IP>:1880, lalu import flow lengkap berikut:

JSON — Node-RED Full Flow
[
    {
        "id": "dashboard_flow",
        "type": "tab",
        "label": "IoT Dashboard Flow",
        "disabled": false,
        "info": "Flow lengkap untuk dashboard monitoring IoT"
    },
    {
        "id": "mqtt_in_all",
        "type": "mqtt in",
        "z": "dashboard_flow",
        "name": "All Sensor Data",
        "topic": "iot/sensor/+",
        "qos": "1",
        "datatype": "auto",
        "broker": "mosquitto_local",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "wires": [["func_validate", "debug_raw"]]
    },
    {
        "id": "func_validate",
        "type": "function",
        "z": "dashboard_flow",
        "name": "Validate & Transform",
        "func": "// Extract device ID dari topik\nvar deviceId = msg.topic.split('/').pop();\nvar data = msg.payload;\n\n// Validasi data\nif (!data.suhu || !data.kelembaban) {\n    node.warn('Invalid data dari ' + deviceId);\n    return null;\n}\n\n// Siapkan untuk InfluxDB\nmsg.payload = [{\n    measurement: 'sensor_reading',\n    tags: { device_id: deviceId },\n    fields: {\n        suhu: parseFloat(data.suhu),\n        kelembaban: parseFloat(data.kelembaban)\n    }\n}];\nmsg.topic = '';\n\n// Duplikat untuk threshold check\nvar msg2 = {\n    payload: data,\n    device_id: deviceId\n};\n\nreturn [msg, msg2];",
        "outputs": 2,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "wires": [["influx_write", "func_threshold"]]
    },
    {
        "id": "influx_write",
        "type": "influxdb out",
        "z": "dashboard_flow",
        "influxdb": "influxdb_01",
        "name": "Write InfluxDB",
        "precision": "ms",
        "retentionPolicy": "",
        "database": "",
        "precision": "ms",
        "retentionPolicy": "",
        "wires": []
    },
    {
        "id": "func_threshold",
        "type": "function",
        "z": "dashboard_flow",
        "name": "Threshold Check",
        "func": "var data = msg.payload;\nif (data.suhu > 35) {\n    node.warn('ALERT: Suhu ' + data.suhu + '°C dari ' + msg.device_id);\n    msg.payload = {\n        alert: 'HIGH_TEMPERATURE',\n        suhu: data.suhu,\n        device: msg.device_id,\n        timestamp: new Date().toISOString()\n    };\n    return msg;\n}\nreturn null;",
        "outputs": 1,
        "wires": [["mqtt_alert_out"]]
    },
    {
        "id": "mqtt_alert_out",
        "type": "mqtt out",
        "z": "dashboard_flow",
        "name": "Publish Alert",
        "topic": "iot/alert",
        "qos": "0",
        "retain": "false",
        "broker": "mosquitto_local",
        "wires": []
    },
    {
        "id": "mosquitto_local",
        "type": "mqtt-broker",
        "name": "Mosquitto",
        "broker": "127.0.0.1",
        "port": "1883",
        "clientid": "nodered",
        "autoConnect": true,
        "usetls": false,
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "nodered/status",
        "birthQos": "0",
        "birthPayload": "online",
        "willTopic": "nodered/status",
        "willQos": "0",
        "willPayload": "offline"
    },
    {
        "id": "influxdb_01",
        "type": "influxdb",
        "hostname": "127.0.0.1",
        "port": "8086",
        "protocol": "http",
        "dbname": "",
        "name": "InfluxDB IoT",
        "influxdbVersion": "2.0",
        "url": "http://127.0.0.1:8086",
        "rejectUnauthorized": true
    }
]

Step 3: Import Dashboard Grafana

Buka Grafana → ➕ → Import Dashboard → paste JSON berikut:

JSON — Grafana Dashboard
{
  "title": "IoT Monitoring Dashboard",
  "tags": ["iot", "sensor", "suhu"],
  "timezone": "Asia/Jakarta",
  "panels": [
    {
      "title": "Suhu Saat Ini",
      "type": "gauge",
      "fieldConfig": {
        "defaults": {
          "thresholds": {
            "steps": [
              {"color": "green", "value": null},
              {"color": "yellow", "value": 30},
              {"color": "red", "value": 35}
            ]
          },
          "unit": "celsius",
          "min": 15,
          "max": 50
        }
      },
      "targets": [{
        "query": "from(bucket:\"iot_sensors\") |> range(start:-1h) |> filter(fn:(r) => r._measurement==\"sensor_reading\") |> filter(fn:(r) => r._field==\"suhu\") |> last()"
      }]
    },
    {
      "title": "Grafik Suhu 24 Jam",
      "type": "timeseries",
      "fieldConfig": {
        "defaults": {
          "unit": "celsius",
          "custom": {"drawStyle": "line", "fillOpacity": 10}
        }
      },
      "targets": [{
        "query": "from(bucket:\"iot_sensors\") |> range(start:-24h) |> filter(fn:(r) => r._measurement==\"sensor_reading\") |> filter(fn:(r) => r._field==\"suhu\") |> aggregateWindow(every:5m, fn:mean)"
      }]
    },
    {
      "title": "Kelembaban Saat Ini",
      "type": "stat",
      "fieldConfig": {
        "defaults": {
          "unit": "percent",
          "thresholds": {
            "steps": [
              {"color": "yellow", "value": null},
              {"color": "green", "value": 40},
              {"color": "red", "value": 80}
            ]
          }
        }
      },
      "targets": [{
        "query": "from(bucket:\"iot_sensors\") |> range(start:-1h) |> filter(fn:(r) => r._measurement==\"sensor_reading\") |> filter(fn:(r) => r._field==\"kelembaban\") |> last()"
      }]
    },
    {
      "title": "Status Device",
      "type": "table",
      "targets": [{
        "query": "from(bucket:\"iot_sensors\") |> range(start:-1h) |> filter(fn:(r) => r._measurement==\"sensor_reading\") |> last() |> pivot(rowKey:[\"_time\"], columnKey:[\"_field\"], valueColumn:\"_value\")"
      }]
    }
  ],
  "time": {"from": "now-24h", "to": "now"},
  "refresh": "30s"
}

Step 4: Verifikasi Seluruh Sistem

â„šī¸ Checklist Verifikasi
  1. ✅ Mosquitto berjalan: sudo systemctl status mosquitto
  2. ✅ InfluxDB berjalan: curl http://localhost:8086/health
  3. ✅ Node-RED berjalan: akses http://<IP>:1880
  4. ✅ Grafana berjalan: akses http://<IP>:3000
  5. ✅ Data MQTT mengalir: cek debug panel Node-RED
  6. ✅ Data terimpan di InfluxDB: cek via InfluxDB UI atau CLI
  7. ✅ Dashboard Grafana menampilkan data real-time
  8. ✅ Alert berfungsi: simulasikan suhu tinggi


8. Optimasi & Maintenance

Sistem monitoring yang berjalan 24/7 membutuhkan perhatian khusus dari sisi performa dan maintenance. Berikut adalah tips optimasi untuk menjaga sistem tetap stabil dan efisien.

Optimasi Performa

Area Optimasi Dampak
InfluxDBGunakan retention policy < 30 hari untuk data high-frequencyHemat disk 70-80%
InfluxDBAktifkan compression (TSM engine default)Ukuran data turun 5-10x
GrafanaGunakan aggregateWindow() untuk range > 1 jamQuery 10x lebih cepat
Node-REDGunakan batch write ke InfluxDB alih-alih per-pesanMengurangi I/O 50%
MQTTAtur QoS = 0 untuk data non-kritisMengurangi overhead jaringan
ServerPisahkan InfluxDB ke volume SSD terpisahWrite latency turun 3x

Cron Job Maintenance

Bash — Maintenance Scripts
# Backup InfluxDB (via cron daily)
influx backup /backups/influxdb_$(date +%Y%m%d) --org iotlab

# Cleanup backup lama (hapus backup > 7 hari)
find /backups -name "influxdb_*" -mtime +7 -exec rm -rf {} \;

# Monitor disk usage
df -h /var/lib/influxdb

# Cek log errors
sudo journalctl -u mosquitto --since "1 hour ago" --priority=3
sudo journalctl -u influxdb --since "1 hour ago" --priority=3
sudo journalctl -u grafana-server --since "1 hour ago" --priority=3

Monitoring Layanan (Systemd)

Gunakan systemd untuk memastikan semua service otomatis restart jika crash:

Bash — Service Status & Auto-restart
# Cek status semua service
echo "=== Mosquitto ===" && sudo systemctl is-active mosquitto
echo "=== InfluxDB ===" && sudo systemctl is-active influxdb
echo "=== Grafana  ===" && sudo systemctl is-active grafana-server
echo "=== Node-RED ===" && systemctl --user is-active nodered

# Restart semua service
sudo systemctl restart mosquitto influxdb grafana-server
systemctl --user restart nodered

# Auto-restart (sudah default di systemd, tapi pastikan):
# Edit /lib/systemd/system/mosquitto.service
# Tambahkan: Restart=always, RestartSec=10
âš ī¸ Tips Penting

Selalu backup InfluxDB secara rutin. Database time-series bisa tumbuh sangat cepat jika volume data tinggi. Pastikan disk space minimal 20% kosong. Gunakan logrotate untuk rotasi log file Mosquitto dan Grafana agar tidak memenuhi disk.



9. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang dashboard monitoring IoT:

Pertanyaan 1: Komponen apa yang berfungsi sebagai middleware visual untuk menghubungkan MQTT ke InfluxDB dalam arsitektur dashboard monitoring?

a) Grafana
b) Node-RED
c) Mosquitto
d) Prometheus

Pertanyaan 2: Port default apa yang digunakan oleh Mosquitto MQTT Broker untuk koneksi TCP tanpa TLS?

a) 1883
b) 8883
c) 3000
d) 1880

Pertanyaan 3: InfluxDB adalah database yang dioptimalkan khusus untuk tipe data apa?

a) Document store (JSON)
b) Key-value pairs
c) Relational (SQL)
d) Time-series

Pertanyaan 4: Untuk mengimpor flow dari JSON ke Node-RED, menu apa yang harus digunakan?

a) Deploy → Import
b) Edit → Paste
c) Import → Clipboard
d) File → Import

Pertanyaan 5: Apa fungsi retention policy di InfluxDB?

a) Menentukan jumlah maksimum kolom per tabel
b) Menentukan berapa lama data disimpan sebelum otomatis dihapus
c) Mengatur kecepatan write data ke disk
d) Membatasi jumlah query per jam
🔍 Zoom
100%
🎨 Tema