I basically just followed these steps. I’m running on Unraid, but ran the commands via an SSH terminal shell:
Once that’s up and running, you should be able to hit that URL in a browser on your local network and get your pool info in JSON format:
I basically just followed these steps. I’m running on Unraid, but ran the commands via an SSH terminal shell:
Once that’s up and running, you should be able to hit that URL in a browser on your local network and get your pool info in JSON format:
I was definitely overthinking the setup… I have a similar setup (HA on a Raspberry Pi 4).
Here’s what I did:
Once I had the add-on running, I just added the sensors @sarahmva shared with the thread (much appreciated).
If you have a Sense 2, you can expose even more in the UI: (I might add Saturation Index at some point)
BTW, somewhat unrelated, but good to know: Waterguru support told me today that TA, CH & CYA values are currently running on a 4 day average. So if you make a change that affects any of those, it’s going to take 4 days to see the end result. I’m hoping that will change soon.
Can you share your config and lovelace yaml?
configuration.yaml:
# Sensors
sensor:
- platform: rest
name: waterguru_raw
unique_id: 'wg14839'
scan_interval: 7200
resource: http://192.168.1.200:53255/api/wg
json_attributes_path: "$.waterBodies[0]"
json_attributes:
- waterTemp
- status
- pods
- measurements
- latestMeasureTime
- latestMeasureTimeHuman
value_template: '{{ value_json.status }}'
- platform: template
sensors:
waterguru_water_temperature:
friendly_name: Waterguru Water Temperature
unique_id: 'wg195046'
unit_of_measurement: F
value_template: >-
{{"%.1f"|format(state_attr('sensor.waterguru_raw','waterTemp')|float)}}
attribute_templates:
temp_fahrenheit: >-
{{state_attr('sensor.waterguru_raw','waterTemp')}}
waterguru_cl:
friendly_name: Waterguru Free Chlorine Level
unique_id: 'wg9284769303'
value_template: >-
{{(state_attr('sensor.waterguru_raw','measurements')[0].floatValue)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','measurements')[0].status)}}
measure_time: >-
{{(state_attr('sensor.waterguru_raw','measurements')[0].measureTime)}}
measure_time_human: >-
{{(state_attr('sensor.waterguru_raw','measurements')[0].measureTimeHuman)}}
advice: >-
{%if 'alerts' in (state_attr('sensor.waterguru_raw','measurements')[0])%}
{{(state_attr('sensor.waterguru_raw','measurements')[0].alerts[0].advice.action.summary)}}
{%else%}
all clear
{%endif%}
waterguru_ph:
friendly_name: Waterguru PH Level
unique_id: 'wg10583983'
value_template: >-
{{(state_attr('sensor.waterguru_raw','measurements')[1].floatValue)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','measurements')[1].status)}}
measure_time: >-
{{(state_attr('sensor.waterguru_raw','measurements')[1].measureTime)}}
measure_time_human: >-
{{(state_attr('sensor.waterguru_raw','measurements')[1].measureTimeHuman)}}
advice: >-
{%if 'alerts' in (state_attr('sensor.waterguru_raw','measurements')[1])%}
{{(state_attr('sensor.waterguru_raw','measurements')[1].alerts[0].advice.action.summary)}}
{%else%}
all clear
{%endif%}
waterguru_wf:
friendly_name: Waterguru Flow
unique_id: 'wg84568945'
value_template: >-
{{(state_attr('sensor.waterguru_raw','measurements')[2].intValue)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','measurements')[2].status)}}
measure_time: >-
{{(state_attr('sensor.waterguru_raw','measurements')[2].measureTime)}}
measure_time_human: >-
{{(state_attr('sensor.waterguru_raw','measurements')[2].measureTimeHuman)}}
advice: >-
{%if 'alerts' in (state_attr('sensor.waterguru_raw','measurements')[2])%}
{{(state_attr('sensor.waterguru_raw','measurements')[2].alerts[0].advice.action.summary)}}
{%else%}
all clear
{%endif%}
waterguru_ta:
friendly_name: Waterguru Total Alkalinity
unique_id: 'wg856749596'
value_template: >-
{{(state_attr('sensor.waterguru_raw','measurements')[3].intValue)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','measurements')[3].status)}}
measure_time: >-
{{(state_attr('sensor.waterguru_raw','measurements')[3].measureTime)}}
measure_time_human: >-
{{(state_attr('sensor.waterguru_raw','measurements')[3].measureTimeHuman)}}
advice: >-
{%if 'alerts' in (state_attr('sensor.waterguru_raw','measurements')[3])%}
{{(state_attr('sensor.waterguru_raw','measurements')[3].alerts[0].advice.action.summary)}}
{%else%}
all clear
{%endif%}
waterguru_ch:
friendly_name: Waterguru CH Level
unique_id: 'wg9876544'
value_template: >-
{{(state_attr('sensor.waterguru_raw','measurements')[4].intValue)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','measurements')[4].status)}}
measure_time: >-
{{(state_attr('sensor.waterguru_raw','measurements')[4].measureTime)}}
measure_time_human: >-
{{(state_attr('sensor.waterguru_raw','measurements')[4].measureTimeHuman)}}
advice: >-
{%if 'alerts' in (state_attr('sensor.waterguru_raw','measurements')[4])%}
{{(state_attr('sensor.waterguru_raw','measurements')[4].alerts[0].advice.action.summary)}}
{%else%}
all clear
{%endif%}
waterguru_cya:
friendly_name: Waterguru CYA Level
unique_id: 'wg9876543'
value_template: >-
{{(state_attr('sensor.waterguru_raw','measurements')[5].intValue)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','measurements')[5].status)}}
measure_time: >-
{{(state_attr('sensor.waterguru_raw','measurements')[5].measureTime)}}
measure_time_human: >-
{{(state_attr('sensor.waterguru_raw','measurements')[5].measureTimeHuman)}}
advice: >-
{%if 'alerts' in (state_attr('sensor.waterguru_raw','measurements')[5])%}
{{(state_attr('sensor.waterguru_raw','measurements')[5].alerts[0].advice.action.summary)}}
{%else%}
all clear
{%endif%}
waterguru_si:
friendly_name: Waterguru Saturation Index
unique_id: 'wg987695738'
value_template: >-
{{(state_attr('sensor.waterguru_raw','measurements')[10].floatValue)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','measurements')[10].status)}}
measure_time: >-
{{(state_attr('sensor.waterguru_raw','measurements')[10].measureTime)}}
measure_time_human: >-
{{(state_attr('sensor.waterguru_raw','measurements')[10].measureTimeHuman)}}
waterguru_cassette:
friendly_name: Waterguru Cassette Status
unique_id: 'wg19004785830'
value_template: >-
{{(state_attr('sensor.waterguru_raw','pods')[0].refillables[0].pctLeft)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','pods')[0].refillables[0].status)}}
measurements_left: >-
{{(state_attr('sensor.waterguru_raw','pods')[0].refillables[0].timeLeftText)}}
waterguru_cassette_left:
friendly_name: Waterguru Cassette Left
unique_id: 'wg19004785831'
value_template: >-
{{(state_attr('sensor.waterguru_raw','pods')[0].refillables[0].timeLeftText)}}
waterguru_battery:
friendly_name: Waterguru Battery
unique_id: 'wg025489093'
unit_of_measurement: "%"
device_class: battery
value_template: >-
{{(state_attr('sensor.waterguru_raw','pods')[0].refillables[1].pctLeft)}}
attribute_templates:
status: >-
{{(state_attr('sensor.waterguru_raw','pods')[0].refillables[1].status)}}
measurements_left: >-
{{(state_attr('sensor.waterguru_raw','pods')[0].refillables[1].amountLeft)}}
Lovelace Raw Editor code:
type: vertical-stack
cards:
- type: horizontal-stack
cards:
- entity: sensor.waterguru_ph
max: 9
min: 7
severity:
green: 7.4
yellow: 0
red: 7.9
type: gauge
name: Pool PH
needle: true
- entity: sensor.waterguru_cl
min: 0
severity:
green: 1
yellow: 0
red: 4
type: gauge
name: Free Chlorine
needle: true
max: 8
- entity: sensor.waterguru_cya
max: 120
min: 0
type: gauge
needle: true
severity:
green: 30
yellow: 0
red: 101
name: CYA
- type: horizontal-stack
cards:
- entity: sensor.waterguru_ta
max: 180
min: 0
severity:
green: 50
yellow: 0
red: 131
type: gauge
name: Total Alkalinity
needle: true
- entity: sensor.waterguru_ch
max: 600
min: 0
severity:
green: 200
yellow: 0
red: 401
type: gauge
name: Calcium Hardness
needle: true
- entity: sensor.waterguru_water_temperature
max: 102
min: 32
type: gauge
needle: true
severity:
green: 84
yellow: 55
red: 0
name: Temperature
- type: custom:mushroom-template-card
primary: >-
Last Measured:
{{(state_attr('sensor.waterguru_ph','measure_time_human'))}}
secondary: >-
{{(as_timestamp(strptime(state_attr('sensor.waterguru_ph','measure_time')[:19],'%Y-%m-%dT%H:%M:%S'))|float
-14400)|timestamp_custom('%m-%d-%Y %H:%M', local=True)}}
{%if state_attr('sensor.waterguru_ph','advice') != 'all clear'%}PH:
{{state_attr('sensor.waterguru_ph','advice')}}{%endif%}
{%if state_attr('sensor.waterguru_cl','advice') != 'all clear'%}Chlorine:
{{state_attr('sensor.waterguru_cl','advice')}}{%endif%}
Saturation Index: {{states('sensor.waterguru_si')}}
Water Flow: {{states('sensor.waterguru_wf')}} GPM
Battery: {{states('sensor.waterguru_battery')}}%
Cassette: {{states('sensor.waterguru_cassette')}}% -
{{state_attr('sensor.waterguru_cassette','measurements_left')}}
icon: mdi:pool
badge_icon: >-
{%if 'alerts' in (state_attr('sensor.waterguru_raw','measurements')[0]) or
'alerts' in (state_attr('sensor.waterguru_raw','measurements')[1])%}
mdi:alert {%else%}
{%endif%}
badge_color: red
multiline_secondary: true
icon_color: |2-
{%if 'alerts' in (state_attr('sensor.waterguru_raw','measurements')[0]) or
'alerts' in (state_attr('sensor.waterguru_raw','measurements')[1])%}
yellow
{%else%}
green
{%endif%}
tap_action:
action: more-info
entity: sensor.waterguru_si
card_mod:
style: |
ha-card {
--card-primary-font-size: 14px;
--card-secondary-font-size: 15px;
--icon-size: 2em;
}
:host {
--mush-icon-symbol-size: 1.7em;
}
NOTE: CYA and CH have flipped on me once in a blue moon, when that happens I just swap them in the UI.
I was able to convert this into a standard custom integration that can be installed via HACS which does not require a separate addon or docker container. I’m testing this week and I’ll post it after I get all the attributes exposed properly.
Awesome!!! If you need any help testing it let me know.
Alright, here it is: GitHub - dwradcliffe/home-assistant-waterguru
It seems to be working for me, although I’m sure there are some edge cases that break. Let me know and I’ll try to fix it when I have a chance.
David,
Awesome work! Thanks for sharing!
I have had a WaterGuru for several years and really like the product. I tried several other pool chemistry monitors before I found WaterGuru and they all either did not work or were unreliable. I been looking for ways to integrate with HA but have always come up short. I stumble on this thread this morning and am definitely going to move ahead with the suggestions here. Thanks everyone for your contributions1
@dwradcliffe thank you for porting WaterGuru-API to a Home Assistant integration. I have been trying to do this for several years and can now add this to my dashboard.
Thank you again.
@sarahmva thanks for posting this example. Great stuff.
@dwradcliffe is it possible to add the latestMeasureTime
and ‘latestMeasureTimeHuman’ to you HA Integration. I think the best approach would be to add these as attributes to each of the entities.
Thank you both for your contributions. This is a huge improvement to my Smart Home!
This is awesome.
You should add a tip jar to github repo my dude
I can’t get this integration to work. Do you need a docker API setup and to update the host ?
There’s a couple solutions in this thread. The most recent does NOT need that Docker container running:
Hi, @dwradcliffe, I’m OP. I cannot thank you enough. Wow. This is absolutely amazing!
@dwradcliffe The Cassette Days Remain is always showing full weeks. For example, WaterGuru shows 5 weeks
and Home Assistant shows 35 days
for the whole week. I have created a template helper to get a more accurate value for cassette days remaining:
{{ (states('sensor.waterguru_back_yard_cassette_remaining') | int) / 100 * 60 | int}}
Thank you for helping me get this worked out.
Now, if the API supported resetting the counter when the cassette is replaced, I would be able to ditch the WaterGuru app all together
You could use an NFC to set off specific intervals.
@ttough66, did you get it to work? I installed following the steps on GitHub - https://github.com/dwradcliffe/home-assistant-waterguru
- and everything just worked. One think I noticed on many integrations is that you username must be all lower case. I generally use Camel case for my username to make it easier to read but this does not seem to work for most home assistant integrations.
Hope this helps.