MajiGuard
IoT Water Quality Monitoring with ML Anomaly Detection and a RAG Advisory Engine
Solo Developer and Researcher · Sept 2025 - May 2026 · University of Nairobi (BSc Dissertation)

MajiGuard is a low-cost, IoT-based water quality monitor built as my final year dissertation at the University of Nairobi. It reads four water parameters continuously, tells a genuine contamination event apart from a sensor that has simply drifted, forecasts where the water is heading over the next 24 hours, and turns all of that into a plain-language safety advisory grounded in WHO and Kenya Bureau of Standards guidelines. The complete unit, sensors, enclosure and microcontroller, costs under KES 15,000 to build.
The problem
Around 41% of rural Kenyan households draw drinking water from unimproved sources such as rivers and unprotected wells, and even piped or borehole supply is inconsistent. Laboratory testing is accurate but slow, results typically take 24 to 72 hours, and expensive enough that it can only cover a fraction of household water sources. Contamination events between test dates go undetected entirely. MajiGuard targets that gap directly: continuous, low-cost monitoring at the point of use, with an alert that arrives while the water is still in the container.

Architecture
The system is three layers. An ESP32 sensor node reads pH, turbidity, total dissolved solids and temperature every 30 seconds and uploads them to Firebase Realtime Database. An always-on Python listener subscribes to that stream, runs the anomaly detection and forecasting pipeline on every new reading, and, when it flags a problem, generates a retrieval-augmented safety advisory and writes the result back to Firebase. A React Native mobile app polls Firebase for live readings and results, and presents everything as a single 0 to 100 water quality score with detail available underneath.
Anomaly detection: telling contamination from a broken probe
Water quality anomaly detection has to be unsupervised, since labelled contamination events are rare and expensive to collect. MajiGuard blends two models: a batch Isolation Forest trained on the site's own clean history for a stable baseline, and an online River HalfSpaceTrees model that adapts incrementally as conditions drift, weighted 0.6 and 0.4 respectively.
On top of that sits a rule that turns out to matter more in practice than either model alone: when a reading is flagged anomalous, the system counts how many of the four parameters are simultaneously implausible. One parameter out of range reads as SENSOR_DRIFT, a hardware fault. Two or more reads as CONTAMINATION. That distinction is deliberately conservative toward the drift side, since a false contamination alert means a household discards water that was probably fine, and it propagates through the whole stack, from the anomaly score to the wording of the advisory itself.

Forecasting
Two forecasting approaches cover different horizons. A rolling-window Ridge Regression model predicts pH, turbidity and TDS at 1, 3 and 6 hours out. Facebook Prophet extends that to 6, 12 and 24 hours with 80% credible intervals, decomposing the series into trend and daily seasonality so it degrades gracefully on the gaps and irregular sampling that come with a real IoT deployment.

The advisory engine
Large language models are useful for turning a numeric anomaly score into something a non-specialist can act on, but they hallucinate specific numbers if left ungrounded, which is not acceptable for a safety threshold. MajiGuard's advisory engine retrieves from a curated 20-chunk knowledge base built from WHO Guidelines for Drinking-Water Quality and Kenya Bureau of Standards KS 459-1, embedded with all-MiniLM-L6-v2 and indexed in FAISS. The top three matching chunks for the current anomaly are injected into a prompt sent to LLaMA 3.3 70B, so an advisory citing a pH threshold or a treatment cost in KES is citing something that was actually retrieved, not recalled from the model's training data.
The mobile app
The React Native Expo app is built around a single principle: nobody should need to interpret raw millivolt readings to know if their water is safe. The home screen leads with a 0 to 100 Water Quality Index and a plain SAFE, CAUTION, or UNSAFE badge; sensor detail, a 24-hour trend chart, the anomaly panel and the forecast card are all one tap away for anyone who wants them. A remote calibration wizard lets a two-point pH calibration be pushed to the device over Firebase, no physical access or reflashing required.

Results
82% precision, 100% recall, F1 of 0.90 across a 1,373-reading labelled evaluation set built from four controlled contamination experiments.
Zero missed contamination events across all four experiments: acid contamination (lemon juice), turbidity and TDS contamination (drinking chocolate), and two real river water samples.
TDS forecasting beat a naive persistence baseline at every horizon tested, with a 67% MAE reduction at one hour.
pH accuracy within plus or minus 0.08 pH units against reference buffer solutions, within WHO's field instrument tolerance.
Total hardware cost of KES 13,200, against a KES 15,000 target.
What's next
The system has been validated on a lab bench and in controlled experiments, not in a real multi-week field deployment, which is the obvious next step and would also fix the current training data's biggest limitation: a single water source over a single day. After that: persistent local storage so a lost Wi-Fi connection does not mean a lost reading, and a path toward detecting bacteriological contamination directly rather than through turbidity as a proxy.