Tools

Grafana + InfluxDB: Dashboard Monitoring IoT Time-Series

TOKEN

Tutorial komprehensif membangun dashboard monitoring IoT menggunakan Grafana dan InfluxDB β€” dari instalasi hingga proyek dashboard suhu real-time lengkap

1. Mengapa Grafana + InfluxDB?

Ketika kamu membangun sistem IoT, perangkat seperti ESP32, Arduino, atau Raspberry Pi akan menghasilkan data secara terus-menerus β€” suhu setiap detik, kelembaban setiap menit, tekanan atmosfer setiap jam. Data yang berubah seiring waktu ini disebut time-series data (data deret waktu).

Menyimpan dan memvisualisasikan data time-series membutuhkan tools khusus. Di sinilah InfluxDB dan Grafana hadir sebagai kombinasi terbaik yang banyak digunakan di industri IoT.

Apa Itu InfluxDB?

InfluxDB adalah Time-Series Database (TSDB) yang dirancang khusus untuk menyimpan data berbasis waktu. Berbeda dengan database relasional seperti MySQL atau PostgreSQL, InfluxDB dioptimalkan untuk:

Apa Itu Grafana?

Grafana adalah platform visualisasi data dan monitoring open-source. Grafana tidak menyimpan data β€” ia membaca data dari berbagai sumber (InfluxDB, PostgreSQL, Prometheus, dll.) dan menampilkannya dalam bentuk grafik, gauge, table, dan panel interaktif lainnya.

Kombinasi Sempurna untuk IoT

Fitur InfluxDB Grafana
Fungsi UtamaMenyimpan data time-seriesMemvisualisasikan data
Jenis SoftwareDatabaseDashboard & Monitoring
Bahasa QueryInfluxQL / FluxMembaca dari data source
Protokol Masuk DataHTTP, MQTT, UDP, TelegrafRead-only dari data source
AlertingChecks & NotificationsAlert Rules & Contact Points
DashboardTidak adaPanel interaktif lengkap
LicenseOpen Source (MIT)Open Source (AGPL)
πŸ’‘ Contoh Use Case IoT

Monitoring Suhu Server Room: Sensor DHT22 di ruang server mengirim data suhu ke InfluxDB setiap 5 detik. Grafana menampilkan grafik real-time, gauge suhu, dan alert jika suhu melebihi 35Β°C. Teknisi dapat melihat dashboard dari HP di mana saja.

Use case lain yang cocok dengan kombinasi ini:

2. Instalasi InfluxDB 2.x

InfluxDB tersedia dalam beberapa metode instalasi. Untuk proyek IoT, kami merekomendasikan menggunakan Docker karena paling cepat dan mudah dikelola. Namun, kami juga akan membahas instalasi manual untuk server produksi.

Metode 1: Instalasi dengan Docker (Direkomendasikan)

Docker memungkinkan menjalankan InfluxDB tanpa perlu menginstal dependencies ke sistem. Cukup jalankan satu perintah:

Terminal β€” Jalankan InfluxDB via Docker
docker run -d \
  --name influxdb \
  -p 8086:8086 \
  -v influxdb-data:/var/lib/influxdb2 \
  -v influxdb-config:/etc/influxdb2 \
  -e DOCKER_INFLUXDB_INIT_MODE=setup \
  -e DOCKER_INFLUXDB_INIT_USERNAME=admin \
  -e DOCKER_INFLUXDB_INIT_PASSWORD=influxdb12345 \
  -e DOCKER_INFLUXDB_INIT_ORG=my-org \
  -e DOCKER_INFLUXDB_INIT_BUCKET=iot-data \
  -e DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-secret-token \
  influxdb:2.7

Penjelasan parameter penting:

Setelah container berjalan, akses InfluxDB UI di http://localhost:8086.

Terminal β€” Verifikasi & Cek Status
# Cek log InfluxDB
docker logs influxdb

# Cek status container
docker ps | grep influxdb

# Output yang diharapkan:
# CONTAINER ID  IMAGE         STATUS         PORTS
# a1b2c3d4e5f6  influxdb:2.7  Up 2 minutes   0.0.0.0:8086->8086/tcp

Metode 2: Instalasi Manual di Ubuntu/Debian

