jcallaghan / home-assistant-config

My Home Assistant configuration & documentation.
https://www.jcallaghan.com/
MIT License
173 stars 8 forks source link

Hot tub water quality #12

Open jcallaghan opened 4 years ago

jcallaghan commented 4 years ago

Objective

My hot tub requires pH, alkalinity and free chlorine levels to be maintained. The levels of these need to be tested daily using dip test strips and chemicals added to maintain appropriate water quality. I want to add sensors to help me monitor the quality of the water in my hot tub. As part of this exercise, I also want to learn about water quality and the chemicals I am adding to my hot tub.

So my plan is to try and monitor the following:

Ingredients

Hot tub specifics

My hot tub is a Lay-z Spa Hawaii Hydrojet Pro. Type Measurement
pH 7.4-7.6
Total Alkalinity 80-120ppm
Free Chlorine 2-4ppm
Volume 795L

Other considerations

jcallaghan commented 4 years ago

To get the water temperature I'm using a Dallas temperature probe with the native ESPHome integration. This is an example of using this in the ESPHome config.

dallas:
  - pin: GPIO21

sensor:
  - platform: dallas
    address: 0x770316457608FF28
    name: "${system_name}_temperature"
jcallaghan commented 4 years ago

I'm using a single ESP32 for all of these sensors.


esphome:
  name: ${system_name}
  platform: ESP32
  board: pico32
jcallaghan commented 4 years ago

The TDS sensor is of the same kind available from Seed Studio. They have a great blog article about the sensor. Amongst the sample sketch, there is a calculation which converts the value returned from the sensor (v) to the TDS ppm value.

  Voltage = sensorValue*5/1024.0;
  tdsValue=(133.42*Voltage*Voltage*Voltage - 255.86*Voltage*Voltage + 857.39*Voltage)*0.5;

I converted this using a lambda filter in ESPHome.

filters:
      - lambda: return (133.42*x*x*x - 255.86*x*x + 857.39*x)*0.5;

To integrate this with ESPHome I am using the ADC integration and a filter to allow me to capture a moving average while also capturing data regularly. This prevents fluctuations in the recorded data.

sensor:
  - platform: adc
    pin: GPIO34
    name: "${system_name}_tds"
    update_interval: 10s
    unit_of_measurement: "ppm"
    icon: "mdi:water-percent"
    filters:
      - lambda: return (133.42*x*x*x - 255.86*x*x + 857.39*x)*0.5;
      - sliding_window_moving_average:
          window_size: 15
          send_every: 15
jcallaghan commented 4 years ago

Sharing the project on Twitter.

jcallaghan commented 4 years ago

Here are the test results I captured as soon as I got it working with some repeatable tests (milk and my tap water). I plan to get a TDS pen tester to validate these tests.

TDS water quality test results

jcallaghan commented 4 years ago

Hands-on for the first time with the TDS sensor. This arrived 23rd April 2020 and I had it up and running in ESPHome within 30 minutes. I was testing it with some milk and fresh tap water. I figured I could easily repeat these tests if I needed to.

Really useful information about the sensor can be found on the DF Robot site.

image

jcallaghan commented 4 years ago

Last weekend I added too much foam remover to the hot tub. To avoid poor water quality and remove the weird white bits that also formed in the water I added some fresh water to the hot tub. The intention was to leave the hose on for 30 minutes or so and let the bad water overfill except I forgot I was running water into the hot tub and I woke a 2am in a panic the hose was still running. I promptly got up, disarmed the house, went downstairs, unlocked the patio and went out and turned the tap off. I then reversed all this and went back to bed. Whilst struggling to sleep I decided I wasn't going to be doing this again. Two things that will help me.

One, an automation to notify me if the temperature drops in the hot tub which is an indication although I plan to make this a little more sophisticated than it currently is and two a solenoid to turn the water tap on and off.

alias: 'Hot Tub - Water temperature falling'

trigger:

  # trigger when the water temperature falls below 35c
  - platform: numeric_state
    entity_id: sensor.esph_hot_tub_water_temperature
    below: '35'

condition:

  # check the automation has not run within the last 60 minutes
  - condition: template
    value_template: "{{ (as_timestamp(states.sensor.date_time.last_changed) - (as_timestamp(state_attr('automation.hot_tub_water_temperature_falling','last_triggered')))) > 3600 }}"

action:

  - service: notify.html5_notification
    data_template:
      title: "Hot Tub water temperature"
      message: "The hot tub water is at {{ states('sensor.esph_hot_tub_water_temperature') }} and falling."

  - service: notify.ios_james_iphone
    data_template:
      title: "Hot Tub water temperature"
      message: "The hot tub water is at {{ states('sensor.esph_hot_tub_water_temperature') }} and falling."
jcallaghan commented 4 years ago

Since extending the sensor on ~5m cable I'm getting different results from the tests I ran last night. This could be power or a signal issue. I'm going to doing some more testing to ensure the sensor is calibrated correctly.

jcallaghan commented 4 years ago

To validate the TDS sensor I attached to an ESP32 board and installed in my hot tub I brought a handheld TDS test pen. I will capture a sample of tests and compare them against my ESP readings.

Pen TDS Readings

Sample Result 1
Tap water 58 ppm
Milk (fridge temp) 1362 ppm
Milk (room temp)
Hot tub at 40c 480 ppm

Hot tub

Sample ESP32 TDS Sensor Test Pen TDS
26 April 405ppm 480 ppm
jcallaghan commented 4 years ago

The pH sensor finally arrived today. Guess I should hook it up and see how well it works.

image

image

jcallaghan commented 4 years ago

This evening I hooked up the pH sensor up to the ESP32 board I am using to track my hot tub water quality through ESPHome. The sensor was providing me with data but not with results I expected based on my test samples. The voltage from the sensor was always maxing out with a low voltage 1.1V. With a little more reading I discovered ESP32 boards have an attenuation property which defaults to 1.1V (0db). When I switched this to 3.9V (11db) I was able to get results that I expected.

I used the following two guides to help me with the conversion from volts to pH and including temperature in the pH calculation.

I also found some libraries that were useful to understand how the sensor works.

According to the Instructables guide, the sensor has an accuracy of +/- 0.2%. Therefore the sensor will operate within this accuracy in the temperature range of 7 - 46°C. As the hot tub heats the water to 40°C no temperature compensation or offset is required

Test samples

I filled espresso cups with samples to test the pH levels with liquids I could easily repeat again if needed.

  1. Malt vinegar
  2. Fresh semi-skimmed milk
  3. Cold tap water
  4. Bleach

Tests

  1. Calibration and test samples
  2. Test samples alongside TDS sensor
  3. Testing in hot-tub water

Observations

Sample Expected Test 1 Test 2 Test 3
Vinegar 2 2.09 pH (0.58V) 2.09 ph (0.59V) N/A
Milk 6 6.82 pH (1.96V) 6.65 pH (1.90V) N/A
Water 7 7.74 pH (2.21V) 7.19 (2.06V) 7.58 pH (2.16 V)
Bleach 13 13.65 pH (3.90V) 13.65 pH (3.90V) N/A

I suspect the subtle differences between Test 1 and Test 2 were due to the milk ageing. I also noticed the sensor takes a few minutes to return to a neutral level when added to an acidic or alkaline substance

Hot tub

Sample ESP32 pH Sensor Test Pen pH
2 May 6.7 pH 6.7 pH

pH Sample Charts

image

image

jcallaghan commented 4 years ago

Some interesting reading on pH sensors. Age/lifetime of the sensor and how the sensor is affected by temperatures.

jcallaghan commented 4 years ago

Awesome Instructables guide about the pH sensor including a case.

jcallaghan commented 4 years ago

Time to squeeze all the the sensor boards into an enclosure. I want the unit to live beside the hot tub. This is mainly driven by the range of leads and not wanting to run them over a long lead.

This is a pre-production version. This summer I plan to build a wooden frame around my hot tub. I will house the sensor boards amongst this frame and that will be my production board.

image

image

image

image

image

image

jcallaghan commented 4 years ago

pH and temperature values are spot on. I have a pH tester arriving today but I don't think there will be any discrepancies with the results I'm getting. What I'm not confident with is the TDS value. My TDS test pen is reporting a value that is 200 points higher than my TDS sensor. I have a feeling this is related to the attenuation or the calculation from volts to TDS. I will carry on reviewing this.

pH test pen confirms my sensor is calibrated and reporting correctly. Both the pen and sensor had identical readings.

jcallaghan commented 4 years ago

I found a really some helpful articles on pool chemistry which pointed me towards the need for an ORP sensor. This will allow me to measure my chlorine levels.

jcallaghan commented 4 years ago

This DF Robot blog post about creating an automatic water sensor calls out a few points for me to consider. Sensors should not be in the water 24/7 as it affects their life.

A random thought came as writing this. What if the pH sensor was in a tube and could be lowered in the hot-tub for a regular sample.

Also when using multiple sensors an analog signal isolator should be used to avoid sensors from affecting other sensors readings.

jcallaghan commented 4 years ago

Alkalinity

