Hayward AquaLogic / ProLogic automation

Really excited to try and get this working but I have not been successful. I have the serial connector wired into the Goldline connector and I can see it on my network and access its web interface. I created a custom_components folder and aqualogic sub folder and included all the .py files I could find related to this project. I restarted Hassio and I see the switches but none of the sensors are working nor the switches. I do not see anything in the system logs of note. Where and how can I confirm that I have installed this correctly and that the RS485 is properly communicating? Many thanks for the help.

I am eager to try this setup, and I just purchased the USR-TCP232-304 serial to Ethernet bridge, but for the life of me I cannot find any documentation on how this is supposed to be wired. The serial bridge has 3 pinouts: A, B and Ground. The RS-485 on prologic board has 4 pinouts: Red 1, Blk 2, Yel 3 and Grn 4. (unless I am completely looking at the wrong connector, but according to the board manual this is the RS-485 connection and it says “remote display” so I believe that’s it)

Can anyone shed some light on how the A and B of the bridge connect to the board? Thanks

Here is a photo of the back of a remote display which shows the pinouts:

Blk -> A
Yel -> B
Grn -> Gnd

1 Like

You shouldn’t need custom_components; it has been part of the base homeassistant build for a while now. If you are having issues there is a standalone command line interface you can try.

It should start spitting out messages like this:

$ python3 aqualogic/cli.py aqualogic 23
Connecting to aqualogic:23...
To toggle a state, type in the State name, e.g. LIGHTS
States: [<States.CHECK_SYSTEM: 4>, <States.POOL: 8>, <States.FILTER: 32>, 
<States.FILTER_LOW_SPEED: 2147483648>]
Check System: None
Pool Temp: 13
Air Temp: None
Pump Speed: 40
Pump Power: 106
States: [<States.CHECK_SYSTEM: 4>, <States.POOL: 8>, <States.FILTER: 32>, 
<States.FILTER_LOW_SPEED: 2147483648>]
1 Like

Thanks much - I now have the sensors working but I cannot get the switches to operate anything. I am not sure what version of the software I have but it’s circa 2002. It looks like someone earlier in the thread had a similar issue and had to modify core.py? Any thoughts on how to troubleshoot ?

Thanks for this, I have connected the USR-TCP232-304 as follows: Blk 2 -> A, Yel 3 -> B, Grn 4 -> Grnd. I’ve setup the serial adapter in “TCP server” mode, picked the local port and configured HASS per the docs to connect to the serial adapter IP and port. I can see in the web interface of the serial adapter that HASS is connected and data is being transmitted, but nothing is showing up in the sensor data.

I also tried cloning the git hub but when I run the CLI I get this:

