Waterway Plastics Oasis Pool Automation

Wondering if there is anyone out there with an Oasis pool automation system by Waterway Plastics. https://waterwayplastics.com/product/oasis/

I’ve proxied my phone through Fiddler and it uses api commands to PubNub. Anyone interested in working this together to bring it into HA?

I have no skills or insight to offer you so if you don’t mind the dead weight, I’ve got an Oasis controller too.

I’ve actually completed much of it through NodeRed. Do you have the wifi add on? Tell me what components you have connected to your oasis.

I’ve got a docker instance for home assistant on a server I’m stretching pretty thin. I don’t use nodered in my setup but I could probably spin up a container as needed.

My Pool setup has a wifi adapter with solar heat and there’s an “aux” pump (not actually an aux pump but we can ignore this for now) and a spa light.

I’ve looked through a tcp dump and am pretty overwhelmed. Kudos to you if you’ve got this figured out.

The NodeRed flow is too large to paste here. Tomorrow I’ll post it and link it here. You can proxy your phone traffic through fiddler on your computer (need to setup the HTTPS portion) and reverse engineer the commands. The commands go through pubnub, but you can call them directly against that web interface of the wifi adapter and bypass pubnub all together.

Try importing this into NodeRed - https://1drv.ms/w/s!AhVJ31p29iHG4HhyM10m2l1FybmG

Thank you so much. This is going to be a crash course in a lot of things for me so I’ll be a while to figure out how nodered, this flow, my pool, and the pool controller api work. But I’ll let you know when I get something up and running.

Thanks again.

How’d you make out?

Good! I still have some more ironing to do but I’ve adapted it to work via a shell script and rest calls.

I threw what I’ve done up on github.

My pool is a solar heated spa/pool overflow config so I don’t have control over j1, j2, or j3 valves like you do. I also have to calculate what mode my pool is in and what mode I’m moving to so I can call the pool on/off toggle the correct number of times. [Pool, Spillover, Spa, Off]

I think I’m going to be able to use this to change my setup to tell my pool it’s not a solar heated and then toggle that valve via home assistant and avoid pool temps of 90+ degrees like last summer.

One problem I’m having though is that I get dropouts when the controller decides to freeze up and not return coherent values. This makes my otherwise pretty temperature graphs look like garbage. I guess I’m going to have to edit the shell script to cache coherent values and then return old values if new ones are null?

Wow!!! You really took it to the next level. I think your cached idea is good, and that’s why my NodeRed script was checking for a HTTP status code to make sure what I was getting a correct response. Although, now that I say that, I think you may be talking about the controller responding, just with nulls. I think the cached is still the way to go. I also added a sensor to. Identify when the last successfully status was received too.

Is your temperature synced as well or just a one way push? I may dump mine for yours! Awesome job!!

Hey HorribleNoises, here is some additional notes I took when I was reverse engineering this. I was proxying the traffic of the Oasis app through Fiddler on my computer and I would run certain functions on the app and see what was being sent back and forth. Hopefully it’s useful.

Also, would you be able to adjust what is needed for a non spa/spillover setup like mine so I can fully use yours?

Temp 80 degrees
$O8,6,2C,50,!,AA,55

Pool light on/offt
$A0,6,02,!,AA,55

  • response on - [[{“G0Msg”: “$G0,0,0002,3A,80,00,39,00,FE,!,AA,55”,“OtherMsg”: “$O9,6,01,0000,!,AA,55”}],“16011245658196411”]
  • response off- [[{“G0Msg”: “$G0,0,0000,3A,00,00,39,00,FE,!,AA,55”,“OtherMsg”: “$O9,6,01,0000,!,AA,55”}],“16011245826073138”]

Water Feature on/off (possibly pump on/off too)
$A0,6,0B,!,AA,55

pool pump on/off
$A0,6,17,!,AA,55

  • response on - [[{“G0Msg”: “$G0,0,0001,3B,84,00,39,64,FE,!,AA,55”,“OtherMsg”: “$O9,6,01,0000,!,AA,55”}],“16011246468570965”]
  • response off- [[{“G0Msg”: “$G0,0,0000,3B,00,00,39,00,FE,!,AA,55”,“OtherMsg”: “$O9,6,01,0000,!,AA,55”}],“16011246660999014”]

deckjets on/off
$A0,6,0C,!,AA,55
1100

STATUS

$G0,0,0001,43,84,00,5D,64,FE,!,AA,55

Convert 0001 hex to base 16 binary

0000000000000001 pump on
1000000000000000 heat on
0000000000000010 light on
0000010000000000 water feature on
0000100000000000 sprinkler on
0001000000000000 new actuator on

84 - heat button off
86 - heat button on

43 = pool temperature
5D = outside temperature

$A5,0,01,002C,51,!,AA,55
51 = set heat temp

