Skip to content
Software Guide of Pool Controller

Software Guide of Pool Controller

Development Environment

Required Libraries

  • RelayModule
  • Vector
  • DallasTemperature
  • OneWire
  • Adafruit Unified Sensor
  • DHT sensor library
  • NTPClient @ 3.2.1
  • TimeZone @ 1.2.4
  • ArduinoJson @ 7.3.0
  • Bounce2
  • PubSubClient @ 2.8
  • Wire

Many thanks to maintainers of these libraries!

Pin Configuration

Within the sources at Config.hpp, the GPIO pin assignments are defined. For details, see also in the hardware guide.

constexpr uint8_t PIN_DS_SOLAR   = 15;  // Pin of Temp-Sensor Solar (GPIO15)
constexpr uint8_t PIN_DS_POOL    = 16;  // Pin of Temp-Sensor Pool (GPIO16)

constexpr uint8_t PIN_RELAY_POOL  = 18;  // Pin to control pool pump relay
constexpr uint8_t PIN_RELAY_SOLAR = 19;  // Pin to control solar pump relay

constexpr uint8_t TEMP_READ_INTERVAL = 30;

Web Interface & Direct Access

The controller includes a built-in web server on port 80 that provides a full management dashboard. It runs in two modes:

ModeWhenAccess
AP Mode (Access Point)No WiFi configured (factory state)SSID Pool-Controller-Setup, IP 192.168.4.1, no password
STA Mode (Station)Normal WiFi connectionDHCP IP of the ESP32 in local network, password login required

API Endpoints

RouteAuthFunction
GET /CookieDashboard SPA (Single Page Application)
GET /loginCookieLogin page
POST /api/login-Issue session cookie (SHA-256 password check)
GET /api/status❌ NoLive telemetry (temperatures, pump states, heap, RSSI)
GET /api/scanYesScan nearby WiFi networks
GET /api/configYesRead current configuration
POST /api/configYesSave configuration (type=settings|wifi|mqtt|password)
GET /api/restartYesReboot the ESP32
GET /api/factory_resetYesWipe config file, reboot into AP setup mode
POST /api/updateYesOTA firmware update (signed .bin upload)

Using the REST API Directly

You can interact with the controller programmatically:

# Get live telemetry (no authentication needed)
curl http://<controller-ip>/api/status

# Get session cookie
SESSION=$(curl -s -c - -X POST -d "password=admin" \
  http://<controller-ip>/api/login | grep session | awk '{print $NF}')

# Read configuration
curl -b "session=$SESSION" http://<controller-ip>/api/config

# Write settings (they persist across reboots and notify Home Assistant)
curl -b "session=$SESSION" -X POST \
  -d "type=settings&mode=auto&max_pool=30.0&min_solar=55.0&hysteresis=1.0" \
  http://<controller-ip>/api/config

Authentication

  • In AP mode the web interface is unprotected (intentional for initial setup)
  • In STA mode, a cookie-based session is required (15 minute timeout)
  • Default password is admin
  • Password is stored as SHA-256 hash in /config.json

Configuration Persistence

Configuration is persisted in two independent storage systems, ensuring all settings survive reboots and power failures:

1. ConfigManager — Device Configuration (LittleFS)

File/config.json
Max Size4 KB
ContentsWiFi, MQTT, NTP, ControllerSettings, admin password hash
ManagementConfigManager::load() at boot, ConfigManager::save() on changes
ResetConfigManager::reset() → factory defaults

2. StateManager — Runtime State (ESP32 NVS / Preferences)

Namespacepool-controller
Contentsopmode, poolMaxTemp, solarMinTemp, hysteresis, timerStart/End
APIStateManager::saveString/Float/Int/Bool → type-safe key-value storage

Data Flow on Settings Changes

Web UI / REST API            MQTT (Home Assistant)
        │                            │
        ▼                            ▼
────────┴────── ConfigManager ───────┴────
                save() → /config.json (LittleFS)
        OperationModeNode
        (runtime parameters)
        MqttPublisher::publishStates()
        → MQTT topics → Home Assistant

Note: When settings are changed via the Web UI, Home Assistant is updated on the next measurement cycle (every loopInterval seconds, default 10s). Changes made via MQTT are confirmed immediately.

MQTT Communication

Protocol

The controller uses Home Assistant MQTT Discovery (default) with topic structure:

homeassistant/<component>/pool-controller/<object-id>/config  (discovery)
homeassistant/<component>/pool-controller/<object-id>/state   (state)
homeassistant/<component>/pool-controller/<object-id>/set     (command)

See docs/mqtt-configuration.md for a complete entity mapping.

Clearing retained messages

If you need to clear retained MQTT messages:

# Clear a specific Home Assistant topic
mosquitto_pub -h hostname -t "homeassistant/sensor/pool-controller/pool-temp/state" -n -r

# Clear a root Homie topic (legacy cleanup)
mosquitto_pub -h hostname -t homie -n -r -d

Configuration

The controller uses a config.json file on its LittleFS filesystem for base configuration (WiFi credentials, MQTT settings). Use uploadfs to deploy it.

Example config.json

{
  "name": "Pool Controller",
  "device_id": "pool-controller",
  "wifi": {
    "ssid": "<SSID>",
    "password": "<XXX>"
  },
  "mqtt": {
    "host": "<MQTT_HOST>",
    "port": 1883
  },
  "ota": {
    "enabled": true
  },
  "settings": {
    "loop-interval": 60,
    "temperature-max-pool": 28,
    "temperature-min-solar": 50,
    "temperature-hysteresis": 0.5
  }
}
Last updated on