Water quality sensors (pH, ORP) + configurable gauges with color-coded thresholds

Hi everyone :waving_hand:

I wanted to share 2 PRs that I just opened, related to a concrete case: integrating my iopool Eco probe (swimming pool water quality monitoring) into Gladys via MQTT.

I’ve sent the probe data to Node-RED, which publishes to the MQTT broker. This allows me to create a virtual MQTT device in Gladys with the following features: temperature, pH, ORP (disinfection capacity), mode, recommended filtration duration, and date of last measurement.

The problem: for pH and ORP, no sensor category matched. I had to use « Unknown Â» for pH and « Air Quality Index Â» for ORP (because airquality-sensor was the closest match). Not ideal.

I therefore made 2 PRs (stack):


PR 1 — Water Quality Sensor Categories

:link: Add water quality sensor categories (pH, ORP) by Terdious · Pull Request #2530 · GladysAssistant/Gladys · GitHub

Added 2 generic categories, reusable by any integration (MQTT, Z2M, Matter, custom services):

  • ph-sensor — Water pH, range 0–14, new dimensionless unit ph
  • orp-sensor — Oxidation-Reduction Potential (Redox / « Disinfection Capacity Â»), in millivolt (existing unit)

Covers swimming pool probes (iopool, Ondilo, BWT), aquariums, rainwater measurement stations, etc.

Naming convention: standard scientific terms (no disinfection-capacity-sensor). But the FR label keeps « ORP / Disinfection Capacity Â» to remain accessible to the general public.


Why No Automatic Coloring on the « Device Â» Widget?

Legitimate question: air quality (CO2, PM2.5, VOC…) displays an automatically colored badge in the Device widget based on the value. Why not do the same for pH and ORP?

Because it only works for measurements with universal thresholds. CO2 at 1200 ppm is bad everywhere, regardless of context — it’s a global health standard.

pH and ORP, on the other hand, are absolute scales whose « correct Â» range depends entirely on the use case:

Use Case Ideal pH Ideal ORP
Swimming Pool 7.0 – 7.4 650 – 750 mV
Freshwater Aquarium 6.5 – 7.5 250 – 400 mV
Reef Aquarium 8.1 – 8.4 350 – 450 mV
Drinking Water 6.5 – 8.5 —
Hydroponics 5.5 – 6.5 —

If we hardcoded swimming pool thresholds in the Device widget, an aquarium user would see their value in red even though their water is perfect. Misleading.

There’s also a technical detail: air quality coloring is monotonic (« the lower, the better Â»). pH is a range: bad at the low and high ends, good in the middle. The existing logic simply doesn’t apply.

That’s why threshold-based coloring is handled by PR2 (configurable gauge): each user defines their own thresholds based on their use case. Neutral, correct for everyone, and reusable far beyond water quality (battery, tank level, etc.).


PR 2 — Configurable Gauge with Colored Thresholds

:link: Gauge dashboard widget: add configurable color thresholds by Terdious · Pull Request #2531 · GladysAssistant/Gladys · GitHub

Reuses the threshold + color logic already present in the « Room Temperature Â» and « Room Humidity Â» widgets, but in a generic way on the Gauge widget:

  • Checkbox « Configure custom thresholds Â» in the editor
  • Double slider to define the 2 thresholds (the slider bounds come from the min/max of the feature, so consistent with pH 0-12, ORP 500-1100, battery 0-100, etc.)
  • 3 color selectors (low zone / in range / high zone) with the chart widget palette
  • Legend under the gauge with the 3 colors and the bounds formatted with the unit
  • No custom thresholds → the original ApexCharts gradient is preserved (zero regression)



Why These Design Choices

  • Separate categories rather than an umbrella category water-quality-sensor with multiple types: aligned with the existing pattern (co2-sensor, pm25-sensor, voc-sensor, etc. — 1 category = 1 physical measurement)
  • Configurable gauge rather than a dedicated swimming pool widget: generic = useful for many more use cases (electric vehicle battery, soil humidity, dB, tank level, etc.)
  • No hardcoded smart coloring by category (e.g., « pH between 7.0-7.4 = green Â»): left to the user’s choice via the editor, to remain neutral on industry conventions (swimming pool ≠ aquarium ≠ spa)

Feedback welcome :folded_hands: — especially on:

  1. The naming of the categories (ph-sensor / orp-sensor vs alternatives?)
  2. The FR wording for ORP — is « Disinfection Capacity Â» clear enough for those who don’t know water chemistry?
  3. Are there other use cases (aquarium, rainwater, hydroponics…) that would benefit from these categories or require others (TDS, conductivity, salinity)?
  4. The configurable gauge — do you see other widgets that would deserve the same threshold/color treatment?

Thanks for reading :slightly_smiling_face:

It’s been a while since I’ve been looking for a probe for my pool. I’ve always been afraid to start because I was afraid the calibration would be totally messed up / change too much over time.

Can you tell me how it is on your side? :wink:

Hi @guim31,

Yes of course, I’ve had this probe since 2022, I took one for a colleague in 2023 (Salt), and one for my dad in 2024 (Salt as well).

For my part, I use Active Oxygen during the summer, I had an issue with an incorrect value in 2024, I bought the recalibration kit and then it was fine. I completely replaced it when starting up again in 2025 because the battery was dead (rated for 2 years, it lasted 3 summers). Unfortunately, it was the first version and it wasn’t disassemblable to replace just the battery, so I had to buy the new version entirely. The new ones can be opened with screws on the head and therefore you can replace the probe or the battery independently.

