Publikasi
Aplikasi Bagaswara (Android)
Arsitektur dan alur kerja aplikasi Android Bagaswara: MVVM, streaming HLS, polling data, sirine, dan autentikasi PIN.
DOKUMENTASI ARSITEKTUR SISTEM & ALUR KERJA (FLOWCHART)
APLIKASI BAGASWARA - SMART VILLAGE (HIBAH KARANGGENENG UNS)
Tanggal Pembaruan: 26 Oktober 2026
Versi Aplikasi: 1.2 (Build versionCode: 3)
Target Platform: Native Android (Kotlin, Jetpack Compose, Material 3, Coroutines, Media3 ExoPlayer, Retrofit2)
1. DOKUMENTASI ARSITEKTUR SISTEM (SYSTEM ARCHITECTURE)
Sistem Bagaswara menggunakan Sistem Terdistribusi Berlapis (Multi-Tier Architecture) yang menghubungkan perangkat keras di lapangan (Hardware Layer), gateway pemrosesan lokal di Desa (STB Server Layer), enkapsulasi jaringan publik (Tunnel Layer), dan aplikasi seluler Android (Android Client Layer).
+-----------------------------------------------------------------------------------+
| 1. HARDWARE / FIELD LAYER |
| |
| +--------------------+ +------------------+ +------------------+ |
| | IP Cameras / NVR | | Sensors / Meters | | ESP32 Controller| |
| | (RTSP H.265 Stream)| | (PLN, Bat, Inv) | | (Village Siren) | |
| +---------+----------+ +--------+---------+ +--------+---------+ |
+------------|-----------------------------|---------------------------|------------+
| | |
v v v
+-----------------------------------------------------------------------------------+
| 2. STB SERVER LAYER (LOCAL GATEWAY) |
| |
| +-----------------------------------------------------------------------------+ |
| | go2rtc Streaming Engine (Port 1984 / 1985) | |
| | - Transcodes RTSP H.265 -> H.264 (FFmpeg pipeline, ~6% CPU) | |
| | - Generates Live HLS Playlist: /api/stream.m3u8?src=<camera_key> | |
| | - Generates Live Snapshot Frame: /api/frame.jpeg?src=<camera_key> | |
| +-------------------------------------+---------------------------------------+ |
| | |
| +-------------------------------------v---------------------------------------+ |
| | Python Backend Daemon / API Service (record.py on Port 8088) | |
| | - Telemetry Endpoint: GET /api/telemetry, /api/cputemp, /api/services | |
| | - Camera Metadata: GET /api/cameras, POST /api/camera, DELETE /api/camera | |
| | - Village Siren Trigger: GET /api/siren, POST /api/siren (Instant 1-Tap) | |
| | - Running Text Ticker: GET/POST /api/ticker (Action: list, add, set, delete) | |
| | - Auth & PIN Security: POST /api/auth, POST /api/pin (Strict 8-digit PIN) | |
| | - Rate Limiter: 30-60 req/min/IP | |
| +-----------------------------------------------------------------------------+ |
+----------------------------------------|------------------------------------------+
|
v
+-----------------------------------------------------------------------------------+
| 3. SECURE NETWORK / TUNNEL LAYER |
| |
| +-----------------------------------------------------------------------------+ |
| | Cloudflare Tunnel Agent (cloudflared ID cb05497d) | |
| | Domain Public: https://bagaswara.hibahkaranggeneng.site | |
| | Routing: /api/* -> 8088 (Backend DB/API) & 1984/1985 (go2rtc Video Stream) | |
| +-------------------------------------+---------------------------------------+ |
+----------------------------------------|------------------------------------------+
| HTTPS (TLS 1.3)
v
+-----------------------------------------------------------------------------------+
| 4. ANDROID CLIENT LAYER (BAGASWARA APP) |
| |
| +-----------------------------------------------------------------------------+ |
| | Network & Data Layer: | |
| | - Retrofit2 ApiService & OkHttpClient (X-API-PIN Header, 20s Timeout) | |
| | - CctvRepository & PreferenceManager (SharedPreferences + RAM Cache) | |
| +-------------------------------------+---------------------------------------+ |
| | |
| +-------------------------------------v---------------------------------------+ |
| | ViewModel Layer: | |
| | - MainViewModel (Coroutines, StateFlow, 15s Background Polling) | |
| | - In-Memory Auth Session (activePin RAM storage, auto-clear on 401/logout) | |
| +-------------------------------------+---------------------------------------+ |
| | |
| +-------------------------------------v---------------------------------------+ |
| | UI Layer (Jetpack Compose & Material 3): | |
| | - MainScreen (HorizontalPager, 4 Bottom Navigation Tabs, Page Transforms) | |
| | - DasborScreen (Telemetry Cards, History Chart Dialog, Instant Siren Button) | |
| | - LiveScreen (1-Col vs 2x2 Grid View, Snapshot Fallback, Fullscreen View) | |
| | - KelolaScreen (Admin PIN Auth, CCTV Management, Ticker Management) | |
| | - PengaturanScreen (Data Saver Switch, Theme Mode, Server URL Config) | |
| | - Media3 ExoPlayer (HLS H.264, LoadControl: 15s-30s Buffer, Auto-Retry 1x) | |
| +-----------------------------------------------------------------------------+ |
+-----------------------------------------------------------------------------------+
Penjelasan Lapisan Arsitektur (Layer Breakdown):
-
Hardware / Field Layer (Perangkat Lapangan):
- IP Camera / NVR: Menangkap video CCTV berprotokol RTSP H.265.
- Sensor & Power Meters: Mengukur parameter listrik PLN (Voltase/Status), Baterai Sistem (Voltase per sel), Inverter AC (Voltase, Frekuensi, Load, Watt), dan Suhu CPU Server/ESP32.
- ESP32 Controller: Mengendalikan relay Sirine Bahaya Desa secara lokal.
-
STB Server Layer (Gateway Lokal Desa):
- Perangkat Set-Top Box (STB ARM 4-core, 2GB RAM) di lokasi pusat desa.
- go2rtc Service (Port 1984/1985): Mentranscode stream video RTSP H.265 menjadi format H.264 (
avc1.640029) menggunakan FFmpeg pipeline (~6% beban CPU) agar kompatibel dengan seluruh perangkat Android dan browser web tanpa perlu HEVC decoder khusus. Menyediakan endpoint HLS M3U8 dan Snapshot Frame JPEG (640x480). - Python Daemon (
record.pyPort 8088): Layanan REST API untuk telemetri, status server, manajemen kamera, sirine, running text, dan autentikasi PIN admin.
-
Secure Network / Tunnel Layer:
- Menggunakan Cloudflare Tunnel (
cloudflared) dengan domain publik resmihttps://bagaswara.hibahkaranggeneng.site. - Mengenkripsi seluruh lalu lintas data dengan TLS 1.3/HTTPS, menghilangkan kebutuhan IP Publik Statis atau Port Forwarding yang berisiko tinggi.
- Menggunakan Cloudflare Tunnel (
-
Android Client Layer (Aplikasi Mobile Bagaswara):
- Architecture Pattern: MVVM (Model-View-ViewModel) + Clean Data Layer + Declarative UI (Jetpack Compose).
- State Management:
StateFlowdancollectAsStateWithLifecycleuntuk update UI secara real-time. - Network: Retrofit2 + OkHttp3 dengan interceptor keamanan (
Level.BASIC) dan timeout 20 detik. - Video Player: Media3 ExoPlayer dengan kustomisasi
DefaultLoadControl(buffer 15s-30s) dan mekanisme Snapshot Fallback otomatis.
2. PENJELASAN ALUR SISTEM (TEXT WORKFLOW FOR FLOWCHARTS)
Berikut adalah urutan logika teks yang dapat Anda salin langsung ke dalam diagram Flowchart (seperti Draw.io, Whimsical, Mermaid, atau Visio):
🟢 FLOWCHART 1: Inisialisasi Aplikasi & Polling Data Latar Belakang (Background Polling)
[ START: User Membuka Aplikasi Bagaswara ]
|
v
[ Tampilkan Splash Screen (Animasi Logo & Branding Hibah UNS 700ms) ]
|
v
[ BACA DATA CACHE LOKAL (PreferenceManager / SharedPreferences) ]
|---> Muat data Telemetri, CPU Temp, Siren, Ticker, & Kamera tersimpan ke StateFlow
|---> UI langsung menampilkan data cepat tanpa kening/blank screen
|
v
[ CEK KONEKSI SERVER: Kirim Request GET /api/cameras (NetworkModule) ]
|
+---> [ RESPON SUKSES (200 OK) ]
| |
| +---> Set isServerOffline = false
| +---> Perbarui Data Cache Kamera & Waktu Sinkronisasi Terakhir
|
+---> [ RESPON GAGAL / TIMEOUT ]
|
+---> Set isServerOffline = true
+---> Tampilkan Banner "Mode Offline" & Dialog "Server Offline"
|
v
[ MULAI BACKGROUND POLLING (MainViewModel) ]
|
+---> Jalankan Loop Timer Setiap 15 Detik (Dispatchers.IO)
|
+---> Eksekusi 5 API Secara Paralel Concurrent (async):
| 1. GET /api/telemetry
| 2. GET /api/cputemp
| 3. GET /api/services
| 4. GET /api/siren
| 5. GET /api/ticker
|
+---> Perbarui StateFlow UI & Simpan Cache Terbaru ke SharedPreferences
|
v
[ END / LOOP SETIAP 15 DETIK ]
📹 FLOWCHART 2: Alur Pemutaran Video Streaming CCTV (Live View & Snapshot Fallback)
[ START: User Membuka Tab Live / CCTV Ringkas di Dasbor ]
|
v
[ CEK STATUS "MODE HEMAT KUOTA" (DataSaverMode) ]
|
+---> [ MODE HEMAT KUOTA = AKTIF (ON) ]
| |
| +---> Tampilkan Foto Snapshot (GET /api/frame.jpeg?src={camera_key})
| +---> Jalankan Timer Refresh Snapshot Otomatis Setiap 4 Detik
| +---> Tampilkan Overlay Tombol "Putar Video Live"
| +---> User Mengetuk Tombol Play?
| |---> Ya: Pindah ke Pemutaran Video Live Stream
| |---> Tidak: Tetap Mode Snapshot (~10KB)
|
+---> [ MODE HEMAT KUOTA = NONAKTIF (OFF) ]
|
v
[ INISIALISASI MEDIA3 EXOPLAYER ]
|
+---> Atur LoadControl (Min Buffer: 15s, Max Buffer: 30s)
+---> Set URL: https://bagaswara.hibahkaranggeneng.site/api/stream.m3u8?src={camera_key}
+---> Panggil prepare() & playWhenReady = true
|
v
[ MONITORING STATUS PLAYBACK (Player.Listener) ]
|
+---> [ STATE_BUFFERING ]: Tampilkan Indikator Loading Putar
|
+---> [ STATE_READY ]: Tampilkan Video Stream H.264 Lancar
|
+---> [ ON_PLAYER_ERROR ]: Terjadi Kesalahan Jaringan / Stream
|
+---> Cek Apakah Sudah Auto-Retry?
|
+---> [ BELUM (First Error) ]:
| |
| +---> Set hasRetried = true
| +---> Tunggu 3 Detik -> Panggil prepare() & play() Otomatis
|
+---> [ SUDAH RETRY KEDUA (Persistent Error) ]:
|
+---> Aktifkan SNAPSHOT FALLBACK
+---> Tampilkan Foto Snapshot (/api/frame.jpeg) Refresh 4s
+---> Tampilkan Pesan "Stream Terputus" & Tombol Manual "Coba Hubungkan Lagi"
|
v
[ END ]
🚨 FLOWCHART 3: Alur Pemicu Sirine Bahaya Desa (Instant Emergency Trigger)
[ START: User Mengetuk Kartu Sirine di Dasbor ]
|
v
[ CEK STATUS SIRINE SAAT INI (isSirenActive) ]
|
+---> [ SIRINE SEDANG AKTIF (MENYALA) ]
| |
| +---> Langsung Panggil viewModel.toggleSiren(false)
| +---> Kirim Request POST /api/siren?action=off (Tanpa PIN, Tanpa Dialog)
| +---> Server Menghentikan Relay Sirine ESP32
| +---> Tampilkan Pesan Toast: "Sirine dimatikan"
|
+---> [ SIRINE SEDANG IDLE (MATI) ]
|
+---> Tampilkan Dialog Konfirmasi:
| "Apakah Anda yakin ingin MENYALAKAN sirine bahaya desa?"
|
+---> Decision User:
|
+---> [ Batal ]: Tutup Dialog, Selesai.
|
+---> [ Ya, "Nyalakan Sirine" ]:
|
+---> Panggil viewModel.toggleSiren(true)
+---> Kirim Request POST /api/siren?action=on (Tanpa PIN)
+---> Server Memicu Relay ESP32 (Durasi Diatur Firmware ESP32)
+---> Kartu Sirine Berubah Warna Merah Kedip & Berdenyut
+---> Tampilkan Pesan Toast: "Sirine diaktifkan"
|
v
[ END ]
🔐 FLOWCHART 4: Autentikasi PIN Admin & Keamanan Operasi Tulis (Write Operations)
[ START: User Buka Tab Kelola / Edit Kamera / Kelola Ticker / Hapus Rekaman Massal ]
|
v
[ CEK STATUS AUTENTIKASI ADMIN (_isAuth) ]
|
+---> [ isAuth == true ]: Tampilkan Tampilan Kelola Konten
|
+---> [ isAuth == false ]: Tampilkan Tampilan PIN Auth (PinAuthScreenContent)
|
+---> User Memasukkan Digit Angka PIN pada OutlinedTextField (NumberPassword)
+---> User Menekan Tombol "Masuk"
|
v
[ VALIDASI KLIEN & SERVER ]
|
+---> Cek Klien: Apakah PIN Kosong atau Mengandung Karakter Non-Angka?
| |---> Ya: Tampilkan Error "PIN hanya boleh berisi angka" / "PIN tidak boleh kosong"
|
+---> Kirim Request POST /api/auth dengan Body {"pin": "<input_user>"}
|
v
[ EVALUASI RESPON SERVER ]
|
+---> [ RESPON HTTP 200 {success: true} ]:
| |
| +---> Set _isAuth = true
| +---> Simpan PIN di Memori RAM activePin = pin (TIDAK Disimpan di SharedPreferences)
| +---> Buka Tampilan Kelola Konten
|
+---> [ RESPON HTTP 401 (PIN Salah) ]:
| |
| +---> Tampilkan Pesan Error: "PIN salah"
| +---> Jalankan Animasi Shake pada Kartu Input PIN
|
+---> [ RESPON HTTP 429 (Rate Limit) ]:
|
+---> Tampilkan Pesan Error: "Terlalu banyak permintaan, coba lagi nanti"
|
v
[ EKSEKUSI OPERASI TULIS (Ganti PIN, Upsert Kamera, Delete Kamera, Ticker Management) ]
|
+---> Setiap Request Tulis Mengirim Header HTTP: X-API-PIN: <activePin>
|
+---> Jika Server Mengembalikan HTTP 401 saat Operasi Tulis:
| |---> Reset activePin = "" & _isAuth = false (Sesi Berakhir)
| |---> Minta User Lakukan Login PIN Kembali
|
+---> Khusus Ganti PIN (POST /api/pin):
|---> Input PIN Lama & PIN Baru Wajib Tepat 8 Digit Angka
|---> Setelah Berhasil: Reset activePin = "" & _isAuth = false
|---> Tampilkan Pesan: "PIN berhasil diubah. Silakan masuk kembali dengan PIN baru."
|
v
[ LOGOUT ADMIN: User Mengetuk Tombol "Keluar Admin" ]
|---> Reset activePin = "" & _isAuth = false (RAM Dikosongkan)
|
v
[ END ]
3. CATATAN UNTUK PRESENTASI UPDATE PROGRESS
Saat menjelaskan update progress kepada tim/dosen/stakeholder, Anda dapat menggunakan poin-poin utama berikut:
- Efisiensi Infrastruktur STB:
- Berhasil mengintegrasikan transcoding H.265 ke H.264 pada STB lokal menggunakan
go2rtcdengan pemakaian CPU yang sangat ringan (~6%), sehingga kompatibel dengan seluruh perangkat Android tanpa perlu decoder HEVC khusus.
- Berhasil mengintegrasikan transcoding H.265 ke H.264 pada STB lokal menggunakan
- Keamanan & Tunneling:
- Menggunakan Cloudflare Tunnel (
https://bagaswara.hibahkaranggeneng.site) untuk keamanan akses jarak jauh tanpa IP Publik Statis. - Mengamankan endpoint administratif menggunakan Header HTTP
X-API-PINdan penyimpanan PIN murni di RAM memori (bebas dari kebocoran SharedPreferences/Logcat).
- Menggunakan Cloudflare Tunnel (
- Keandalan Akses Darurat & Hemat Kuota:
- Sirine Darurat: Akses pemicu sirine dapat diaktifkan secara instan (1-tap konfirmasi) tanpa hambatan PIN untuk merespons keadaan darurat desa secepat mungkin.
- Mode Hemat Kuota & Snapshot Fallback: Aplikasi mendukung penghematan kuota dengan opsi penggantian video live stream ke foto snapshot (~10KB) yang di-refresh otomatis jika koneksi lambat.