Chris Ziehr · Indie developer

I build odd, useful things
and then measure them honestly.

Android apps, sensor networks buried in plant pots, AI tools that run on a box under my desk, and data experiments designed to catch me fooling myself. One developer, one server, a lot of shipped work.

12+live services
23Android apps shipped
1.5Mlottery draws scored
1home server runs it all

Things I've built

Every project here is running now. Most talk to a single self-hosted Linux box: Node, Flask and Python services behind nginx, with Android clients on the other end.

01

RockID

Point your phone at a rock. Get a geologist's walkthrough.

You take a photo and a vision model finds the features: the grain texture, the rusty iron staining, the dark mineral streaks along hairline cracks. Each one comes back as a box on the photo. The app then gives you a guided tour, flying the camera to each feature in turn with an explanation underneath.

  • Where you found it matters. GPS is read from the photo, reverse-geocoded, and turned into local bedrock context: native stone, glacial erratic, or beach cobble carried in.
  • Built for bad signal. Identification runs as a server-side job. The phone can lock, switch apps or lose the network and the answer still arrives, with cancel and one-tap retry.
  • The zoom maths is tested off-device: 4,530 assertions across screen sizes, photo shapes and feature positions.
Java / AndroidNode / ExpressClaude visionjob queueNominatim
RockID result: quartzite pebble with six numbered features and a plain-language explanationRockID tour zoomed on feature 1, sugary granular surfaceRockID tour zoomed on feature 3, iron staining
02

Listening to Plants

ESP32 sensors wired into living plants, streaming around the clock.

Three sensor nodes read bioelectric signals from two different plants, with an open-air node as a baseline. They stream over WebSocket to a Node backend that stores every reading, draws a live dashboard, and turns the signal into sound on an "EMF Radio" page.

  • Firmware that heals itself: WiFi recovery and over-the-air updates, so nobody has to walk over with a USB cable.
  • Storm capture: it pulls Environment Canada's lightning grid every 10 minutes. When a strike lands within 25 km, it automatically archives the sensor data from before the storm, so the evidence survives the 30-day pruning.
ESP32 / C++OTANode / WebSocketSQLiteReactECCC open data
EMF sensor readings over time
03

Sparky

An Android app that gives a coding AI agent a phone.

Sparky connects over SSH to an AI agent running on my server. I talk to it by voice or text, and it writes code, builds Android apps and runs the servers. It talks back through the app:

  • an Install button appears when it has built an APK
  • generated images show up right in the chat
  • when it needs a decision it asks with push-notification buttons, then keeps working
  • a Control screen arms and disarms autopilot jobs (outreach, social, video), and a nightly Dreams run pitches new projects for a thumbs-up

If I send a message while it's still working, Sparky stops the job cleanly and merges the two requests. Several of the other projects on this page were built mostly from Sparky.

KotlinJetpack ComposeSSH (sshj)stream-JSONFCM-style push
Sparky chat with an Install button for a freshly built APKSparky Control screen: autopilot modulesSparky Dreams: nightly project ideas, tracked from idea to build
04

HailStorm

A machine-learning trading system with its own control panel.

Eight models (LSTM regression and classification) trade one stock using technical indicators and scored news sentiment. It's all watched through a Flask dashboard, a phone app and a home-screen widget. The widget shows intraday sparklines and the day's change, and its settings screen drives the server's risk controls: stop-loss, daily loss limit, and automatic suspension when a model's accuracy drops.

PythonTensorFlow / KerasFlaskFirestoreAndroid widget
HailStorm app main screenHailStorm statistics
05

BeachBook + Satellite Reports

A crowd-sourced ground truth for coastlines, checked from orbit.

A Flutter app where people document beaches: sand, driftwood, flora and wildlife across 30+ metrics. Cloud Functions merge everyone's entries into one agreed profile per beach, shown as heatmaps.

Behind it, a paid report service pulls Sentinel-2 imagery through STAC, adds NOAA charts, and emails a finished report. A photo plant-ID endpoint runs on the same box.

Flutter / DartFirebaseSentinel-2 / STACFlaskStripe
BeachBook data inputBeachBook beach detailsBeachBook map
06

Ground Boots

A field-survey platform that works where the signal doesn't.

A native Android app for roadside fieldwork: GPS, accelerometer and cell-signal logging, photo and voice observations, stop-proximity alerts and a home-screen widget. Everything is saved offline first, marked where it was a dead zone, and synced when coverage returns. Guided routes walk the driver through a survey leg by leg, and drive, hike and bike modes tag the data for who it's useful to. On the server, every field photo goes into a queue and gets tagged with plant species automatically.

Java / AndroidRoomWorkManagerForeground servicesNode
Ground Boots Drive screen: points, distance and dead zones logged, with drive, hike and bike modesGround Boots guided route, leg by leg (route end blurred)Ground Boots settings: planned and active survey trips
07

Saver Ferry Planner

The cheapest way around the BC coast, on live sailings.

A route planner over the BC Ferries network. It pulls live sailing times, merges two feeds that each leave out half the fields, and estimates Saver-fare tiers from departure time. It also handles the fare quirks, like free northbound legs where the fare is only collected on the way back. It will wait for a cheaper sailing, but only within a limit you set, so it won't strand you overnight to save four dollars.

Node / Expressgraph searchlive API merge
Saver Ferry Planner
08

What's For Dinner?

A week of meals for picky kids, cooked up by a model on my own computer.

You describe your kids and it plans seven days of meals plus the grocery list. The model runs locally through Ollama, not a cloud API. Kids' details stay in the browser: they're sent to the model for one job, used, and thrown away. Generation runs as a background job with a live "cooking" progress bar, so closing the tab doesn't lose the menu.

NodeOllama (local LLM)SSEprivacy by design
Dinner Helper privacy notice
09

And more on the same box

  • Farm Reports: satellite crop health (NDVI/NDMI) with weekly emailed snapshots and Stripe billing.
  • LottoLedger: an astrological number picker whose claims are publicly tested by Sky Ledger (see the Data Science tab).
  • NewLiver: a "just moved here" app with a scraped local events feed.
  • A private app store for sideloading my own APKs, plus a social media scheduler and a visitor analytics server.
PythonNodeAndroidnginxsystemd

Earlier work

Caloz
CalozA calorie tracker built around your daily calorie delta. On Google Play.
Play Store
HotFacts
HotFactsType one word and get a finished YouTube fact video (script, images, voice).
Example video
LuckyDay
LuckyDayMatches your personal events against lunar phases to find your "luckiest" days. The question Sky Ledger later tested properly.
Repo

About

I'm a self-taught, full-stack developer and I run Nimpact Environmental. I hold Google's Data Analytics certificate and an AutoCAD certificate from SAIT in Calgary, and have studied machine learning through Stanford Online. I like projects with hardware, fieldwork or a real question at one end, and a phone in someone's pocket at the other.

Everything on this page runs on one Linux box I administer myself: systemd services, nginx, nightly backups, and an AI agent I talk to from my phone.

Say hi

ziehro@gmail.com
driftwest.xyz · nimpact.ca
github.com/ziehro