Terminal β€” Instalasi Manual InfluxDB 2.x
# 1. Tambah repository InfluxDB
curl --silent --location -O https://repos.influxdata.com/influxdata-archive.key
echo "943666881a1b8d9b849b74caebf02d3465d6beb716510d86a39f6c8dc8267464  influxdata-archive.key" | sha256sum --check - && cat influxdata-archive.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive.gpg > /dev/null
echo "deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive.gpg] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list

# 2. Instalasi
sudo apt-get update && sudo apt-get install influxdb2

# 3. Jalankan service
sudo systemctl enable influxdb
sudo systemctl start influxdb

# 4. Setup awal via CLI
influx setup \
  --username admin \
  --password influxdb12345 \
  --org my-org \
  --bucket iot-data \
  --retention 0 \
  --force
⚠️ Keamanan Token API

Token API yang dibuat saat setup awal bersifat admin full-access. Di lingkungan produksi, buat token terpisah dengan permission spesifik (read/write bucket tertentu) melalui UI InfluxDB β†’ API Tokens β†’ Generate API Token. Jangan pernah commit token ke repository Git!

Konsep Dasar InfluxDB

Penting untuk memahami struktur data InfluxDB sebelum mulai:

Diagram: Struktur Data InfluxDB
  Measurement: suhu_ruang
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Tag: location=server-room-1                              β”‚
  β”‚ Fields: suhu=28.5, kelembaban=72.0                      β”‚
  β”‚ Timestamp: 2026-06-20T10:30:00Z                         β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ Tag: location=server-room-2                              β”‚
  β”‚ Fields: suhu=26.3, kelembaban=65.0                      β”‚
  β”‚ Timestamp: 2026-06-20T10:30:05Z                         β”‚
  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
  β”‚ Tag: location=server-room-1                              β”‚
  β”‚ Fields: suhu=28.7, kelembaban=71.5                      β”‚
  β”‚ Timestamp: 2026-06-20T10:30:10Z                         β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Struktur: measurement,tag=value,tag=value field=value timestamp

  Bucket = Kumpulan data dengan retention policy
  Organization = Namespace untuk multi-tenant
  Token = Kunci akses API

Measurement sama dengan tabel di database relasional. Tag adalah metadata berbasis string yang diindeks untuk query cepat (contoh: lokasi sensor). Fields adalah data numerik atau string yang tidak diindeks (contoh: nilai suhu). Timestamp adalah kapan data direkam β€” ini yang membuat data "time-series".

3. Instalasi Grafana

Grafana tersedia dalam dua edisi utama: Grafana OSS (Open Source) dan Grafana Cloud (managed service). Untuk tutorial ini, kita menggunakan Grafana OSS yang dijalankan sendiri.

Metode 1: Instalasi dengan Docker (Direkomendasikan)

Terminal β€” Jalankan Grafana via Docker
docker run -d \
  --name grafana \
  -p 3000:3000 \
  -v grafana-data:/var/lib/grafana \
  -e "GF_SECURITY_ADMIN_USER=admin" \
  -e "GF_SECURITY_ADMIN_PASSWORD=grafana12345" \
  -e "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-piechart-panel" \
  grafana/grafana:latest

Setelah container berjalan, akses Grafana di http://localhost:3000 dengan username admin dan password grafana12345.

Metode 2: Instalasi Manual di Ubuntu/Debian

Terminal β€” Instalasi Manual Grafana OSS
# 1. Tambah GPG key dan repository
curl -fsSL https://apt.grafana.com/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/grafana.gpg
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list

# 2. Instalasi
sudo apt-get update
sudo apt-get install -y grafana

# 3. Jalankan service
sudo systemctl enable grafana-server
sudo systemctl start grafana-server

# 4. Cek status
sudo systemctl status grafana-server

File konfigurasi utama Grafana berada di /etc/grafana/grafana.ini. Beberapa pengaturan penting yang perlu dikonfigurasi untuk produksi:

grafana.ini β€” Pengaturan Penting
[server]
http_port = 3000
root_url = https://monitoring.example.com

[security]
admin_user = admin
admin_password = ganti_dengan_password_kuat

[auth.anonymous]
enabled = false

Docker Compose: InfluxDB + Grafana Sekaligus

Untuk menjalankan InfluxDB dan Grafana bersamaan secara otomatis, gunakan Docker Compose:

YAML β€” docker-compose.yml
version: "3.8"

