Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

217 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

AkvaLink πŸ’§

Latest release

Battery-powered Matter pool & aquatic temperature sensor Single-SoC design on u-blox NORA-W40 (ESP32-C6, Wi-Fi 6 + Thread + BLE 5.3)

Multi-year battery life. Local Matter connectivity. No cloud, ever.

🌐 Live demo & landing page: stenmo.github.io/AkvaLink (available in English Β· Svenska β€” connect to a nearby sensor live over Bluetooth, right in your browser)


Why AkvaLink?

Pool, spa, aquarium, wine cellar, or cold-storage temperature monitoring β€” environments where the temperature barely changes, but you want to know immediately if it does.

  • πŸ”‹ Years on 2Γ— AA β€” adaptive sampling + Matter SED + threshold reporting
  • πŸ“± Works with Apple Home, Google Home, Alexa β€” standard Matter sensor
  • 🌐 No cloud β€” local Matter over Thread or Wi-Fi
  • πŸ’§ Waterproof probe β€” DS18B20 in stainless steel (10 m+ cable possible)
  • πŸ›  Open source β€” built on esp-matter, Apache-2.0 license

Hardware

Component Part Why
Module NORA-W401 / NORA-W406 Wi-Fi 6 + Thread + BLE in one tiny module
MCU ESP32-C6 (RISC-V @ 160 MHz) Inside NORA-W40
Sensor DS18B20 (stainless probe) Β±0.5 Β°C, 12-bit (0.0625 Β°C steps), 1-Wire, ~$3
Power 2Γ— AA alkaline (or 18650 Li) ~5–7 years realistic on 2Γ— AA (Thread SED, pool conditions)*

Schematic (direct GPIO, default build):

                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚       NORA-W40 / EVK-NORA-W40            β”‚
  +3V3 ────────┬──────── β”‚ GPIO15 (J15.4)  ← DS18B20 DQ 1-Wire      β”‚
               β”‚         β”‚                                          β”‚
              4.7 kΞ©     β”‚ GPIO9  (BOOT)   ← re-provision button    β”‚
               β”‚         β”‚                   long-press 5 s β†’       β”‚
DS18B20 β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚                   erase Wi-Fi, re-prov   β”‚
  DQ ──────────────────► β”‚                                          β”‚
  VDD ────────────────── β”‚ +3V3            ← future: battery ADC    β”‚
  GND ────────────────── β”‚ GND                                      β”‚
                         β”‚                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
  Battery (+) ──── R1 ──── ADCx (future) ◄────── R1 / R2  β”‚         β”‚
  Battery (-) ──── GND   β”‚                     β”‚ divider  β”‚         β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

R1/R2 voltage divider (not yet populated): e.g. 390 kΞ© / 100 kΞ© scales 3.3 V full-charge to β‰ˆ 0.68 V, safely within the ESP32-C6 ADC input range.

For long cable runs (> 5 m), a DS2482-800 I2C-to-1-Wire bridge variant is also supported (--clickboard build flag).

Quick start

# One-time setup (installs ESP-IDF + esp-matter in WSL, ~10 GB)
.\akvalink.cmd setup

# Build & flash (Thread variant β€” needs a Thread Border Router)
.\akvalink.cmd build
.\akvalink.cmd flash COM62

# Or build the Wi-Fi variant (no border router needed)
.\akvalink.cmd --wifi build

# Or the Wi-Fi AP variant β€” open "AkvaLink" hotspot + captive web page showing
# the temperature. No hub, no app, works on ANY phone (incl. iPhone).
# NOTE: an always-on SoftAP is NOT battery-friendly β€” this variant needs
# external (mains/USB) power.
.\akvalink.cmd --ap build

# Or the Wi-Fi station variant β€” joins your home Wi-Fi (provisioned once over
# BLE with the free "ESP BLE Provisioning" app), then serves the temperature
# page at http://akvalink-<last4mac>.local (found via mDNS, unique per device).
# Also publishes to MQTT for Home Assistant autodiscovery (default broker:
# homeassistant.local:1883), plus high/low temperature alerts on
# akvalink/<mac>/alert once you set a threshold (menuconfig β†’ AkvaLink).
.\akvalink.cmd --station build

# Or just bench-test the DS18B20 probe (no Matter/BLE β€” logs temp every 30 s)
.\akvalink.cmd --sensor build

# Or the e-ink display receiver β€” listens for --espnow sensors' broadcasts
# and logs them (no e-ink panel driver yet). See docs/EINK_DISPLAY_PLAN.md.
.\akvalink.cmd --display build

# Or the ESP-NOW variant β€” deep-sleep broadcast, no hub, no provisioning,
# maximum battery life (receiver needs its own ESP32 sketch).
.\akvalink.cmd --espnow build

# Or ESPHome β€” native Home Assistant API, adopted + OTA-updated straight from
# the ESPHome dashboard. Builds with ESPHome directly, not akvalink.cmd:
esphome compile esphome/akvalink.yaml

Commission with the Apple Home, Google Home, or Alexa app β€” scan the QR code printed on the serial console at first boot.

πŸ“– Full step-by-step: see GETTING_STARTED.md

Companion app (optional)

A native Flutter app (Windows/Linux/macOS/Android/iOS) shows live temperature over Bluetooth or Wi-Fi (finds a --station device on the LAN via mDNS) and one-click OTA-updates the device β€” same GATT/HTTP contract as the web page, no browser needed:

.\akvalink.cmd --app --run

πŸ“– See app_flutter/README.md.

Battery life examples

For a heated pool at 28–29 Β°C with 0.25 Β°C report threshold. Leading with the realistic number for each cell: alkaline (AAA/AA) self-discharge and Li-ion (18650) calendar aging cap real-world life at roughly 5–7 years no matter what the draw-limited model alone predicts, so that cap is shown wherever the model overshoots it. CR2477 (lithium primary) has the best shelf life of the four and needs no such cap β€” its model figure already is the realistic one:

Battery Thread SED Wi-Fi (TWT) Wi-Fi (disconnect)
CR2477 (1000 mAh) ~5 years ~6 months ~3.3 years
2Γ— AAA (1200 mAh) ~5–6 years ~8 months ~4 years
2Γ— AA (2800 mAh) ~5–7 years (model: ~12 years) ~1.8 years ~5–7 years (model: ~9 years)
18650 Li-ion (3400 mAh) years, not decades (model: ~15+ years) ~2.2 years years, not decades (model: ~11 years)

The italic (model: ...) figure is the theoretical, draw-limited ceiling β€” only shown where it's materially higher than the realistic number. Real measurement (PPK2/Joulescope) to replace "years, not decades" with an actual figure is on the roadmap.

See docs/POWER_AND_HARDWARE.md for the full analysis (DTIM strategies, TWT setup, sensor variants, schematic).

Project docs

Roadmap

  • Matter Temperature Sensor over Thread (single-SoC, NORA-W40)
  • Matter Temperature Sensor over Wi-Fi
  • Adaptive sampling + threshold reporting
  • Light sleep + DFS + flash power-down
  • DS2482 Click board (long cable variant)
  • BLE firmware update over the air (custom GATT over esp_ota, --ble variant)
  • Standalone BLE GATT variant β€” live temperature direct-to-app, no hub (--ble)
  • Live temperature in the browser over Web Bluetooth β€” on the landing page
  • Wi-Fi AP variant (--ap) β€” open hotspot + captive web page, any phone incl. iPhone (needs external power)
  • Wi-Fi station variant (--station) β€” BLE-provisioned, akvalink.local, Home Assistant MQTT autodiscovery, no hub
  • ESP-NOW variant (--espnow) β€” deep-sleep broadcast, no hub, no provisioning
  • ESPHome variant β€” native Home Assistant API, dashboard-adopted + dashboard OTA
  • Native Flutter companion app (Windows/Linux/macOS/Android/iOS) β€” live temperature + one-click OTA
  • Temperature alerts β€” high/low thresholds set from the browser or the app, stored on the device; the --station build publishes crossings to Home Assistant over MQTT
  • 24 h / 7 d history β€” sparkline on the device's own page and in the app (Wi-Fi path; RAM-only, resets on reboot)
  • Matter keepalive report so a dead-flat sensor isn't marked offline
  • Real power measurement (Joulescope/PPK2) + deep sleep β€” see TODO.md
  • E-ink display (big-digit, battery, trend) β€” --display build variant receives --espnow sensor broadcasts and logs them; e-ink panel driver still to come; see docs/EINK_DISPLAY_PLAN.md
  • Wi-Fi 6 TWT integration in code (currently DTIM only)
  • Battery voltage monitoring β€” firmware side is in (CONFIG_AKVALINK_BATTERY_ADC, off by default), but no board has the sense divider fitted, so the level reads as unknown
  • OTA via Matter
  • Production enclosure design (waterproof, IP67)

Origin & Credits

AkvaLink is a clean-room productisation of the companion/opencpu/nora-w40-thermometer/ NORA-W40 thermometer reference from u-blox, tracked at u-blox/u-connectMatter (that public repo now hosts prebuilt reference binaries; the source tree is internal to u-blox).

Built on:

Contributing & security

  • 🀝 CONTRIBUTING.md β€” how to build, test, and submit changes (KISS, battery-first, no cloud)
  • πŸ”’ SECURITY.md β€” report a vulnerability privately (AkvaLink is a networked Matter device)
  • πŸ” Code signing policy β€” how the Windows companion app is signed (free signing via SignPath.io)

License

Apache-2.0 β€” matches esp-matter and connectedhomeip.

About

Battery-powered single-SoC Matter pool/aquatic temperature sensor on u-blox NORA-W40 (ESP32-C6: Wi-Fi 6 + Thread + BLE 5.3). Multi-year battery life, local-only, no cloud.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages