No description
  • JavaScript 100%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Philipp A. Baer f8391e5a60
All checks were successful
Validate frontend / validate (push) Successful in 3s
Validate frontend / release (push) Successful in 17s
fix: render badges with proper font size
2026-07-26 09:55:40 +02:00
.forgejo/workflows fix: overwrite tags 2026-07-26 08:42:51 +02:00
.github/workflows feat: refactor ui (#1) 2026-07-26 06:34:41 +00:00
scripts feat: refactor ui (#1) 2026-07-26 06:34:41 +00:00
.gitignore Properly build and bundle the card 2026-07-18 08:55:10 +02:00
ha-poolsensor.js fix: render badges with proper font size 2026-07-26 09:55:40 +02:00
hacs.json feat: refactor ui (#1) 2026-07-26 06:34:41 +00:00
LICENSE Make this MIT licensed 2026-07-18 09:02:21 +02:00
package-lock.json feat: refactor ui (#1) 2026-07-26 06:34:41 +00:00
package.json feat: refactor ui (#1) 2026-07-26 06:34:41 +00:00
README.md feat: refactor ui (#1) 2026-07-26 06:34:41 +00:00
renovate.json Properly build and bundle the card 2026-07-18 08:55:10 +02:00
translations.js feat: refactor ui (#1) 2026-07-26 06:34:41 +00:00

Pool Water Quality Card

A Home Assistant Lovelace card for showing pool-water measurements from entities you already have. It does not create, transform, or aggregate entities, so your existing integrations and automations remain the source of truth.

Installation

HACS

  1. In HACS, open the three-dot menu and choose Custom repositories.
  2. Add this repository's GitHub URL and select Dashboard as its type.
  3. Install Pool Water Quality Card.
  4. Add the card resource in your Lovelace dashboard:
resources:
  - url: /hacsfiles/ha-poolsensor/ha-poolsensor.js
    type: module

HACS installs a versioned release. The release asset is a single, self-contained ha-poolsensor.js file: it includes the translations and does not require a separate translations.js file. The default branch is deliberately not offered for installation because it contains the unbundled development sources.

Manual installation

Download ha-poolsensor.js from the chosen release, copy it to config/www/, then add /local/ha-poolsensor.js as a module resource.

Lovelace card

Configure the entities that provide the measurements you want to display:

type: custom:poolsensor-water-quality-card
title: Pool Water Quality
ph: sensor.pool_ph
free_chlorine: sensor.pool_cl
orp: sensor.pool_orp
temperature: sensor.pool_temperature
ambient_temperature: sensor.outdoor_temperature
salinity: sensor.pool_salinity
tds: sensor.pool_tds
ec: sensor.pool_ec
language: de
filter: switch.pool_filter
filter_power: sensor.pool_filter_power
heating: switch.pool_heating
heating_power: sensor.pool_heating_power

The optional filter/heating badges use icons and color to show on/off state; filter_power and heating_power are normalized to one decimal place in watts. Click a badge to open the configured filter/heating entitys standard Home Assistant details dialog. Equipment state does not affect the water-quality grade.

ambient_temperature is optional. It is shown beside the water-temperature reading and, when water temperature is configured, includes the waterair temperature difference. It does not affect the water-quality grade.

History graphs

The card intentionally focuses on current water status and remains compact on mobile. For responsive trends, use Home Assistants native statistics-graph below it. It uses Recorder statistics and can show the minimum, maximum, and mean for sensors with long-term statistics.

type: statistics-graph
title: Pool temperatures
chart_type: line
days_to_show: 1
period: 5minute
stat_types:
  - min
  - max
  - mean
entities:
  - sensor.pool_temperature
  - sensor.outdoor_temperature

For pH and free chlorine, create separate statistics graphs because they use different units and practical scales. Development dependencies are defined in package.json; run npm ci && npm run build after changing the authored source files in the repository root to create a local dist/ha-poolsensor.js.

Graphable pH and free-chlorine helpers

If the source entities do not expose long-term statistics, mirror them with modern template sensors that explicitly declare state_class: measurement. Add the following under template: in configuration.yaml, replacing the source entity IDs if necessary, then restart Home Assistant or reload template entities.

template:
  - sensor:
      - name: Pool pH graph
        unique_id: pool_ph_graph
        unit_of_measurement: pH
        state_class: measurement
        availability: "{{ is_number(states('sensor.pool_ph')) }}"
        state: "{{ states('sensor.pool_ph') | float }}"

      - name: Pool free chlorine graph
        unique_id: pool_free_chlorine_graph
        unit_of_measurement: mg/L
        state_class: measurement
        availability: "{{ is_number(states('sensor.pool_cl')) }}"
        state: "{{ states('sensor.pool_cl') | float }}"

Use sensor.pool_ph_graph and sensor.pool_free_chlorine_graph in the statistics graphs. Statistics begin collecting after these helper entities are created; they do not backfill historical data.

HACS graph alternatives

Install either Mini Graph Card or ApexCharts Card from HACS before using the corresponding example. Both examples use 20-minute median buckets over the last 24 hours, so they are directly comparable.

Mini Graph Card

This is the more compact option, suited to a mobile dashboard.

type: custom:mini-graph-card
name: Pool temperatures
hours_to_show: 24
points_per_hour: 3
aggregate_func: median
group_by: interval
line_width: 2
height: 130
show:
  icon: false
  state: false
  fill: false
  points: false
  labels: hover
  legend: true
entities:
  - entity: sensor.pool_temperature
    name: Water
    color: var(--primary-color)
  - entity: sensor.outdoor_temperature
    name: Ambient
    color: var(--secondary-text-color)

ApexCharts Card

This option is better when you want pH and free chlorine in one chart with their own axes and a richer touch tooltip.

type: custom:apexcharts-card
header:
  show: true
  title: Pool water quality
graph_span: 24h
update_interval: 5min
all_series_config:
  type: line
  curve: smooth
  stroke_width: 2
  group_by:
    func: median
    duration: 20min
    fill: last
yaxis:
  - id: ph
    min: 6
    max: 9
    decimals: 2
  - id: chlorine
    opposite: true
    min: 0
    max: 3
    decimals: 2
apex_config:
  chart:
    height: 220
    toolbar:
      show: false
  legend:
    position: bottom
  tooltip:
    shared: true
    intersect: false
series:
  - entity: sensor.pool_ph
    name: pH
    yaxis_id: ph
    color: var(--info-color)
    show:
      extremas: true
  - entity: sensor.pool_cl
    name: Free chlorine
    yaxis_id: chlorine
    color: var(--warning-color)
    show:
      extremas: true

ApexCharts Card can show min/max values in the header (show.extremas), but its standard Home Assistant entity-series configuration cannot create a true shaded minmax envelope. Mini Graph Card likewise has no min/max band feature. For the median/mean line with a genuine min/max band, use the native statistics-graph example above with stat_types: [min, max, mean].

Renovate

Renovate updates the source dependencies and lockfile. The release workflows build the distributable, so dependency-update PRs need no generated bundle or special Renovate command permission.

Customization

You can override acceptable ranges in the card configuration:

type: custom:poolsensor-water-quality-card
title: Pool Status
ph: sensor.pool_ph
free_chlorine: sensor.pool_cl
ranges:
  ph: '6.5 - 7.3'
  free_chlorine: '0.3 - 0.6'

Each configured target is displayed as a range bar: the green centre is the target region, the faded red sections are outside it, and the dot is the current reading. Measurements without a configured entity are omitted. Values are read directly from Home Assistant and are never persisted or modified by the card.

All range bars share one normalized scale: the configured target always occupies the central 4060% of the bar, so equal relative deviations look equal across pH, chlorine, ORP, and other measurements. Readings beyond the displayed scale use a directional arrow at the relevant edge; the exact value remains visible beside the bar.

The default targets are pH (6.57.3), free chlorine (0.30.6 mg/L), ORP (650750 mV), and a temperature comfort range (2430 °C). The pH/free-chlorine pair follows German Federal Environment Agency guidance. It is not an EU-wide legal limit: set your own range for local rules, stabiliser use, pool type, and equipment instructions. Salinity, TDS, and EC have no default target: configure them only from your chlorinator manual, pool type, and source-water test results, using the same unit as the entity. ORP is a supporting signal, not a chemical-dosing target by itself.

Guidance

When one or more readings are outside their targets, the card shows one prioritized, conservative next step. It does not calculate chemical dosages. Hover a status dot to see whether that reading is above, below, or within its target. You can replace a message for a measurement and direction with guidance:

guidance:
  salinity:
    low: Follow the salt chlorinator manual before adding salt.

Always confirm an out-of-range reading with a reliable water test and follow the instructions for your equipment and pool chemicals.

Measured status grade

The card shows a Measured status grade, not a declaration that the water is safe to swim in. It requires valid pH and free-chlorine readings:

  • A: all configured readings that have a target are on target.
  • B: pH and free chlorine are on target, but a supporting reading is not.
  • C/D: one/multiple primary readings need attention.
  • F: free chlorine is below its configured minimum, or a configured critical range is exceeded.
  • : pH/free chlorine are not configured or do not have valid readings.

By default, pH and free chlorine are the primary readings. You can set a hard pH boundary that produces an F:

grading:
  primary:
    - ph
    - free_chlorine
  critical_ranges:
    ph: '6.3 - 7.5'

Set grading.enabled: false to hide the grade.

Visual editor

When adding or editing the card from a Home Assistant dashboard, choose Pool Water Quality Card and select the title and measurement entities in the visual editor. Range overrides remain available through the YAML editor.

Languages

Select the card language in the visual editor or set language in YAML. Supported values are en, de, fr, it, and es. This translates the card labels, range/status tooltips, overall recommendation, and grade explanation.