Langsung ke konten
AFM Studio
  • Halaman

    AFM Studio
  • Karya
  • Lab
  • Tentang
  • CV
  • Kontak
  • Proyek

    AksaraPerpustakaan pengetahuan Otorita IKN yang bisa dicari, dengan server memeriksa akses setiap pembaca di tiga tingkat
  • Daily TaqwaSistem presensi salat anti-manipulasi untuk ~2.000 pegawai OIKN di Masjid Negara IKN
  • Lantara v2Mesin perizinan Otorita IKN tempat administrator menambah jenis izin baru dari layar, tanpa developer
  • eKiosk IKNDua ruang kendali untuk Nusantara: konten kios dan pelacakan bus live dengan estimasi kedatangan yang menilai dirinya sendiri
  • E-Monev IKNPlatform pemantauan pembangunan Nusantara selama 23 tahun, melacak progres triwulan setiap unit terhadap 24 KPI
  • JDIH OIKNPortal dokumen hukum publik OIKN, dengan alur penerbitan terkendali dan ringkasan AI yang tidak pernah keluar dari server
  • Jejak PenanamanAplikasi absen acara penanaman pohon IKN yang membuktikan peserta hadir di lokasi lewat selfie ber-geofence
  • Dashboard SAKTIPipeline malam dan dashboard yang menggantikan unduhan anggaran manual di keenam satker OIKN
  • DoseRxKalkulator dosis untuk 127 obat yang membulatkan dosis ke tablet dan sirup yang dijual apotek Indonesia
  • CubiqPelatih speedcubing dengan timer setara kompetisi dan solver buatan sendiri untuk 8 puzzle utama
  • ScimotionPerpustakaan sains interaktif berisi 86 artikel, masing-masing dijelaskan bersama animasi yang bisa dikendalikan pembaca
  • WA Daily Scrum BotBot WhatsApp yang menagih laporan standup tim 14 orang dan menandai tugas yang macet berhari-hari

↑ ↓ untuk berpindah · Enter untuk membuka · Esc untuk menutup

ClimateWatch

Situs riwayat iklim untuk 94 kota di Indonesia, dengan suhu dan curah hujan harian sejak 1950

Tangkapan layar
kota di Indonesia dengan data iklim harian
94
tahun catatan iklim harian, sejak 1950
77
episode El Niño dan La Niña yang dilacak
45
Di halaman ini

Masalahnya

Orang Indonesia terus mendengar soal perubahan iklim, tapi hampir tidak ada yang bisa menunjukkan angka kotanya sendiri. Apakah kota saya memang makin panas, makin basah, atau makin kering? Datanya ada. Data itu tersimpan di dataset reanalysis global sebagai baris harian mentah, yang tidak bisa dibaca pelajar, jurnalis, atau petani tanpa menulis kode.

Saya membangun ClimateWatch untuk pembaca seperti itu: masyarakat yang penasaran, pelajar, jurnalis yang butuh konteks cepat, dan petani yang peduli kapan hujan mulai turun. Aplikasi ini mengubah puluhan tahun data suhu dan curah hujan harian menjadi grafik yang bisa dibaca dalam hitungan detik. Gratis, tanpa login.

Yang saya bangun

Satu pengaturan tetap mencegah tren pemanasan palsu

Arsip Open-Meteo diam-diam berganti model cuaca di tengah rekamannya, dan saya menemukan pergantian itu sendiri menambah sekitar 1,5°C ke suhu tertinggi harian Jakarta hanya dalam satu tahun, cukup untuk memalsukan tren pemanasan yang sebenarnya tidak ada di data. Saya mengunci setiap permintaan ke satu keluarga model saja, supaya seluruh rekaman dari 1950 sampai sekarang tetap sebanding. Indonesia memang punya sedikit stasiun cuaca dengan catatan panjang yang tidak terputus. Itu sebabnya dataset reanalysis ini cocok sejak awal: data harian tanpa celah untuk titik mana pun di peta, ada stasiunnya atau tidak, untuk ke-94 kota dengan cara yang sama.

Setiap grafik membaca ringkasan yang sudah dihitung

Sembilan puluh empat kota dengan data harian sejak 1950 berarti jutaan baris. Saya meringkasnya menjadi tabel bulanan dan tahunan lebih dulu, lewat proses latar yang terjadwal. Saat halaman dibuka, aplikasi cukup membaca tabel kecil, tanpa menjumlahkan puluhan tahun data saat itu juga. Data hariannya disimpan di database time-series, dipecah per tanggal dan diindeks sesuai cara halaman memintanya: per kota, lalu per tanggal.

Data yang kosong tetap kosong

Kalau sumber tidak punya nilai untuk suatu hari, saya menyimpannya sebagai kosong. Saya tidak pernah mengubahnya menjadi nol. Hujan nol milimeter dan "kita tidak tahu" adalah dua fakta berbeda, dan data kosong sering muncul di tahun-tahun awal. Sebuah lencana peringatan memberi tahu pembaca kalau cakupan data sebuah kota atau bulan terlalu tipis untuk dipercaya.

Hari panas berarti berbeda di tiap daerah

Ambang 35°C untuk "hari panas" adalah konvensi iklim sedang, dan itu tidak berlaku di sebagian besar wilayah maritim Indonesia. Seperempat kota yang datanya sudah dimuat tidak pernah sekalipun melewati ambang itu dalam 77 tahun, jadi grafik hari panasnya kosong saja. Saya menambahkan ambang kedua yang relatif per daerah, yaitu 5% hari terpanas masing-masing kota dari baseline 1951-1980-nya, dan tetap menyimpan angka 35°C tetap hanya untuk membandingkan antarkota.

