Skip to content

Repository files navigation

hacs_badge License: MIT Quality Scale GitHub release Donate

Fluidra Pool Integration for Home Assistant πŸŠβ€β™‚οΈ

A Home Assistant integration for Fluidra Connect pool equipment β€” variable-speed pumps, heat pumps, salt chlorinators / electrolysers, water analysers and connected lighting. It talks to the Fluidra cloud (AWS Cognito auth) and exposes each device as native Home Assistant entities.

The integration was built by reverse-engineering the Fluidra Connect API. Most device mappings were confirmed by the community against the official Fluidra Pool app β€” if your model isn't recognised yet, open an issue and help us add it.


πŸ’° Support the Project

If this integration is useful to you, you can support its development:

Your contributions help me keep improving this project and adding new equipment. Thank you! πŸ™


✨ Features

  • Cloud login with MFA β€” email/password sign-in, multi-factor (OTP) challenge support, automatic token refresh, plus re-authentication and reconfigure flows when your credentials change or expire.
  • Automatic device discovery β€” pools and their equipment are discovered from your account; each device is created with proper Home Assistant device grouping.
  • Robust cloud client β€” bounded timeouts, exponential-backoff retries on 429/5xx, a circuit breaker for sustained outages, and a rate limiter.
  • Localized UI β€” English, French, Spanish and Portuguese translations; failed commands surface a clear, translated error instead of silently doing nothing.
  • Diagnostics β€” downloadable diagnostics (with credentials redacted) for bug reports.

🧩 Entity platforms

Platform What it controls
switch Pump on/off, auto mode, heater, heat pump, chlorinator, boost, schedule slots
select Pump speed / mode, chlorinator mode, light effect/scene, per-slot schedule speed
number Custom pump speed (0–100%), chlorination level, pH & ORP setpoints, light effect speed
climate Heat-pump control (HVAC mode/action, target temperature, preset modes)
light LumiPlus Connect RGBW (on/off, brightness, colour)
time Schedule start/end time editing
button Victoria VS pump Stop (halt without disarming the schedule)
sensor pH, ORP, free chlorine, salinity, temperatures, pump speed/mode, power & head & flow (VS pumps), firmware, signal, status

πŸ”Œ Supported Hardware

Device recognition is data-driven and community-confirmed. Many models below were added and verified through GitHub issues. Anything not matched falls back to a sensible generic profile, so unknown equipment is usually still usable.

πŸ’§ Variable-Speed Pumps

  • E30iQ (also matches LE* / PUMP* serials)
    • 3 speeds: Low (45%), Medium (65%), High (100%)
    • Automatic / scheduled mode
    • Custom speed control (0–100%)
    • Up to 8 daily schedule slots (per-slot speed + start/end time)
  • Victoria Smart Connect VS (AstralPool, mppvs) β€” running state, live output %, AUTO / QUICK FUNCTION mode, speed or flow-rate setpoint, plus power (W), head (m) and flow rate (mΒ³/h) sensors, and an activity sensor that reports the transient priming / calibration phases separately from the speed. Control mirrors the app: an Auto-schedule toggle and a dedicated Stop button (halts the motor without disarming the schedule); speed-preset dry-contact inputs are exposed as diagnostic binary sensors. Direct speed/quick-function control (via /schedulers) is still being added β€” see #144.
  • Generic variable-speed pump fallback

