Hayward AquaLogic / ProLogic automation

@amit1 ,

I am NOT using my fork of aqualogic as an integration. I thought this would be too cumbersome to restart HA every time I tried a new fix in the aqualogic core. More on that below along with code for what I am using. At this point, I could possibly update to using the integration, but since things are working for me, that’s not a priority.

I just pushed my latest changes to my fork. I don’t remember all I’ve done, but roughly speaking:

  • I tweaked how and when commands are inserted. Generally, I get most key presses to work from HA, but sometimes it goes into a funky state where they don’t. Just waiting a few seconds seems to let it recover. I mainly split out the sending of messages into another thread that could using timing events and response messages from the main thread to know when was a good time to send and what the result looked like.
  • I added a “key logger” file that tracks what response occurs whenever a button is pressed. This is whether it was pressed on the console, on my wireless keypad, or by HA. I hope to use this to “learn” how to detect when the HA-initiated button press doesn’t work and then re-send smartly. Since things work well enough, I might not ever go back to this.
  • I added an MQTT front-end. I did this because much of my system is on MQTT and node-red, so I can do quite a bit of fixing things up this way without restarting HA every time.
  • I changed the accessory names to match my system (eg, I have a blower on one of the aux devices).
  • I added NO documentation and made no effort to make this easily customized to the details of any given system (I don’t know enough about what those could even look like to try), so sorry and good luck :wink:

Earlier in this thread, I posted a screen grab of my HA dashboard. Here’s the latest along with the frontend yaml for it. It works well enough that I can press buttons to navigate the menu and accomplish what I want. I made it look/work roughly like the keypad console.

Dashboard yaml:

type: vertical-stack
cards:
  - show_name: false
    show_icon: false
    show_state: true
    type: glance
    entities:
      - entity: sensor.pool_display
  - square: false
    columns: 3
    type: grid
    cards:
      - type: custom:mushroom-light-card
        entity: switch.pool_menu_switch
        icon_type: icon
        name: Menu
        secondary_info: name
        layout: horizontal
        primary_info: none
        icon: mdi:menu-open
      - type: custom:mushroom-light-card
        entity: switch.pool_plus_switch
        icon_type: icon
        layout: vertical
        secondary_info: none
        icon: mdi:plus
        primary_info: none
      - type: custom:mushroom-title-card
      - type: custom:mushroom-light-card
        entity: switch.pool_left_switch
        icon_type: icon
        layout: vertical
        secondary_info: none
        icon: mdi:menu-left
        primary_info: none
      - type: custom:mushroom-light-card
        entity: switch.pool_minus_switch
        icon_type: icon
        layout: vertical
        secondary_info: none
        icon: mdi:minus
        primary_info: none
      - type: custom:mushroom-light-card
        entity: switch.pool_right_switch
        icon_type: icon
        layout: vertical
        secondary_info: none
        icon: mdi:menu-right
        primary_info: none
  - square: false
    columns: 3
    type: grid
    cards:
      - type: custom:mushroom-entity-card
        entity: binary_sensor.pool_pool_mode
        name: Pool
        tap_action:
          action: call-service
          service: switch.turn_on
          data: {}
          target:
            entity_id: switch.pool_pool_switch
        primary_info: none
        secondary_info: name
      - type: custom:mushroom-entity-card
        entity: binary_sensor.pool_heater_mode
        name: Heater
        tap_action:
          action: call-service
          service: switch.turn_on
          data: {}
          target:
            entity_id: switch.pool_heater_switch
        secondary_info: name
        primary_info: none
      - type: custom:mushroom-entity-card
        entity: binary_sensor.pool_heater_auto_mode
        name: Heater Auto
        tap_action:
          action: call-service
          service: switch.turn_on
          data: {}
          target:
            entity_id: switch.pool_heater_switch
        secondary_info: name
        primary_info: none
      - type: custom:mushroom-entity-card
        entity: binary_sensor.pool_spa_mode
        name: Spa
        tap_action:
          action: call-service
          service: switch.turn_on
          data: {}
          target:
            entity_id: switch.pool_spa_switch
        primary_info: none
        secondary_info: name
      - type: custom:mushroom-entity-card
        entity: binary_sensor.pool_blower_mode
        name: Blower
        tap_action:
          action: call-service
          service: switch.turn_on
          data: {}
          target:
            entity_id: switch.pool_blower_switch
        secondary_info: name
        primary_info: none
      - type: custom:mushroom-entity-card
        secondary_info: name
        primary_info: none
      - type: custom:mushroom-entity-card
        entity: binary_sensor.pool_filter_mode
        name: Filter
        tap_action:
          action: call-service
          service: switch.turn_on
          data: {}
          target:
            entity_id: switch.pool_filter_switch
        secondary_info: name
        primary_info: none
      - type: custom:mushroom-entity-card
        entity: binary_sensor.pool_lights_mode
        name: Lights
        tap_action:
          action: call-service
          service: switch.turn_on
          data: {}
          target:
            entity_id: switch.pool_lights_switch
        secondary_info: name
        primary_info: none

I’m using node-red to receive status, create sensors, and create switches which then turn into MQTT commands for button presses from/to the aqua logic MQTT interface. Here’s my node-red flow.

[{"id":"c704a53ed403401a","type":"tab","label":"Pool","disabled":false,"info":"","env":[]},{"id":"ee6f9c95a572c983","type":"junction","z":"c704a53ed403401a","x":520,"y":840,"wires":[["c555b498e722c912","dfe4e95db26c3b34"]]},{"id":"0b9ed40c4708e333","type":"junction","z":"c704a53ed403401a","x":40,"y":1180,"wires":[["ae35ea489576f8ac","3a338b0e7902447e","ce724bc00d066e66","ea0e4b95a09f71c2","e1b00ec3910d1e3f","1c3180f7f3f5313c","523f87eb3bb090cf","179e38dfd95028b0","8fa7d58d0b19f384","e0d8347e8c4cc962","b6e40e13bc5701c9","8524255cc8766b0d"]]},{"id":"6fe9b274fd9fec23","type":"mqtt in","z":"c704a53ed403401a","name":"","topic":"aqualogic/status/#","qos":"2","datatype":"utf8","broker":"62d4a8d7.7b1c88","nl":false,"rap":true,"rh":0,"inputs":0,"x":110,"y":220,"wires":[["587b1d5cf542a32a"]]},{"id":"5e722f82966547e4","type":"debug","z":"c704a53ed403401a","name":"debug 18","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":260,"y":120,"wires":[]},{"id":"c204d47a2b5d8d07","type":"switch","z":"c704a53ed403401a","name":"","property":"key","propertyType":"msg","rules":[{"t":"eq","v":"available","vt":"str"},{"t":"eq","v":"display","vt":"str"},{"t":"eq","v":"air_temp","vt":"str"},{"t":"eq","v":"pool_temp","vt":"str"},{"t":"eq","v":"pump_speed","vt":"str"},{"t":"eq","v":"pump_power","vt":"str"},{"t":"eq","v":"POOL","vt":"str"},{"t":"eq","v":"SPA","vt":"str"},{"t":"eq","v":"FILTER","vt":"str"},{"t":"eq","v":"HEATER_1","vt":"str"},{"t":"eq","v":"HEATER_AUTO_MODE","vt":"str"},{"t":"eq","v":"BLOWER","vt":"str"},{"t":"eq","v":"LIGHTS","vt":"str"}],"checkall":"false","repair":false,"outputs":13,"x":450,"y":220,"wires":[["22286e59905bf2e0"],["22286e59905bf2e0"],["329e5351bde42910"],["71401de35fc5d95e"],["11ab7fc17cf79c02"],["3e83276e66ee3780"],["bfd30b47a1b42817"],["0a4a962f1534cb5a"],["1abf44bcd6302bfb"],["58089d5cbb0160f5"],["29671f5272173a52"],["0eaa72c4d8302b2c"],["6062440072052c3a"]]},{"id":"587b1d5cf542a32a","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"key","pt":"msg","to":"$replace(topic, \"aqualogic/status/\", \"\")","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":220,"wires":[["5e722f82966547e4","c204d47a2b5d8d07"]]},{"id":"22286e59905bf2e0","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Display","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Pool Display"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":750,"y":40,"wires":[[]]},{"id":"329e5351bde42910","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Air Temperature","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Pool Air Temperature"},{"property":"device_class","value":"temperature"},{"property":"icon","value":""},{"property":"unit_of_measurement","value":"°F"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":780,"y":80,"wires":[[]]},{"id":"a47045e73d18696f","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Water Temperature","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Pool Water Temperature"},{"property":"device_class","value":"temperature"},{"property":"icon","value":""},{"property":"unit_of_measurement","value":"°F"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":1390,"y":100,"wires":[[]]},{"id":"11ab7fc17cf79c02","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Pump Speed","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Pool Pump Speed"},{"property":"device_class","value":"power_factor"},{"property":"icon","value":""},{"property":"unit_of_measurement","value":"%"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":770,"y":260,"wires":[[]]},{"id":"3e83276e66ee3780","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Pump Power","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Pool Pump Power"},{"property":"device_class","value":"power"},{"property":"icon","value":""},{"property":"unit_of_measurement","value":"W"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":770,"y":300,"wires":[[]]},{"id":"bfd30b47a1b42817","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Pool Mode","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"binary_sensor","config":[{"property":"name","value":"Pool Pool Mode"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":760,"y":360,"wires":[[]]},{"id":"0a4a962f1534cb5a","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Spa Mode","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"binary_sensor","config":[{"property":"name","value":"Pool Spa Mode"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":760,"y":400,"wires":[[]]},{"id":"1abf44bcd6302bfb","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Filter Mode","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"binary_sensor","config":[{"property":"name","value":"Pool Filter Mode"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":760,"y":440,"wires":[[]]},{"id":"58089d5cbb0160f5","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Heater Mode","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"binary_sensor","config":[{"property":"name","value":"Pool Heater Mode"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":770,"y":520,"wires":[[]]},{"id":"71401de35fc5d95e","type":"api-current-state","z":"c704a53ed403401a","name":"","server":"1777b72c.cb0709","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.pool_filter_mode","state_type":"str","blockInputOverrides":true,"outputProperties":[],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":860,"y":140,"wires":[["a47045e73d18696f"],["e00758629ab5b0ae"]]},{"id":"e00758629ab5b0ae","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"offline","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":160,"wires":[["a47045e73d18696f"]]},{"id":"ae35ea489576f8ac","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Filter Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Filter Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":740,"wires":[["a814f80c5cb4ddc3"],[]]},{"id":"3a338b0e7902447e","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Pool Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Pool Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":780,"wires":[["083068017d4d5288","fcacd26161586052"],[]]},{"id":"a814f80c5cb4ddc3","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"FILTER","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":740,"wires":[["ee6f9c95a572c983"]]},{"id":"083068017d4d5288","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"POOL","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":780,"wires":[["ee6f9c95a572c983"]]},{"id":"edc914744c56fddf","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"SPA","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":820,"wires":[["ee6f9c95a572c983"]]},{"id":"228ee673e2912a3d","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"HEATER_1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":860,"wires":[["ee6f9c95a572c983"]]},{"id":"40e6385c5c375a6c","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"LIGHTS","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":900,"wires":[["ee6f9c95a572c983"]]},{"id":"fa37afe966a5c4af","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"BLOWER","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":940,"wires":[["ee6f9c95a572c983"]]},{"id":"0eaa72c4d8302b2c","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Blower Mode","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"binary_sensor","config":[{"property":"name","value":"Pool Blower Mode"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":770,"y":600,"wires":[[]]},{"id":"c555b498e722c912","type":"mqtt out","z":"c704a53ed403401a","name":"","topic":"aqualogic/command","qos":"2","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"62d4a8d7.7b1c88","x":680,"y":840,"wires":[]},{"id":"dfe4e95db26c3b34","type":"trigger","z":"c704a53ed403401a","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"200","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":640,"y":1180,"wires":[["c39be751337193dc"]]},{"id":"a6e9bc02780b086a","type":"inject","z":"c704a53ed403401a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"600","crontab":"","once":true,"onceDelay":"120","topic":"","payload":"","payloadType":"date","x":470,"y":1180,"wires":[["dfe4e95db26c3b34"]]},{"id":"c39be751337193dc","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"enable","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":1180,"wires":[["0b9ed40c4708e333"]]},{"id":"6062440072052c3a","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Lights Mode","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"binary_sensor","config":[{"property":"name","value":"Pool Lights Mode"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":770,"y":660,"wires":[[]]},{"id":"ce724bc00d066e66","type":"debug","z":"c704a53ed403401a","name":"debug 19","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":160,"y":1180,"wires":[]},{"id":"fcacd26161586052","type":"debug","z":"c704a53ed403401a","name":"debug 20","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":360,"y":700,"wires":[]},{"id":"ea0e4b95a09f71c2","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Spa Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Spa Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":180,"y":820,"wires":[["edc914744c56fddf"],[]]},{"id":"e1b00ec3910d1e3f","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Heater Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Heater Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":860,"wires":[["228ee673e2912a3d"],[]]},{"id":"1c3180f7f3f5313c","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Lights Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Lights Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":900,"wires":[["40e6385c5c375a6c"],[]]},{"id":"523f87eb3bb090cf","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Blower Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Blower Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":940,"wires":[["fa37afe966a5c4af"],[]]},{"id":"179e38dfd95028b0","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Menu Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Menu Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":980,"wires":[["25cb496fe9eab358"],[]]},{"id":"25cb496fe9eab358","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"MENU","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":980,"wires":[["ee6f9c95a572c983"]]},{"id":"8fa7d58d0b19f384","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Left Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Left Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":180,"y":1020,"wires":[["77edf18b8c78fb81"],[]]},{"id":"77edf18b8c78fb81","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"LEFT","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":1020,"wires":[["ee6f9c95a572c983"]]},{"id":"e0d8347e8c4cc962","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Right Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Right Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":1060,"wires":[["63a95269e4b13ee6"],[]]},{"id":"63a95269e4b13ee6","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"RIGHT","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":1060,"wires":[["ee6f9c95a572c983"]]},{"id":"b6e40e13bc5701c9","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Minus Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Minus Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":1100,"wires":[["ae86948d3f9f0551"],[]]},{"id":"ae86948d3f9f0551","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"MINUS","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":1100,"wires":[["ee6f9c95a572c983"]]},{"id":"8524255cc8766b0d","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Plus Switch","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":2,"entityType":"switch","config":[{"property":"name","value":"Pool Plus Switch"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":true,"outputPayload":"","outputPayloadType":"str","x":190,"y":1140,"wires":[["1d2de971866ed5b6"],[]]},{"id":"1d2de971866ed5b6","type":"change","z":"c704a53ed403401a","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"PLUS","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":1140,"wires":[["ee6f9c95a572c983"]]},{"id":"29671f5272173a52","type":"ha-entity","z":"c704a53ed403401a","name":"Pool Heater Auto Mode","server":"1777b72c.cb0709","version":2,"debugenabled":false,"outputs":1,"entityType":"binary_sensor","config":[{"property":"name","value":"Pool Heater Auto Mode"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"","outputPayloadType":"str","x":790,"y":560,"wires":[[]]},{"id":"62d4a8d7.7b1c88","type":"mqtt-broker","name":"","broker":"10.0.1.29","port":"8883","tls":"8f64fdf5.552818","clientid":"","autoConnect":true,"usetls":true,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"1777b72c.cb0709","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30},{"id":"8f64fdf5.552818","type":"tls-config","name":"home ca","cert":"","key":"","ca":"/ssl/tendot_certs/tendot_ca.crt","certname":"","keyname":"","caname":"ca.crt","servername":"","verifyservercert":false}]

This may be completely useless to you, so sorry in advance :grinning_face_with_smiling_eyes:

  • Benjamin

I am looking for input on how you are or will be using the integration to the pool from HA?

I have created custom component that integrates to Dryden da-gen pool controllers and maybe more Hayden controllers. It uses the backend services for this site:Domotic for swimmingpools

For now it shows the following values and enables switching on/off the pool light:

I can’t believe I missed this. Thank you!!

One issue though, I tried adding AUX2 as a switch and it does not keep its state in HASS, it’ll immediately reset to an off position, even though it successfully turned on AUX2. Any suggestions @amscanne?

Hi all, I know this issue has been discussed a few times already in this thread but after reading the entire thing a number of times I’m still having some trouble. I am up to the software troubleshooting stage in that everything is connected and I am getting usable data in HA. Initially, I followed the steps to set up the default HomeAssistant/aqualogic integration. However, after getting everything set up I am only getting a few sensor readings showing up and am unable to effectively control any of the switches via HA. Upon reading some of the above posts I also created a custom configuration folder under config and git cloned the 3.3 version of the integration via SSH. (Not sure what exactly I have to do in order to make HA use this version over the one that ships with HA or if it’s even the same version). Anyway, nothing changed after that. Using the hex codes some people have provided above I am able to turn switches on and off using the USR IoT Test Software but it takes many attempts to go through (I guess normal from what I’ve read). I’m not getting any errors in the HA log when I try to toggle the switches there, they just revert shortly after pressing. And yes the switch status updates immediately in HA once it goes through either using the Hayward Remote or the USR test software. What can I do to troubleshoot these switches not working as well as the sensor data that isn’t showing?

Thanks for any help and Merry Christmas!

As a follow-up to this. I have figured out how to enable logging and can see the attempts from HA to send commands to the pool. When I toggle the Aux 1 switch I see the following in logs.


Thus the code that HA is trying to send is 10 02 00 02 00 02 00 02 00 18 10 03. However, In my testing with the USR-TCP232 Test software, the code that seems to work is 10 02 00 02 00 02 00 00 00 02 00 00 00 18 10 03. So it seems that my controller needs to see those extra 00 in the command. I have read that this is the case for some others but I am unsure how to adjust the code of AquaLogic to compensate for this and additionally where exactly it can be modified. Some people had mentioned possibly adjusting what I have highlighted below to 4 instead of 2 but that didn’t seem to change anything for me and the logs show that the same command format is sent. How can I verify that HA is using this custom configuration rather than the baked-in one?

Thanks again!

Here is the screenshot of my attempt at editing core.py I mentioned above.

Did you get it working?

If not yet, this is what worked for my system, though note I’m using a wired connection, not WiFI.

    def _get_key_event_frame(self, key):
        frame = bytearray()
        frame.append(self.FRAME_DLE)
        frame.append(self.FRAME_STX)

        if key.value > 0xffff:
            self._append_data(frame, self.FRAME_TYPE_WIRELESS_KEY_EVENT)
            self._append_data(frame, b'\x01')
            self._append_data(frame, key.value.to_bytes(4, byteorder='little'))
            self._append_data(frame, key.value.to_bytes(4, byteorder='little'))
            self._append_data(frame, b'\x00')
        else:
            # self._append_data(frame, self.FRAME_TYPE_LOCAL_WIRED_KEY_EVENT)
            self._append_data(frame, self.FRAME_TYPE_REMOTE_WIRED_KEY_EVENT)
            self._append_data(frame, key.value.to_bytes(2, byteorder='little'))
            self._append_data(frame, b'\x00')
            self._append_data(frame, b'\x00')
            self._append_data(frame, key.value.to_bytes(2, byteorder='little'))
            self._append_data(frame, b'\x00')
            self._append_data(frame, b'\x00')

(I suspect the double self._append_data(frame, b’\x00’) could be written better, I’m straining my limits of Python here)

Unfortunately, nothing changed for me. I removed the def _get_key_event_frame block in the existing core.py and implemented your code in place but it seems the same command format is being sent. Was there anything you had to do in order to know that HA was using your custom integration over the base one or will any custom config override a built-in one? Just for reference, here is how I’m able to get the command to go through in testing, with send as hex checked on the USR Test software.


If I spam the send button with this method the command eventually takes, and again this is using the first code and HA is sending the second one.

10 02 00 02 00 02 00 00 00 02 00 00 00 18 10 03
10 02 00 02 00 02 00 02 00 18 10 03

I’m not super knowledgeable in hex or python but I feel like it should be possible to modify something to get the format correct for my system.

Thanks again for all your help here!

Actually, I am now realizing that my issues are stemming from HA not using the custom_components version of AquaLogic that I have created. Can anyone provide some insight on how you were able setup your custom component? Using SFTP I created the custom_components folder. From the swilson GitHub I selected Code → Dowload ZIP extracted the files and placed them within the custom_components folder. From my research I learned that HA needs a manifest.json to load the custom component so I created my own but now I get errors in the logs about loading switches and sensors (Do I need to create a switches.py and sensors.py) Heres what the folder setup looks like.

And my manifest.json has the following
{
“domain”: “aqualogic”,
“name”: “AquaLogic”,
“documentation”: “AquaLogic - Home Assistant”,
“requirements”: [],
“codeowners”: [],
“version”: “1.0”,
“iot_class”: “local_push”,
“loggers”: [“aqualogic”]
}

Can anyone using a custom implementation of this please share their file structure or explain what was needed to properly enable it?

I’m of the understanding that where things reside varies by the implementation method used for Home Assistant. I’m running HASS OS in a VirtualBox VM, and my custom AquaLogic code is located as follows:

config/
  custom_components/
    aqualogic/
	  __init__.py
	  core.py
	  keys.py
	  manifest.json
	  sensor.py
      states.py
      switch.py

I started with the latest default code I could find in a Home Assistant development install (as of spring 2022) – that is, I didn’t pull it from any git repository – and went from there.

Nothing needed be done for the custom code to be picked up, I believe it gets used by virtue of the right stuff being in the right place.

Thank you for that. However, I’m still not able to get the code format to change despite multiple attempts to edit core.py. Using your edits and some others suggested above the code that is sent is still the same according to the debug logger. I am wondering if you enable the logger does your system report that it’s sending the longer code? This is what my log looks like when I try to trigger the Aux_1 switch.


Are the unknown frame messages something I need to deal with as well or they can be ignored? And lastly, would you or anyone else here be willing to share your core.py file in it’s entirety? I’ve been trying to learn python this past week and still haven’t had any luck trying to get the chains to move.

Yes, the unknown frame messages are a nuisance, they can be ignored.

It looks like your debugger might be set to “info”, as that’s all your screen shot is showing. If you haven’t tried “debug” for the aqualogic integration, please do, as it may reveal some additional useful detail.

I’ve DM’d you through the forum with a link to my aqualogic code. As shown above in posting #327, I had added additional “self._append_data(frame, b’\x00’)” to pad out the frame message to the format the ProLogic integration required.

Hello. I have similar board as shown in post 175 by sj777fj for my Hayward and used those images as a guide for the hardware and wiring setup, but am having trouble making this work. Here is the hardware I used:

ESP8266 ESP-01 Serial/WiFi transeiver
https://www.amazon.com/dp/B010N1ROQS?psc=1&ref=ppx_yo2ov_dt_b_product_details

TTL to RS485 adapter
https://www.amazon.com/dp/B08ZNF55V9?psc=1&ref=ppx_yo2ov_dt_b_product_details

LM2596 Buck Converter
–new user link limitation–

I think my issue is the ESP is not sending the serial data. This is my first attempt at using one of these modules and to be honest don’t really know what I’m doing. I did upload a sketch with the Arduino IDE based on the built in WiFiTelnetToSerial example. Google has not been friendly and it’s the closest thing I can find that looks to do what I need it to. I do have the module connected to my network and can ping with a response and connect via putty over telnet. If someone has a sketch they’ve used successfully or a link to a detailed guide, that would be awesome. Thanks in advance.

Also, if someone could point me to a debugging tool so I can at least see the packets being sent (if any) from the ESP module, that would be a plus.

As for HA, I added the integration in the config.yaml file and while the sensors are exposed, they are all in an unknown state. The following error pops in the log every 10 seconds.

Logger: homeassistant.components.aqualogic
Source: components/aqualogic/init.py:90
Integration: AquaLogic
First occurred: 4:42:41 PM (46 occurrences)
Last logged: 4:53:59 PM

Connection to 10.0.7.167:4328 lost

I’m more of a software guy than hardware, but my python is rusty. If I’m reading the init code right, there’s no data received, so it doesn’t break the loop and tries again. Is that correct?

Any help is greatly appreciated! Let me know if any other info is needed.

Adam

Did some more digging and found others using ESP-Link. So I flashed that and am seeing data come over in the microcontroller console (screen shot below). Some plain text, e.g. pool temp, air temp, etc., some garbled. I can also putty to the IP port 23 over telnet and get the same data. I plugged in my IP and port 23 into my HA config, but I’m getting an error that the host is unreachable. I’m assuming it’s the wrong port, but I am not sure what it would be (don’t see it in ESP-Link web page). Any ideas?

Uncaught thread exception
Traceback (most recent call last):
File “/usr/local/lib/python3.10/threading.py”, line 1016, in _bootstrap_inner
self.run()
File “/usr/src/homeassistant/homeassistant/components/aqualogic/init.py”, line 84, in run
panel.connect(self._host, self._port)
File “/usr/local/lib/python3.10/site-packages/aqualogic/core.py”, line 130, in connect
self.connect_socket(host, port)
File “/usr/local/lib/python3.10/site-packages/aqualogic/core.py”, line 135, in connect_socket
self._socket.connect((host, port))
OSError: [Errno 113] Host is unreachable

Adam

OK, I’m up and running. Rebooted my network and port 23 started working. Sometimes it just helps to get the issue out in the open. While there were no responses to my posts (relatively short timeframe), I’d like to thank everyone in this thread. This is great!

Adam

1 Like

Read through the whole thread now–great stuff, thanks all!

I’m just setting this up, and am at the point where everything reading is working but I can’t control anything with the switches–not one successful switch toggle so far. I thought that the upgrade of the aqualogic library to 2.6 a while back fixed this for most by switching to emulating the wireless remote. Is that correct or are people having to use the custom integration to get simple things like filter and aux_1 to be controllable? I’m still using the stock integration. I have an Aqua Plus saltwater system, not sure about the specific board version… there’s a sticker that says “G1-011049F-1 F”??

Hi SphtKr, a friend of mine runs an AquaPlus system so I’m curious about your situation. He had described his system as being somewhat limited as compared to the AquaLogic.

Could you tell me what sensors your AquaPlus has and which of them successfully appear in the Home Assistant integration? And the same for the switches.

My understanding is the AquaLogic integration was developed by a Home Assistant user (thank you swilson), based on someone else’s (partial) reverse engineering of Hayward’s protocol. That it works at all with your AquaPlus system indicates Hayward is using a similar protocol there.

Your best bet may be to turn on debug-level logging for the integration, and compare what codes the commands on your AquaPlus writes to the log vs what Home Assistant logs.

Hi–My AquaPlus seems to be about as functional as I could expect or hope (except for the switches), I get all the capabilities in the screenshot below seemingly working and reporting data. Of course, I had to specify all these in my configuration.yaml, but they do show up.

Are you mixing the AquaPlus up with the AquaRite? One or two people on this thread have had AquaRite systems and they look a little more limited.

What are the magic words for turning on debug-level logging for this integration? Remember, I’m using the one in core still … is this the thing where you get the GitHub repo and try the command-line tool? I can try that too.

Thanks for the screenshot. And you’re probably right, my friend’s system is likely an AquaRite.

For debug logging, add the appropriate version of the following to your configuration.yaml:

logger:
  logs:
    somethingsomethingaqualogic: debug

Since my integration is custom – which requires a different namespace – I’m uncertain whether you’d specifically stipulate:

homeassistant.components.aqualogic: debug

Or just:

aqualogic: debug

Though maybe either world work? If you need’em, logger details can found under the Integrations documentation. You’ll need to restart Home Assistant for it to take effect.

The AquaLogic integration is pretty chatty and will scribble volumes to the Home Assistant log, I recommend you only have the logger going while you’re actively debugging. And as mentioned somewhere above, ignore the annoying unknown frame messages, I assume they’re immaterial Hayward protocol that never got reverse engineered.

Mind DM`ing me a copy as well? I’m dealing with intermittent switch functionality.

Is there anything special I need to do in the configuration.yaml to get it to reference your version of the code base or will HA look in custom_components first?