services:
  influxdb:
    image: influxdb:2.7
    container_name: influxdb
    ports:
      - "8086:8086"
    volumes:
      - influxdb-data:/var/lib/influxdb2
      - influxdb-config:/etc/influxdb2
    environment:
      - DOCKER_INFLUXDB_INIT_MODE=setup
      - DOCKER_INFLUXDB_INIT_USERNAME=admin
      - DOCKER_INFLUXDB_INIT_PASSWORD=influxdb12345
      - DOCKER_INFLUXDB_INIT_ORG=my-org
      - DOCKER_INFLUXDB_INIT_BUCKET=iot-data
      - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-secret-token
    restart: unless-stopped

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=grafana12345
      - GF_INSTALL_PLUGINS=grafana-clock-panel
    depends_on:
      - influxdb
    restart: unless-stopped

volumes:
  influxdb-data:
  influxdb-config:
  grafana-data:

networks:
  default:
    name: iot-monitoring
Terminal β€” Jalankan dengan Docker Compose
# Jalankan semua service
docker compose up -d

# Cek status
docker compose ps

# Output:
# NAME       IMAGE                  STATUS         PORTS
# grafana    grafana/grafana:latest Up 5 seconds   0.0.0.0:3000->3000/tcp
# influxdb   influxdb:2.7           Up 5 seconds   0.0.0.0:8086->8086/tcp

4. Setup Data Source InfluxDB di Grafana

Grafana membutuhkan Data Source (sumber data) untuk mengetahui dari mana membaca data. Kita perlu menghubungkan Grafana ke InfluxDB agar dashboard dapat menampilkan data time-series.

Langkah-langkah Setup

  1. Buka Grafana di http://localhost:3000
  2. Login dengan username admin dan password yang sudah diatur
  3. Klik menu βš™οΈ Settings β†’ Data Sources (atau βš™οΈ β†’ Connections β†’ Data sources di Grafana versi baru)
  4. Klik tombol "Add data source"
  5. Ketik "InfluxDB" pada kolom pencarian, lalu pilih
  6. Pilih Query Language: Flux (bukan InfluxQL)
  7. Isi konfigurasi berikut:
Field Nilai Keterangan
HTTP URLhttp://influxdb:8086Gunakan influxdb jika pakai Docker Compose (sesuai nama service). Gunakan localhost jika pakai instalasi manual.
Organizationmy-orgOrganization yang dibuat saat setup InfluxDB
Tokenmy-super-secret-tokenAPI Token yang dibuat saat setup awal
Default Bucketiot-dataBucket default untuk query
HTTP MethodPOSTGunakan POST untuk query Flux
πŸ’‘ Tips: Test Koneksi

Setelah mengisi semua field, scroll ke bawah dan klik tombol "Save & test". Jika konfigurasi benar, akan muncul pesan hijau "Data source is working". Jika merah, periksa URL, token, dan pastikan container InfluxDB berjalan.

Jika Menggunakan Docker Network Terpisah

Jika InfluxDB dan Grafana berjalan di container terpisah (bukan dalam satu docker-compose), pastikan mereka berada di jaringan Docker yang sama:

Terminal β€” Buat jaringan Docker bersama
# Buat jaringan bersama
docker network create iot-monitoring

# Hubungkan container ke jaringan yang sama
docker network connect iot-monitoring influxdb
docker network connect iot-monitoring grafana

5. Membuat Dashboard: Panel, Graph, Gauge, Table

Setelah data source terkonfigurasi, saatnya membuat dashboard pertama. Dashboard di Grafana terdiri dari panel-panel β€” masing-masing menampilkan data dalam format berbeda.

Jenis Panel di Grafana

Jenis Panel Fungsi Cocok Untuk
Time SeriesGrafik garis berbasis waktuMonitor tren suhu, kelembaban, tekanan dari waktu ke waktu
GaugeIndikator analog seperti speedometerMenampilkan nilai saat ini (suhu, voltage, persentase)
StatAngka besar satu nilaiKoneksi aktif, total energi, suhu rata-rata
TableData dalam format baris & kolomDaftar sensor, log kejadian, data perangkat
Bar GaugeProgress bar horizontal/vertikalKapasitas storage, utilisasi CPU, level baterai
Pie ChartGrafik lingkaran proporsiDistribusi error, kategori kejadian

Membuat Panel Pertama: Grafik Suhu Real-Time

  1. Di halaman Grafana, klik βž• (Create) β†’ New Dashboard β†’ Add visualization
  2. Pilih Data Source InfluxDB
  3. Pada editor panel, tulis query Flux berikut:
Flux β€” Query Suhu Real-Time
from(bucket: "iot-data")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
  |> yield(name: "suhu_realtime")
  1. Panel akan menampilkan grafik garis suhu dari 1 jam terakhir
  2. Klik "Apply" di pojok kanan atas
  3. Klik "Save Dashboard" (πŸ’Ύ ikon simpan)
  4. Beri nama "IoT Monitoring Dashboard"

Menambahkan Panel Gauge

  1. Klik tombol "Add panel" (βž•) di dashboard
  2. Ubah tipe panel dari dropdown menjadi "Gauge"
  3. Tulis query untuk suhu terkini:
Flux β€” Query Suhu Terkini
from(bucket: "iot-data")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> last()
  |> yield(name: "suhu_sekarang")

Pengaturan Panel Gauge

Setelah query berjalan, konfigurasi tampilan Gauge di panel sebelah kanan:

πŸ’‘ Tips: Layout Dashboard

Klik dan drag panel untuk mengatur ukuran dan posisi. Gunakan fitur Row untuk mengelompokkan panel (misal: "Suhu Ruangan", "Kelembaban", "Status Perangkat"). Klik ikon βš™οΈ pada panel untuk edit, atau ikon πŸ—‘οΈ untuk menghapus.

6. Query Flux untuk InfluxDB

Flux adalah bahasa query functional yang digunakan di InfluxDB 2.x. Flux jauh lebih fleksibel dibanding InfluxQL (bahasa query versi lama) karena mendukung operasi multi-measurement, transformasi data, dan join antar dataset.

Sintaks Dasar Flux

Diagram: Alur Query Flux
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ from()   │───▸│ range()  │───▸│ filter() │───▸│ aggregate│───▸ yield()
  β”‚ Pilih    β”‚    β”‚ Rentang  β”‚    β”‚ Saring   β”‚    β”‚ Agregasi β”‚    Output
  β”‚ bucket   β”‚    β”‚ waktu    β”‚    β”‚ data     β”‚    β”‚ window   β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Pipe operator (|>) mengalirkan data dari satu fungsi ke fungsi berikutnya
  Seperti unix pipe (|) di terminal bash

Contoh Query Penting

Flux β€” 7 Contoh Query Berguna
// 1. Rata-rata suhu per jam
from(bucket: "iot-data")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> aggregateWindow(every: 1h, fn: mean)
  |> yield(name: "rata_rata_per_jam")

// 2. Suhu maksimum hari ini
from(bucket: "iot-data")
  |> range(start: today())
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> max()
  |> yield(name: "suhu_maks_hari_ini")

// 3. Nilai terakhir dari semua field
from(bucket: "iot-data")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> last()
  |> yield(name: "nilai_terakhir")

// 4. Suhu rata-rata per lokasi
from(bucket: "iot-data")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> group(columns: ["location"])
  |> mean()
  |> yield(name: "rata_rata_per_lokasi")

// 5. Batasi jumlah hasil (top 10)
from(bucket: "iot-data")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> sort(columns: ["_value"], desc: true)
  |> limit(n: 10)
  |> yield(name: "top_10_suhu")

