Try this: Template
Why not just use the dropdown and set unit of measurement to F. Home assistant will do conversions for you.
I was fiddling with the YAML and didnât realize you could do that! Thank you! That fixed it without any fancy coding.
I am still testing it but low ORP can be boost up using OXI treatment based on POTASSIUM MONOPERSULFATE. It is non-chlorine shock which removes unwanted chloramines and organic residues and rises oxidation (ORP). There are many products on the market available, for example AstralPool CTX-23 in Europe.
Hi,
I just read the whole thread but nothing has helped me. Let me describe my setup (sorry if it is long).
I previously had a RPi with a Sonoff USB Dongle Plus for all my Zigbee devices (other than bulbs that are managed by a Philips Hue Bridge, so reliable that I do not want to change that).
Summer â24 I bought the BLE-YL01 device (white on top, cyan on botom cover). Managed to pair it with the Sonoff dongle and Z2M. Was working ok, got values reported.
Spring 25â, the device stopped working. Tried to charge it via USB, to reset it, no red light flashing.
Luckily, I did purchase it from a french dealer, so I just opened a case for warranty repair, and I got it replaced free of charge by the upgraded yellow version, which arrived at my home less than a week ago.
Paired it with Z2M, but had some trouble with signal quality. (My RPi+Sonoff dongle are in the middle of first floor in my house, the pool is 5.50m diameter located 2m away of the external walls of my house).
I noticed that some sensors also had trouble to connect when located at the opposite of my house.
After searching, I decided to change my setup to the following (done yesterday as I received the parcel):
- SMLIGHT SLZB-06M as coordinator in the middle of 1st floor of my house
- SMLIGHT SLZB-06M as router in the middle of ground floor of my house
- One Zigbee plug (Nous A7Z) somewhere in ground floor
- A pair of Zigbee outdoor plugs (Nous A4Z) near the pool, to automate the pump.
Added Z2M as a plugin to Home Assistant, kept my external MQTT server.
Paired all my devices to the new setup and turned off the RPi.
I now get good coverage for my far away sensors, unfortunately some Aqara sensors are loosing the link without notice, even if these are just lying 1m away of the coordinator, but thatâs another story.
So, the pool sensor at first didnât report any values. I thought Iâd let it overnight so the Zigbee network arranges it self with all these new devices.
So, this morning I discovered the pool sensor did report some values in the night, but stopped reporting. Itâs been 6 hours without any report. While I was writing this text, I just saw the values did update 5 minutes ago. Now waited, no update since 15 minutes.
Here is a graph oh my Zigbee network where I see there should be no signal issue:
So Iâm a bit stuck, why donât these values update every 10 minutes or 5 minutes as I understood it should be reading the code of the PR that integrates this device to Z2M ?
A lot of people are talking about a âbacklight_valueâ that should be modified to poll the sensors, but I donât have this entity neither in Z2M nor HA. Whatâs wrong with my setup?
As a side note, this new sensor still reports in Z2M as the blue one with BLE-YL01 model, is this just because these âfriendlyâ name and picture were not updated when pushing the PR with the new device support?
Back to some testing, after days of trouble having one measurement every 10 hours or so, I just paired the device to my âoldâ RPi + Sonoff dongle, and Iâm now getting one measurement every 5 minutes or so, exactly what I was expecting.
BUT, I cannot say if this is an issue with the SMLight coordinator vs Sonoff dongle, or if this is due to Z2M version.
On my VM (linked to the SMLight), Iâm running 2.5.1 commit: ffdd353e
vs
On my RPi, Iâm running 1.39.1-dev commit: 00923685
And honestly, I donât want to upgrade Z2M on my RPi just to check this out, I prefer having an old version and something running!
I was planning to decommission the RPi for an enhanced network based on the SMLight coordinators, but finaly I will keep the RPi running just for the pool sensor âŠ
Hi all,
I think I finally make it WORK !! Thanks for all the previous messages in several threads (not only this one).
Here is my updated config.
First, you need an external converter for zigbee2mqtt, to place in the âzigbee2mqtt/external_converters/ext_converter.jsâ
The code is as follow (please not that i made some modification around what can be found in several posts (i changed the divider for PH and i added support of backlight_value, to trigger updates from the pool sensor) :
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const color = require('zigbee-herdsman-converters/lib/color');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const e = exposes.presets;
const ea = exposes.access;
const legacy = require('zigbee-herdsman-converters/lib/legacy');
const lumi = require('zigbee-herdsman-converters/lib/lumi');
const utils = require('zigbee-herdsman-converters/lib/utils');
const {logger} = require('zigbee-herdsman-converters/lib/logger');
const {develcoModernExtend} = require('zigbee-herdsman-converters/lib/develco');
const m = require('zigbee-herdsman-converters/lib/modernExtend');
const NS = 'extconverter';
const definition = {
fingerprint: tuya.fingerprint("TS0601", ["_TZE200_v1jqz5cy", "_TZE200_d9mzkhoq"]),
model: "BLE-YL01",
vendor: "Tuya",
description: "Smart WiFi Zigbee chlorine meter CUSTOM4",
whiteLabel: [tuya.whitelabel("Tuya", "YK-S03", "Smart pH and Chlorine Tester for Swimming Pool", ["_TZE200_d9mzkhoq"])],
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints],
// Don't query too often. Values are not always updated. https://github.com/Koenkk/zigbee2mqtt/issues/18704
onEvent: tuya.onEvent({
queryOnDeviceAnnounce: true,
queryIntervalSeconds: 10 * 60,
}),
configure: tuya.configureMagicPacket,
exposes: [
e.numeric("tds", ea.STATE).withUnit("ppm").withDescription("Total Dissolved Solids"),
e.temperature(),
e.battery(),
e
.numeric("ph", ea.STATE)
.withUnit("pH")
.withDescription(
"pH value, if the pH value is lower than 6.5, it means that the water quality " +
"is too acidic and has impurities, and it is necessary to add disinfectant water for disinfection",
),
e.numeric("ec", ea.STATE).withUnit("”S/cm").withDescription("Electrical conductivity"),
e
.numeric("orp", ea.STATE)
.withUnit("mV")
.withDescription(
"Oxidation Reduction Potential value. If the ORP value is above 850mv, it " +
"means that the disinfectant has been added too much, and it is necessary to add water or change the water for neutralization. " +
"If the ORP value is below 487mv, it means that too little disinfectant has been added and the pool needs to be disinfected again",
),
e
.numeric("free_chlorine", ea.STATE)
.withUnit("mg/L")
.withDescription(
"Free chlorine value. The water in the swimming pool should " +
"be between 6.5-8ph and ORP should be between 487-840mv, and the chlorine value will be displayed normally. Chlorine will not " +
"be displayed if either value is out of range",
),
e.numeric("ph_max", ea.STATE_SET).withUnit("pH").withDescription("pH maximal value").withValueMin(0).withValueMax(20),
e.numeric("ph_min", ea.STATE_SET).withUnit("pH").withDescription("pH minimal value").withValueMin(0).withValueMax(20),
e
.numeric("ec_max", ea.STATE_SET)
.withUnit("”S/cm")
.withDescription("Electrical Conductivity maximal value")
.withValueMin(0)
.withValueMax(20000),
e
.numeric("ec_min", ea.STATE_SET)
.withUnit("”S/cm")
.withDescription("Electrical Conductivity minimal value")
.withValueMin(0)
.withValueMax(100),
e
.numeric("orp_max", ea.STATE_SET)
.withUnit("mV")
.withDescription("Oxidation Reduction Potential maximal value")
.withValueMin(0)
.withValueMax(1000),
e
.numeric("orp_min", ea.STATE_SET)
.withUnit("mV")
.withDescription("Oxidation Reduction Potential minimal value")
.withValueMin(0)
.withValueMax(1000),
e
.numeric("free_chlorine_max", ea.STATE_SET)
.withUnit("mg/L")
.withDescription("Free Chlorine maximal value")
.withValueMin(0)
.withValueMax(15),
e
.numeric("free_chlorine_min", ea.STATE_SET)
.withUnit("mg/L")
.withDescription("Free Chlorine minimal value")
.withValueMin(0)
.withValueMax(15),
e
.numeric("salinity", ea.STATE)
.withUnit("ppm")
.withDescription("Salt value"),
e
.numeric("backlightvalue", ea.STATE_SET)
.withUnit("gg")
.withDescription("Backlight Value")
.withValueMin(0)
.withValueMax(1),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[1, "tds", tuya.valueConverter.raw],
[2, "temperature", tuya.valueConverter.divideBy10],
[7, "battery", tuya.valueConverter.raw],
[10, "ph", tuya.valueConverter.divideBy10],
[11, "ec", tuya.valueConverter.raw],
[101, "orp", tuya.valueConverter.raw],
[102, "free_chlorine", tuya.valueConverter.divideBy10],
[105, 'backlightvalue', tuya.valueConverter.raw],
[106, "ph_max", tuya.valueConverter.divideBy10],
[107, "ph_min", tuya.valueConverter.divideBy10],
[108, "ec_max", tuya.valueConverter.raw],
[109, "ec_min", tuya.valueConverter.raw],
[110, "orp_max", tuya.valueConverter.raw],
[111, "orp_min", tuya.valueConverter.raw],
[112, "free_chlorine_max", tuya.valueConverter.divideBy10],
[113, "free_chlorine_min", tuya.valueConverter.divideBy10],
[117, "salinity", tuya.valueConverter.raw],
],
},
};
module.exports = definition;
Then, RESTART zigbee2mqtt
in order to verify if it does LOAD the external converter, make sure there is a âCUSTOM4â in the device page
Then, you need to setup a Home assistant automation, that will modify the backlight_value for triggering devices update. here is the code, feel free to change the update time (mine is every 10 minutes, but it might drain the battery, i don t know yet)
alias: Pool testing
description: ""
triggers:
- minutes: /10
trigger: time_pattern
conditions:
- condition: sun
after: sunrise
before: sunset
enabled: true
before_offset: "-00:30:00"
- condition: not
conditions:
- condition: state
entity_id: sensor.z_poolsensor_temperature
state: unavailable
actions:
- repeat:
count: 24
sequence:
- metadata: {}
data:
value: "0"
target:
entity_id: number.z_poolsensor_backlightvalue
action: number.set_value
- delay:
hours: 0
minutes: 0
seconds: 1
milliseconds: 0
- metadata: {}
data:
value: "1"
target:
entity_id: number.z_poolsensor_backlightvalue
action: number.set_value
- delay:
hours: 0
minutes: 0
seconds: 4
milliseconds: 0
mode: single
Note that you need to edit the automation, so that the entity_id reflects your entity name.
To verify if it works, you can trigger the automation manually, and you should see values of the sensor change (note that it needs several seconds for all the sensors to update).
Hope it will work for you ! (i have the blue BLE-YL01, not the yellow one)
Please tell me if it works for you.
I still think the âFree Chlorineâ is giving incorrect results⊠maybe it shoudnât be divided by 10, but taken has raw value.
Do you experience same issue with the âFree Chlorineâ sensor ?
Please tell me if it works for you !
and : BLE-YL01 is spamming network. · Issue #23946 · Koenkk/zigbee2mqtt · GitHub
I just scrolled up in this thread for several posts, but can someone please make a little summary of the current recommended devices?
I am searching for a zigbee or zwave device for my pool. But it should report correct values ![]()
After reading this thread, I have a question, will this solution also work with a cheaper sensor, for example:
Tuya ZigBee Intelligent Chlorin Meter 7in1 PH ORP TotalâŠ
Is it necessary to purchase the original gateway? I have many sensors and switches in my network that work over Zigbee.
this is the one i have (not so cheap around 75$).
if you want to make it work you need to follow my post, above, thanks to a LOT of users, we managed to make it work. I do not have the orginal gateway, but a zigbee2mqtt with a SONOFF zigbee dongle.
This sounds good.
Does anybody compared the two versions and knows which one has the better accuracy?
Which one should we buy? ![]()
The yellow one is upgraded.
Did you solve the issue with negative ORP-Values?
Yes, I posted here how to boost ORP.
A question: did you put the product in the pool where the sensor is or did you make a solution to clean the sensor probe?
Thank you
OXI is treatment for pool water. KCL is for probes cleaning.
I imagined that. Thank you for the confirmation and for all the help.
Thanks for the info. Iâm willing to give it a try, since some days I get frequent updates, while on others it only updates twice a day. How do you calibrate yours? Is it possible to do this without a Tuya gateway? My chlorine values also seem quite low, so Iâm thinking calibration might help. How is calibration usually handled? Could we, for example, create a template sensor that applies calibration parameters provided by the user to adjust the values?
Chlorine value is correlated to ORP. Device comes calibrated. ORP is more important value than Chlorine, but both values are involved by PH and temperature. So when ORP is low or negative, try OXI treatment which removes chloramine residuals and improve oxidation, which is most important for safe water.
Does anyone have this issue, with the new sensors (the yellow one)
No salinity metrics are getted on z2m , but are ok on tuya app?
Thanks


