Overview
Perumdam Tirta Pandalungan is the water utility for Jember Regency. Every month, meter readers walk routes, check customer meters, write readings on paper forms, then hand them to data entry staff who type everything into a system. Slow, error-prone, and wasteful.
DIMETRI is a mobile app that puts the data entry in the field. Meter readers use their phones to log readings on-site. The app validates the data, flags anomalies, and syncs to the billing system. No paper. No double entry. No transcription errors.
I built both the mobile app and the backend API. The app had to work offline because meter readers don't always have signal. It had to be fast because they have hundreds of meters to read per day. And it had to be accurate because billing depends on it.
This is the kind of project that doesn't win design awards, but it saves thousands of hours of manual work. Infrastructure software. Boring, essential, and satisfying when it works.
Client
Perumdam Tirta Pandalungan serves over 100,000 customers in Jember Regency, East Java. They're a government-owned utility, which means they care about efficiency and accountability. They also have limited budgets, so the solution had to be cost-effective.
The meter reading process was their biggest bottleneck. Readings took weeks to process. Errors caused billing disputes. They needed to modernize, but they couldn't afford a big enterprise system.
Features
Route management assigns meter readers to specific areas with customer lists. The app shows the route on a map and guides readers through their assigned meters in sequence. Each customer has a profile with address, meter number, and reading history.
Meter reading is the core feature. Readers enter the current reading, take a photo of the meter, and submit. The app validates the reading against historical data — if it's too high or too low, it flags it for review. GPS coordinates are logged to verify the reader was on-site.
Offline mode is critical. Readers download their route data at the start of the day and work offline. Readings are stored locally and synced when they're back online. The sync is smart — it handles conflicts and retries failed uploads.
Anomaly detection catches common errors. If a reading is lower than the previous month (possible meter rollover or typo), the app warns the reader. If it's unusually high (leak or data entry error), it requires confirmation. This reduces billing disputes.
Tech Stack
Flutter for the mobile app. GetX for state management and routing. SQLite for local storage with background sync. Google Maps API for route visualization and GPS logging.
Laravel for the backend API. MySQL for the database. JWT authentication with role-based access. The API handles route assignments, reading submissions, anomaly detection, and reporting.
Image compression before upload to save bandwidth. Retry logic for failed syncs. Push notifications for route assignments and system updates.
My Role
Full-stack developer. I designed the database schema, built the backend API, developed the mobile app, and deployed both to production. I also worked with the client to map their existing workflow and identify pain points.
The offline sync was the hardest part. Meter readers might be offline for hours. I had to ensure data integrity, handle conflicts, and make sure nothing got lost. Ended up with a queue-based system that stores readings locally and syncs in batches.
I also had to think about edge cases. What if a meter is broken? What if a customer refuses access? What if the reader makes a typo? The app needed to handle these scenarios without blocking the workflow.
Training was important. I ran sessions with the meter readers to show them how to use the app. Got feedback, fixed bugs, and simplified the UI based on what they actually needed. The first version had too many features. I stripped it down to the essentials.
The app has been in production for over a year. The utility reports faster billing cycles, fewer errors, and better data quality. Meter readers like it because it's faster than paper. That's a win.
