1. Apa Itu OOP?
Object-Oriented Programming (OOP) adalah paradigma pemrograman yang mengorganisir kode ke dalam bentuk "objek" — entitas yang memiliki data (atribut/properti) dan perilaku (method/fungsi). Berbeda dari pemrograman prosedural yang berfokus pada urutan eksekusi fungsi, OOP berfokus pada modeling dunia nyata ke dalam kode.
Dalam konteks Internet of Things (IoT), OOP menjadi sangat powerful karena sistem IoT secara alami terdiri dari entitas-entitas yang bisa dimodelkan sebagai objek: sensor, aktuator, perangkat, gateway, pesan, dan lainnya. Setiap entitas ini memiliki data tersendiri dan perilaku tersendiri — persis seperti konsep objek dalam OOP.
Empat Pilar OOP
| Pilar | Penjelasan Singkat | Contoh di IoT |
|---|---|---|
| Inheritance | Kelas anak mewarisi atribut & method dari kelas induk | SensorSuhu mewarisi dari kelas Sensor |
| Polymorphism | Method yang sama bisa berperilaku berbeda di tiap kelas | Metode baca() berbeda untuk sensor suhu vs sensor gas |
| Encapsulation | Menyembunyikan detail internal, hanya ekspos interface publik | Method kalibrasi sensor disembunyikan, hanya get_data() yang publik |
| Abstraction | Menyederhanakan kompleksitas dengan abstraksi tingkat tinggi | Kelas abstrak Device tanpa detail spesifik hardware |
OOP vs Pemrograman Prosedural
PROSEDURAL OOP
def baca_suhu(): class Sensor:
def baca_kelembaban(): def baca(self):
def kirim_mqtt(): def kirim(self):
def cek_threshold(): def cek_threshold(self):
data = baca_suhu() sensor = SensorSuhu(pin=4)
if data > 30: data = sensor.baca()
kirim_mqtt("panas") if data > 30:
sensor.kirim("panas")
Fokus: urutan fungsi Fokus: objek & interaksi
Python secara teknis mendukung multi-paradigma — Anda bisa menulis kode prosedural, OOP, atau bahkan fungsional dalam satu file. Namun untuk proyek IoT yang berkembang, OOP akan menghemat banyak waktu karena kode lebih terstruktur dan mudah di-maintain.
2. Classes & Objects
Class adalah blueprint (cetakan) untuk membuat objek. Ibarat arsitektur rumah — satu desain bisa menghasilkan banyak rumah. Sedangkan object adalah instance (kejadian) nyata dari class tersebut — rumah yang sudah dibangun dari desain tadi.
2.1 — Membuat Class Pertama
8. Design Patterns untuk IoT
Design patterns adalah solusi template untuk masalah desain yang umum. Dalam pengembangan sistem IoT, beberapa pattern sangat membantu untuk membuat kode yang bersih dan scalable.
8.1 — Singleton Pattern
Memastikan hanya ada satu instance dari sebuah class — cocok untuk MQTT client, database connection, atau konfigurasi global.
"""
Singleton Pattern untuk MQTT Manager
BeebaneLabs - https://beebanelabs.pages.dev
"""
class MQTTManager:
"""Singleton — hanya satu instance yang boleh ada."""
_instance = None
_initialized = False
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, broker="localhost", port=1883):
if MQTTManager._initialized:
return
self.broker = broker
self.port = port
self._connected = False
self._subscribers = {}
MQTTManager._initialized = True
print(f"[MQTT] Manager dibuat — broker: {broker}:{port}")
def connect(self):
self._connected = True
print(f"[MQTT] Terhubung ke {self.broker}:{self.port}")
def subscribe(self, topic, callback):
self._subscribers[topic] = callback
print(f"[MQTT] Subscribe: {topic}")
# Semua variabel ini menunjuk ke INSTANCE YANG SAMA
mqtt1 = MQTTManager("192.168.1.10", 1883)
mqtt2 = MQTTManager("broker-lain.com", 8883) # Parameter diabaikan!
print(f"mqtt1 is mqtt2: {mqtt1 is mqtt2}") # True
print(f"Broker: {mqtt2.broker}") # 192.168.1.10 (tetap dari inisialisasi pertama)
8.2 — Observer Pattern
Membangun sistem event-driven di mana perubahan pada satu komponen (sensor) secara otomatis memberitahu komponen lain (aktuator, logger, notifikasi).
"""
Observer Pattern untuk Event-Driven IoT
BeebaneLabs - https://beebanelabs.pages.dev
"""
class EventEmitter:
"""Base class untuk event system."""
def __init__(self):
self._listeners = {}
def on(self, event_name, callback):
"""Mendaftarkan listener untuk event tertentu."""
if event_name not in self._listeners:
self._listeners[event_name] = []
self._listeners[event_name].append(callback)
def emit(self, event_name, data=None):
"""Memancarkan event ke semua listener."""
if event_name in self._listeners:
for callback in self._listeners[event_name]:
callback(data)
class SensorMonitor(EventEmitter):
"""Sensor yang memancarkan event saat threshold terlampaui."""
def __init__(self, nama, threshold_high=None, threshold_low=None):
super().__init__()
self.nama = nama
self.threshold_high = threshold_high
self.threshold_low = threshold_low
self._nilai_terakhir = None
def update(self, nilai):
self._nilai_terakhir = nilai
if self.threshold_high and nilai > self.threshold_high:
self.emit("threshold_high", {
"sensor": self.nama,
"nilai": nilai,
"threshold": self.threshold_high
})
if self.threshold_low and nilai < self.threshold_low:
self.emit("threshold_low", {
"sensor": self.nama,
"nilai": nilai,
"threshold": self.threshold_low
})
self.emit("data_update", {"sensor": self.nama, "nilai": nilai})
# --- Penggunaan ---
monitor_suhu = SensorMonitor("Suhu", threshold_high=35, threshold_low=15)
monitor_gas = SensorMonitor("Gas MQ-135", threshold_high=1000)
# Daftarkan listener
def alert_handler(data):
print(f"🚨 ALERT: {data['sensor']} = {data['nilai']} (threshold: {data['threshold']})")
def log_handler(data):
print(f"📝 LOG: {data['sensor']} → {data['nilai']}")
def dashboard_handler(data):
print(f"📊 DASHBOARD: Update {data['sensor']}: {data['nilai']}")
monitor_suhu.on("threshold_high", alert_handler)
monitor_suhu.on("threshold_low", alert_handler)
monitor_suhu.on("data_update", log_handler)
monitor_suhu.on("data_update", dashboard_handler)
monitor_gas.on("threshold_high", alert_handler)
# Simulasi update
monitor_suhu.update(28) # Normal
monitor_suhu.update(36.5) # Threshold high triggered!
monitor_suhu.update(12) # Threshold low triggered!
monitor_gas.update(1500) # Gas bahaya!
8.3 — Factory Pattern
Membuat object tanpa perlu tahu class spesifiknya — cocok untuk membuat sensor berdasarkan konfigurasi file.
"""
Factory Pattern untuk Membuat Sensor dari Config
BeebaneLabs - https://beebanelabs.pages.dev
"""
import json
class SensorFactory:
"""Factory untuk membuat object sensor dari konfigurasi."""
_registry = {}
@classmethod
def register(cls, tipe, class_ref):
"""Mendaftarkan tipe sensor ke factory."""
cls._registry[tipe] = class_ref
@classmethod
def buat(cls, config):
"""Membuat sensor dari dict konfigurasi."""
tipe = config.get("tipe")
if tipe not in cls._registry:
raise ValueError(f"Tipe sensor tidak dikenal: {tipe}")
sensor_class = cls._registry[tipe]
return sensor_class(**{k: v for k, v in config.items() if k != "tipe"})
@classmethod
def buat_dari_file(cls, filepath):
"""Membuat semua sensor dari file JSON config."""
with open(filepath, "r") as f:
configs = json.load(f)
sensors = []
for cfg in configs:
sensor = cls.buat(cfg)
sensors.append(sensor)
return sensors
# Register semua tipe sensor
# SensorFactory.register("dht22", SensorDHT)
# SensorFactory.register("ultrasonik", SensorUltrasonik)
# SensorFactory.register("ldr", SensorLDR)
# Contoh config JSON:
# [
# {"tipe": "dht22", "nama": "Suhu Ruang", "pin": 4},
# {"tipe": "ultrasonik", "nama": "Jarak Tangki", "pin_trigger": 17, "pin_echo": 27},
# {"tipe": "ldr", "nama": "Cahaya Taman", "pin": 22}
# ]
| Pattern | Kegunaan di IoT |
|---|---|
| Singleton | MQTT client, database connection, config manager — hanya satu instance |
| Observer | Event-driven notifications — sensor threshold, alert system |
| Factory | Membuat sensor/aktuator dari konfigurasi — fleksibel dan scalable |
| Strategy | Ganti algoritma (filter data, format payload) secara dinamis |
| State | Menangani state perangkat (idle, running, error, sleep) |
9. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang OOP dalam Python untuk IoT: