Skip to content
Software Guide of Pool Monitor

Software Guide of Pool Monitor

Development Environment

The Pool Monitor firmware is built with PlatformIO, a cross-platform build system for embedded development.

Prerequisites

  • Git

  • PlatformIO — install via:

    pip install platformio
    # Or use the VS Code extension

Build & Flash

# Clone the repository
git clone https://github.com/smart-swimmingpool/monitor.git
cd monitor

# Build the firmware
pio run --environment LILYGO_T5_V231

# Flash to the device (auto-detects USB port)
pio run --environment LILYGO_T5_V231 --target upload

# Monitor serial output
pio run --environment LILYGO_T5_V231 --target monitor

# Run static analysis
pio check --environment LILYGO_T5_V231 --skip-packages

Note: The first build downloads and compiles all library dependencies automatically. This takes 2–5 minutes depending on your internet connection.

Project Structure

monitor/
├── platformio.ini           # Build configuration
├── Makefile                 # Local dev tasks (lint, build, format)
├── CPPLINT.cfg              # C++ linting config
├── src/
│   ├── main.cpp             # Arduino entry point (setup, loop)
│   └── PoolMonitor/         # Subsystem classes (namespace PoolMonitor)
│       ├── Config.hpp       # Pin definitions & compile-time constants
│       ├── PoolMonitorContext.{hpp,cpp}     # Core context — owns all subsystems
│       ├── DisplayManager.{hpp,cpp}         # E-Ink display management
│       ├── NetworkManager.{hpp,cpp}         # WiFi & MQTT connection
│       ├── OtaUpdater.{hpp,cpp}             # OTA firmware updates
│       ├── SystemMonitor.{hpp,cpp}          # Watchdog, memory, boot-loop detection
│       └── TimeClientHelper.{hpp,cpp}       # NTP time sync & timezone
├── lib/                     # External libraries (managed by PlatformIO)
├── docs/
│   ├── hardware-guide.md    # Hardware assembly guide
│   ├── software-guide.md    # This document
│   └── users-guide.md       # Setup & configuration
├── .github/workflows/       # GitHub Actions CI
└── platformio.ini           # Build configuration

Required Libraries

Libraries are declared in platformio.ini with version pins and resolved automatically by PlatformIO:

  • zinggjm/GxEPD — E-Ink display driver
  • juerd/ESP-WiFiSettings — Captive portal for WiFi/MQTT config
  • olikraus/U8g2 — Icon fonts for display
  • olikraus/U8g2_for_Adafruit_GFX — U8g2 integration with Adafruit GFX
  • knolleary/PubSubClient — MQTT client
  • arduino-libraries/NTPClient — NTP time synchronisation
  • jchristensen/Timezone — Timezone & DST handling
  • adafruit/Adafruit BusIO — SPI/I2C abstraction
  • adafruit/Adafruit GFX Library — Graphics primitives
  • bblanchon/ArduinoJson — JSON parsing for OTA update metadata

Many thanks to the maintainers of these libraries!


Build Configuration

The build configuration is defined in platformio.ini.

Build Defines

DefineValueDescription
SERIAL_SPEED115200Serial monitor baud rate
LILYGO_T5_V2311Board variant (see Hardware Guide)

Run-Time Constants

Defined in src/PoolMonitor/Config.hpp:

ConstantDefaultDescription
DEVICE_NAME"pool-monitor"mDNS hostname and WiFi AP name
TIME_TO_SLEEP_SECONDS180Deep sleep duration (seconds)
NTP_SYNC_INTERVAL_SECONDS3600Time between NTP synchronizations (1 hour)
MQTT_PAYLOAD_BUFFER_SIZE128Max MQTT message payload size (bytes)

Configuration

WiFi & MQTT Setup

The firmware uses the ESP-WiFiSettings library for the captive portal configuration. For the end-user setup process (connecting to the AP, entering credentials, QR code portal on error), see the Users Guide.

MQTT Topics

The Pool Monitor subscribes to Home Assistant state topics published by the Pool Controller. These are fixed topics — no dynamic discovery is used.

DataTopicPayload Example
Pool water temperaturehomeassistant/sensor/pool-controller/pool-temp/state25.3
Solar collector temperaturehomeassistant/sensor/pool-controller/solar-temp/state55.1
Pool pump statushomeassistant/switch/pool-controller/pool-pump/stateON / OFF
Solar pump statushomeassistant/switch/pool-controller/solar-pump/stateON / OFF
Operation modehomeassistant/select/pool-controller/mode/stateauto

The monitor only subscribes to these topics — it does not publish any data itself.

Preferences (NVS)

⚠️ This section is outdated — the NVS layout has been refactored into the PoolMonitor subsystem. See PoolMonitorContext.cpp for the current implementation.

The firmware stores runtime state in ESP32 NVS (Non-Volatile Storage) using the Arduino Preferences library under the pool-monitor namespace:

KeyTypePurpose
boot_countuintNumber of boots (across deep sleep cycles)
total_uptimeulongCumulative uptime across sleep cycles (seconds)
last_ntp_synculongUptime value at last NTP sync
last_epochulongUnix timestamp at last NTP sync
last_updatestringFormatted time string (HH:MM)
pool_tempfloatLast pool water temperature
solar_tempfloatLast solar collector temperature
pump_poolboolPool pump running?
pump_solarboolSolar pump running?
pool_modestringPool controller operation mode

Time Sync & Display

  • NTP sync occurs every 3600 seconds (1 hour). The server europe.pool.ntp.org is used.
  • Between syncs, the current time is reconstructed from the stored epoch and elapsed uptime.
  • The display shows local time with automatic daylight saving time handling (CET/CEST, configured in src/PoolMonitor/TimeClientHelper.hpp).
  • The E-Ink display updates only when data changes (received via MQTT).
Last updated on