There isn't a sensor for alkalinity which made me think, could I build a sensor to read the colors from a test strip.

B-Hartley commented 3 years ago

This is all really great stuff. I'm getting a new hot tub is a few weeks. (I have an inflatable one at the moment).

I'd be really interested to replicate what you've done.

Is it still working sucessfully for you? any learnings ?

monsieurlatte commented 3 years ago

Just found this as I just started getting into ESP stuff to integrate with my HA. What an amazing write up, I may look into giving this a go myself!

jcallaghan commented 3 years ago

https://twitter.com/pvizeli/status/1392532069427863560

https://ufire.co/shop/

Twitter
Pascal Vizeli on Twitter
“I found some nice hardware on @ufire_co. My order comes next Friday, time to start adding upstream support for @esphome_ and make the sensor data easily available on @home_assistant ❤️”
B-Hartley commented 3 years ago

Looks interesting. Will be following with interest.

bscuderi13 commented 2 years ago

I found this super useful as I wanted to use esp home to program a sensor for TDS and Im more familiar with raw arduino code. I found that you were struggling with accurate values from your TDS. I believe it may be related to the boards analog port measuring between 0 and 1 volt at the chip level is what is outputted so you have to relate that voltage to a converted value of 3.3 volts at least for a wemos D1 mini thats what I had to do.... heres the rteference on the esp homesite Note This component prints the voltage as seen by the chip pin. On the ESP8266, this is always 0.0V to 1.0V Some development boards like the Wemos D1 mini include external voltage divider circuitry to scale down a 3.3V input signal to the chip-internal 1.0V. If your board has this circuitry, add a multiply filter to get correct values:

sensor:
  - platform: adc
    # ...
    filters:
      - multiply: 3.3

so my sensor looks like this and it now matches my handheld tds meter very very close

sensor:
  - platform: adc
    pin: A0
    unit_of_measurement: 'PPM'
    name: "Gary TDS"
    update_interval: 10s
    icon: "mdi:water-percent"
    filters:
      - multiply: 3.3
      - lambda: return (133.42*x*x*x - 255.86*x*x + 857.39*x)*0.5;
      - sliding_window_moving_average:
          window_size: 15
          send_every: 15
Gamerayers commented 2 years ago

This looks awesome, and I'm curious if it means no more need for test strips or anything. How's it been working?

Do you have a full build manual, rather than having to piece it together from each of the different updates?

SawadeeKC commented 2 years ago

Interesting project!

How did you integrate the ORP sensor?

Coolie1101 commented 2 years ago
    filters:
      - lambda: return (133.42*x*x*x - 255.86*x*x + 857.39*x)*0.5;

Doesn't the TDS reading require temperature compensation?

bscuderi13 commented 2 years ago
```yaml
    filters:
      - lambda: return (133.42*x*x*x - 255.86*x*x + 857.39*x)*0.5;

Doesn't the TDS reading require temperature compensation?

Yes and here’s how I solved that dilema if it helps. In a nutshell I take a raw reading of analog for tds then temp compensate that reading before plugging into the formula as per documentation on tds sensors.

# Raw TDS Reading
  - platform: adc
    pin: A0
    unit_of_measurement: 'V'
    name: "Gary Aquarium Raw Voltage"
    id: gary_raw
    update_interval: 60s
    icon: "mdi:eye"
    accuracy_decimals: 3
    filters:
      - multiply: 3.0

# Temperature Compensated Voltage
  - platform: template
    name: "Gary Aquarium Compensated Voltage"
    icon: "mdi:eye"
    id: gary_comp
    unit_of_measurement: 'V'
    accuracy_decimals: 3
    lambda: 'return ((id(gary_raw).state) / (1 + (0.02 * ((id(gary_temp).state) - 25.0))));'
    update_interval: 60s    

# Temperature Compensated TDS
  - platform: template
    name: "Gary Aquarium TDS"
    icon: "mdi:water-percent"
    unit_of_measurement: 'PPM'
    accuracy_decimals: 0    
    lambda: return (133.42*(id(gary_comp).state)*(id(gary_comp).state)*(id(gary_comp).state) - 255.86*(id(gary_comp).state)*(id(gary_comp).state) + 857.39*(id(gary_comp).state))*0.5;
Coolie1101 commented 2 years ago

Amazing, are the readings comparable to a pen test?, when I use your formula my reading is more than 100ppm less, see below

The first reading is the result of (133.42*x*x*x - 255.86*x*x + 857.39*x)*0.5; without any compensation, which is closer to my TDS pen reading, and the following is the reading after applying your templates.

image

Came across the following which doesn't use any temperature compensation. https://www.seeedstudio.com/blog/2020/01/19/tds-in-water-what-is-tds-and-how-do-you-measure-tds-in-water/

bscuderi13 commented 2 years ago

Amazing, are the readings comparable to a pen test?, when I use your formula my reading is more than 100ppm less, see below

The first reading is the result of (133.42*x*x*x - 255.86*x*x + 857.39*x)*0.5; without any compensation, which is closer to my TDS pen reading, and the following is the reading after applying your templates.

image

Came across the following which doesn't use any temperature compensation. https://www.seeedstudio.com/blog/2020/01/19/tds-in-water-what-is-tds-and-how-do-you-measure-tds-in-water/

Hmmm it was closer for me using the pen one I had to compare. What are you using for the temperature? Celsius it should be if it isn’t already that as that could cause a big difference in the two.

Coolie1101 commented 2 years ago

What are you using for the temperature? Celsius it should be if it isn’t already that as that could cause a big difference in the two.

O, Fahrenheit, I'll switch it and check.

Coolie1101 commented 2 years ago

@bscuderi13 That was it, thanks for sharing, been trying to figure out how to apply the formula for days.

image

freekeys commented 2 years ago

Love this! Want to do something similar this summer. Is the ORP sensor integrated with ESPHome? I saw this on ESPHome docs but don't know if it covers this device.

admiralroflknife commented 2 years ago

I'm working on doing similar integrations as well. I have a Coleman saluspa which I now have working with the open source wifi board from another GitHub project that lets me control the tub with mqtt and home assistant. Right now I just have a ozone generator dropped in running in cycles throughout the day. Im toying with trying to figure out a cheap electrolyzer and converting it to a salt water as well to really automate the process but I need more data. I hate to leach but I hope this project continues to progress especially with the free chlorine aspect.

daniloortodontia commented 1 year ago
```yaml
    filters:
      - lambda: return (133.42*x*x*x - 255.86*x*x + 857.39*x)*0.5;

