Hayward pool heater with custom component

Hi everyone!

I’m happy to share that I got my Hayward pool heat pump connected to Home Assistant.

I used a Wemos D1 mini with a TTL to RS485 adapter and wrote a custom ESPHome component to interface with it, pulling sensor data and controlling settings like temperature and mode.

This is the device:

And here are some screenshots from Home Assistant.

The project is fully documented here: Hayward heat pump - connecting to ESPHome and HomeAssistant | Leontin Chiru

The new components is in the hayward branch of my esphome fork.
This branch also has some changes to the modbus component that I made.

If anyone has a similar heat pump, please give it a try.
The yaml configuration needed to use it:

uart:
  tx_pin: 1
  rx_pin: 3
  baud_rate: 9600

logger:
  baud_rate: 0

external_components:
  - source:
    type: git
    url: https://github.com/cleontin/esphome
    ref: hayward
  components: [ modbus, hayward ]

modbus:
  flow_control_pin: 2
  role: server

hayward:
  accept_broadcast: true
  server_address: 2

time:
  platform: homeassistant

I’m looking forward for any type of feedback.

Thanks!

1 Like

Awesome project! I’m a little curious if this will work with some of their other heat pump models. I’ve got a summit

Hi Mike

This should work with models that have the option to add an external control panel with a four wire interface (modbus).

Looking at the Summit model, I think it does not suport an external control panel but it does have remote control input via terminals P and S. From the diagrams, it seems like you can connect a relay to the P and S terminals and use it to switch between the pool and spa profiles, allowing for some level of control.

Hi! If anyone is interested I created custom component which does not require esphome fork: GitHub - grandalos/hayward: ESPHome external component for Hayward heat pumps with PC1002 over RS485, with climate control and schedule support · GitHub

this is still experimental release but feel free to test it

Hey Leontin,
Awesome work btw, I pushed forward and made a PCB to tidy things up alittle, happy to share the file once I can prove it all works

When I try to flash the D1 Mini, I’m getting a schema issue error in ESPHome. Claude is suggesting it is due to ESPHome 2026.3.3 changes.

This is kind of above my level, but does your github need updating to reflect these changes and that is why its failing? Or is it something I can change my side?

INFO ESPHome 2026.3.3
INFO Reading configuration /config/esphome/hayward-heatpump.yaml...
ERROR Unexpected exception while reading configuration:
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/esphome/esphome/__main__.py", line 1925, in <module>
    sys.exit(main())
             ^^^^^^
  File "/esphome/esphome/__main__.py", line 1916, in main
    return run_esphome(sys.argv)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1895, in run_esphome
    config = read_config(
             ^^^^^^^^^^^^
  File "/esphome/esphome/config.py", line 1323, in read_config
    res = load_config(command_line_substitutions, skip_external_update)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/config.py", line 1180, in load_config
    return _load_config(command_line_substitutions, skip_external_update)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/config.py", line 1168, in _load_config
    return validate_config(config, command_line_substitutions, skip_external_update)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/config.py", line 1059, in validate_config
    target_platform = core_config.preload_core_config(config, result)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/core/config.py", line 404, in preload_core_config
    if _is_target_platform(domain):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/core/config.py", line 354, in _is_target_platform
    return get_component(name, True).is_target_platform
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/loader.py", line 235, in get_component
    return _lookup_module(domain, exception)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/loader.py", line 211, in _lookup_module
    module = importlib.import_module(f"esphome.components.{domain}")
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 999, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/data/external_components/50eec081/esphome/components/hayward/__init__.py", line 339, in <module>
    cv.Optional(s[CONF_KEY], default={}): switch.switch_schema(
                                          ^^^^^^^^^^^^^^^^^^^^^
TypeError: switch_schema() missing 1 required positional argument: 'class_'

Had a play and with the help of Claude. I think I’ve managed to get it flashed correctly.
Still waiting on the RS485 to TTL component to arrive to test with heatpump but can now see entities in Home Assistant

Had to fork it to make the changes, but to not take away from @cleontin will remove if/when he updates his repository

Ended up making these changes to line 339

cv.Optional(s[CONF_KEY], default={}): switch.switch_schema(switch.Switch,

and line 359

cv.Optional(s[CONF_KEY], default={}): climate._CLIMATE_SCHEMA.extend(cv.COMPONENT_SCHEMA).extend(

Hey Tandarra,

Thanks for using this and for the list of changes. I’ve been trying to figure out how to get this to compile with the new esphome. I’ll include your changes soon.

I’m also planning to re-work this component. It should live on a repo of it’s own, not a full clone of esphome. And I’ll be trying to make it work with the standard modbus, since some of the changes I needed are already there.
I’ll update here when I manage to get that done.

Your board looks nice. It would be a great improvement for what I have right now, and maybe the perfect start for me into ordering custom PCBs. It would be nice if you could share it here or in github.

Its the first PCB I have made so isn’t perfect.
I used easyeda.com to design online - EasyEDA(Standard) - A Simple and Powerful Electronic Circuit Design Tool

It uses a library of custom components from users and components from LCSC which then can be taken over to JLCPCB to manufacture.

One of the components I think the mini buck converter has its GND set to the wrong pad or I simply couldn’t figure out how to change polarity and connect the track correctly, so the simple fix is to change pins on the JST connector physically. I’m sure you will see the issue when you load it up

But have a look and let me know what you think, fix it up and I’ll delete my repository once yours is updated to not confuse anyone.