TKK_E32230206/laporan_414_arsitektur_inte...

6.0 KiB

4.1.4 Arsitektur dan Integrasi Sistem


Paragraf 1 — Gambaran Arsitektur Sistem

Aplikasi JTA merupakan komponen antarmuka (frontend) dalam sebuah ekosistem IoT yang terdiri dari empat lapisan utama: perangkat keras sensor (ESP32 + DHT22), server backend (Node.js di Railway), layanan database dan autentikasi (Supabase), serta aplikasi mobile Flutter sebagai ujung akses pengguna. Data sensor mengalir dari ESP32 melalui protokol MQTT menuju backend, kemudian disimpan ke database Supabase. Aplikasi Flutter mengambil data tersebut melalui REST API dan menampilkannya secara near real-time kepada pengguna. Lingkup pengembangan pada laporan ini berfokus pada aplikasi mobile Flutter sebagai komponen antarmuka sistem.

Gambaran Umum Arsitektur Sistem

Gambar 4.x — Gambaran umum arsitektur sistem JTA. Lingkup laporan ini adalah lapisan Aplikasi Flutter (paling kanan).


Paragraf 2 — Arsitektur Internal Aplikasi Flutter

Aplikasi Flutter dikembangkan menggunakan pola arsitektur berlapis (layered architecture) yang memisahkan tanggung jawab antara tampilan, logika bisnis, dan akses data. Terdapat lima lapisan yang disusun secara hierarkis:

  1. Presentation Layer — halaman dan widget yang ditampilkan ke pengguna (MonitoringPage, ControlPage, SchedulePage, dsb.)
  2. State Management (Riverpod) — mengelola state aplikasi secara reaktif melalui MonitoringNotifier, ControlNotifier, dan AuthNotifier
  3. Repository Layer — abstraksi antara notifier dan sumber data, diimplementasikan oleh IotRepository dan AuthRepository
  4. Service Layer — bertanggung jawab atas komunikasi jaringan: ApiIotService untuk data sensor, ApiControlService untuk perintah kontrol, dan AuthService untuk autentikasi
  5. External Services — REST API backend (Railway) dan Supabase (autentikasi + database)

Arsitektur Internal Aplikasi Flutter

Gambar 4.x — Arsitektur internal aplikasi Flutter (JTA) dengan lima lapisan terpisah.

Pemisahan lapisan ini memudahkan pengujian dan penggantian implementasi—misalnya, IotRepository dapat menerima implementasi ApiIotService atau implementasi mock untuk keperluan pengujian tanpa mengubah kode di lapisan atas.


Paragraf 3 — Koneksi dan Konfigurasi Layanan Eksternal

Aplikasi menggunakan dua layanan eksternal: REST API backend dan Supabase. Konfigurasi base URL API terpusat pada kelas ApiConfig, sehingga pergantian environment (lokal, staging, production) cukup dilakukan di satu titik:

// lib/core/api_config.dart
class ApiConfig {
  static const String baseUrl =
      'https://backendjamur-production.up.railway.app/api';
}

Seluruh request HTTP menggunakan package dio (v5.4.0) yang diinstansiasi per service. Endpoint yang dikonsumsi aplikasi meliputi:

Endpoint Metode Fungsi
/history/{deviceId} GET Ambil data sensor terbaru & histori
/history/{deviceId}/daily GET Rata-rata sensor per hari
/history/{deviceId}/hourly GET Rata-rata sensor per jam
/mode/{deviceId} GET / POST Baca & ubah mode operasi
/threshold/{deviceId} GET / POST Baca & ubah batas suhu/kelembapan
/schedule/{deviceId} GET / POST Kelola jadwal irigasi
/schedule/{deviceId}/now POST Siram manual langsung

Koneksi ke Supabase diinisialisasi satu kali saat aplikasi pertama dijalankan menggunakan package supabase_flutter (v2.8.0). Supabase dimanfaatkan khusus untuk modul autentikasi—login, registrasi, dan persistensi sesi berbasis JWT—sementara akses data sensor sepenuhnya melalui REST API backend.

// lib/main.dart
await Supabase.initialize(
  url: 'https://tqibzvranbroouzdwhhh.supabase.co',
  anonKey: '<anon_key>',
);

Sesi login pengguna disimpan secara persisten oleh supabase_flutter sehingga pengguna tidak perlu login ulang setiap kali membuka aplikasi. Data device_id yang terikat ke akun pengguna diambil dari sesi ini dan digunakan sebagai parameter di setiap request API.


Paragraf 4 — Mekanisme Pembaruan Data Sensor

Data sensor diperbarui secara near real-time melalui mekanisme polling periodik yang dikelola oleh MonitoringNotifier. Saat halaman monitoring dibuka, notifier melakukan inisialisasi awal dengan mengambil histori penuh dari API, kemudian mengaktifkan timer yang memanggil ulang API setiap 5 detik. Hasilnya dikomparasi dengan data terakhir berdasarkan timestamp—hanya data baru yang ditambahkan ke state, sehingga grafik historis tidak memuat duplikat.

// Inisialisasi dan polling otomatis
_timer = Timer.periodic(const Duration(seconds: 5), (_) => fetchData());

Setiap respons API memperbarui MonitoringState melalui state.copyWith(), yang secara otomatis memicu rebuild hanya pada widget yang bergantung pada state tersebut (reaktivitas Riverpod). State juga menyertakan sinkronisasi status relay dan mode operasi ke ControlNotifier agar seluruh halaman aplikasi mencerminkan kondisi perangkat yang sesungguhnya.

Mekanisme Polling Data Sensor

Gambar 4.x — Alur pembaruan data sensor: dari inisialisasi hingga polling periodik 5 detik.


Paragraf 5 — Penutup Sub-bab 4.1

Seluruh komponen aplikasi mobile JTA—mulai dari konfigurasi koneksi, arsitektur berlapis, manajemen state, hingga mekanisme pembaruan data—telah berhasil dikembangkan dan diintegrasikan dengan layanan backend dan Supabase. Pemisahan lapisan yang jelas antara presentation, state management, repository, dan service menjadikan aplikasi mudah dipelihara dan dikembangkan lebih lanjut. Pembahasan selanjutnya pada Sub-bab 4.2 Implementasi Sistem akan merinci tampilan antarmuka dan hasil implementasi fitur-fitur aplikasi secara keseluruhan.