// 6. Agregasi bergerak (moving average 5 data terakhir)
from(bucket: "iot-data")
  |> range(start: -6h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> movingAverage(n: 5)
  |> yield(name: "moving_average")

// 7. Transformasi ke Fahrenheit
from(bucket: "iot-data")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> map(fn: (r) => ({ r with _value: r._value * 1.8 + 32.0 }))
  |> yield(name: "suhu_fahrenheit")

Fungsi Agregasi yang Sering Digunakan

Fungsi Fungsi Contoh Penggunaan
mean()Rata-rataSuhu rata-rata per jam
min()MinimumSuhu terendah hari ini
max()MaksimumSuhu tertinggi hari ini
sum()jumlah totalTotal energi terkonsumsi
count()Jumlah data pointJumlah pembacaan sensor
stddev()Standar deviasiStabilitas pembacaan sensor
percentile()PersentilP99 latency

Fungsi Window (aggregateWindow)

Fungsi aggregateWindow() membagi data ke dalam jendela waktu sebelum mengagregasi. Parameter every menentukan ukuran jendela:

Flux β€” Contoh Window
|> aggregateWindow(every: 1m, fn: mean)   // Rata-rata per menit
|> aggregateWindow(every: 5m, fn: mean)   // Rata-rata per 5 menit
|> aggregateWindow(every: 1h, fn: mean)   // Rata-rata per jam
|> aggregateWindow(every: 1d, fn: mean)   // Rata-rata per hari

7. Alerting di Grafana

Alerting adalah fitur kritis untuk sistem monitoring IoT. Grafana memungkinkan kamu membuat aturan alert yang akan mengirim notifikasi ke email, Telegram, Slack, atau webhook saat nilai data melewati threshold tertentu.

Konsep Alerting di Grafana

Diagram: Alur Alerting Grafana
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Data    │───▸│  Alert   │───▸│  Contact │───▸│  Kirim   β”‚
  β”‚  Source   β”‚    β”‚  Rule    β”‚    β”‚  Point   β”‚    β”‚  Notif   β”‚
  β”‚  (Query)  β”‚    β”‚ (Threshold)β”‚  β”‚ (Email,  β”‚    β”‚  (HP,    β”‚
  β”‚          β”‚    β”‚          β”‚    β”‚  TG, WA)  β”‚    β”‚  Slack)  β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Evaluasi berulang setiap interval tertentu (contoh: setiap 1 menit)

Langkah 1: Buat Contact Point (Kanal Notifikasi)

  1. Buka menu Alerting β†’ Contact points
  2. Klik "Add contact point"
  3. Beri nama (misal: "Admin Telegram")
  4. Pilih tipe integrasi (Telegram, Email, Webhook, dll.)

Konfigurasi Notifikasi Email

grafana.ini β€” Konfigurasi Email SMTP
[smtp]
enabled = true
host = smtp.gmail.com:587
user = alert@kamu.com
password = app-password-gmail
from_address = alert@kamu.com
from_name = IoT Monitoring

Konfigurasi Notifikasi Telegram

Untuk Telegram, buat bot via @BotFather, dapatkan token, lalu konfigurasikan di Contact Point:

Konfigurasi Telegram Contact Point
Integration: Telegram
Bot Token: 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
Chat ID: 123456789

Langkah 2: Buat Alert Rule (Aturan Alert)

  1. Buka menu Alerting β†’ Alert rules
  2. Klik "New alert rule"
  3. Pilih Data Source InfluxDB
  4. Tulis query untuk data yang ingin dimonitor:
Flux β€” Query untuk Alert Suhu
from(bucket: "iot-data")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> last()

Langkah 3: Atur Threshold & Label

Pengaturan Nilai Keterangan
Evaluate every1mEvaluasi alert setiap 1 menit
Evaluate for5mAlert aktif jika kondisi terpenuhi selama 5 menit
Threshold> 35Alert jika suhu melebihi 35Β°C
SeverityCriticalTingkat keparahan: Warning, Critical
Summary"Suhu melebihi 35Β°C!"Pesan ringkas yang ditampilkan di notifikasi

Langkah 4: Pilih Contact Point

Setelah alert rule tersimpan, pilih contact point yang ingin menerima notifikasi (misal: "Admin Telegram"). Alert akan dikirim ketika query menghasilkan nilai > 35.

⚠️ Tips Alerting yang Baik
  • Jangan terlalu sensitif β€” atur Evaluate for minimal 5 menit untuk menghindari false alarm
  • Gunakan severity levels: Warning untuk threshold awal, Critical untuk batas atas
  • Gunakan grouping untuk menggabungkan notifikasi serupa dalam satu pesan
  • Siapkan silence rules untuk maintenance window agar alert tidak mengganggu

8. Proyek: Dashboard Monitoring Suhu IoT Lengkap

Sekarang kita akan menggabungkan semua yang telah dipelajari ke dalam proyek lengkap. Kita akan membangun sistem monitoring suhu menggunakan ESP32 + DHT22 yang mengirim data ke InfluxDB, kemudian divisualisasikan di Grafana.

Arsitektur Sistem

Diagram: Arsitektur Sistem Monitoring Suhu IoT
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     WiFi/HTTP     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚   ESP32    β”‚ ─────────────────▸ β”‚  InfluxDB   β”‚
  β”‚ + DHT22    β”‚   POST /api/v2/   β”‚  2.7        β”‚
  β”‚ Sensor     β”‚   write            β”‚  :8086      β”‚
  β”‚ :3000      β”‚                    β”‚             β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                           β”‚
                                           β”‚ Flux Query
                                           β–Ό
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚   Grafana   β”‚
                                    β”‚   Dashboard β”‚
                                    β”‚   :3000     β”‚
                                    β”‚             β”‚
                                    β”‚ πŸ“Š Grafik   β”‚
                                    β”‚ 🎯 Gauge    β”‚
                                    β”‚ πŸ“‹ Table    β”‚
                                    β”‚ πŸ”” Alert    β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                           β”‚
                                           β–Ό
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚  Notifikasi  β”‚
                                    β”‚  Telegram /  β”‚
                                    β”‚  Email       β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Bagian 1: Kode ESP32 Mengirim Data ke InfluxDB

Kode ini membuat ESP32 membaca sensor DHT22 dan mengirim data ke InfluxDB melalui HTTP API setiap 30 detik:

C++ β€” iot_monitor.ino
// IoT Temperature Monitor - ESP32 + DHT22 + InfluxDB
// BeebaneLabs - https://beebanelabs.pages.dev

#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>

// === KONFIGURASI WIFI ===
const char* WIFI_SSID = "NamaWiFi";
const char* WIFI_PASS = "PasswordWiFi";

// === KONFIGURASI INFLUXDB ===
const char* INFLUXDB_URL = "http://192.168.1.100:8086/api/v2/write";
const char* INFLUXDB_ORG = "my-org";
const char* INFLUXDB_BUCKET = "iot-data";
const char* INFLUXDB_TOKEN = "my-super-secret-token";

// === KONFIGURASI SENSOR ===
#define DHT_PIN 4
#define DHT_TYPE DHT22
#define SENSOR_LOCATION "server-room-1"
#define DEVICE_ID "esp32-001"

DHT dht(DHT_PIN, DHT_TYPE);

// Setup WiFi
void connectWiFi() {
  Serial.print("Menghubungkan WiFi: ");
  Serial.println(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("WiFi terhubung! IP: ");
  Serial.println(WiFi.localIP());
}

// Kirim data ke InfluxDB
void kirimKeInfluxDB(float suhu, float kelembaban) {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("[ERROR] WiFi terputus, mencoba reconnect...");
    connectWiFi();
    return;
  }

  HTTPClient http;
  String url = String(INFLUXDB_URL) + "?org=" + INFLUXDB_ORG 
             + "&bucket=" + INFLUXDB_BUCKET + "&precision=s";

  http.begin(url);
  http.addHeader("Authorization", "Token " + String(INFLUXDB_TOKEN));
  http.addHeader("Content-Type", "text/plain");

  // Format InfluxDB Line Protocol
  // measurement,tag=value field=value timestamp
  String payload = "suhu_ruang,location=" + String(SENSOR_LOCATION) 
                 + ",device=" + String(DEVICE_ID) 
                 + " suhu=" + String(suhu, 1) 
                 + ",kelembaban=" + String(kelembaban, 1) 
                 + " " + String(millis());

  int httpCode = http.POST(payload);

  if (httpCode == 204 || httpCode == 200) {
    Serial.print("[OK] Data terkirim: suhu=");
    Serial.print(suhu);
    Serial.print("Β°C, kelembaban=");
    Serial.print(kelembaban);
    Serial.println("%");
  } else {
    Serial.print("[ERROR] HTTP ");
    Serial.println(httpCode);
    Serial.println(http.getString());
  }

  http.end();
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("=== IoT Temp Monitor ===");

  dht.begin();
  connectWiFi();

  Serial.println("Siap mengirim data setiap 30 detik!");
}

void loop() {
  float suhu = dht.readTemperature();
  float kelembaban = dht.readHumidity();

  if (isnan(suhu) || isnan(kelembaban)) {
    Serial.println("[ERROR] Gagal membaca sensor!");
    delay(5000);
    return;
  }

  kirimKeInfluxDB(suhu, kelembaban);
  delay(30000);  // Kirim setiap 30 detik
}

Bagian 2: Membuat Dashboard Lengkap di Grafana

Berikut adalah layout dashboard yang akan kita buat dengan 6 panel:

Panel Tipe Fungsi
Suhu Saat IniGaugeMenampilkan suhu terkini dengan threshold warna
Kelembaban Saat IniGaugeMenampilkan kelembaban terkini
Tren Suhu 24 JamTime SeriesGrafik garis suhu per menit selama 24 jam
Tren Kelembaban 24 JamTime SeriesGrafik garis kelembaban per menit
Statistik HarianStatMin, Max, rata-rata suhu hari ini
Log Data TerbaruTable10 data terakhir dengan timestamp

Query Flux untuk setiap panel:

Flux β€” Query untuk Dashboard Lengkap
// === PANEL 1: Suhu Saat Ini (Gauge) ===
from(bucket: "iot-data")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> last()

// === PANEL 2: Kelembaban Saat Ini (Gauge) ===
from(bucket: "iot-data")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "kelembaban")
  |> last()

