Dari Pembacaan Meter ke Invoice: Arsitektur Billing Utilitas IoT

Dari Pembacaan Meter ke Invoice: Arsitektur Billing Utilitas IoT
Sistem billing utilitas IoT yang tahan sengketa bentuknya selalu sama: lima tahap, dari pembacaan meter mentah sampai invoice terbit. Saya beberapa kali membangun pipeline ini untuk utilitas gedung — submetering listrik dan air di lokasi multi-tenant — dan polanya tidak pernah berubah.
Dashboard IoT kebanyakan cukup kelihatan masuk akal: grafik meleset satu-dua pembacaan, tidak ada yang protes. Billing beda urusan. Angka di ujung pipeline itu tagihan atas uang orang, dan cepat atau lambat ada tenant yang mempersoalkannya. Jadi setiap keputusan arsitektur dari meter sampai invoice diambil dengan satu asumsi: sengketa itu pasti datang.
Tahap satu: ingestion
Meter utilitas umumnya mengeluarkan data lewat dua cara. Pulse output menutup kontak setiap N liter atau watt-hour — harus ada yang menghitung pulsanya. Bayangkan petugas di pintu masuk yang mengklik tally counter tiap ada tamu lewat: lengah sebentar, hitungan itu hilang selamanya. Register read lain lagi: meter menyimpan total kumulatif yang bisa dibaca lewat Modbus RTU di atas RS-485, mirip odometer mobil. Gateway bertindak sebagai Modbus master, mem-polling meter tiap beberapa detik, lalu mem-publish nilainya ke backend lewat MQTT.
Kalau meter menyediakan register kumulatif, pakai itu. Pulse counter yang sempat offline kehilangan konsumsinya selamanya — pulsanya tetap terjadi, tapi tidak ada yang menghitung. Register kumulatif tidak punya masalah itu: begitu gateway hidup lagi, pembacaan berikutnya otomatis mencakup semua konsumsi selama mati. Satu pilihan di lapisan paling bawah ini menentukan seberapa repot Anda mengurus gap di lapisan paling atas.
Tahap ingestion sendiri — tahap menerima dan mencatat data yang masuk — biarkan tipis: validasi pembacaan, beri identitas meter dan timestamp, simpan mentah-mentah di tabel time-series, tabel data berderet waktu yang tiap barisnya punya stempel waktu. Jangan ada hitung-hitungan di sini. Pembacaan mentah itu barang bukti — semua angka di hilir nanti diaudit balik ke sana.
Tahap dua: agregasi interval
Pembacaan mentah masuk tiap beberapa detik, sementara tarif dan invoice berpikir dalam jam, hari, dan bulan. Tahap agregasi menjembatani keduanya: pembacaan kumulatif digulung jadi interval konsumsi. Hitungannya sederhana — konsumsi satu interval adalah selisih nilai register di akhir dan di awal interval.
Simpan interval di tabel terpisah, diturunkan dari data mentah, dan jangan pernah menimpa data mentahnya. Saat tenant mempersoalkan tagihan, Anda tinggal menyusuri rantainya mundur: dari baris invoice ke interval yang dicakupnya, dari interval ke pembacaan mentah di dalamnya. Agregat yang menimpa inputnya sendiri tidak akan bisa menjawab pertanyaan itu.
Tahap tiga: tariff engine
Tariff engine mengubah konsumsi jadi uang: harga per kWh atau per meter kubik, tier konsumsi, biaya tetap bulanan, plus override per tenant atau per gedung. Dua aturan yang membuatnya bisa dipertanggungjawabkan:
- Tarif diberi versi, bukan diedit. Perubahan harga berarti baris tarif baru dengan jendela masa berlaku. Versi tarif yang dipakai menghitung invoice lama harus tetap ada, utuh, saat sengketanya baru datang setahun kemudian.
- Invoice mencatat versi tarif yang dipakai menghitungnya. Hitung ulang invoice lama harus menghasilkan angka lama persis — bukan angka dengan harga hari ini.
Tahap empat: siklus billing dan pembuatan invoice
Tiap tenant punya ritme tagihan sendiri: harian untuk skema mirip prabayar, mingguan untuk tenant komersial jangka pendek, bulanan untuk sisanya. Scheduler memeriksa billing plan dan membuat invoice setiap kali satu siklus tutup.
Batas siklus itu konsep kalender, jadi scheduler wajib paham timezone. "Akhir 30 Juni" jatuh di momen berbeda untuk tiap lokasi. Portofolio yang melintasi beberapa wilayah harus mengelompokkan pembacaan per hari lokal masing-masing lokasi — masalah yang saya bahas di mengelompokkan time-series per hari lintas timezone di PostgreSQL.
Pembuatan invoice dua langkah, bukan satu. Sistem menghasilkan draft yang bisa direview operator; manusia atau aturan approval yang menerbitkannya. Begitu terbit, invoice tidak boleh diubah lagi — koreksi masuk sebagai credit note atau baris penyesuaian, bukan edit.
Pembacaan hilang dan gap
Gateway kehilangan daya. Jaringan putus. Yang membedakan platform billing dari spreadsheet adalah kejujuran sistemnya selama gap itu.
Dengan register kumulatif, gap cuma mengorbankan resolusi, bukan uang. Pembacaan pertama setelah gateway hidup lagi mencakup seluruh periode kosong; konsumsinya Anda sebar sepanjang gap sebagai interval estimasi, dan ditandai begitu. Dengan input pulse, konsumsinya benar-benar hilang. Opsi yang bisa dipertanggungjawabkan tinggal dua: estimasi dari profil historis — lagi-lagi dengan tanda — atau kirim orang untuk baca meter langsung.
Apa pun jalannya, kuantitas estimasi harus tampil di invoice sebagai estimasi. Menyembunyikan tanda itu adalah resep mengubah gangguan kecil jadi skandal tagihan.
Karantina juga perlu: pembacaan yang lompatannya tidak masuk akal — register mundur, delta melebihi kapasitas fisik meter — ditahan di luar jalur billing sampai ada orang yang melepasnya. Penyebab klasiknya penggantian meter. Meter baru mulai dari nol, dan tanpa catatan serah terima, deltanya kelihatan seperti tenant mengisi kolam renang semalaman.
Audit trail
Semua tahap di atas bermuara di sini. Untuk tiap invoice terbit, sistem harus bisa menunjukkan: pembacaan mentahnya, interval turunannya, versi tarif yang dipakai, siapa yang membuat draft, siapa yang menerbitkan, dan setiap estimasi yang ditandai di sepanjang jalan.
Rantai itulah produknya. Tenant tidak percaya tagihan karena dashboard-nya cantik. Mereka percaya karena begitu bertanya "angka ini dari mana", jawabannya keluar dalam hitungan detik — dan tahan digugat.
Intinya
Simpan data mentah selamanya. Agregasikan ke interval tanpa membuang sumbernya. Hitung harga lewat tarif berversi. Buat draft, biar manusia yang menerbitkan. Tandai setiap estimasi.
Lakukan lima hal itu, dan sengketa berubah dari adu argumen jadi sekadar lookup. Infrastruktur yang lebih luas di bawahnya — broker, ingestion, dashboard live — saya bahas di panduan lengkap backend IoT.
Artikel Terkait
Mau bangun hal serupa?
Jasa Pengembangan Backend IoT & Integrasi Multi-Protokol
Backend yang menyerap telemetri perangkat lintas MQTT, WebSocket, Modbus, dan BLE, lalu menyatukannya jadi dashboard real-time yang andal.
Lihat cara saya bisa bantu