Hayward AquaLogic / ProLogic automation

Hi @mrmoorey , thanks for sharing your automations. I’m not sure how much it matters to you, but the waiting 2 seconds between button presses is a limitation that we can probably fix. The current display sensors have this behavior because they use the periodic 2 second display message. I mentioned that I have ideas on decoding the presumed-to-be confirmation codes plus display message that come immediately after a button press. These would be able to do a “real time” update to the display text sensors as well as give positive assurances that the button press succeeded. Since I don’t observed failed captures often, I was keeping that on the back burner, but I have noticed the 2 second lag of display and LED updates when using the HA buttons. So, I’ll probably resume looking at this soon.

I very interested to know if you have frequent occurrences of a failed update where you have to bail on a capture. Do you have any sense of that?

Thanks as always

@b3nj1 Is this something that you will incorporate into your code base to enhance reliability? My scripts fail occasionally, where they appear to not notice the change in menu item or displayed text, but they tend to work when run a second time. Since my scripts are not mission-critical and purely serve as a mechanism for checking the current system configuration for misconfigured parameters, it’s not a big deal. However, when you choose to move forward with your enhancements, I’ll be happy to test the code for you.

@mrmoorey , thanks for the offer to test! Yes, I’ll probably pick up working on it this coming week.

@mrmoorey , I have some updates that you can try out and give feedback on. I really hope these are useful to figure out if and why you are getting script failures.

I did extensive analysis of my bus, and came to these conclusions:

  • Menu / Left / Right / Plus / Minus: The only reliable way to detect these is if a 01 03 or 04 0a with a text change occurs (text before the button compared to after the button). The default for this is using a 200ms timeout as that seemed sufficient from my logging (overridable if needed)
  • Other buttons all have a corresponding LED change (or multiple LED in the case of Poo/Spa/Spillover). I found 400ms was a good timeout for this (overridable if needed)

The PR is here: hayward/aqualogic: response-monitor confirmation, discovery tooling, decoder fixes (v4.3.1-v4.6.0) by b3nj1 · Pull Request #8 · b3nj1/rs485_frame-examples · GitHub

To use it, you can point to v4.6.0-rc4:

external_components:
  - source: github://b3nj1/[email protected]
packages:
  rs485:
    url: https://github.com/b3nj1/rs485_frame-examples
    ref: v4.6.0-rc4    

The updated examples for the PR examples of “response monitoring” that you can do. The release candidate example file can be seen here: rs485_frame-examples/hayward/aqualogic/example-device.yaml at 3456f8e6fe5cb36a8fab7abaefa6c9a1d8554c00 · b3nj1/rs485_frame-examples · GitHub

This style will add diagnostic sensors that you can enable for counting success or failure of the button. LED-updating buttons use “response_monitor.yaml” (I should rename that to include LED) and display updating buttons use “response_monitor_display.yaml”. The “${bit_filter}” are new substitutions I added since we now refer to those values multiple times, you can incorporate those from the example or you can fill in the right bit as a number.

      - path: hayward/aqualogic/response_monitor_fields.yaml
      - path: hayward/aqualogic/response_monitor.yaml
        vars: { monitor_name: "filter", button_name: "Filter", bit: "${bit_filter}" }
      - path: hayward/aqualogic/response_monitor_display.yaml
        vars: { monitor_name: "menu", button_name: "Menu" }

If you want to perform actions on success or failure, you can do that too. I didn’t provide a helper package for that but I think we could. Here’s an example I’m testing. It uses another new feature I added: rs485_frame.dump_frame_trace: pool which will print out recent frames so we can debug why a failure happened. The “frame_trace” is enabled when you include the diagnostics.yaml package. Unlike dump_frames which streams all frames as they occur, this “frame_trace” only is output when asked and only has a small (configurable) history depth.

rs485_frame:
  - id: !extend pool
    response_monitor:
      - name: lights_confirm_actions
        trigger:
          button_name: "Lights"
        window: 200ms
        signature:
          - field: led_mask_01_02
            type: changed
            bit: "${bit_lights}"
          - field: led_mask_04_0a
            type: changed
            bit: "${bit_lights}"
        on_confirmed:
          - logger.log: "Lights button confirmed"
          - rs485_frame.dump_frame_trace: pool
        on_failed:
          - logger.log: "Lights button did not confirm"
          - rs485_frame.dump_frame_trace: pool

Thanks all, from this thread I got my Waveshare device up and connected in only a couple of hours with minimal fuss!

Question: I would like to get several of these functions (Filter, Lights, AUX N) set up as switches vs. Button+LED … I have a couple of approaches for that either in ESPHome or Home Assistant, but has anyone else already done this? (Sorry if it’s in the thread and I missed it.)

@SphtKr , What component are you using for your Waveshare? If it’s mine (b3nj1/rs485_frame-examples), I’d be interested in any feedback you have and what parts took the most time of the “couple hours”.

My personal take on button vs switch is rooted in my experience dating back to USB+python based solutions: It was simply too unreliable to have the confidence that a switch would demand. After using the ESPhome-based solution, I have a lot more confidence.

I think I can have a switch option at the ESPPhome device yaml today for the 1:1 cases like “Filter, Lights AUX N”. That is - if you’re using mine :sweat_smile:

It would look something like these 2 entities being replaced:

      - path: hayward/aqualogic/led.yaml
        vars: { bit: "${bit_lights}", led_name: "Lights", device_class: light }
      - path: hayward/aqualogic/button.yaml
        vars: { button_name: "Lights", button_command: [0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] }

With:

      - path: hayward/aqualogic/switch.yaml
        vars: { button_name: "Lights", bit: "${bit_lights}", button_command: [0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] }

@b3nj1 Yes, it’s yours, thanks! Plus a little cribbing off of @mrmoorey’s posted example config.

If the “couple hours” sounded bad, sorry, it wasn’t meant to. I think that was “a little over two” and included everything, like building/stripping cables and drilling holes in a project box for a cable gland. I think the only software/config issues I had that took any time were that I assumed the Waveshare ESP32-S3-RS485-CAN device didn’t need a flow-control pin enabled, and so troubleshooting no data took.a bit–which was where cribbing @mrmoorey’s config eventually came in. That might have also included initial fiddling with trying to make switches vs. buttons. Also, I’m a little green with ESPHome, so e.g. this is the first time I’ve used an external package at all, so just working to understand what was going on there went into the time estimate.

On switches, yes I know what you mean, my Python AquaLogic-MQTT broker hit some similar difficulties. I was primarily interested in the functions with direct LED bit mask representation though, yes, so that should be much simpler.

I started building switch entities in my ESPHome config, then briefly considered trying to make a PR on your project to do them instead, then decided to back off and ask first if the problem had already been solved by someone. I think at a minimum it would be good to add IDs to your button entties–the LEDs/binary_sensors already have IDs, and if the buttons did also I think one could make the entities in their own config fairly easily. But, if you add switch entities directly to the project that can be optionally enabled like the other entities, I won’t complain about not having to do the extra work!

Oh, a little note on “why” for adding switches… I find the switches significantly simpler when building automations on the Home Assistant side. E.g., in my old Python-based setup, I am running the filter schedule from Home Assistant based on sunrise/sundown (so it can run less in the winter, and really I should try to work up an automation that limits filter time based on air/water temperature), and I have an automation that cuts off AUX1 (booster pump for cleaning robot) if the Filter is turned off either manually or via schedule…

So with those sorts of things, the automation actions become far simpler–I can say “turn the switch off” without having to worry about what its current state is first.

@SphtKr ,
Thanks for the feedback. A couple hours for all that is not bad.

I’ve cut a new release (v4.6.0) with switches for the Filter, Lights, AUX… cases. Please try it out and let me know if it works or you have issues. I’ve tested it, so I’m hoping you don’t have trouble.

It’d probably be easiest to start somewhat fresh with the example with switches yaml file because it swaps the LED+Button for Switch for Filter, Lights…

If you want to stitch it into your existing yaml instead, the key touch points would be:
1:

external_components:
  - source: github://b3nj1/[email protected]

2:

packages:
  rs485:
    url: https://github.com/b3nj1/rs485_frame-examples
    ref: v4.6.0 

3: Add switches using Lights as an example here. But note: If you keep the existing Button+LED and add the same Switch, they will collide on their IDs. To get around that, you have to change the switch_name to something unique.

      - path: hayward/aqualogic/switch.yaml
        vars: { switch_name: "Lights", bit: "${bit_lights}", switch_command: [0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] }

I’ve been trying to hide the ID from the main yaml. That may be a mistake, but so far, I’ve been able to manage. The included packages set the IDs based on the names.

Regarding the flow-control, I’ve added the Waveshare settings to the README including the flow control pin.

Let me know how it goes!

Hey @b3nj1. I will look a little later in the week at your new build. I have just got my other Waveshare device in place for my Navien water heater, so I’m just finishing my tweaks to the setup.

@SphtKr I’m glad my configs helped you get set up. Two hours is good for having done the wiring, too. I also made an assumption that the control pin wasn’t needed, but I found the integration failed when I removed it. The same applied to my Waveshare integration with the Navien. It runs counter to what my research and interactions with Gemini revealed. @b3nj1’s integration worked when I rebooted the device, but was unreliable, so I left the flow control switch enabled.

@b3nj1

Hmm, trying this, if I enable the include of response_monitor_fields.yaml I get an error,

[response_fields] is an invalid option for [rs485_frame]. Please check the indentation.

I might have missed something in the directions.

Otherwise, the switches look good and seem to work! They’re putting in my new liner tomorrow so I will have to wait a bit to test better.

Edit: Possibly relevant, though I doubt it… I’m still on 2026.7, haven’t moved to 2026.8 yet.

@SphtKr , glad to hear the switches work. Good luck with the liner.

If the following doesn’t get you going with the response monitor, then please post your full yaml that produces the error in an issue on GitHub - or DM it to me.

Here’s the relevant snippets that are working for my test case which has both a light button and switch.

Near the top. This is my guess at what might be your issue - you might be on an older component version:

external_components:
  - source: github://b3nj1/[email protected]

Under “files:” and All are at the same indent level:

      - path: hayward/aqualogic/led.yaml
        vars: { bit: "${bit_lights}", led_name: "Lights", device_class: light }
      - path: hayward/aqualogic/button.yaml
        vars: { button_name: "Lights", button_command: [0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] }
      - path: hayward/aqualogic/switch.yaml
        vars: { switch_name: "LightSwitch", switch_command: [0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] , bit: "${bit_lights}"}

      - path: hayward/aqualogic/response_monitor_fields.yaml

      - path: hayward/aqualogic/response_monitor.yaml
        vars: { monitor_name: "lights", button_name: "Lights", bit: "${bit_lights}" }

      - path: hayward/aqualogic/response_monitor.yaml
        vars: { monitor_name: "LightSwitch", button_name: "LightSwitch", bit: "${bit_lights}" }

I’ve been working on a standalone Wi-Fi interface for an older AquaLogic system after my AQL-WMW-RF remote died.

The current version is running read-only on an AquaLogic PS-4, revision 2.93. It connects to the panel’s RS-485 accessory bus and provides a local webpage showing equipment state, pool and air temperatures, salt level, chlorinator output, diagnostics, and three days of temperature history. It does not require Home Assistant, MQTT, or a cloud service.

Control is deliberately disabled right now. I’m waiting for an isolated RS-485 interface and still need to characterize safe transmit timing and verify the key codes against the actual panel. I don’t want to claim that part works before it has been tested.

The screenshot below shows the current status page; control remains locked in the firmware.

I’m trying to determine how many older AquaLogic and ProLogic systems are still in service and whether there is enough interest to develop this into something other owners could test.

If you still have one, I’d be interested in:

  • Controller model: P4, PS-4, PS-8, PS-16, etc.
  • Main software revision
  • Whether your original remote or network interface still works
  • Whether you would be interested in testing a standalone Wi-Fi interface once control has been validated

I’m also interested in comparing bus behavior across different models and firmware revisions.

Here is a couple of pictures of the interface

@discojax ,
I have 4.47 (ProLogic installed in 2022). @mrmoorey is at 2.85. My ESPHome component works for both of these. The timings are the same. The difference is in the command set for certain buttons that we worked out here: Bug Report / Protocol Update: 2-Byte vs. 4-Byte Payload Split on Firmware v2.85 · Issue #3 · b3nj1/rs485_frame-examples · GitHub .

What hardware you running the standalone Wi-Fi interface on?

In theory, I could add a direct web interface to my ESPHome config. I might try it.