Frontend yang sama berjalan dengan dua cara, live atau statis

Open-Meteo diketahui pernah macet atau membatasi permintaan dari GitHub Actions, jadi mengimpor data saat build di cloud tidak bisa diandalkan, dan sebuah backend butuh biaya untuk terus menyala. Frontend-nya kini beralih lewat satu variabel lingkungan antara memanggil API Django yang live atau membaca hasil ekspor JSON siap pakai. Saya menjalankan impor dari koneksi biasa sendiri dan meng-commit hasilnya, jadi deploy publiknya tidak butuh server dan tidak butuh panggilan live ke Open-Meteo sama sekali.

Hasilnya

ClimateWatch sudah live di GitHub Pages, dan kodenya publik. Cakupannya 94 kota di Indonesia dengan 77 tahun data harian, dari 1950 sampai sekarang. Setiap halaman kota menghitung hari panas, hari hujan lebat, dan gelombang panas terpanjang per tahun dengan garis tren, dan memperkirakan kapan musim hujan dimulai. Panel "Looking ahead" kini memproyeksikan masa depan tiap kota dari beberapa model CMIP6, di luar rencana awal. Pengguna bisa membandingkan dua kota, melihat bagaimana 45 episode El Niño dan La Niña yang terlacak mengubah cuaca sebuah kota, dan mengurutkan semua kota berdasarkan panas, hujan, atau kecepatan pemanasannya.

Situs live-nya adalah snapshot statis: Open-Meteo membatasi server build di cloud, jadi saya menjalankan impor sendiri lalu menerbitkan berkas datanya, dan angkanya diperbarui hanya saat saya menjalankan ulang ekspor itu. Saya membangunnya antara Juli dan September 2026.

Di balik layarDetail teknis untuk engineer
  • Data berasal dari ERA5 lewat API arsip Open-Meteo. PRD menyebut archive.open-meteo.com, yang tidak bisa di-resolve; host yang benar adalah archive-api.open-meteo.com.
  • Enam model konkret: IndonesiaRegion, ClimateDaily, ClimateMonthly, ClimateAnnual, ENSOEvent, ClimateProjection. Celery Beat (django-celery-beat) menjadwalkan pengambilan data harian dan ringkasan bulanan/tahunan.
  • ClimateProjection menyimpan perubahan tiap model CMIP6 terhadap rata-rata model itu sendiri di 1995–2014, bukan suhu absolut mentah, karena tiap model punya bias skala kota sebesar satu derajat lebih.
  • ClimateDaily adalah hypertable TimescaleDB yang dipartisi pada date. Hypertable mewajibkan setiap unique index memuat kolom partisi, jadi primary key id otomatis dihapus dan diganti constraint keunikan komposit (region, date), yang juga cocok dengan indeks kueri utama.
  • Pengambilan data memakai potongan per tahun dengan jeda sopan, exponential backoff pada HTTP 429 dengan atau tanpa header Retry-After, dan bisa dilanjutkan dengan --skip-existing. seed_demo membuat data sintetis yang bisa direproduksi, berlabel bukan ERA5.
  • Awal musim hujan adalah jendela 5 hari pertama setelah 1 Agustus dengan curah hujan kumulatif minimal 40 mm. Garis tren adalah regresi linear dari simple-statistics. Fase ENSO diambil dari data kejadian ONI milik NOAA.
  • Fingerprint dibuat dengan D3 secara manual; grafik lainnya memakai Recharts, kini hanya grafik batang bulanan dan panel bandingan, setelah grafik hari-ekstrem dan pergeseran-musim yang semula berdiri sendiri dilebur menjadi lapisan yang bisa dinyalakan-matikan di Fingerprint. Peta cakupan di beranda menggambar garis pantai Indonesia dari topojson-client dan world-atlas, tanpa Leaflet.
  • Perbaikan warna: ramp satu warna dari gelap ke terang, diperiksa monoton pada kecerahan dan saturasi.
  • Desain gelap "Musim Nokturnal" menggantikan palet terang "Musim" dari PRD. Setiap warna data diperiksa kontras WCAG-nya terhadap permukaan yang sebenarnya, dan warna mengikuti kota di semua grafik, bukan metriknya.
  • Satu frontend bisa di-build dua cara, diatur oleh NEXT_PUBLIC_DATA_MODE: memanggil Django REST API yang live, atau static export Next.js yang membaca JSON siap pakai. manage.py export_static menulis JSON itu; workflow Pages menyalinnya ke public/ lalu build. Bootstrap di CI dihapus karena Open-Meteo menahan permintaan dari runner GitHub Actions.
  • Situsnya dwibahasa, Indonesia lebih dulu, merender kedua bahasa ke HTML statis dan menampilkan salah satunya lewat boot script sebelum render pertama.
  • Static export-nya sekitar 33 MB di 1.416 berkas JSON. Frontend-nya punya 46 komponen di 6 route utama (beranda, kota, bandingkan, peringkat, cerita, tentang); backend-nya punya 8 perintah manajemen dan 14 kasus tes.
  • 16 route API dan 161 commit antara 3 Juli dan 28 September 2026. Pada snapshot pertengahan proyek sebelumnya, backend berisi sekitar 1.980 baris Python dan frontend sekitar 3.525 baris TypeScript.

Tangkapan layar

Beranda
Beranda (2)
Beranda (3)
City Detail
City Detail (Sidik Iklim)
City Detail (Forecast)

Sedang merekrut, atau membangun hal serupa?

Saya terbuka untuk posisi full-time dan proyek freelance tertentu.