← back to portfolio
Case Study / FIG. C1
Home Automation & Aquarium Monitoring — Two Real-Time Platforms, One Source of Truth
Role Sole engineer, design through operations
Stack Home Assistant, Vue 3, FastAPI, ESPHome, Zigbee/Matter, MQTT
Context
I run a self-hosted Home Assistant deployment covering security (alarm, gate, entry), climate, lighting, and camera-triggered automations (Frigate). Sitting alongside it is Project Nemo, a purpose-built aquarium monitoring platform I designed and built from scratch — real-time sensor dashboards, dosing/maintenance schedules, and AI-assisted water testing, all talking to the same Home Assistant instance for device control.
Architecture
Project Nemo is a bilingual (Polish/English) Vue 3 + Pinia PWA backed by a FastAPI + SQLite service. A WebSocket pushes live sensor and smart-plug state every 30 seconds; Home Assistant's REST API drives the physical devices (Tapo smart plugs for filter/heater/light), MQTT and Zigbee2MQTT bring in a Zigbee temperature probe, and InfluxDB stores the sensor time-series for trend charts. APScheduler runs the background jobs — daily summaries, overdue-maintenance checks, and auto-resuming devices after a feeding pause — with n8n and ntfy handling the Telegram/push notifications.
Engineering Problems Worth Describing
- Reverse-engineered BLE integration — the aquarium's RGBW light only shipped with a phone app. I captured the BLE traffic (HCI snoop), decoded the GATT write frames, and wrote a native Home Assistant custom component (config_flow, number entities, protocol module) so the light is controllable from the same dashboard as everything else, without a phone in Bluetooth range.
- Computer vision with a local-LLM fallback — water test strips are read from a photo via an OpenCV pipeline (row clustering, HSV colour matching against a reference chart in the same shot), falling back to a local Ollama vision model (
llava-phi3) when the CV pass can't confidently detect the strip. A perceptual-hash cache means re-scanning the same photo never re-runs inference.
- Matter/Zigbee interoperability — extending the platform to support Matter, the newer cross-vendor smart-home standard, alongside the existing Zigbee fleet, by mapping Zigbee device metadata onto Matter's data model so both protocols keep working side by side during the transition.
- Custom ESPHome firmware — a dedicated sensor node for temperature and pH, respecting the ESP32's ADC1-only constraint for analog reads while Wi-Fi is active, calibrated per-probe via
calibrate_linear, and doubling as a BLE proxy so Home Assistant can reach the aquarium light even when no tablet is nearby.
The interesting engineering problem here isn't any single sensor — it's getting three different ecosystems (Home Assistant's entity model, a bespoke FastAPI backend, and ESPHome firmware) to agree on the same source of truth in real time, in two languages, on hardware that has to run unattended.
Related Work — Matter/Zigbee Interoperability
The Matter/Zigbee compatibility layer described above is ongoing work — the kind of protocol-bridging problem that mirrors integration challenges in much larger distributed systems, just running at home-lab scale.