Wastewater tracking app with HMS ML Kit sound detection and Jetpack Compose
Water is a finite resource and we should be aware to not waste it.
It’s estimated that the average American uses about 575 litres of water a day, while the average European uses around 250 litres of water.
Can you imagine how much is 250 litres?
Imagine a room filled with 250 of those big one litre bottles!
Sometimes is hard to figure out how much water we are wasting with simple gestures and habits.
With the help of current technologies, we can quickly increase this awareness.
I’ve developed a demo app using Machine Learning to detect when water is running and giving an estimation of how many litres we are consuming.
It’s should not be considered as a perfect tracker as many variables are in the game, like how much water runs through your tap every second or if there are any leaks in the system.
But it can help to give us a rough idea.
The App
This app UI is based on a trivial design:
Just one button, a counter and a water animation.
Tapping on the button will enable or disable the listening for water running.
The component for the button is very similar to the approach used for
If running water is detected we will see a cool animation of water raising from the bottom of the screen to the top and an increasing counter, representing how many litres we are consuming.
When the water has stopped the animation and the counter will pause until maybe the water is running again or we decide to stop listening tapping the button again.
Water detection
To detect the sound of the water running I’ve used HMS ML Kit. This SDK has the interesting feature enabling detection of common sounds, among these, there is the Water Running sound.
The code using the HMS ML Kit capabilities are enclosed in the SoundDetector class
If you need more info about the API of HMS ML Kit Sound Detections you can refer to this article :
and the official documentation:
At the moment this framework does not raise any event if the sound is not listened to anymore, so to identify this kind of event I’ve used a system of timeouts:
Every time the running water is detected we stop the detector and we will enable it to check again in X seconds ( You can configure these parameters as you prefer)
We assume that during this wait the water is still running, choosing a good time parameter can make us achieve a good estimation.
When the detector is started again if it does not detect any water after Y seconds we can assume the water has been stopped and we pause the counter and the animation, waiting for the water to be detected again.
This system designed in this way has a little “inertia” to perceive when the water is stopped but it is compensated by the detection time to detected the water running as the SDK needs 6/7 seconds to understand that effectively the water is started.
The time is started from the first time when the running water is detected and every second we modify the counters and check the condition to update the UI
The UI composition
To implement the UI part, I’ve used Jetpack Compose, because Who wants to touch XML again to build beautiful UIs :) ?
The main UI is just composed of a Box containing the composable of the Counter (Text), the Button (DetectorStatus) and the Water animation (TimeWave)
In depth, to create the water animation part we’ve used the API to draw on the Canvas using the same idea of Julien Salvi.
If you are interested in how can we use Jetpack Compose and the Canvas API I suggest you read his article:
The TimeWave composable in this case is just modified to draw two waves using 2 paths in the canvas animated as waves and translating them from the bottom of the screen to the top, gradually, if the running water is detected
Conclusion
That’s a wrap, if you need the complete source code you can check it here:
And try to think every day to not waste our precious water!