My colleague has the new version, he hasn’t had any issues yet, maybe when starting up this year for the battery. Regarding the probe, he is a metrologist and his feedback is that it works very well. Drifts are normal in this kind of use with hibernation in the winter, but calibration is fine. Regarding the probe, as a metrologist, he gives a lifespan of 5 to 10 years, which is totally normal. For active oxygen or chlorine use, the probes are cheaper.

My dad lives in the south, he doesn’t hibernate it, and no issues so far, not even a recalibration.

For monitoring deviations for recalibration, you can do strip tests directly with the application to spot the deviations. I also equipped myself with an electronic pH and ORP sensor to ensure reliability.

Personally, I didn’t know ORP, but Redox makes much more sense to me because when I need to check, it’s the Redox I verify (I’m also on salt).
By the way, for pools, we talk more about Redox than ORP (or maybe I need to find a bigger pool :joy:).
I would be more in favor of redox-sensor than orp-sensor, what do you think?

And great job on the development, thanks for all you do :wink:

That sounds great! Awesome development :slight_smile:

I’ll let you know as soon as I’ve had a chance to check it out!

For your probe, wouldn’t it make sense to have a Matterbridge plugin?

Don’t hesitate to test the factory, that’s what it’s for :wink: (even if, for you who already uses Claude Code, it won’t impress you as much!)

Thanks so much for your feedback, I’ll take a closer look thanks to you!!!

Hi mutmut,

You’re right about the pool context in France: Redox is indeed the dominant term (Zodiac, Hayward, CCEI… all label their regulators « Redox Â»). A small clarification though: « for pools, we talk more about Redox than ORP Â» → that’s true in France, but internationally (and in English in general), ORP remains the standard according to my brief research. And in other fields that might use this category — aquariums, hydroponics, drinking water treatment — ORP also dominates, especially because almost all probes sold online are labeled « ORP probe Â».
Technically, both refer to exactly the same thing (oxidation-reduction potential in mV), it’s just a matter of regional/sectoral usage.

So I would suggest a compromise: keep orp-sensor on the code side (international consistency, more universal for SEO and equipment search), but display « Redox / ORP Â» on the French UI.
It speaks to everyone, French pool professionals as well as aquarists, without excluding anyone.

What do you think?

Thanks Pierre-Gilles :grinning_face_with_smiling_eyes:

For the Matterbridge plugin, why not indeed! Connecting to the iopool API is quite simple, and there’s already an example integration on the Home Assistant side that we can draw inspiration from.
On my end, I can share my Node-RED flow that already does the job, that should give a good basis for development.

However, this will be more for the community than for me: I’m really not a fan of Matter at the moment​:sweat_smile:

I’ll test the factory with pleasure, a bit curious to see what it gives anyway.

I think the compromise is very good :+1:

It’s done!

Issue created by the AI → for the AI :sweat_smile:: [PLUGIN REQUEST] iopool EcO – pool water quality monitor (temperature, pH, ORP) · Issue #15 · GladysAssistant/matterbridge-ai-plugin-factory · GitHub

With a point raised by Claude Opus 4.7:

« One honest reservation to keep in mind: since pH and ORP don’t have a standard Matter cluster, the display in Gladys will probably be perfect for temperature and « best-effort Â» for pH/ORP — this is exactly the kind of feedback Pierre-Gilles expects from this test. Â»

I tested the plugin generated by the factory on my Matterbridge instance (3.7.9). First assessment :backhand_index_pointing_down:

:white_check_mark: What works well

  • The plugin installs and runs (status Running), connects to the iopool API, discovers my pool, and names it correctly (« Piscine DUBLEM », the name defined in iopool).
  • Water temperature is perfect: reported in a real Matter TemperatureMeasurement cluster → 11.15 °C, natively usable. For this part, the plugin does exactly the job.

:warning: The pH / ORP trap — exactly what we anticipated

Since Matter has no pH or ORP clusters, the AI did its best: it exposes pH and ORP… in TemperatureMeasurement clusters as well. Result:

  • 3 « temperature sensors » for a single pool (water + pH + ORP).
  • pH: the correct figure (6.69) but displayed in °C.
  • ORP: completely wrong — displayed 5.73 instead of 573 mV. The temperature cluster is in hundredths of degrees (Ă·100 on the controller side), and ORP doesn’t fit in this scale → value divided by 100.

:cross_mark: Another bug found: the « Online » status

The device is marked « Online » permanently (reachable = true fixed). This only reflects the success of the cloud API call, not the actual state of the probe — my probe is currently out of the water, and the plugin still shows it as « Online » with the last cached values. The iopool API does provide isValid + measuredAt to handle this correctly.

:magnifying_glass_tilted_left: Conclusion

The factory produced a very good first draft: connection, discovery, temperature → perfect. But this confirms in black and white the fundamental issue: Matter cannot structurally support pH and ORP. The « temperature workaround » is the only possible one today, but it gives false/misleading data in any controller.

:person_raising_hand: Decision to be made — @pierre-gilles

I prepared a detailed feedback for issue #15 (checklist + bugs + root cause). Before posting it, your opinion on pH/ORP on the Matterbridge plugin side:

  1. We keep them in the plugin, clearly documenting the traps (pH = read the value without the unit, ORP = Ă—100 mentally)?
  2. We remove them from the Matter plugin and assume « temperature only » as the Matter deliverable, with pH/ORP remaining on the MQTT channel (categories ph-sensor/orp-sensor from my PR) until Matter has the clusters?

The reachable/« Online » bug and a cosmetic productUrl are correctable by a --fix from the factory, whatever happens.

(In parallel, I created a feature request on project-chip/connectedhomeip for real pH/ORP clusters — long-term subject 6-24 months, if taken into account.)

In this case, the big advantage of Matterbridge plugins is that I’m not needed, do what seems best to you :wink:

My goal is not to be the bottleneck on these topics, total freedom :wind_face:

Great!