Blue Connect pool measurements

Not sure if the temperature correction is right, since someone suggested that the Blueriiot has a build in temp correction. Curious about other reading and how you implement the corrections.

The current calculation doesn’t do that. My (and others) guess is that the cloud somehow does that.
When you would have multiple reading with the trusted source we could look into the calculation and alter it

If you use my code, check this ble_tracker section.

There’s a filter for mac, remove it and it should show all devices advertising. Maybe you have to remove also the “then”, I can’t remember now, experiment a bit.

It will log everything about the devices found.

1 Like

Hi Peerke,

Yes I could do that when I am back from my two month trip to NL. It’s working good enough to be happy with it but will try to get the device back for multiple readings. It’s salinity only though.
All device I have, (the Chinese pen versions), give very different readings. Not a good source for finetuning and for me only ORP seems way off.

I just purchased a unit last month. I have been using your YAML with the following adjustments

Did you replace the probe or the whole unit? Did you calibrate the probe through the probe settings in the app?

Brand new, calibrated from factory.

When I first purchased my unit and put it in the pool I was getting very low ORP readings from the App. I then checked the FC level with a test strip and inputted the results in the app. The next reading with the App my ORP jumped significantly. I dont know if this was just coincidental or somehow the FC from the test strip result was used as a calibration.
Do you know the FC level at the time of the reading?
Because things like CYA are know to affect the ORP readings and the real reason we are monitoring ORP is to be able to roughly determine the levels of sanitizer. I would suggest calibrating based on FC PPM
Online calculators suggest FC can be roughly calculated from ORP by
ORP-650/200x10
Your raw hex reading (0B06) = 2822/4= 705.5
705.5-650/200x10= 2.77
Does that closely match a test strip reading?

you’re right. I did a test with a strip and FC is between 2 and 3 (good luck with these colors). So, this thing could not be really trusted. I’ll keep the old formula back and stop using the app. We’ll see how good it is. I have a peristaltic pump ready to be deployed, so these reading must be valid in order to make sense.

It’s now reporting 673 as ORP (from 2713 raw) and it makes sense based on the strip value. Thanks for the heads-up!

I am currently running a chlorinator with trichlor as the sanitizer. I have also been logging data to determine the best deployment for liquid chlorine as I was afraid the trichlor would cause an overabundance of CYA. Luckily/unluckily my main source of water loss is my kids splashing so CYA levels are not building. We are on tiered electrical rates so I run my pump early AM and Late PM. The peaks and valleys are when the pump/chlorinator turns on and off. Over time the peaks and valleys trend lower. This is caused by CC building and/or the pucks depleting. The very high peaks are from shocking the pool with a non-chlorine oxidizer. I am starting to conclude that ORP is not great for injection directly, but great as an indication of a problem that requires intervention. I would look at dosing set amounts based on your typical rate of depletion


.

Because of your negatively correlated comment, I started playing with the theory that the data transmitted as “salt” is resistivity as resistivity is the inverse of conductivity. The APP reports the reading as micro siemens/cm if you set it up as a chlorine pool or TDS G/L if it is salt.
This is what I’ve been able to come up with so far but I can’t check lower resistivity or higher conductance as I don’t have a salt water pool. If someone with a saltwater pool can try this math or post a few packets with the app readings, that would be great.

Never mind the request for packets. I found some in this thread

I have a Go. Are you suggesting that the values are reported and it’s the app that’s showing them based on the model?

I would look at dosing set amounts based on your typical rate of depletion

That’s what I’m doing right now and it’s working great. I just want an indication that things are wrong, but since it’s a covered (and heated) pool, values are very stable and I rarely put ph+/- in (unless it rained a lot or at starting of the season) and I just add chlorine every 3-4 days. The idea is to just inject chlorine everyday in smaller quantities and have alerts when it’s low (or skip when it’s too high). We’ll see, thanks for the advice!

I believe the raw value in the Bluetooth packet that has been labeled as salt in this thread is resistance expressed in decimal ohms-cm.
Using the reading # 1 line of the excel sheet I posted this would be a value of 0.000728 ohms-cm
728 x .000001 = 0.000728
To convert to microsiemens-cm (μS/cm) 1/0.000728 = 1373.626373626374 microsiemens-cm
Of the 19 reading data set I took this result was an average of 6.15% low compared to the 1459 μS/cm reported in the App ( more on this later)
1373.626373626374 μS/cm x 1.0615= 1458.104395604396 μS/cm
We now have a value that is very to close to the App’s reported value. the small discrepancies could be explained by the time it takes to retrieve the two samples. For me this is between 2-5 mins.

If the desired result is in g/L we have to do some more conversions

first μS/cm to dS/m 1458.104395604396 x0.001 = 1.458104395604396 dS/m

Then because saltwater pools use NaCI (Sodium Chloride) we need to use the 500ppm scale to get TDS mg/l
1.458104395604396 x 500 = 729.0521978021978

Finally we can covert to TDS g/L by TDS mg/L / 1000
729.0521978021978 / 1000 = 0.7290521978021978 TDS g/L

What I can’t yet explain is why the need to add 6.15% in order to closely match the App. I initially thought about temperature compensation. Typically EC would be compensated to 25 at rate of aprox 2% per degree C but this would be a higher result for a reading taken at 29c
then the App, not lower.

For now, the readings taken at 25 - 32 C have pretty good results. The readings taken below 25 are not

Conductivity in μS/cm and Salinity in g/L if someone would like to use them

- platform: template
    id: sensor_${blueriiot_id_prefix}_cond
    name: "${blueriiot_name_prefix} Conductivity"
    unit_of_measurement: "µS/cm"
    icon: "mdi:water-sync"
    state_class: "measurement"
    accuracy_decimals: 0

  - platform: template
    id: sensor_${blueriiot_id_prefix}_salt
    name: "${blueriiot_name_prefix} Salinity"
    unit_of_measurement: "g/L"
    icon: "mdi:water-sync"
    state_class: "measurement"
    accuracy_decimals: 1


          float raw_cond = (float)( (int16_t) (x[8]<< 8) + x[7]);
          float cond = (float) (int16_t) 1 / (raw_cond * 0.000001) * 1.0615 ;
          ESP_LOGD("cond", "%f", cond);
          id(sensor_${blueriiot_id_prefix}_cond).publish_state(cond);

          float salt = (float) (int16_t) 1 / (raw_cond * 0.001) * 1.0615 * 500 / 1000 ;
          ESP_LOGD("salt", "%f", salt);
          id(sensor_${blueriiot_id_prefix}_salt).publish_state(salt);

2 Likes

Many thanks for this! Your salt formula in the comment below seems to work well for my pool. I have a NaCl pool which is 30c. Agree that there is a temperature dependence. I checked with some old values from when starting up my pool and it was only 20c. Salt formula does not work for this.

I am still using the Salt reading from the app but temperature, ORP and pH from ESP. Reason being that salt changes much slower than the other values.

I have the same sensor for conductivity since a couple of days.

I’ve also added a FC sensor that I’m monitoring, using the formula you posted above (ORP-650/200). Thanks!

1 Like

Thank You for your support.
Planning to give back soon to this thread.

Integrated the Bluerioot Sensor with

  • Tank Depth sensor - in my case to measure pH+ tank
  • Leak Detection: to block automatically pump and alert in case of leak in the tech room

Integrating with LVGL GUITION Panel to display

  • above data
  • turn on garden/pool lights / pump
  • Steer Arylic Pool Media Player

It will take some time but I will publish the draft soon hopefully

I’ve stumbled upon a complex formula for accurate salinity (temperature adjusted) that appears promising. I just took the temperature and raw salinity results and used the formula in a template sensor. I’m a coding novice, so I apologise in advance for my un-simplified template sensor.

Feel free to use with find and replace for:
Raw Salinity: sensor.esphome_ble_1_pool_salinity_raw
Temperature: sensor.esphome_ble_1_pool_temperature

Template Sensor (ppm):

{{ ((0.008+((-0.1692)*((((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))**0.5))+25.3851*(((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))+14.0941*((((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))**1.5)+((-7.0261)*((((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))**2))+2.7081*((((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))**2.5)+(((((states('sensor.esphome_ble_1_pool_temperature') | float))-15)/(1+0.0162*(((states('sensor.esphome_ble_1_pool_temperature') | float))-15)))*(0.0005+((-0.0056)*((((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))**0.5))+((-0.0066)*(((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) ))))+((-0.0375)*((((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))**1.5))+((0.0636)*((((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))**2))+((-0.0144)*((((((1/(states('sensor.esphome_ble_1_pool_salinity_raw') | float))*1000000)/42900)/( 0.6766097+0.0200564*((states('sensor.esphome_ble_1_pool_temperature') | float))+0.0001104259*(((states('sensor.esphome_ble_1_pool_temperature') | float))**2)+(-6.9698*(10**(-7)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**3)+(1.0031*(10**(-9)))*(((states('sensor.esphome_ble_1_pool_temperature') | float))**4) )))**2.5))))) * 1000) | round(-1) }}

Really interested in your calc because my current one seems off but everything in one line is confusing.
Would you mind showing your actual code?

I am running a Purapool system without Chlorinator but with an Oxynator, in general my readings should be lower but they are not and I see 2700ppm in steady of 2400 ppm (measured by the pool guys with a good meter) and with the setup from Peerke.
Really hope to get closer to those meters.

hey all,

my system worked until recently. since then, the switch is stuck from time to time for some hours:

Is this also the same at yours? Really annoying :frowning: Thanks!

Some more info:


[14:44:48][I][esp-idf:000][BTU_TASK]: W (234999) BT_HCI: hcif disc complete: hdl 0x0, rsn 0x8

[14:44:48][W][component:157]: Component ble_client.text_sensor set Warning flag: unspecified
[14:45:00][I][main:187]: Found Blueriiot sensor
[14:45:00][I][esp-idf:000][BTU_TASK]: E (246498) BT_BTM: BTM_BleScan scan not active


[14:45:00][I][esp-idf:000][BTU_TASK]: W (246506) BT_APPL:  bta_dm_ble_scan stop scan failed, status=0x6


[14:45:00][I][esp32_ble_client:067]: [3] [00:A0:5asdasdasd] 0x00 Attempting BLE connection
[14:45:02][I][ble_text_sensor:034]: [blueriiot reading data] Connected successfully!
[14:45:02][I][esp32_ble_client:227]: [3] [00:A0asdasdasd] Connected
[14:45:02][I][main:356]: Connected to Blueriiot sensor
[14:45:24][I][esp-idf:000][BTU_TASK]: W (270475) BT_APPL: gattc_conn_cb: if=3 st=0 id=3 rsn=0x8

[14:45:24][I][esp-idf:000][BTU_TASK]: W (270480) BT_APPL: gattc_conn_cb: if=4 st=0 id=4 rsn=0x8

[14:45:24][I][esp-idf:000][BTU_TASK]: W (270483) BT_APPL: gattc_conn_cb: if=5 st=0 id=5 rsn=0x8

[14:45:24][I][esp-idf:000][BTU_TASK]: W (270485) BT_APPL: gattc_conn_cb: if=6 st=0 id=6 rsn=0x8

[14:45:24][I][esp-idf:000][BTU_TASK]: W (270501) BT_HCI: hcif disc complete: hdl 0x0, rsn 0x8