core-ssh:/aqualogic/aqualogic# /usr/share/bash-completion/completions/python /aqualogic/aqualogic/cli.py 111
/usr/share/bash-completion/completions/python: line 46: syntax error near unexpected token (' /usr/share/bash-completion/completions/python: line 46: !(?(/)python([0-9.])|?(/)pypy([0-9.])|-?))’

Any suggestions?

Guessing there is something wrong with your python installation.

You were right, I foolishly assumed that python was already installed without checking first. Installed python 3 with apk add --no-cache python3 and I was able to use the CLI to help diagnose the first major issue, the baud rate on my serial adapter didn’t match the rate on my prologic board. Found the board is set to 19,200 instead of 115,200, so now I’m actually getting data (progress!).

However, the cli is showing a few errors and I can’t seem to control anything, here is what I see in cli:

core-ssh:/aqualogic/aqualogic# python3 ./cli.py 111
Connecting to…
To toggle a state, type in the State name, e.g. LIGHTS
Pool Temp: None
Air Temp: None
Pump Speed: None
Pump Power: None
States: [<States.POOL: 8>, <States.FILTER: 32>]
Pool Temp: None
Air Temp: None
Pump Speed: None
Pump Power: None
States: [<States.POOL: 8>, <States.FILTER: 32>]
Pool Temp: 85
Air Temp: None
Pump Speed: None
Pump Power: None
States: [<States.POOL: 8>, <States.FILTER: 32>]
Pool Temp: 85
Air Temp: 100
Pump Speed: None
Pump Power: None
States: [<States.POOL: 8>, <States.FILTER: 32>]
INFO:core:Unknown frame: b’0407’ b’’
INFO:core:Unknown frame: b’0004’ b’03’
INFO:core:Unknown frame: b’04a0’ b’’
INFO:core:Unknown frame: b’0004’ b’3031323020’
INFO:core:Unknown frame: b’04ae’ b’’
INFO:core:Unknown frame: b’0004’ b’fbd3’

Based on earlier comments in the thread I am guessing this means I need to edit the hex data values to match what my board is sending. Not sure exactly where to go next for logs/code, any pointers appreciated. Thanks!

I was able to answer my own question (somewhat) after reading through this thread again carefully and also looking at the blog here: http://www.desert-home.com/p/swimming-pool.html#Protocol

I’ll summarize a couple of observations/tips that might help others:

  1. The goldline protocol seems to be a bit of a mess, if you are looking at the Hex data coming from your RS-485 adapter you will likely see quite a lot of messages that don’t make sense/aren’t decoded, these will show up as “unknown frames” and be ignored. Since it’s not clear what these frames are this is probably ok (I looked for a goldline protocol reference but couldn’t find one)

  2. How to see the Hex: the RS485 to Ethernet adapter I’m using (USR-TCP232-304) has some software you can install to monitor the TX/RX of both the RS485 side and the Ethernet side. For the RS485 side you’ll need a usb to RS485 adapter if you want to plug your desktop/laptop into the RS485 and see the codes, I used one from DSD Tech.

  3. Everything that displays information (filter on, date, temp, etc) has a code, these seem to be fairly consistent across different aqua/pro logic boards. Every control (turn on filter, turn on light, etc) also has a code, these do NOT seem to be completely consistent. I did some monitoring on my RS485 while I was turning things on/off (you’ll see them b/c everything is on a common bus, i.e. broadcast) using my remote and the codes I see don’t match anything I see in this thread or on other blogs. I see references to codes “00 02”, “00 03” and “00 83”, in my case for my remote it’s “00 05”. This may be due to the kind of remote (spa side remote for me), the version of the firmware on the board, the type of board or some combination of all. However, I did manage to get the standard build to turn on/off my filter and my pool light, so either the code already takes these variations into account or the board will take various codes for these components (or both). At first I thought the default build wasn’t working for turning things on, but it turns out I just had to select the on/off multiple times, usually 2 to 4, and it would work. Sometimes it works the first time, but usually I have to select it multiple times in HASS before it works. (probably collisions on the bus are causing this)

  4. The one thing that seems consistent are that sensor or control codes start with 10 02 and end with 10 03, that frames the packets. There is also a keepalive packet that seems to be consistently 10 02 01 01 00 14 10 03, there are LOTS of those. Also, display information seems to consistently start (after the 10 02 header) with 01 03. Using this you can usually find the control packets if you capture the RS485 data to a text file, then use a text editor to filter out the keepalive pattern and flag the header 10 02 and trailer 10 03 (I used (H) and (F)) and then look for patterns inside the (H) and (F) for the frame contents. This is tedious to do manually and could be done programatically if you are inclined. In any case, that’s how I determined my control packets start with 00 05 for my remote.

  5. The software to monitor the RS485 may be able to display either Hex or ASCII, the hex is needed for the codes, but if you watch the ASCII you can see the messages that are displayed which also helps you figure out what hex codes are doing what if you flip back and forth (or just paste the codes into a hex to ascii converter)

  6. If you think you have the control codes, then you can try sending them through the RS485 adapter. For example, in my case to turn on the filter the code is 10 02 00 05 02 00 02 00 7F 00 9A 10 03 (note the header and trailer). This process WILL work, but there is a TON of data constantly on the bus, so if you are doing it manually you have to keep hitting send, send, send, etc and eventually I could get it to work. sometimes it took a dozen sends before the code takes. Also, in my case the software had a specific “send as hex” setting I had to check to make it work. I’m not sure how my hayward remote avoids the issue, but it must have a way to send a code that “clears” the bus for a split second b/c I never have to hit the button more than once on my remote for something to work, but I can rarely get it to take the code the first time from HASS.

I’d like to thank swilson for his work on this, without this thread and the code he wrote I would never have gotten this far.

The final step for me is to add in the ability to switch the valves from pool to spa so I can get the spa running remotely. This doesn’t seem to be in the default build, but I have the code to turn the valves, so hopefully I can figure out how to make this happen.


I purchased this for mine before I found HA. Does the Ethernet to 485 adapter replace the need for this? Does the Hex in the PDF help? https://www.aqua-man.com/images/pdf/Manual343.pdf

Hey all, this is really cool. Not sure if anybody on this thread can help, but I’ve purchased this wifi to serial converter: https://www.usriot.com/products/779.html, and hooked it up. I have the HA component set up and it can read data from the converter, i.e. I can see the current state of lights, filter, temp, etc. However when I try to flip the switch for lights, nothing happens. I’ve set up the monitoring software and I don’t see the writes from HA to the converter coming through. I think this should allow bi-directional, but looks like only reads are working. It will be somewhat impractical to run ethernet out, so am hoping I can get this to work. Any advice?

Hi, thanks so much for this. Unfortunately the HA GitHub link is no longer valid. Can anyone point me to the latest, or post the most recent?


The component has been integrated into the main HA build: https://www.home-assistant.io/integrations/aqualogic/

Ah, perfect. Thanks for the quick reply!

Just wanted to say thank you for the hard work. I was able to use this code on my Raspberry Pi to troubleshoot why my OnCommand controller was not receiving signal from my Hayward Chlorinator. After hooking up to and pinging both, it turns out that when my chlorinator’s thermistor died and I replaced it, apparently it took the RS485 sending circuit with it. The chlorinator was receiving but not sending.

Also, I adapted your Core code for my RS485 serial device. If anyone wants the code let me know.

I’ve been following this thread for quite some time and wanted to restart the discussion. It seems that most of us commenting here are having the same issue; we can’t reliably send commands to our pool controller. I’d like to suggest that a config setting be added for latency and propose a code change for the timing of sending the command. This is beyond my skill level, so I will just go so far as explaining my logic here. BTW-I have an Aqualogic PS-4

I spent quite a bit of time analyzing the output from my RS-485 device and came up with a few conclusions. First, I don’t believe that the output from the Aqualogic is as convoluted as it seems. I dumped a couple minutes of the output log and then painstakingly broke it into consistent lines by inserting a CRLF whenever “10 03” is found. I also read through the aq-co-serial device manual. The manual actually explains a lot, including timing, and is consistent with what’s been decoded here so far. What I found is:

  • The display is updated every 2 seconds.
  • A “listen” packet is sent every 100ms, ten times in a row. This correlates to the aq-co-serial manual.
  • There is only one weird packet sent, that’s the “00 E0 18 80 00 E6 00 18 9E 00 E0 1E 80” which is also sent every 2 seconds, opposite the display update. I suggest that this is either a command to clear the comm bus or has to do with the radio.
  • I believe that the “keep alive” packet is actually the “listen” packet and is the KEY to avoiding data bus collisions.
  • The timing seems to be:
    • Display type 1 (Led status, display message combined)
    • Display type 2 (Led status only)
    • Display type 3 (display message only)
    • Listening packet sent 10 times (every 100 ms) “10 02 01 01 00 14 10 03”
    • Unformatted packet; maybe this clears the comm bus? “00 E0 18 80 00 E6 00 18 9E 00 E0 1E 80”
    • Listening packet sent 10 times (every 100 ms) “10 02 01 01 00 14 10 03”
    • Repeat

My second conclusion is that the “listen” or “keep-alive” packet is the key to communicating back to the controller. I hypothesize that the outgoing command needs to be buffered and sent first thing after the FIRST listening packet is received; either after the last display update or after the “00 E0 18 80 00 E6 00 18 9E 00 E0 1E 80” packet is received. Either way, there is a window of 1 sec with 10 listening packets interspersed.

But this still won’t prevent collisions. Due to the latency of different networks, I believe that we need a delay or latency constant in the config file. This value, in milliseconds, could then be tweaked by each user to add to the send time. The value could be anywhere between 0 ms and 1000 ms.

By sending immediately after the FIRST listening packet, we could then avoid collisions by tweaking the latency constant so that the command is RECEIVED immediately after a listen packet is sent from the controller; but not necessarily the first packet. We have a window of 100 ms between commands, providing that we avoid the display update and the “00 E0 18 80 00 E6 00 18 9E 00 E0 1E 80” packet.

In theory,

  • Format and buffer the command to send
  • Wait for the first listening packet either after the display updates or the “00 E0 18 80 00 E6 00 18 9E 00 E0 1E 80” is received.
  • Send the buffered command.
  • If it’s not acted upon by the controller, e.g. lights don’t turn on, the add 10 ms to the latency constant and try again.
  • Each system should be able to adjust the latency constant to their own needs to get consistent key press action.

So this is beyond my skill level and I’m hoping that someone on the forum could take up this project and code it. I’m more than happy to assist with testing it out.

The other thing I’d like to see is adding all the buttons/keypresses to be able to navigate the menu. I believe these are all the button codes beginning with the 5th byte (after “10 03 00 83”; where the “00 83” may differ by control). All the commands repeat in each packet.

01 01 00 00 00 01 00 00 00 00 Right Arrow
01 02 00 00 00 02 00 00 00 00 Menu/Enter
01 04 00 00 00 04 00 00 00 00 Left Arrow
01 08 00 00 00 08 00 00 00 00 Service
01 10 00 00 00 10 00 00 00 00 Down Arrow
01 20 00 00 00 20 00 00 00 00 Up Arrow
01 40 00 00 00 40 00 00 00 00 Pool/Spa/Spillover
01 80 00 00 00 80 00 00 00 00 Filter
01 00 01 00 00 00 01 00 00 00 Lights
01 00 02 00 00 00 02 00 00 00 Aux 1
01 00 04 00 00 00 04 00 00 00 Aux 2
01 00 08 00 00 00 08 00 00 00 Aux 3
01 00 10 00 00 00 10 00 00 00 Aux 4
01 00 20 00 00 00 20 00 00 00 Aux 5
01 00 40 00 00 00 40 00 00 00 Aux 6
01 00 80 00 00 00 80 00 00 00 Aux 7
01 00 00 01 00 00 00 01 00 00 Valve 3
01 00 00 02 00 00 00 02 00 00 Valve 4
01 00 00 04 00 00 00 04 00 00 Heater 1
01 00 00 08 00 00 00 08 00 00 Aux 8
01 00 00 10 00 00 00 10 00 00 Aux 9
01 00 00 20 00 00 00 20 00 00 Aux 10
01 00 00 40 00 00 00 40 00 00 Aux 11
01 00 00 80 00 00 00 80 00 00 Aux 12
01 00 00 00 01 00 00 00 01 00 Aux 13
01 00 00 00 02 00 00 00 02 00 Aux 14

So that’s what I got. Discussion please!


Nice analysis! Note that the aqualogic library already buffers commands until it sees a keep-alive message. It doesn’t attempt to avoid the display update message though. It waits up to 2 seconds for the state to change; if it doesn’t it re-queues the message to send on the next keep-alive.

Note that a hard-coded latency may not help given the non-real-time nature of HA and the network, but it is worth a shot.

May be a while before I have time to look into implementing these suggestions (also my pool is shut down for the winter).

swilson - Thanks for your comments. I knew that you were buffering the command, just didn’t think about it. My thought process is that others have kind of figured this out: e.g. Autelis, but probably using a chip, Creston but using the aq-co-serial. So there’s something in the timing of sending the command. I’m using the free rs-485 software to monitor the line so I don’t have timing. Not sure if there’s such a thing, but an output monitor with a time stamp could also show when a command is sent and received. This would allow some idea of the turn around time of a command. Just thinking out loud here.

I agree that latency can vary depending on the system, but I think most pi’s are just sitting there listening 99.9% of the time. I was thinking that a program to determine latency would be one way of determining if this could work. Here’s how it would work.

  1. Set latency to 0ms.
  2. At the first keep alive after the display update, send a command and listen for a response. Do this 10 (or hundred) times and log how many successful commands received.
  3. Increment latency by 5ms.
  4. Repeat step 2 and 3. Continue the loop until latency is at 2000ms.

My though is that we’ll see a bell curve where the middle is receiving commands close to 100% of the time. We might even see a double hump or multiple humps. Regardless, I think the output would be very enlightening. On the other hand, maybe no pattern ever exists, in which case, the problem isn’t solvable.

Anyway, I really appreciate all the work that you’ve put into developing this control and I know others do too!


I have a Pro Logic PL-PS-8 controller and I also happen to have a AQ-CO-SERIAL home automation interface device. Has anyone tried to integrate home assistant via the AQ-CO-SERIAL?

Hello All,
swilson, great work on the python code for the aqualogic integration. I’ve got HA running on a RPi3B and I have a USB.RS485 adapter available. I’m wondering if there is any reason that I can not use the USB adapter instead of purchasing an ethernet/RS485 device. Does anyone have a modified version with the necessary serial code?