valves (2nd bit
wfeat = 100
sprinlger = 1000

click home button, some type of get status
$O1,6,00,!,AA,55

  • response [[{“G0Msg”: “$G0,0,0000,3A,00,00,39,00,FE,!,AA,55”,“OtherMsg”: “$O1,6,00,01405000020114000300FF000400FF000500FF000600FF000700FF00,!,AA,55”}],“16011245370357024”]

$O7,6,2E,!,AA,55

  • response [[{“G0Msg”: “$G0,0,0000,3A,00,00,39,00,FE,!,AA,55”,“OtherMsg”: “$O1,6,00,01405000020114000300FF000400FF000500FF000600FF000700FF00,!,AA,55”}],“16011245370357024”]

$O1,6,01,!,AA,55

  • response [[{“G0Msg”: “$G0,0,0000,3A,00,00,39,00,FE,!,AA,55”,“OtherMsg”: “$O1,6,01,0800FF000900FF000A00FF000B3E37010C3C37000D00FF000E00FF01,!,AA,55”}],“16011245389465071”]

$O2,6,!,AA,55

  • response [[{“G0Msg”: “$G0,0,0000,3A,00,00,39,00,FE,!,AA,55”,“OtherMsg”: “$O2,6,00644E,200926060848,!,AA,55”}],“16011245405660935”]

$O9,6,01,!,AA,55

  • response [[{“G0Msg”: “$G0,0,0000,3A,00,00,39,00,FE,!,AA,55”,“OtherMsg”: “$O9,6,01,0000,!,AA,55”}],“16011245422438079”]

SET DATE/TIME
$S6,6,D,20,10,05,W,1,T,14,00,00,!,AA,55
20 = year
10 = month
05 = day
14 = hour (24 hour time)
00 = minute
00 = second

$O6,6,00,00,7F1200120064,!,AA,55

Thanks for the kind words.

Yeah, the retry section of your nodered took me the longest to figure out. I rarely have problems with it returning non 200 responses. My controller will flat out send me garbage in the xml.

<ctrlstatus>$G0,0,0000,3A,00,???d??e??f??g??h??i??I??tatus.xml6,!,AA,55</ctrlstatus>

Maybe mine has had a heatstroke.

The set temperature is two way. You use input_number.pool_settemp to view & control.

I’ve updated the files on github if you want to take a look. I’ve added some instructions to customize it for a setup like yours, added the caching, and reworked a few things to make a bit more sense.

12 hours after adding caching and things are starting to look much nicer:

I’d really like some insight from a programmer because there’s still probably a ton of things I’m not doing the correct way but… I’m a guy who knows some shell scripting and SED. When you only have a hammer…

I reference things by the outputs on the controller. So for your system:
light is aux1
Water Feature is j1
Sprinkler is j2
New Actuator is j3

I’m sure that each output is defined in one of the many 56-ish hex strings it dumps out but I’m not reverse engineering that.

I have a TidalFit DT13 using a Wateway controller and I’m trying to setup your integration from github. I’ve got it loading and have modified the IP address in waterway.yaml, json.sh and setpool.sh. I’m getting the following error:

ogger: homeassistant.helpers.event
Source: helpers/template.py:425
First occurred: 1:31:16 PM (4 occurrences)
Last logged: 1:31:16 PM

Error while processing template: Template("{{ state_attr(‘sensor.pool’, ‘PoolTemp’)|int }}")
Error while processing template: Template("{{ state_attr(‘sensor.pool’, ‘AirTemp’)|int }}")
Error while processing template: Template("{{ state_attr(‘sensor.pool’, ‘SolarTemp’)|int }}")
Error while processing template: Template("{{ state_attr(‘sensor.pool’, ‘PumpSpeed’)|int }}")
Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 423, in async_render
render_result = _render_with_context(self.template, compiled, **kwargs)
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 1950, in _render_with_context
return template.render(**kwargs)
File “/usr/local/lib/python3.10/site-packages/jinja2/environment.py”, line 1301, in render
self.environment.handle_exception()
File “/usr/local/lib/python3.10/site-packages/jinja2/environment.py”, line 936, in handle_exception
raise rewrite_traceback_stack(source=source)
File “”, line 1, in top-level template code
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 1729, in forgiving_int_filter
raise_no_default(“int”, value)
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 1411, in raise_no_default
raise ValueError(
ValueError: Template error: int got invalid input ‘None’ when rendering template ‘{{ state_attr(‘sensor.pool’, ‘PoolTemp’)|int }}’ but no default was specified

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 540, in async_render_to_info
render_info._result = self.async_render(variables, strict=strict, **kwargs)
File “/usr/src/homeassistant/homeassistant/helpers/template.py”, line 425, in async_render
raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: ValueError: Template error: int got invalid input ‘None’ when rendering template ‘{{ state_attr(‘sensor.pool’, ‘PoolTemp’)|int }}’ but no default was specified

I’m guessing that I’m not getting a return value from the controller. Do you have any suggestions for how I can debug this?

Oh hey. I didn’t think anyone was interested so I haven’t updated the github repository with any of the modifications I’ve been making.

I’ve updated github with my current build. Try updating that and let me know what problems you have. I don’t have a TidalFit, I built this to work with the Oasis so I can’t make any promises that it won’t break or mess something up with your pool or controller so please please tread carefully.

At first glance, I think your problems were because I was using the old sensor template which is or is going to be depreciated. Updating should hopefully solve that. On second read, it looks like either my garbage filtering isn’t adequate or the values being returned from your controller aren’t quite what’s expected from the Oasis.

Thanks for the update. I’ve grabbed the new package and will try it out shortly. I opened up the swim spa and found out it’s a NEO controller (TP500) instead of an OASIS so the messages could be different.

Hi All. I have a spa with a Waterways NEO 1500 control system (all in one spa pack) using the Waterway NEO/OASIS app to connect to the spa controller via the WIFI interface. Any ideas if the communication is similar to the OASIS? This is the only project I see with any promising info. Appreciate all the work so far!

1 Like

Lmk if you get anywhere. The most recent Android app version (2.0.31) seems to have broken things so it would be great to get local communication working.

I’ve got the integration loaded, but I’m not getting any data. I dug in a bit, ran a port scan and it appears port 80 is closed. I get no data from “http://MY_IP/status.xml”.