πŸ”₯ Heat Pumps

  • LG Eco Elyo β€” reversible: Smart Heating / Cooling, Boost, Silence presets; target temp; water-temp sensor
  • Z250iQ / Z25iQ β€” same firmware family as the Z260iQ, so the same feature set: HVAC modes (heat / cool / heat-cool), presets, no-flow alarm, water/air temperatures, running hours, WiFi signal
  • Z260iQ β€” HVAC modes (heat / cool / heat-cool), presets, no-flow alarm, water/air temperatures
  • Z550iQ+ β€” HVAC modes (heat / cool / auto), presets, HVAC action (heating/cooling/idle/no-flow), water/air temperatures
  • Z650iQ β€” HVAC modes (heat / cool / heat-cool), Smart+/Smart/Ecosilence/Boost presets, on/off switch, water/air temperatures, running hours, compressor running hours, WiFi signal, instantaneous power (Watts) and compressor modulation (percent). Reverse- engineered from live captures; some registers remain undecoded and show up in the unmapped-register debug log.
  • Gre HPGIC β€” on/off, target temperature, water temperature
  • Generic heat-pump fallback

πŸ§‚ Salt Chlorinators / Electrolysers

  • tecnoLC2 family (30+ models) β€” AstralPool Clear Connect / Clear Connect Evo / Scalable, Blauswim, IrriPool / Irrijardin iSalt, KLINWASS Mark Salt, Zodiac GenSalt OE iQ, Zodiac Ei2 iQ / Ei2 pH Evo, Gre, Energy Connect, and more (CC* / LC* serials, including bridged *.nn_* devices)
  • Automatic tecnoLC2 detection β€” a chlorinator whose serial isn't on file yet is auto-recognised from its component signature and reads pH, ORP, water temperature and salinity on the right registers, so unknown units work correctly without waiting for their serial to be added by hand
  • Zodiac EXO iQ (e.g. iQ35 / NS25) β€” 0–100% chlorination in 5% steps, output schedules, Boost (with remaining-time countdown), Low and freeze protection, Aux 1 / Aux 2 outputs (Off/On/Auto), heating setpoint
  • DM24049704 (Domotic S2) β€” program/slot schedule format
  • Typical capabilities (model-dependent): chlorination level (0–100%), pH setpoint, ORP/Redox setpoint, boost mode, schedules, and sensors (pH, ORP, free chlorine, salinity, water temperature)

tecnoLC2: there is no free-chlorine probe. These units expose 11 components and carry exactly two probes β€” pH and ORP/Redox. The Free Chlorine sensor stays unavailable for their whole lifetime (verified against a recorder database: not a single numeric state, ever). That is the hardware, not a bug in this integration, so please don't open an issue for it. Use ORP as the disinfection proxy β€” 650 mV is the usual floor β€” and measure free chlorine with a test kit.

πŸ§ͺ Water Analysers

  • Zodiac Blue Connect Silver / Gold (WA*, BC3) β€” pH, ORP and water-temperature sensors (read-only)

πŸ’‘ Pool Lighting

  • LumiPlus Connect (RGBW) β€” on/off, brightness (0–100%), RGBW colour + white channel, effect/scene selection and effect speed, light schedules
  • Generic LED light fallback

♨️ Heaters

  • Generic on/off heater (component-9) with optional temperature attributes

πŸ†• Adding New Equipment

Your equipment isn't listed or is only partially recognised? Help us add it:

  1. Enable debug logs
    logger:
      logs:
        custom_components.fluidra_pool: debug
  2. Open an issue with:
    • Your equipment model and serial prefix
    • The device-discovery debug logs
    • The features/values shown in the official Fluidra Pool app
  3. Test and share your results β€” most new models are added this way.

πŸš€ Installation

HACS (recommended)

  1. Add this repository as a custom repository (category Integration):
    https://github.com/foXaCe/Fluidra-pool
    
  2. HACS β†’ search "Fluidra Pool" β†’ Download
  3. Restart Home Assistant
  4. Settings β†’ Devices & Services β†’ Add Integration β†’ "Fluidra Pool"

Manual

git clone https://github.com/foXaCe/Fluidra-pool.git
cp -r Fluidra-pool/custom_components/fluidra_pool /config/custom_components/

Then restart Home Assistant and add the integration from the UI.


βš™οΈ Configuration

