Simulator tests Custom card HA config Integration tests Wokwi
A DIY sailboat monitoring, AIS, and alerting system for a Hunter 41DS on Lake Erie.
Built around a single ESP32-S3 on the boat, a Home Assistant instance at home, and a zero-subscription infrastructure — no cloud dependencies, no third-party integrations required, no ongoing costs.
Iterations 1 + 2 complete. Boots end-to-end in simulation:
- ✅ Boat telemetry simulator (Python) with 9 scenarios — covered by 164 pytest tests
- ✅ Home Assistant configuration: 3 dashboards, 9 rollup template sensors, 2 themes (Modern Minimal + Marine Classic), Captain's Glance primary-alert engine
- ✅ Custom Lovelace card (
evenkeel-boat-card) — HACS-installable, Lit + TypeScript + Vite, top-down Hunter 41DS sailboat silhouette with severity overlays + animated power flow + tap-to-drill navigation, helm/mast/nav-light detail layer, 73 unit tests - ✅ ESP32-S3 firmware — minimal ESPHome boat-mon.yaml that boots, prints "BoatMon-1 booted", connects WiFi/MQTT, publishes RSSI/uptime/SoC-temp on canonical
boat/hunter41/health/*topics - ✅ Wokwi smoke test — workflow builds the firmware and runs it under a headless ESP32-S3 (token setup: see
firmware/README.md) - ✅ pytest-bdd test harness — Gherkin features driven through a BoatAdapter Protocol with virtual / HIL / live modes; first telemetry feature green in CI
- ✅ CI: 5 GitHub Actions workflows — pytest (Python 3.10/3.11/3.12), custom-card build (Node 20/22), HA config check, integration tests against ephemeral mosquitto, Wokwi
- ✅ Local dev stack: docker-compose runs mosquitto + HA + simulator end-to-end
Iterations 3 + 4 complete. Six green CI workflows, full data-plane and HA-side observation, real-firmware Wokwi smoke:
- ✅ 23 Gherkin telemetry scenarios across bilge, battery, engine, leak, AIS targets, and anchor watch — running through the BoatAdapter Protocol against a real Mosquitto in CI
- ✅ 7 SimulatorPublisher integration tests that spin up the actual publish loop in a background asyncio task and assert on canonical topics
- ✅ 6 Playwright e2e tests against the real Chromium-rendered custom card, with the bundle rebuilt from source on every CI run
- ✅ 13 HA-bridged scenarios spanning the full Phase 6 critical-path stack across 4 alert flows — bilge water (6 scenarios: wet/dry ×ばつ binary_sensor / template-sensor rollup / persistent_notification), low house-battery SoC with hysteresis (2), anchor drag with disarm clearing (3), shore power loss + restoration (2). All round-trip through MQTT discovery → HA
binary_sensor/sensor/ template-sensor → productionboat_alerts.yamlautomation →persistent_notification.create/dismiss. Production HA Docker image, productionhome-assistant/config tree, MQTT integration pre-baked into.storageso HA subscribes on boot, onboarding bootstrap via/api/onboarding/users→/auth/token. The verification step asserts the scenarios actually ran (not silently skipped). - ✅ Three-mode adapter harness structurally complete —
VirtualAdapter(full, with httpx-based HA REST),LiveIntegrationAdapterandHilAdapter(skeletons; gatedNotImplementedErroruntil Phase 6 / Phase 4 commissioning). Seetests/adapters/README.md. - ✅ 8 firmware packages (base, network, health, bilge, temperature, power, engine, AIS) — full multi-package
boat-mon.yamlbuilding clean in CI, includingexternal_componentsfor the AIS TCP stream-server. GPS + test_mode shipped as documented placeholders pending Phase 6 / 8. - ✅ Wokwi smoke test runs the slim
boat-mon-wokwi.yamlbuild and reachesBoatMon-1 bootedin the simulator within seconds (after fixing the ESP32-S3 logger's defaulthardware_uart: USB_SERIAL_JTAGrouting to UART0) - ✅ HACS metadata at repo root + HACS validation workflow
Test surface gating master: 122 tests across 5 layers — 23 BDD telemetry + 7 simulator integration + 13 HA-bridged + 6 Playwright e2e + 73 custom-card vitest. Plus 164 simulator pytest cases on simulator-tests.yml. 286 tests total when the simulator workflow runs.
Next:
- Engine-coolant high-temp + oil-pressure-loss alerts (same
boat_alerts.yamlpattern, lands one automation + one BDD scenario each). - Live-mode HMAC handshake + on-boat test_mode injection — turns
--mode=livefrom a skeleton into a working stimulus path against deployed firmware (Phase 6 commissioning, security-design decisions). - Phase 2 cloud relay (
relay/) — aisstream.io forwarder, fairly self-contained Python service. - Wokwi diagram improvements (pushbutton → bilge GPIO, DS18B20s on the 1-wire bus, BME280 on I2C) so the simulation exercises real sensor read paths, not just boot logging.
git clone https://github.com/pdrakeweb/even-keel.git cd even-keel cp home-assistant/secrets.yaml.example home-assistant/secrets.yaml docker compose up -d # Open http://localhost:8123, log in, navigate to "How's My Boat", # Dev tab → toggle "Use simulated boat data" → pick a scenario.
See docs/ui-dev-quickstart.md for the full walkthrough.
Via HACS:
- HACS → Frontend → ⋮ → Custom repositories.
- Add
https://github.com/pdrakeweb/even-keel, category Lovelace. - Find "EvenKeel Boat Card" and install.
- Refresh browser; card type is
custom:evenkeel-boat-card.
Or build from source:
cd custom-card
npm install
npm run build
cp dist/evenkeel-boat-card.js ../home-assistant/www/Then add the resource in HA: Settings → Dashboards → Resources → + → URL /local/evenkeel-boat-card.js, type JavaScript Module.
# Python simulator — 164 tests cd simulator pip install -e '.[dev]' pytest # Custom card — 73 tests (TypeScript + happy-dom) cd ../custom-card npm install npm run lint # tsc --noEmit npm run test # vitest npm run build # vite → dist/evenkeel-boat-card.js
research/ original design docs (v1.0 + continuation brief)
planning/ research reports + synthesis (architecture, roadmap, custom-card-research)
firmware/ ESPHome YAML — boat node + Tier 1 dashboard head (Iteration 2)
tests/ pytest-bdd test harness (virtual / HIL / live modes — Iteration 2)
hil-rig/ bench hardware-in-the-loop stimulator
home-assistant/ HA configuration: dashboards, themes, automations, packages, README
simulator/ boat telemetry simulator + 164 pytest tests; Docker-built service
custom-card/ HACS-installable Lovelace card: Lit + TS + Vite, 73 vitest tests
relay/ optional aisstream.io forwarder
docs/ runbooks, photos, install guides — start at ui-dev-quickstart.md
tools/ one-off scripts (MQTT replay, AIS capture, cert rotation)
docker-compose.yml local dev stack (mosquitto + HA + simulator)
.github/workflows/ CI: simulator pytest, custom-card build, HA config check, integration-tests, Wokwi
.env.example template for WOKWI_CLI_TOKEN, HA_TOKEN, Pushover keys
| Topic | File |
|---|---|
| Project overview | This file |
| Plan & roadmap | planning/README.md → planning/roadmap.md |
| System architecture | planning/architecture.md |
| Hardware bill of materials | planning/hardware-deep-dive.md |
| Custom card design | planning/custom-card-research.md |
| NMEA 2000 integration | planning/nmea2000-integration.md |
| Sensor expansion (5–30+ sensors) | planning/sensor-expansion.md |
| Open questions | planning/open-questions.md |
| TDD / test architecture | planning/tdd-architecture.md |
| Local dev quickstart | docs/ui-dev-quickstart.md |
| HA configuration | home-assistant/README.md |
| Simulator service | simulator/README.md |
| Custom card plugin | custom-card/README.md |
| HIL bench rig | hil-rig/README.md |
- Reliability under marine conditions. Fail-open severity (a missing sensor never paints the dashboard red), watchdogs, OTA recovery.
- No subscription dependencies. Every required feature works on Pete's own hardware. Optional integrations (Pushover, aisstream.io) are explicitly opt-in.
- ESPHome YAML-first. Minimal custom firmware. The simulator and tests speak the same MQTT topics the real ESP32 will.
- Commercial, replaceable parts. No custom PCBs. STEMMA QT / Qwiic plug-together for sensors.
- Phased. Each phase ships working end-to-end functionality. Pete can stop at any phase and have a useful system.
- Test-driven. Natural-language Gherkin scenarios + pytest-bdd, runnable against simulated boat or real hardware via the same step definitions.
The HA "How's My Boat" dashboard surfaces 8 boat-system categories as colored buttons (green / orange / red), with a Captain's Glance headline at the top describing the single most-urgent issue in plain English ("Water in the bilge — Pete needs to check now"). Tap any category for drill-down detail.
The custom card layers on top: a top-down Hunter 41DS diagram where each compartment lights up by severity, with an animated shore→battery power-flow line.
Apache-2.0.