The problem
Decompression illness comes from ascending without the stops a diver’s body needs, and the rules that prevent it live in dive tables that are easy to misread under water. Everything else a diver needs — a logbook, the weather, the nearest hospital — is scattered across separate apps and paper. A client asked me for one planner that put all of it in a diver’s pocket.
The tables are the hard part to get right. The Recreational Dive Planner is split into three tables, and each one depends on the result of the one before it: a first dive gives a pressure group, a surface interval changes that group, and the group then sets the limits for the next dive. A diver reading them on a boat, tired and in a hurry, can easily pick the wrong row. The first thing I had to do was understand the tables well enough to turn them into code, and only then ask where a trained model could add something the tables alone could not.
Who it was for
Recreational divers, on a single trip or a regular schedule, who wanted one place to plan a dive, check it, log it, and reach help if something went wrong.
My role
I owned and implemented the Dive Simulation & Safety Profile Planner end to end: requirements, dive-domain research, collecting and preparing the training data (partly through web scraping), training and comparing the safety-classification models, the recommendation logic, the Android app, Firebase, API integration, hosting, testing, and delivery.
What I built
The app is a planning and education aid, not a safety device. It doesn’t replace a dive computer, formal training, or a diver’s own judgement — it’s a second check that sits alongside those things, built to help someone think through a plan before they’re in the water.
A typical session starts with signing in with Google and confirming the email address from a message the app sends, which the app requires before it saves anything. From the Dive tab, a diver can open eRDPML to work out a pressure group: bottom time and maximum depth for a first dive, or surface interval and the previous pressure group on top of those for a second one. Or they can open AI Simulation, enter depth, bottom time, the oxygen percentage in the tank, and whether it is the first or second dive of the day, and tap Check. PPO₂ is calculated for them from the depth and the gas mix, so there is one less number to get wrong.
AI Simulation
Enters a planned dive and asks the trained model whether it's safe, based on max depth, bottom time, O₂ percentage, dive order, and surface interval.
eRDPML
The RDP tables as a calculator — pressure group for first and repetitive dives, with a no-decompression-limit warning.
MOD calculator
Maximum operating depth, worked out from FO₂ and PPO₂.
Logbook
Records location, instructor, and date for every dive.
Accident report form
A structured form for a responder arriving at an unresponsive diver.
Weather
Live conditions, a map-picked location, and a 7-day forecast.
Emergency
The local emergency number (123), nearest hospitals, the DAN hotline, and safety tips in one place.
Egyptian dive-site guide
A guide to dive sites along the Egyptian coast.
Google sign-in
Sign-in with email verification before any dive data is saved.

Check
Enter a planned dive — max depth, bottom time, and gas mix — and ask the model.

Flag it
A flagged plan surfaces "Recommend a Safe One!" with one tap.

Recommend
From 45 m / 10 min, the app searched shallower and shorter until the model accepted a plan: 37 m / 2 min.
01 / 01












01 / 01
How it works
The Android client posts a dive plan to a hosted model API, which returns a safe or not-safe result; a not-safe result feeds the recommendation loop, which narrows the plan and asks again, while the same client also talks to the eRDPML calculator, Firebase, and map and weather services directly.
The model itself lives behind a small Python API hosted on PythonAnywhere, so the Android app never carries the model. It sends the plan, gets back safe or not safe, and the Recommend button repeats that exchange with a shallower, shorter plan each time. Firebase handles sign-in and holds users, logbook entries, and accident reports, Google Maps Platform supplies the map picker and the nearest hospitals, and OpenWeather supplies live conditions and the seven-day forecast. Because the app depends on that many outside services, I traced the traffic between them while I built it to confirm that every request and response was what I expected.
Two of the features are there for the worst day of a dive. The accident report is a form that can be filled in and saved ahead of time or completed when the ambulance arrives, so responders reaching an unresponsive diver can see quickly what happened. The Emergency screen puts a call to the local number, the nearest hospitals one tap away, the DAN number, and a short list of safety tips in one place, so nobody has to search for them under stress.
Decisions that mattered
I chose an ML safety check plus a deterministic RDP calculator over relying on either the model or the dive tables alone because the two approaches catch different mistakes, and showing both keeps the model's judgment checkable against the same tables divers already trust
I chose POST requests for user and dive data over GET requests with data in the URL because dive plans and personal details don't belong in a URL or a server log
I chose AES-encrypted passwords and explicit database access rules over relying on the platform's defaults alone because an app that stores health-adjacent data needed a deliberate answer for how credentials and records were protected
Hard problems I solved
ProblemThe app depends on many external services — weather, maps, hospitals, the model API — each with its own way of failing.
FixI built error handling and fallbacks around every external call so one slow or unavailable service didn't take down the rest of the planner.
ProblemA safety-adjacent app needed a tone that was useful without ever sounding like a guarantee.
FixI paired every model result with the deterministic RDP calculation and wrote the surrounding language to describe a planning aid, not a verdict.
ProblemWhen someone files an accident report, other nearby users need to know quickly.
FixI built a broadcast that notifies other users when an accident is reported, so the report doesn't just get logged, it alerts people who might be close enough to help.
Tech stack
- Android app
- Android (Java/XML): Client application language and layouts
- Retrofit: HTTP client to the model API
- Gson: JSON serialization
- Lottie: Loading and result animations
- Glide: Image loading
- Data, auth & location
- Firebase: Auth and Realtime Database for users, logbook, and accident reports
- Google Maps Platform: Map picking and nearest-hospital locations
- OpenWeather: Live and 7-day forecasts
- Google Cloud Platform: Cloud hosting
- Model service
- Python: Model API language
- scikit-learn: Trains and compares the four safety classifiers
- PythonAnywhere: Hosts the model API
- OpenCSV: Dataset preparation
- Google Colab: Model training and comparison
- Testing & tooling
- JUnit: Unit tests
- Espresso: UI tests
- PyCharm
Security got its own attention because the app stores personal details. Passwords are encrypted with AES, access to the Realtime Database is limited by per-user permissions, and every request that carries user data is a POST, so the data travels in the body of the request instead of in a URL.
Outcome
I delivered the planner to the client in June 2024. It has not been published to Google Play. What exists is a working app that plans a dive, checks it against a trained model and a deterministic RDP calculator, logs it, and connects a diver to weather, maps, and emergency information in one place — again, a planning and education aid, not a replacement for a dive computer, training, or professional judgement.
The decision tree’s 99.5% test accuracy is an offline score on the project’s own dataset. It says the model generalized well to data it hadn’t trained on; it doesn’t say a dive plan is safe, and the app was never designed to make that claim on its own.
What I learned
Combining deterministic domain calculations with a model made the planner more explainable than either one alone.
A diver can see the same RDP numbers dive tables have always shown, and see the model’s check sitting next to them, instead of trusting a single black-box verdict. That pairing did more for the app’s credibility than any one model’s accuracy did.
What I’d do next
The project’s own future work points toward technical-diving calculators, such as trimix, and toward gathering more dive records directly from dive centres so the underlying dataset reflects a wider range of real dives. More records would let me retrain the models and see whether the offline scores hold up on dives the first dataset never covered. The other direction is technical diving, where divers breathe mixed gases such as trimix. That would need calculators for the maximum allowed depth from the oxygen percentage, a way to work out a blend of oxygen, nitrogen, and helium, and a separate model, since the current one was trained only on recreational dives.
Links
The Android client is public. It isn’t polished for a general audience, since it was built for a specific client, but it’s the real, delivered implementation described above.