The integration is configured entirely from the UI (config flow):

  • Email β€” your Fluidra Connect account email
  • Password β€” your Fluidra Connect password
  • MFA β€” if your account uses multi-factor authentication, you'll be prompted for the code
  • Re-auth / Reconfigure β€” Home Assistant prompts you to re-authenticate if the token is rejected; you can also reconfigure (e.g. change the account email) from the integration menu

Important

Region β€” EMEA (Europe) only. This integration talks to Fluidra's EMEA backend (api.fluidra-emea.com). Only myFluidra / Fluidra Connect accounts registered in the EMEA region can log in. Accounts created in other regions β€” e.g. North America (iAquaLink US) or Australia / APAC β€” live on a different Fluidra backend and will be rejected with an "invalid credentials" error even though the same credentials work in the official app. Multi-region support isn't available yet (it needs the regional endpoints and a test account to implement safely).

Options

  • Update interval β€” polling interval in seconds, configurable from 30 to 1800 (default 30 s). Change it via the integration's Configure button.

πŸŽ›οΈ Usage

Pump speed automation

automation:
  - alias: "Pool β€” economy mode at night"
    triggers:
      - trigger: time
        at: "22:00:00"
    actions:
      - action: select.select_option
        target:
          entity_id: select.pool_pump_speed
        data:
          option: "low"

⏱️ Measuring real filtration hours (no extra hardware)

If your pump is driven by a mechanical timer or an external contactor, the integration still tells you when it actually ran β€” no wiring, no extra sensor, no touching the electrical panel. When the unit loses power its entities go unknown, so the chlorinator's alarm binary sensor doubles as a run-time log:

-- Home Assistant recorder database (/config/home-assistant_v2.db)
-- Works with the container stopped: docker cp homeassistant:/config/home-assistant_v2.db ./ha.db
SELECT s.state,
       datetime(s.last_updated_ts, 'unixepoch') AS utc
FROM states s
JOIN states_meta m ON m.metadata_id = s.metadata_id
WHERE m.entity_id = 'binary_sensor.<your_chlorinator>_alarm'   -- slug follows your HA language
ORDER BY s.last_updated_ts;

unknown β†’ off is a start; off β†’ unknown is a stop. Two caveats measured on a real installation:

  • Polling is roughly 35 s, so every transition carries that much uncertainty. Fine for hours/day, useless for anything that needs the second.
  • Discard the first sample after each start (see Troubleshooting) β€” it is stale, and it will skew any average you compute over the block.

The same trick verified a mechanical timer disc that closed its contact ~6.7 min before the mark and opened it on the mark β€” about 20 extra minutes of filtration a day that no one had accounted for.

πŸ” The first value after a reconnect is not real

Every time the unit comes back online, the integration emits one wrong value per entity before the real one arrives on the next poll (~35 s later). It affects sensors and number entities alike, and on the number entities it is the more dangerous of the two, because those are the control surfaces.

Measured on a tecnoLC2. The number entities repeat this exact two-step sequence on every reconnect in the recorder; the sensor figures are from one clean power cycle:

Entity 1st value after reconnect 2nd value (real)
sensor.*_orp 694 mV 659 mV
sensor.*_ph 7.50 7.70
number.* pH setpoint 7.2 7.7
number.* ORP setpoint 700 750
number.* chlorination level 0 60

For the sensors it is a stale reading; for the number entities the first value is a placeholder that never corresponded to anything on the device. Either way:

Discard the first value after every reconnection. An automation that reads a chlorination level of 0, or a pH setpoint of 7.2, and acts on it, is acting on a value the equipment never held. The same goes for any average or statistic computed across a power cycle.

A reconnect is easy to spot: entities pass through unavailable/unknown on the way back, so a for: delay of about a minute on that transition β€” or simply ignoring the first update after it β€” is enough.

Services