// === PANEL 3: Tren Suhu 24 Jam (Time Series) ===
from(bucket: "iot-data")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
  |> yield(name: "tren_suhu")

// === PANEL 4: Tren Kelembaban 24 Jam (Time Series) ===
from(bucket: "iot-data")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "kelembaban")
  |> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
  |> yield(name: "tren_kelembaban")

// === PANEL 5: Statistik Harian (Stat) ===
// Gunakan 3 query terpisah:
// Query A (min):
from(bucket: "iot-data")
  |> range(start: today())
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> min()
  |> yield(name: "min_suhu")

// Query B (max):
from(bucket: "iot-data")
  |> range(start: today())
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> max()
  |> yield(name: "max_suhu")

// Query C (mean):
from(bucket: "iot-data")
  |> range(start: today())
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> mean()
  |> yield(name: "mean_suhu")

// === PANEL 6: Log Data Terbaru (Table) ===
from(bucket: "iot-data")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu" or r._field == "kelembaban")
  |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> sort(columns: ["_time"], desc: true)
  |> limit(n: 10)
  |> yield(name: "log_terbaru")

Bagian 3: Setup Alert di Proyek

Buat alert rule di Grafana dengan query berikut:

Flux β€” Query Alert Suhu Kritis
from(bucket: "iot-data")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "suhu_ruang")
  |> filter(fn: (r) => r._field == "suhu")
  |> aggregateWindow(every: 1m, fn: mean)
  |> last()

