A custom Home Assistant integration for Poollab/LabCom Cloud API, allowing you to monitor your pool water quality parameters directly in Home Assistant.
- π Multiple Pools Support - Monitor all your pools/devices with a single integration
- ποΈ Monitor pH levels
- π§ Track chlorine levels (free, total, combined, unbound, and CYA-bound)
- π€ Monitor bromine residual
- π«§ Monitor active oxygen (MPS) residual
- π‘οΈ Monitor water temperature
- βοΈ Alkalinity tracking
- π‘οΈ Stabilizer (CYA) monitoring in chlorine mode
- π§ Salt level monitoring
- π Per-device Backend Update Mode: Cloud polling or Manual refresh (12h safety sync)
- β±οΈ Manual refresh (12h safety sync) includes a 12-hour safety refresh while Home Assistant is running
- π Native refresh button entity in Manual refresh (12h safety sync) mode (works in dashboards and automations)
- β Data validation β out-of-range values are discarded automatically
- Open HACS in Home Assistant
- Go to Integrations
- Click the three-dot menu β "Custom repositories"
- Add
https://github.com/stefanh12/poollabwith category "Integration" - Search for "Poollab" and install
- Restart Home Assistant
- Download the latest release
- Copy the
poollabfolder tocustom_components/in your Home Assistant config directory - Restart Home Assistant
- Ensure that you have synced at least one measurement from your device to Labcom cloud If you do not have any readings the setup will fail
- Go to Settings β Devices & Services β Integrations
- Click "Create Integration" and search for "Poollab"
- Get your personal API token:
- Visit: https://labcom.cloud
- Your token is generated in https://labcom.cloud/pages/user-setting GraphiQL.
- Generate a token and copy the token string
- Paste your personal token into the Home Assistant config
- The integration will automatically discover all your devices/pools
- For each discovered device, choose:
- Sanitation method (Chlorine or Bromine + Active Oxygen)
- Backend Update Mode
- Cloud polling: regular backend updates (default, every 5 minutes)
- Manual refresh (12h safety sync): adds a refresh button and still performs a safety refresh every 12 hours
- Configuration complete!
If your LabCom account has multiple pools or devices:
- Automatic Discovery: The integration automatically discovers ALL your pools when you add it
- One Integration Entry: You only need to enter your token once per account
- Separate Device Entries: Each pool appears as a separate device in Home Assistant
- Named Devices: Sensors are named with your pool name (e.g., "Backyard Pool pH", "Front Pool Temperature")
- Manage Separately: You can enable/disable sensors per pool in Home Assistant settings
The integration creates the following sensors for each pool/device:
During setup, each device is assigned a sanitation method:
- Chlorine: exposes chlorine sensors, Stabilizer (CYA), and chlorine chemistry calculations
- Bromine + Active Oxygen: exposes bromine and active oxygen sensors instead of chlorine-family sensors and CYA
Each device also gets a Backend Update Mode:
- Cloud polling: backend is polled automatically every 5 minutes
- Manual refresh (12h safety sync): use a button entity to fetch data on demand, with an automatic safety refresh every 12 hours while Home Assistant is running
| Sensor | Description | Unit | Valid Range |
|---|---|---|---|
| pH | Current pool pH | pH | 0 β 14 |
| Chlorine | General chlorine level (legacy) | ppm | 0 β 10 |
| Free Chlorine | Active chlorine available for sanitization | ppm | 0 β 10 |
| Total Chlorine | Free + combined chlorine | ppm | 0 β 10 |
| Combined Chlorine | Chloramines β calculated (Total β Free) | ppm | 0 β 5 |
| Unbound Chlorine | Free chlorine from ActiveChlorine model β calculated | ppm | 0 β 5 |
| Chlorine Bound to CYA | Chlorine sequestered by stabilizer β calculated | ppm | 0 β 5 |
| Temperature | Pool water temperature | Β°C | 0 β 50 |
| Alkalinity | Total alkalinity | ppm | 0 β 300 |
| Stabilizer (CYA) | Cyanuric acid level (chlorine mode only) | ppm | 0 β 200 |
| Salt Level | Salt concentration | ppm | 0 β 3600 |
| Bromine | Bromine concentration (bromine + active oxygen mode only) | mg/l Brβ | 0 β 9 |
| Active Oxygen | Active Oxygen concentration (bromine + active oxygen mode only) | mg/l Oβ | 0 β 20 |
| Sensor | Description |
|---|---|
| Measurement Count | Total number of measurements stored for the device |
| Invalid Measurement Count | Total number of overrange/invalid measurements stored for the device |
| Last Measurement | Timestamp of the most recent measurement |
When a device is configured with Manual refresh (12h safety sync), the integration creates:
- Refresh Data button (one per device)
Pressing this button triggers an immediate backend fetch for that device.
Manual refresh (12h safety sync) is designed for users who measure infrequently (for example once or twice per week):
- Data can be refreshed on demand with the button entity
- A 12-hour fallback refresh still runs so data does not stay stale indefinitely
- The button can be triggered from automations using
button.press
alias: "Pool: Daily Manual Refresh"
trigger:
- platform: time
at: "08:00:00"
action:
- service: button.press
target:
entity_id: button.backyard_pool_refresh_dataalias: "Pool: Refresh Before Chemistry Check"
trigger:
- platform: state
entity_id: input_boolean.run_pool_check
to: "on"
action:
- service: button.press
target:
entity_id: button.backyard_pool_refresh_data
- delay: "00:00:05"
- service: notify.mobile_app
data:
title: "Pool Data Refreshed"
message: "Latest Poollab backend values have been fetched."The integration also provides a service that refreshes all configured devices in the entry:
poollab.refresh_data
| Sanitizer | Sensor | Integration Behavior | Typical Practical Target* | Documented Valid Range |
|---|---|---|---|---|
| Chlorine | sensor.pool_name_free_chlorine (plus total/combined/unbound/bound variants) |
Mix of direct values + calculated metrics (combined/unbound/bound) | Free chlorine: 1-3 ppm; Combined chlorine: < 0.5 ppm | 0-10 ppm (free/total), 0-5 ppm (combined), 0-10 ppm (unbound/bound) |
| Bromine | sensor.pool_name_bromine |
Direct LabCom measurement (PL Bromine) |
Often 2-5 ppm | 0-13.5 ppm |
| Active Oxygen | sensor.pool_name_active_oxygen |
Direct LabCom measurement with multiple aliases (MPS and localized names) | Often 4-8 ppm | 0-30 ppm |
* Practical targets depend on product instructions, local regulations, pool/spa type, and water conditions.
The integration provides detailed chlorine measurements in chlorine mode:
- Free Chlorine (Active Chlorine): The chlorine available for sanitization. Ideal range: 1β3 ppm.
- Total Chlorine: All chlorine in the pool (free + combined).
- Combined Chlorine: Automatically calculated as (Total β Free). Represents chloramines and water quality. Should be < 0.5 ppm.
- Unbound Chlorine / Bound to CYA: Calculated by the LabCom
ActiveChlorineAPI using your pH, temperature, chlorine, and CYA readings. Requires at least pH and free chlorine measurements to be available.
- Bromine: Direct bromine residual measurement from LabCom (
PL Bromine). No local formula is applied by the integration. - Useful when your pool or spa uses bromine tablets/systems instead of chlorine.
See BROMINE_CHEMISTRY.md for detailed bromine guidance and automation ideas.
- Active Oxygen: Direct residual measurement from LabCom. The integration supports multiple field name variants used by LabCom exports, including
PL Active Oxygen,PL Active Oxygen (MPS),PL Active Oxygen MPS,PL MPS, and German labels. - Useful when your system uses MPS/active oxygen sanitizing products.
See ACTIVE_OXYGEN_CHEMISTRY.md for interpretation guidance and automation examples.
For chlorine-specific deep guidance, see CHLORINE_CHEMISTRY.md.
The integration validates all measurement values from the API against the physical ranges listed in the table above. Values outside these ranges (e.g. a pH reading of β1 or 99) are treated as invalid and the sensor reports unavailable instead, with a warning logged. The same validation applies to inputs used for the ActiveChlorine calculation β if any required input is out of range, the calculation is skipped for that update cycle.
This integration requires:
- Valid Labcom API token
- At least one Poollab device registered in your account
- Internet connectivity for API communication
- Verify your API token is correct
- Check the token at https://backend.labcom.cloud/graphiql
- Ensure your Labcom account is active
- Check your internet connection
- Log in to your Labcom account
- Verify you have a Poollab device registered
- Ensure the device is associated with your account
- Check network connectivity
- Verify API token is still valid
- Check Home Assistant logs for error messages
- If a specific sensor is unavailable, verify the measurement is synced to the Poollab backend
- A value that is out of the valid range listed above will also cause the sensor to report unavailable (a warning will appear in the logs)
- In Manual refresh (12h safety sync) mode, updates happen when you press the refresh button or trigger
button.press - A safety refresh still runs every 12 hours while Home Assistant is running
- If you need fresher values, run refresh from a dashboard button or automation
For issues, feature requests, or questions, please visit: https://github.com/stefanh12/poollab/issues
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.