Doesn't the TDS reading require temperature compensation?

Yes and here’s how I solved that dilema if it helps. In a nutshell I take a raw reading of analog for tds then temp compensate that reading before plugging into the formula as per documentation on tds sensors.

# Raw TDS Reading
 - platform: adc
   pin: A0
   unit_of_measurement: 'V'
   name: "Gary Aquarium Raw Voltage"
   id: gary_raw
   update_interval: 60s
   icon: "mdi:eye"
   accuracy_decimals: 3
   filters:
     - multiply: 3.0

# Temperature Compensated Voltage
 - platform: template
   name: "Gary Aquarium Compensated Voltage"
   icon: "mdi:eye"
   id: gary_comp
   unit_of_measurement: 'V'
   accuracy_decimals: 3
   lambda: 'return ((id(gary_raw).state) / (1 + (0.02 * ((id(gary_temp).state) - 25.0))));'
   update_interval: 60s    

# Temperature Compensated TDS
 - platform: template
   name: "Gary Aquarium TDS"
   icon: "mdi:water-percent"
   unit_of_measurement: 'PPM'
   accuracy_decimals: 0    
   lambda: return (133.42*(id(gary_comp).state)*(id(gary_comp).state)*(id(gary_comp).state) - 255.86*(id(gary_comp).state)*(id(gary_comp).state) + 857.39*(id(gary_comp).state))*0.5;

196 / 5 000 Resultados da tradução Congrats on the post friend! I would like to know how you used this temperature compensation function! I would like to implement it in a butane gas pressure project! thanks

jcallaghan commented 1 year ago

Folks, thanks for your comments and contributions. Life has been a little hectic and I've had my focus elsewhere, forgive me. Over the coming weeks I will respond to each and every one of your comments as well as bring this repo back to life. I have lots to share. 🫶🏼

image
timmyjane commented 1 year ago

Looking forward to hearing/seeing your progress.

kars85 commented 1 year ago

Curious where the final placement of the components will be. Great job!

andyhawkes commented 1 year ago

Very interesting - I have a very simple temperature monitor for my pool house (indoor air temp, outdoor air temp, and water temp) running on Wemos D1 Mini but I would love to be able to add pH, Chlorine, and Total Alkalinity to it at some point!

ervee commented 1 year ago

This is a pretty nice project! I just built my own pool monitoring "box" with an ESP32-C3 2MB (which on its own was a challenge) dev-board and a Dallas temperature probe. I would love to add free chlorine monitoring. Thank you for all the great information above and if I have something to add I'll be happy to do so.

tyfoon commented 1 year ago

Great stuff @jcallaghan Would be great if you can post the final setup & code. Would love to re-create!