Pengaturan alert:

πŸ’‘ Checklist Selesai Proyek

Pastikan semuanya berjalan:

  • βœ… ESP32 terhubung WiFi dan mengirim data ke InfluxDB
  • βœ… Data muncul di InfluxDB UI (localhost:8086 β†’ Data Explorer)
  • βœ… Grafana dashboard menampilkan 6 panel dengan data real-time
  • βœ… Alert dikirim ke Telegram/email saat suhu > 35Β°C
  • βœ… Dashboard bisa diakses dari browser HP di jaringan yang sama

9. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Grafana dan InfluxDB:

Pertanyaan 1: InfluxDB dirancang khusus untuk menyimpan data tipe apa?

a) Data relasional (tabel dengan JOIN)
b) Data time-series (data deret waktu)
c) Data dokumen (JSON-like)
d) Data graf (node & edge)

Pertanyaan 2: Di Grafana, apa yang berfungsi sebagai sumber data untuk panel dashboard?

a) Data Source yang terkonfigurasi
b) File CSV lokal
c) Database Grafana bawaan
d) API Google Sheets

Pertanyaan 3: Dalam InfluxDB, mana yang benar tentang Tag dan Field?

a) Tag dan Field sama-sama diindeks untuk query cepat
b) Field diindeks, Tag tidak diindeks
c) Tag diindeks untuk query cepat, Field tidak diindeks
d) Keduanya tidak diindeks sama sekali

Pertanyaan 4: Fungsi aggregateWindow(every: 1h, fn: mean) dalam query Flux bertujuan untuk...

a) Menghapus data yang lebih lama dari 1 jam
b) Membatasi hasil query maksimal 1 jam
c) Menghitung rata-rata data dalam jendela waktu 1 jam
d) Mengkonversi timestamp ke format 1 jam

Pertanyaan 5: Untuk menghindari false alarm pada alerting Grafana, pengaturan terbaik adalah...

a) Set Evaluate for ke 0 detik agar langsung terkirim
b) Nonaktifkan alerting sepenuhnya
c) Set Evaluate for minimal 3-5 menit agar kondisi benar-benar terpenuhi
d) Kirim alert ke semua contact point sekaligus
← Sebelumnya Node-RED untuk IoT Selanjutnya β†’ MikroTik Queue Management