eKiosk IKN
Dua ruang kendali untuk Nusantara: konten kios dan pelacakan bus live dengan estimasi kedatangan yang menilai dirinya sendiri

- ruang kendali: konten kios dan armada bus
- 2
- jeda pembacaan posisi bus live
- ~5 dtk
- rentang akurasi kedatangan, per jam dan halte
- 1/2/3 mnt
- halaman di kedua aplikasi
- 24
Di halaman ini
Masalahnya
Program kota cerdas IKN menempatkan kios informasi di ruang publik di seluruh Nusantara. Setiap kios menjalankan aplikasi yang menampilkan konten pemerintah: peta, pengumuman, dan jadwal transportasi. Tanpa kendali terpusat, mengubah tampilan sebuah kios berarti harus mengurus perangkat itu satu per satu. Cara ini tidak bisa bertahan saat jumlah kios terus bertambah. Operator juga tidak tahu apakah sebuah kios menyala, macet, atau masih menampilkan konten lama.
IKN juga mengoperasikan armada bus rapid transit. Layanan internal sebelumnya hanya menyimpan posisi bus di memori. Tidak ada riwayat, dan layanan itu tidak bisa memberi tahu penumpang atau operator kapan bus berikutnya tiba. Ada dua tim yang butuh alat: staf konten yang mengelola playlist kios, dan staf transportasi yang memantau armada.
Yang saya bangun
Kios melapor, server yang menentukan statusnya
Setiap kios melapor setiap lima menit: apa yang sedang diputar, di mana posisinya, serta sisa storage dan memorinya. Dari laporan itu, server menentukan apakah kios beroperasi, tertinggal, terputus, atau sedang dirawat. Setiap playlist membawa sidik jari yang berubah saat isinya berubah. Kios melaporkan sidik jari yang terakhir dimuatnya, jadi server langsung tahu apakah perangkat itu tertinggal. Operator menyusun playlist dengan menyeret media ke urutan yang diinginkan, dan perubahannya sampai ke kios dengan sendirinya.
Estimasi kedatangan dari riwayat bus itu sendiri
Sebuah layanan latar membaca posisi GPS setiap bus kira-kira setiap lima detik dan menempatkannya di rutenya. Untuk waktu kedatangan, saya tidak memakai kecepatan tetap. Setiap malam, sebuah job mempelajari perjalanan sebelumnya dan menghitung berapa lama biasanya setiap ruas antarhalte ditempuh, per jam dan per hari kerja atau akhir pekan. Estimasi dimulai dari posisi bus di jalan, lalu ditambah waktu tempuh hasil belajar itu halte demi halte. Kalau riwayatnya belum cukup, sistem memakai jadwal, lalu jarak, lalu jumlah halte, jadi selalu ada jawaban.
Sistem menilai prediksinya sendiri
Saya ingin tahu apakah estimasi kedatangannya akurat, jadi sistem ini memeriksa dirinya sendiri. Sistem mengambil sampel prediksinya, lalu mencatat selisihnya begitu bus tiba di halte itu. Sebuah laporan menampilkan rata-rata selisih dan persentase kedatangan yang meleset dalam satu, dua, atau tiga menit, dirinci per jam dan per halte. Staf bisa melihat persis di mana estimasinya paling lemah.
Bus yang pindah rute terdeteksi tanpa bolak-balik
Bus kadang dipindahkan atau keluar dari rute jadwalnya. Sebuah pemeriksaan terpisah membandingkan lintasan terakhir setiap bus dengan semua rute, lalu menyarankan koreksi kalau satu rute jelas paling cocok. Versi pertama saya memindahkan bus setelah beberapa titik GPS berada dekat rute lain. Di halte yang dilewati beberapa rute sekaligus, bus jadi berpindah bolak-balik. Sekarang perpindahan hanya terjadi setelah bus melewati halte yang khas milik rute baru, atau minimal 80% halte rute itu. Setiap koreksi dicatat.
Dua aplikasi, satu login
Yang awalnya satu dashboard dengan tab armada sekarang menjadi dua aplikasi terpisah, eKiosk CMS dan Fleet Management, dengan launcher bersama dan tombol untuk berpindah di antara keduanya. Operator login sekali lewat single sign-on IKN, dan Fleet Management hanya untuk staf. Kios tidak memakai login itu sama sekali. Kios mendaftar dengan ID yang diberikan saat pertama menyala, karena tidak ada orang yang login di sana.
Hasilnya
Kedua aplikasi berjalan di produksi untuk IKN, dengan total 24 halaman. Staf konten mengelola playlist kios dan memantau kesehatan perangkat, lengkap dengan grafik tren dan email peringatan saat kios tidak melapor. Staf transportasi mendapat peta bus live, editor rute dan halte, jadwal armada, perencana perjalanan dengan titik tujuan, serta laporan jarak antarbus, waktu tempuh, dan akurasi kedatangan. Laporan armada harian dulu sering timeout saat beban tinggi, jadi saya menulis ulang menjadi satu kueri database. Pengerjaannya berlangsung dari Maret sampai Juli 2026. Sistem ini hanya melacak kendaraan; tidak ada data penumpang atau tarif.
Di balik layarDetail teknis untuk engineer
- Status kios (OPERATIONAL / STALE / DISCONNECTED / MAINTENANCE) adalah
@propertymodel yang diturunkan darilast_heartbeat,heartbeat_interval,operational_status, dan hash playlist, jadi tidak bisa difilter lewat ORM. Endpoint ringkasan memfilternya di Python. - Setiap playlist menyimpan hash SHA-256 deterministik dari item-item terurutnya, dihitung ulang saat disimpan. Status sinkronisasi cukup dibandingkan dalam O(1).
- Endpoint kios memakai
AllowAny; kios dikenali lewat UUID yang diberikan saat boot pertama. Pengguna dashboard login lewat Keycloak denganmozilla-django-oidc, JWT disimpan di Zustand, dan NIP, jabatan, serta direktorat disinkronkan keUserProfilesetiap login. poll_gps_databerjalan sebagai service Docker sendiri,transport-poller. Pergerakan di-bulk-insert keVehicleTrackkira-kira setiap 60 detik, hanya jika melewati jarak minimum.RouteGraphadalah directed graph buatan sendiri dengan sentinel terminal yang menutup loop. Ini menghindari dependensi networkx sebesar 30 MB.compute_segment_statsberjalan tiap malam lewat cron di host. Job ini memecah riwayat GPS menjadi perjalanan, membuang outlier di atas 3× median, dan menyimpan median, p25, dan p75 per bucket (rute, halte asal, halte tujuan, jam, hari kerja/akhir pekan) setelah ada minimal tiga sampel.- ETA memproyeksikan posisi GPS ke segmen polyline yang sedang dilalui, lalu berjalan maju lewat bucket
SegmentTravelStat. Fallback: selisih jadwal, jarak haversine dibagi kecepatan asumsi, lalu jumlah halte. EtaPredictionLogmengambil sampel paling banyak sekali per kendaraan dan halte berikutnya per 60 detik, ditutup saat bus masuk geofence dengan selisih bertanda dalam detik.route_detectormenilai lintasan dengan jarak tegak lurus ke segmen terdekat, dengan margin keyakinan terhadap rute runner-up dan gerbang konfirmasi spasial. Kembali ke rute jadwal butuh beberapa tick konfirmasi. Perubahan dicatat diRouteCorrectionLog.- Analitik armada adalah satu kueri PostgreSQL dengan
LAG(), haversine inline, dan klausaFILTER, menggantikan loop Python yang membuat worker gunicorn timeout. - Tanpa pandas, numpy, geopy, shapely, networkx, Celery, atau Redis. Statistik memakai modul stdlib
statistics. - Frontend: React 19 dan Vite, polling TanStack Query (kendaraan setiap 5 detik, panel kinerja setiap 30 detik, tanpa websocket), React Leaflet, @dnd-kit, Recharts, dan design system inline-style buatan sendiri tanpa library komponen.
- 4 Django app, sekitar 30 action di
TransportViewSet, sekitar 7.500 baris Python dan 17.200 baris JSX, 113 commit backend dan 133 commit frontend.
Tangkapan layar
Sedang merekrut, atau membangun hal serupa?
Saya terbuka untuk posisi full-time dan proyek freelance tertentu.