The integration registers three services for schedule management. The device_id is the Fluidra equipment serial (visible in the device's Diagnostics / Device info).

fluidra_pool.set_schedule β€” replace the schedule of a device:

action: fluidra_pool.set_schedule
data:
  device_id: "LE24500883"
  schedules:
    - enabled: true
      start_time: "08:00"
      end_time: "12:00"
      mode: "1"            # 0 = Low, 1 = Medium, 2 = High
      days: [1, 2, 3, 4, 5]  # 1 = Monday … 7 = Sunday
    - enabled: true
      start_time: "18:00"
      end_time: "20:00"
      mode: "2"
      days: [6, 7]

fluidra_pool.clear_schedule β€” remove all schedules of a device:

action: fluidra_pool.clear_schedule
data:
  device_id: "LE24500883"

fluidra_pool.set_preset_schedule β€” apply a ready-made schedule preset:

action: fluidra_pool.set_preset_schedule
data:
  device_id: "LE24500883"
  preset: "standard"   # standard | intensive | eco | summer | winter
Preset Schedule
standard 08:00–12:00 + 18:00–20:00 (Medium)
intensive 08:00–18:00 (High)
eco 10:00–14:00 (Low)
summer 06:00–10:00 + 16:00–22:00 (High)
winter 12:00–16:00 (Low)

Lovelace dashboard

type: entities
title: Pool Control
entities:
  - entity: switch.pool_pump
  - entity: select.pool_pump_speed
  - entity: number.pool_chlorination_level
  - entity: climate.pool_heat_pump
  - entity: light.pool_light

Entity IDs depend on your device names (entities use has_entity_name); the names above are illustrative.


πŸ”§ Troubleshooting

  1. Authentication fails β€” check the email/password, and complete the MFA prompt if shown. If the token was rejected, Home Assistant starts a re-authentication flow automatically.
  2. No pools found β€” confirm your equipment appears in the official Fluidra Pool app.
  3. Enable debug logs (see Adding New Equipment) and attach them to any issue.
  4. Download diagnostics β€” from the integration's device page (credentials are redacted).
Symptom Likely cause / fix
Invalid credentials but the app works Account registered outside EMEA (North America, Australia, …) β€” not supported (see Configuration)
Authentication failed Wrong credentials or expired token β†’ re-authenticate
No pools found Account has no equipment, or it's offline in the Fluidra app
Wrong readings after a HACS update (e.g. a chlorinator's pH shows a temperature) A custom integration's code only reloads on a full Home Assistant restart (Settings β†’ System β†’ Restart) β€” a "Reload" is not enough. Restart, then re-check
Device shows unavailable The device reports itself offline to the Fluidra cloud
Commands seem ignored Check debug logs; transient cloud rejections now surface as errors
Setpoints/switches never change (no error) Account has viewer (read-only) access to the pool β€” the cloud accepts writes but doesn't apply them. Check the access_level attribute on the pool status sensor; owner access is required to control equipment
Free chlorine is permanently unavailable (tecnoLC2) Expected β€” the unit has no free-chlorine probe, only pH and ORP (see Salt Chlorinators). Use ORP as the disinfection proxy
The first value after the unit powers back on is wrong Affects sensors and number entities alike β€” every reconnection emits one bad value before the real one. See The first value after a reconnect is not real

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Run the checks β€” ruff check, ruff format, mypy, and pytest (see requirements_test.txt)
  4. Commit your changes (Conventional Commits)
  5. Open a Pull Request

CI runs Ruff, HACS validation, Hassfest, the pytest suite (with a coverage gate) and mypy.

πŸ“„ License

MIT β€” see LICENSE.

πŸ™ Acknowledgments

  • Fluidra for their equipment
  • Home Assistant for the platform
  • The community for testing, device captures and feedback

πŸ“ž Support


⭐ If this integration is useful to you, feel free to leave a star!

About

πŸŠβ€β™‚οΈ Home Assistant integration for Fluidra pool equipment

Topics

Resources

Stars

40 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages