1. Raspberry Pi untuk IoT
Raspberry Pi adalah komputer berukuran kartu kredit yang dikembangkan oleh Raspberry Pi Foundation di Inggris. Awalnya dirancang untuk pendidikan komputasi, Raspberry Pi kini menjadi salah satu platform paling populer untuk proyek Internet of Things (IoT) karena kombinasi performa komputer sungguhan, harga terjangkau, dan ekosistem komunitas yang luas.
Berbeda dengan ESP32 atau Arduino yang merupakan mikrokontroler, Raspberry Pi menjalankan sistem operasi lengkap (Linux). Ini artinya Anda bisa menjalankan Python, Node.js, database, web server, bahkan container Docker dalam satu perangkat kecil β menjadikannya ideal sebagai gateway IoT atau edge computing node.
Raspberry Pi memiliki prosesor ARM multi-core, RAM hingga 8 GB, WiFi bilt-in, Bluetooth, GPIO, dan dukungan USB. Dengan kekuatan komputasi ini, Anda bisa mengumpulkan data dari banyak sensor, memprosesnya, menyimpan ke database, dan menampilkan dashboard web β semuanya dalam satu perangkat.
Model Raspberry Pi untuk IoT
| Model | Prosesor | RAM | WiFi | Harga (Rp) | Cocok Untuk |
|---|---|---|---|---|---|
| Raspberry Pi 5 (4GB) | BCM2712 Quad-Core A76 @ 2.4GHz | 4 GB | WiFi 5 + BT 5.0 | ~900rb | Gateway, server, heavy processing |
| Raspberry Pi 5 (8GB) | BCM2712 Quad-Core A76 @ 2.4GHz | 8 GB | WiFi 5 + BT 5.0 | ~1.2jt | Server lengkap, database besar |
| Raspberry Pi 4B (4GB) | BCM2711 Quad-Core A72 @ 1.5GHz | 4 GB | WiFi 5 + BT 5.0 | ~650rb | Gateway, dashboard, relai data |
| Raspberry Pi 3B+ | BCM2837 Quad-Core A53 @ 1.4GHz | 1 GB | WiFi 5 + BT 4.2 | ~400rb | Sensor sederhana, belajar |
| Raspberry Pi Zero 2W | BCM2710A1 Quad-Core A53 @ 1GHz | 512 MB | WiFi 4 + BT 4.2 | ~300rb | Node sensor ringan, portable |
Perbandingan: Raspberry Pi vs Arduino vs ESP32
| Fitur | Raspberry Pi 4 | ESP32 | Arduino Uno |
|---|---|---|---|
| Jenis | SBC (Single Board Computer) | Mikrokontroler SoC | Mikrokontroler |
| Prosesor | Quad-Core 1.5GHz | Dual-Core 240MHz | Single-Core 16MHz |
| RAM | 1-8 GB | 520 KB | 2 KB |
| Sistem Operasi | Linux (full) | Tanpa OS bare-metal | Tanpa OS bare-metal |
| WiFi | β Built-in | β Built-in | β Perlu shield |
| GPIO | 26 pin (3.3V) | 34 pin (3.3V) | 14 digital + 6 analog (5V) |
| Konsumsi Daya | ~700 mA (idle) | ~80 mA (WiFi on) | ~50 mA |
| Harga (Rp) | ~650rb | ~45rb | ~70rb |
| Cocok untuk | Server, gateway, dashboard | Node sensor, edge IoT | Kontrol sederhana |
Pilih Raspberry Pi jika membutuhkan komputasi berat (proses data, database, web server), menjalankan banyak layanan bersamaan, atau menjadi gateway untuk mengumpulkan data dari banyak node sensor (ESP32/Arduino). Pilih ESP32/Arduino untuk node sensor individual yang hemat daya.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β ARSITEKTUR IoT SYSTEM β β β β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β β β ESP32 β β ESP32 β β ESP8266 β β Arduino β β β β Sensor β β Sensor β β Sensor β β Sensor β β β β DHT22 β β Ultrasonicβ β Relay β β PIR β β β ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ β β β MQTT β MQTT β MQTT β MQTT β β ββββββββββββββ΄βββββββββββββ΄βββββββββββββ β β β β β ββββββ΄βββββ β β β MQTT β β β β Broker β β β β (Mosquitto)β β β ββββββ¬βββββ β β β β β ββββββββββββ΄βββββββββββ β β β RASPBERRY PI 4 β β β β β β β β βββββββββββββββββ β β β β β Python Script β β β Subscriber MQTT β β β βββββββββ¬ββββββββ β β β β β β β β β βββββββββ΄ββββββββ β β β β β SQLite / JSON β β β Penyimpanan Data β β β βββββββββ¬ββββββββ β β β β β β β β β βββββββββ΄ββββββββ β β β β β Flask Server β β β Dashboard Web β β β β (Port 5000) β β β β β βββββββββ¬ββββββββ β β β β β β β β ββββββββββββΌβββββββββββ β β β WiFi / Ethernet β β ββββββ΄βββββ β β β Browser β β User melihat Dashboard β β βββββββββββ β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2. Setup Raspberry Pi OS
Raspberry Pi OS (sebelumnya Raspbian) adalah sistem operasi berbasis Debian yang dioptimalkan untuk perangkat Raspberry Pi. Untuk proyek IoT, kita akan menggunakan Raspberry Pi OS Lite (tanpa desktop) agar ringan dan hemat resource.
Langkah 1: Download dan Flash OS
- Kunjungi https://www.raspberrypi.com/software/
- Download Raspberry Pi Imager untuk Windows/Mac/Linux
- Buka Raspberry Pi Imager
- Klik Choose OS β Raspberry Pi OS (other) β Raspberry Pi OS Lite (64-bit)
- Klik Choose Storage, pilih microSD card Anda
- Klik ikon βοΈ gear untuk mengatur pre-config (opsional tapi disarankan)
- Klik Write dan tunggu hingga selesai
Gunakan menu gear di Raspberry Pi Imager untuk mengatur hostname, WiFi, dan SSH sebelum flashing. Ini memungkinkan Anda mengakses Pi tanpa monitor dan keyboard (headless setup).
Langkah 2: Boot dan Akses via SSH
Setelah microSD card ter-flash, masukkan ke Raspberry Pi, colok power supply, dan tunggu sekitar 1-2 menit untuk boot pertama kali.
# Akses Raspberry Pi dari komputer lain via SSH ssh pi@raspberrypi.local # Atau gunakan IP address langsung ssh pi@192.168.1.100 # Password default: raspberry (HARUS diubah!) # Pada versi baru, password di-set saat flashing via Imager
Langkah 3: Update dan Install Paket Dasar
# Update daftar paket sudo apt update && sudo apt upgrade -y # Install paket dasar untuk IoT sudo apt install -y python3-pip python3-venv git curl # Install library GPIO untuk Python pip3 install RPi.GPIO gpiozero # Install paho-mqtt untuk MQTT client pip3 install paho-mqtt # Install Flask untuk web server pip3 install flask # Verifikasi semua terinstal python3 --version pip3 --version
Langkah 4: Aktifkan Interface GPIO
# Jalankan Raspberry Pi Configuration Tool sudo raspi-config # Navigasi: Interface Options β I2C β Enable # Navigasi: Interface Options β SPI β Enable # Navigasi: Interface Options β SSH β Enable # Navigasi: Interface Options β Serial Port β # Login shell over serial: No # Serial port hardware enabled: Yes # Reboot setelah perubahan sudo reboot
3. GPIO di Raspberry Pi
GPIO (General Purpose Input/Output) adalah pin pada Raspberry Pi yang bisa dikonfigurasi sebagai input maupun output digital. Raspberry Pi 4 memiliki 40 pin GPIO yang tersusun dalam dua baris. Dari total 40 pin, terdapat 26 GPIO yang bisa diprogram, sementara sisanya adalah pin power (3.3V, 5V, GND).
GPIO Raspberry Pi beroperasi pada tegangan 3.3V, bukan 5V seperti Arduino. Memberikan input 5V langsung ke pin GPIO akan merusak Raspberry Pi secara permanen. Gunakan logic level converter jika perlu berkomunikasi dengan perangkat 5V.
Pinout Raspberry Pi 4
| Pin (BCM) | Fisik (BOARD) | Fungsi Default | Keterangan |
|---|---|---|---|
| GPIO 2 | 3 | I2C SDA | Data I2C, juga bisa GPIO |
| GPIO 3 | 5 | I2C SCL | Clock I2C, juga bisa GPIO |
| GPIO 4 | 7 | GPIO | Umum, sering dipakai untuk DHT |
| GPIO 14 | 8 | UART TX | Serial transmit |
| GPIO 15 | 10 | UART RX | Serial receive |
| GPIO 17 | 11 | GPIO | Input/Output umum |
| GPIO 18 | 12 | PWM / GPIO | PWM0 untuk kontrol servo |
| GPIO 27 | 13 | GPIO | Input/Output umum |
| GPIO 22 | 15 | GPIO | Input/Output umum |
| GPIO 23 | 16 | GPIO | Input/Output umum |
| GPIO 24 | 18 | GPIO | Input/Output umum |
| GPIO 25 | 22 | GPIO | Input/Output umum |
| GPIO 10 (MOSI) | 19 | SPI | SPI Data Out |
| GPIO 9 (MISO) | 21 | SPI | SPI Data In |
Raspberry Pi 4 GPIO Header (Tampak Atas)
3.3V (1) (2) 5V
GPIO 2 (3) (4) 5V
GPIO 3 (5) (6) GND
GPIO 4 (7) (8) GPIO 14 β TX
GND (9) (10) GPIO 15 β RX
GPIO 17 (11) (12) GPIO 18 β PWM0
GPIO 27 (13) (14) GND
GPIO 22 (15) (16) GPIO 23
3.3V (17) (18) GPIO 24
GPIO 10 (19) (20) GND β MOSI
GPIO 9 (21) (22) GPIO 25 β MISO
GPIO 11 (23) (24) GPIO 8 β SCLK
GND (25) (26) GPIO 7 β CE0
GPIO 0 (27) (28) GPIO 1
GPIO 5 (29) (30) GND
GPIO 6 (31) (32) GPIO 12
GPIO 13 (33) (34) GND
GPIO 19 (35) (36) GPIO 16
GPIO 26 (37) (38) GPIO 20
3.3V (39) (40) GPIO 21
Pin merah = Power (3.3V / 5V)
Pin hitam = Ground (GND)
Pin hijau = GPIO (General Purpose)
Pin kuning = Alternatif fungsi (SPI, I2C, UART)
Program GPIO dengan Python (RPi.GPIO)
Ada dua library utama untuk GPIO di Raspberry Pi: RPi.GPIO (populer, low-level) dan gpiozero (lebih tinggi tingkat abstraksinya). Kita akan memulai dengan RPi.GPIO untuk pemahaman fundament.
#!/usr/bin/env python3
# Program LED Blink di Raspberry Pi
# IoTHub - https://iothub.id
import RPi.GPIO as GPIO
import time
# Konfigurasi GPIO
LED_PIN = 17 # GPIO 17 (fisik pin 11)
GPIO.setmode(GPIO.BCM) # Gunakan penomoran BCM
GPIO.setup(LED_PIN, GPIO.OUT) # Set sebagai output
print("LED Blink dimulai! Tekan Ctrl+C untuk berhenti.")
try:
while True:
GPIO.output(LED_PIN, GPIO.HIGH) # Nyalakan LED
print("LED ON")
time.sleep(1)
GPIO.output(LED_PIN, GPIO.LOW) # Matikan LED
print("LED OFF")
time.sleep(1)
except KeyboardInterrupt:
print("\nProgram dihentikan.")
finally:
GPIO.cleanup() # Selalu bersihkan GPIO saat selesai
Membaca Input GPIO (Tombol)
#!/usr/bin/env python3
# Membaca status tombol dari GPIO
# IoTHub - https://iothub.id
import RPi.GPIO as GPIO
import time
TOMBOL_PIN = 27 # GPIO 27 (fisik pin 13)
LED_PIN = 17 # GPIO 17 (fisik pin 11)
GPIO.setmode(GPIO.BCM)
GPIO.setup(TOMBOL_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(LED_PIN, GPIO.OUT)
print("Tahan tombol untuk menyalakan LED. Tekan Ctrl+C untuk berhenti.")
try:
while True:
# Tombol aktif-low (pressed = LOW)
if GPIO.input(TOMBOL_PIN) == GPIO.LOW:
print("Tombol DITEKAN β LED ON")
GPIO.output(LED_PIN, GPIO.HIGH)
else:
print("Tombol LEPAS β LED OFF")
GPIO.output(LED_PIN, GPIO.LOW)
time.sleep(0.1)
except KeyboardInterrupt:
print("\nProgram dihentikan.")
finally:
GPIO.cleanup()
4. Membaca Sensor dengan Python
Salah satu keunggulan Raspberry Pi untuk IoT adalah kemampuan Python-nya yang kaya library. Kita akan membahas cara membaca dua sensor populer: DHT22 (suhu & kelembaban) dan HC-SR04 (ultrasonic jarak).
Sensor DHT22 (Suhu & Kelembaban)
DHT22 memiliki rentang suhu -40Β°C hingga 80Β°C dengan akurasi Β±0.5Β°C, lebih baik dari DHT11 (0-50Β°C, Β±2Β°C). DHT22 juga lebih cepat dalam pembacaan data. Untuk proyek IoT serius, DHT22 sangat direkomendasikan.
Raspberry Pi DHT22
ββββββββββββββββ ββββββββββββ
β β β ββββββββ β
β 3.3V (1)ββββββββ€1β VCC β β
β β β β β β
β GPIO 4 (7) ββββββββ€2β DATA β β
β β β β β β [10kΞ© pull-up]
β β β β NC β3β dari VCC ke DATA
β GND ββββββββ€4β GND β β
β β β ββββββββ β
ββββββββββββββββ ββββββββββββ
Catatan: Resistor 10kΞ© antara VCC dan DATA pin.
#!/usr/bin/env python3
# Membaca Sensor Suhu & Kelembaban DHT22
# IoTHub - https://iothub.id
# Install: pip3 install adafruit-circuitpython-dht
# Jalankan: sudo python3 baca_dht22.py (butuh akses GPIO)
import adafruit_dht
import board
import time
# Inisialisasi sensor DHT22 pada GPIO4
dht = adafruit_dht.DHT22(board.D4)
print("=== Pembaca Sensor DHT22 ===")
print("Membaca data setiap 5 detik...")
try:
while True:
try:
suhu = dht.temperature
kelembaban = dht.humidity
if suhu is not None and kelembaban is not None:
print(f"Suhu : {suhu:.1f} Β°C")
print(f"Kelembaban : {kelembaban:.1f} %")
# Hitung Heat Index sederhana
if suhu > 27 and kelembaban > 40:
heat_index = (
suhu + (kelembaban - 40) * 0.1
)
print(f"Indeks Panas: {heat_index:.1f} Β°C")
print("---")
else:
print("[WARN] Gagal membaca data sensor")
except RuntimeError as e:
print(f"[ERROR] {e}")
time.sleep(5)
except KeyboardInterrupt:
print("\nPembacaan dihentikan.")
finally:
dht.exit()
Sensor HC-SR04 (Ultrasonic Jarak)
Sensor ultrasonic HC-SR04 mengukur jarak dengan mengirim gelombang suara dan mengukur waktu pantulan. Jangkauan pengukuran 2cm - 400cm dengan akurasi Β±3mm.
#!/usr/bin/env python3
# Membaca Jarak dengan Sensor Ultrasonic HC-SR04
# IoTHub - https://iothub.id
import RPi.GPIO as GPIO
import time
# Konfigurasi Pin
TRIG_PIN = 23 # GPIO 23 (fisik pin 16) - Trigger
ECHO_PIN = 24 # GPIO 24 (fisik pin 18) - Echo
GPIO.setmode(GPIO.BCM)
GPIO.setup(TRIG_PIN, GPIO.OUT)
GPIO.setup(ECHO_PIN, GPIO.IN)
def baca_jarak():
"""Mengukur jarak dalam cm."""
# Kirim pulse trigger
GPIO.output(TRIG_PIN, GPIO.HIGH)
time.sleep(0.00001) # 10 microdetik
GPIO.output(TRIG_PIN, GPIO.LOW)
# Tunggu echo
awal_waktu = time.time()
while GPIO.input(ECHO_PIN) == GPIO.LOW:
awal_waktu = time.time()
akhir_waktu = time.time()
while GPIO.input(ECHO_PIN) == GPIO.HIGH:
akhir_waktu = time.time()
# Hitung jarak
# Kecepatan suara = 34300 cm/s
# Waktu bolak-balik dibagi 2
durasi = akhir_waktu - awal_waktu
jarak = (durasi * 34300) / 2
return round(jarak, 2)
print("=== Sensor Ultrasonic HC-SR04 ===")
print("Arahkan sensor ke objek. Tekan Ctrl+C untuk berhenti.\n")
try:
while True:
jarak = baca_jarak()
if 2 <= jarak <= 400:
print(f"Jarak terukur: {jarak} cm")
else:
print("[INFO] Objek di luar jangkauan sensor")
time.sleep(0.5)
except KeyboardInterrupt:
print("\nPembacaan dihentikan.")
finally:
GPIO.cleanup()
5. MQTT Subscriber di Raspberry Pi
MQTT (Message Queuing Telemetry Transport) adalah protokol komunikasi ringan yang dirancang khusus untuk IoT. Raspberry Pi berperan sebagai subscriber (penerima data) yang mendengarkan pesan dari berbagai sensor (ESP32, ESP8266) yang terhubung ke MQTT broker yang sama.
Pertama-tama, kita perlu menginstal Mosquitto (MQTT broker) langsung di Raspberry Pi untuk memudahkan pengujian:
# Install Mosquitto broker dan client
sudo apt install -y mosquitto mosquitto-clients
# Aktifkan Mosquitto agar berjalan otomatis
sudo systemctl enable mosquitto
sudo systemctl start mosquitto
# Verifikasi layanan berjalan
sudo systemctl status mosquitto
# Test manual dengan Mosquitto client
# Terminal 1: Subscriber
mosquitto_sub -h localhost -t "iot/sensor/#"
# Terminal 2: Publisher (kirim test message)
mosquitto_pub -h localhost -t "iot/sensor/dht22" -m '{"suhu":29.5,"kelembaban":72}'
Program MQTT Subscriber dalam Python
#!/usr/bin/env python3
# MQTT Subscriber untuk Raspberry Pi
# IoTHub - https://iothub.id
import paho.mqtt.client as mqtt
import json
import time
from datetime import datetime
# Konfigurasi MQTT
BROKER_HOST = "localhost" # Atau IP broker eksternal
BROKER_PORT = 1883
TOPIC = "iot/sensor/#" # Wildcard: terima semua topik sensor
# Callback saat terhubung ke broker
def on_connect(client, userdata, flags, rc):
if rc == 0:
print(f"[{timestamp()}] Terhubung ke MQTT Broker!")
client.subscribe(TOPIC)
print(f"[{timestamp()}] Subscribe ke topik: {TOPIC}")
else:
print(f"[{timestamp()}] Gagal koneksi, kode error: {rc}")
# Callback saat menerima pesan
def on_message(client, userdata, msg):
topik = msg.topic
payload = msg.payload.decode("utf-8")
print(f"\n{'='*50}")
print(f"[{timestamp()}] Pesan diterima!")
print(f" Topik : {topik}")
# Coba parse sebagai JSON
try:
data = json.loads(payload)
print(f" Data :")
for k, v in data.items():
print(f" {k}: {v}")
except json.JSONDecodeError:
print(f" Data : {payload}")
print(f"{'='*50}")
def timestamp():
return datetime.now().strftime("%H:%M:%S")
# Inisialisasi client
client = mqtt.Client(
client_id="raspi-gateway-01",
protocol=mqtt.MQTTv311
)
client.on_connect = on_connect
client.on_message = on_message
print("=== MQTT Subscriber Raspberry Pi ===")
print(f"Menghubungkan ke {BROKER_HOST}:{BROKER_PORT}...")
try:
client.connect(BROKER_HOST, BROKER_PORT, keepalive=60)
client.loop_forever() # Loop tak hingga, handle pesan
except KeyboardInterrupt:
print(f"\n[{timestamp()}] Disconnect dari broker.")
client.disconnect()
except ConnectionRefusedError:
print(f"[ERROR] Tidak bisa terhubung ke broker!")
print("Pastikan Mosquitto berjalan: sudo systemctl start mosquitto")
6. Web Server Flask untuk Dashboard
Flask adalah micro web framework untuk Python yang ringan dan mudah digunakan. Dengan Flask, kita bisa membuat dashboard web untuk menampilkan data sensor secara real-time langsung dari browser.
#!/usr/bin/env python3
# Dashboard IoT dengan Flask
# IoTHub - https://iothub.id
from flask import Flask, jsonify, render_template_string
from datetime import datetime
import json
app = Flask(__name__)
# Penyimpanan sederhana di memori (untuk demo)
sensor_data = {
"dht22": {"suhu": 0.0, "kelembaban": 0.0, "terakhir": "-"},
"ultrasonic": {"jarak": 0.0, "terakhir": "-"}
}
# Template HTML Dashboard
DASHBOARD_HTML = """
<!DOCTYPE html>
<html lang="id">
<head>
<title>Dashboard IoT - IoTHub</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { font-family: 'Segoe UI', sans-serif; background: #0f172a;
color: #e2e8f0; margin: 0; padding: 20px; }
h1 { text-align: center; color: #3ecf8e; margin-bottom: 30px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit,
minmax(300px, 1fr)); gap: 20px; max-width: 900px;
margin: 0 auto; }
.card { background: #1e293b; border-radius: 12px; padding: 24px;
border: 1px solid #334155; }
.card h2 { margin-top: 0; color: #22d3ee; font-size: 1.1rem; }
.value { font-size: 2.5rem; font-weight: 700; color: #3ecf8e;
margin: 10px 0; }
.unit { font-size: 1rem; color: #94a3b8; }
.meta { font-size: 0.85rem; color: #64748b; }
</style>
</head>
<body>
<h1>π Dashboard IoT Raspberry Pi</h1>
<div class="grid">
<div class="card">
<h2>π‘οΈ Sensor DHT22</h2>
<div>
<div class="value" id="suhu">--</div>
<div class="unit">Β°C (Suhu)</div>
</div>
<div style="margin-top:15px">
<div class="value" id="lembab">--</div>
<div class="unit">% (Kelembaban)</div>
</div>
<div class="meta" id="waktu-dht"></div>
</div>
<div class="card">
<h2>π Sensor Ultrasonic</h2>
<div>
<div class="value" id="jarak">--</div>
<div class="unit">cm (Jarak)</div>
</div>
<div class="meta" id="waktu-ult"></div>
</div>
</div>
<script>
async function updateData() {
const res = await fetch('/api/data');
const data = await res.json();
document.getElementById('suhu').textContent = data.dht22.suhu.toFixed(1);
document.getElementById('lembab').textContent = data.dht22.kelembaban.toFixed(1);
document.getElementById('waktu-dht').textContent = data.dht22.terakhir;
document.getElementById('jarak').textContent = data.ultrasonic.jarak.toFixed(1);
document.getElementById('waktu-ult').textContent = data.ultrasonic.terakhir;
}
setInterval(updateData, 2000);
updateData();
</script>
</body>
</html>
"""
@app.route("/")
def index():
"""Halaman utama dashboard."""
return render_template_string(DASHBOARD_HTML)
@app.route("/api/data")
def api_data():
"""Endpoint API untuk data sensor (JSON)."""
return jsonify(sensor_data)
@app.route("/api/update/suhu/<float:suhu>/<float:lembab>")
def update_suhu(suhu, lembab):
"""Endpoint untuk update data DHT22."""
sensor_data["dht22"]["suhu"] = suhu
sensor_data["dht22"]["kelembaban"] = lembab
sensor_data["dht22"]["terakhir"] = datetime.now().strftime("%H:%M:%S")
return jsonify({"status": "ok"})
@app.route("/api/update/jarak/<float:jarak>")
def update_jarak(jarak):
"""Endpoint untuk update data ultrasonic."""
sensor_data["ultrasonic"]["jarak"] = jarak
sensor_data["ultrasonic"]["terakhir"] = datetime.now().strftime("%H:%M:%S")
return jsonify({"status": "ok"})
if __name__ == "__main__":
print("Dashboard IoT berjalan di http://0.0.0.0:5000")
app.run(host="0.0.0.0", port=5000, debug=True)
Jalankan script: python3 dashboard.py. Buka browser di komputer yang sama jaringan, akses http://<IP_RASPBERRY_PI>:5000. Dashboard akan memperbarui data secara otomatis setiap 2 detik menggunakan fetch API.
7. Integrasi dengan Database SQLite
SQLite adalah database ringan yang tersimpan dalam satu file dan tidak memerlukan server terpisah. Sangat cocok untuk Raspberry Pi karena hemat resource. Setiap data sensor yang masuk akan dicatat ke database untuk keperluan analisis dan histori.
#!/usr/bin/env python3
# Handler Database SQLite untuk IoT
# IoTHub - https://iothub.id
import sqlite3
import json
from datetime import datetime, timedelta
DB_NAME = "iot_data.db"
def init_db():
"""Inisialisasi database dan buat tabel jika belum ada."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
# Tabel pembacaan sensor
cursor.execute("""
CREATE TABLE IF NOT EXISTS sensor_readings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_id TEXT NOT NULL,
sensor_type TEXT NOT NULL,
value_json TEXT NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
""")
# Tabel device yang terdaftar
cursor.execute("""
CREATE TABLE IF NOT EXISTS devices (
device_id TEXT PRIMARY KEY,
device_name TEXT NOT NULL,
location TEXT,
last_seen DATETIME
)
""")
# Index untuk query cepat berdasarkan waktu
cursor.execute("""
CREATE INDEX IF NOT EXISTS idx_timestamp
ON sensor_readings(timestamp)
""")
conn.commit()
conn.close()
print("[DB] Database diinisialisasi.")
def simpan_reading(device_id, sensor_type, data_dict):
"""Simpan pembacaan sensor ke database."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("""
INSERT INTO sensor_readings (device_id, sensor_type, value_json)
VALUES (?, ?, ?)
""", (device_id, sensor_type, json.dumps(data_dict)))
# Update last_seen di tabel devices
cursor.execute("""
INSERT INTO devices (device_id, device_name, last_seen)
VALUES (?, ?, ?)
ON CONFLICT(device_id)
DO UPDATE SET last_seen = excluded.last_seen
""", (device_id, f"Device {device_id}", datetime.now().isoformat()))
conn.commit()
conn.close()
def ambil_data_terakhir(device_id, sensor_type, limit=10):
"""Ambil data terakhir dari database."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("""
SELECT value_json, timestamp
FROM sensor_readings
WHERE device_id = ? AND sensor_type = ?
ORDER BY timestamp DESC
LIMIT ?
""", (device_id, sensor_type, limit))
results = []
for row in cursor.fetchall():
results.append({
"data": json.loads(row[0]),
"waktu": row[1]
})
conn.close()
return results
def ambil_rata_rata_harian(device_id, sensor_type):
"""Hitung rata-rata harian dari data sensor."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("""
SELECT AVG(CAST(json_extract(value_json, '$.suhu') AS REAL))
FROM sensor_readings
WHERE device_id = ? AND sensor_type = ?
AND timestamp >= date('now', '-1 day')
""", (device_id, sensor_type))
result = cursor.fetchone()
conn.close()
return round(result[0], 2) if result[0] else None
# === Contoh penggunaan ===
if __name__ == "__main__":
init_db()
# Simulasi data dari sensor
simpan_reading("esp32-01", "dht22", {
"suhu": 29.5, "kelembaban": 72.3
})
simpan_reading("esp32-01", "dht22", {
"suhu": 29.8, "kelembaban": 71.0
})
simpan_reading("esp32-02", "ultrasonic", {
"jarak": 23.45
})
# Ambil data terakhir
data = ambil_data_terakhir("esp32-01", "dht22")
print("\n=== Data Terakhir esp32-01 ===")
for d in data:
print(f" {d['waktu']}: {d['data']}")
# Hitung rata-rata
avg = ambil_rata_rata_harian("esp32-01", "dht22")
print(f"\nRata-rata suhu 24 jam terakhir: {avg} Β°C")
SQLite tidak memerlukan proses server terpisah, hanya satu file database, dan query-nya sangat cepat. Untuk Raspberry Pi dengan RAM 1GB, SQLite jauh lebih efisien dibanding MySQL atau PostgreSQL yang memakan banyak resource.
8. Proyek: Gateway IoT dengan Raspberry Pi
Sekarang kita akan menggabungkan semua yang telah dipelajari menjadi satu proyek lengkap: Gateway IoT yang menerima data dari sensor via MQTT, menyimpan ke database SQLite, dan menampilkan di dashboard Flask secara real-time.
ββββββββββββββ MQTT βββββββββββββββββββββββββββββββββββ
β ESP32 #1 ββββββββββββββββΆβ RASPBERRY PI β
β DHT22 β iot/sensor/ β β
ββββββββββββββ esp32-01 β βββββββββββββββββββββββββββββ β
β β mqtt_subscriber.py β β
ββββββββββββββ MQTT β β - Terima pesan MQTT β β
β ESP32 #2 ββββββββββββββββΆβ β - Parse JSON β β
β HC-SR04 β iot/sensor/ β β - Simpan ke SQLite β β
ββββββββββββββ esp32-02 β β - Update dashboard Flask β β
β βββββββββββββββββββββββββββββ β
ββββββββββββββ MQTT β β
β ESP32 #3 ββββββββββββββββΆβ βββββββββββββββββββββββββββββ β
β DHT22 + β iot/sensor/ β β SQLite Database β β
β Relay β esp32-03 β β iot_data.db β β
ββββββββββββββ β βββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββ β
β β Flask Server (Port 5000) β β
β β /api/data β JSON β β
β β / β Dashboard HTML β β
β βββββββββββββ¬ββββββββββββββββ β
ββββββββββββββββΌββββββββββββββββββ
β
ββββββββββ΄βββββββββ
β Web Browser β
β Dashboard IoT β
βββββββββββββββββββ
Script Utama: gateway.py
#!/usr/bin/env python3
# Gateway IoT Lengkap - Raspberry Pi
# Menggabungkan MQTT Subscriber + SQLite + Flask Dashboard
# IoTHub - https://iothub.id
import paho.mqtt.client as mqtt
import sqlite3
import json
import threading
from datetime import datetime
from flask import Flask, jsonify, render_template_string
# =============================================
# KONFIGURASI
# =============================================
MQTT_BROKER = "localhost"
MQTT_PORT = 1883
MQTT_TOPIC = "iot/sensor/#"
DB_FILE = "iot_gateway.db"
FLASK_PORT = 5000
# =============================================
# DATABASE HANDLER
# =============================================
def init_database():
"""Buat tabel database jika belum ada."""
conn = sqlite3.connect(DB_FILE)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS readings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_id TEXT,
sensor_type TEXT,
data TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
""")
conn.commit()
conn.close()
def simpan_data(device_id, sensor_type, data):
"""Simpan data sensor ke database."""
conn = sqlite3.connect(DB_FILE)
cursor = conn.cursor()
cursor.execute(
"INSERT INTO readings (device_id, sensor_type, data) VALUES (?, ?, ?)",
(device_id, sensor_type, json.dumps(data))
)
conn.commit()
conn.close()
def ambil_semua_data(limit=50):
"""Ambil data terbaru dari database."""
conn = sqlite3.connect(DB_FILE)
cursor = conn.cursor()
cursor.execute("""
SELECT device_id, sensor_type, data, created_at
FROM readings ORDER BY created_at DESC LIMIT ?
""", (limit,))
results = []
for row in cursor.fetchall():
results.append({
"device": row[0],
"tipe": row[1],
"data": json.loads(row[2]),
"waktu": row[3]
})
conn.close()
return results
# =============================================
# MQTT SUBSCRIBER
# =============================================
def on_connect(client, userdata, flags, rc):
if rc == 0:
print(f"[MQTT] Terhubung ke broker!")
client.subscribe(MQTT_TOPIC)
print(f"[MQTT] Subscribe: {MQTT_TOPIC}")
else:
print(f"[MQTT] Error koneksi: {rc}")
def on_message(client, userdata, msg):
"""Handler saat pesan MQTT diterima."""
try:
topik = msg.topic
data = json.loads(msg.payload.decode())
# Ekstrak device_id dari topik: iot/sensor/{device_id}
parts = topik.split("/")
device_id = parts[2] if len(parts) > 2 else "unknown"
# Tentukan tipe sensor dari data
if "suhu" in data:
sensor_type = "dht22"
elif "jarak" in data:
sensor_type = "ultrasonic"
else:
sensor_type = "generic"
# Simpan ke database
simpan_data(device_id, sensor_type, data)
print(f"[{datetime.now():%H:%M:%S}] "
f"Diterima: {device_id} | {sensor_type} | {data}")
except Exception as e:
print(f"[MQTT] Error memproses pesan: {e}")
def jalankan_mqtt():
"""Jalankan MQTT subscriber di thread terpisah."""
client = mqtt.Client(
client_id="rpi-gateway",
protocol=mqtt.MQTTv311
)
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_BROKER, MQTT_PORT, keepalive=60)
client.loop_forever()
# =============================================
# FLASK DASHBOARD
# =============================================
flask_app = Flask(__name__)
DASHBOARD_TEMPLATE = """
<!DOCTYPE html>
<html lang="id">
<head>
<title>Gateway IoT Dashboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Segoe UI', sans-serif;
background: #0a0f1a; color: #e2e8f0; padding: 20px; }
h1 { text-align: center; color: #3ecf8e;
margin-bottom: 10px; font-size: 1.8rem; }
.subtitle { text-align: center; color: #64748b;
margin-bottom: 30px; font-size: 0.9rem; }
table { width: 100%; max-width: 900px; margin: 0 auto;
border-collapse: collapse; }
th { background: #1e293b; color: #22d3ee; padding: 12px 16px;
text-align: left; font-size: 0.85rem; }
td { padding: 10px 16px; border-bottom: 1px solid #1e293b;
font-size: 0.85rem; }
tr:hover td { background: rgba(62,207,142,0.05); }
.badge { background: #1e3a5f; color: #22d3ee; padding: 3px 8px;
border-radius: 12px; font-size: 0.75rem; }
</style>
</head>
<body>
<h1>π Gateway IoT Dashboard</h1>
<p class="subtitle">Raspberry Pi 4 β Data dari MQTT via Subscriber</p>
<table>
<thead>
<tr>
<th>Device ID</th>
<th>Tipe Sensor</th>
<th>Data</th>
<th>Waktu</th>
</tr>
</thead>
<tbody id="data-table"></tbody>
</table>
<script>
async function loadData() {
const res = await fetch('/api/readings');
const data = await res.json();
const tbody = document.getElementById('data-table');
tbody.innerHTML = data.map(d => `
<tr>
<td><span class="badge">${d.device}</span></td>
<td>${d.tipe}</td>
<td>${JSON.stringify(d.data)}</td>
<td>${d.waktu}</td>
</tr>
`).join('');
}
setInterval(loadData, 3000);
loadData();
</script>
</body>
</html>
"""
@flask_app.route("/")
def index():
return render_template_string(DASHBOARD_TEMPLATE)
@flask_app.route("/api/readings")
def api_readings():
data = ambil_semua_data(limit=20)
return jsonify(data)
# =============================================
# MAIN - JALANKAN SEMUA LAYANAN
# =============================================
if __name__ == "__main__":
print("=" * 50)
print(" GATEWAY IoT RASPBERRY PI")
print(" IoTHub - https://iothub.id")
print("=" * 50)
# Inisialisasi database
init_database()
print("[DB] Database siap.")
# Jalankan MQTT di background thread
mqtt_thread = threading.Thread(target=jalankan_mqtt, daemon=True)
mqtt_thread.start()
# Jalankan Flask di main thread
print(f"[FLASK] Dashboard: http://0.0.0.0:{FLASK_PORT}")
print("[GATEWAY] Semua layanan aktif! Ctrl+C untuk berhenti.\n")
flask_app.run(host="0.0.0.0", port=FLASK_PORT, debug=False)
Cara Menjalankan Proyek
# Install semua dependensi
pip3 install paho-mqtt flask
# Pastikan Mosquitto berjalan
sudo systemctl start mosquitto
# Jalankan gateway (butuh akses GPIO β gunakan sudo)
sudo python3 gateway.py
# Output:
# ==================================================
# GATEWAY IoT RASPBERRY PI
# ==================================================
# [DB] Database siap.
# [MQTT] Terhubung ke broker!
# [MQTT] Subscribe: iot/sensor/#
# [FLASK] Dashboard: http://0.0.0.0:5000
# [GATEWAY] Semua layanan aktif!
#
# [14:30:15] Diterima: esp32-01 | dht22 | {'suhu': 29.5, 'kelembaban': 72.3}
# [14:30:18] Diterima: esp32-02 | ultrasonic | {'jarak': 23.45}
Untukι¨η½² produksi, gunakan systemd service agar gateway otomatis berjalan saat boot. Buat file service di /etc/systemd/system/iot-gateway.service dan jalankan sudo systemctl enable iot-gateway. Jangan gunakan debug=True di Flask untuk environment produksi.
9. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Raspberry Pi untuk IoT: