Rego 6xx based heat pumps

Hi everyone,

I’m a new HA user currently in the process of migrating from OpenHAB, which I’ve used for many years.

One of the key components in my setup is a heat pump based on the Rego 6xx controller. These heat pumps have been around for many years and are used in many installations, so many integrations already exist. Originally, since there was no native support available in OpenHAB (in 2016!), I developed my own binding for it. That project eventually became an official OpenHAB binding and is still being used today.

During my migration to HA and based on my previous experience developing the OH binding, I decided to implement a HA integration as well.

GitHub repository:

Example of some readouts:

I’ve been using it in my own setup for a couple of weeks, and it seems stable so far, so I’ve shared it on GitHub in case anyone would like to test it and provide feedback - in my setup I’m using an ESP module with ser2net in my HP since I don’t have a cable connection to the HP, but that should work too.

If anyone here is using a Rego 6xx based heat pump and is interested in testing or contributing, feedback is very welcome.

Original OpenHAB binding thread (contains a lot of information on how to connect to the heat pump) for reference:

Any feedback or suggestions would be greatly appreciated.

1 Like

Hi,
I have an IVT Heatpump using the Rego637 controller. I’ve been using a old RPi with a USB<->Serial TLL cable, and then forwaring though MQTT, but it is very cumbersome, so i would like to check out your solution. What hardware are you using for the ethernet-serial brigde that supports the 5V TTL?

Best Regards
Chriswein

Hi Chriswein,

I’m using a solution similar to the one shown here:


(from https://rago600.sourceforge.io/)

It uses an optocoupler to provide galvanic isolation between the heat pump and my hardware, and at the same time performs the required level conversion.

This interface is connected to an ESP8266, running ESPEasy together with ser2net, which provides the ethernet-to-serial bridge functionality. I’m planning to migrate to esphome for better HA integration, but since this has been working flawlessly for years, I haven’t changed it yet.

ESPEasy ser2net settings:

And from my custom component in HA I use socket://<IP:PORT>, i.e. socket://192.168.1.100:9265 to connect to my HP through ser2net.

Since you already have rpi connected to HP maybe try running ser2net on rpi?

Best regards,
Boris

P.S. Adding my initial HP setup for reference.

More info New binding - Rego 6xx based heat pumps - #132 by crnjan - Bindings - openHAB Community

Hi Boris

What a great idea!
And it works!!!
I just went with the most basic settings of “ser2net”:
connection: &con00
accepter: tcp,9500
connector: serialdev,/dev/ttyUSB0,19200n81,local

I will keep you posted with my experiences and suggestions

Great to hear you got it working!

I noticed in your screenshot that the operating hours value was negative. This has been corrected in release 0.0.2, so if you update to the latest version, it should now display the correct positive values.

You might also consider adding the following options to your ser2net configuration to avoid potential conflicts if multiple clients try to connect at the same time:

options:
  max-connections: 1
  kickolduser: true

This ensures that only one client can access the serial interface at a time, and if a new client connects, it cleanly replaces the existing one.

Thanks again for testing — looking forward to your feedback!

Hi Boris,

Thanks for the tip with ser2net.

Regarding the values, there were no error. When they installed the system they had a date misconfiguration and when i corrected it 9 years later when i bought the house it messed up the counters, but i haven’t figured out how to reset them. They are also messed up on the Rego user panel.

I was referring to


which should never be negative (heat pump operating hours).

The issue was caused by the values being processed as signed 16-bit integers. I didn’t notice it during testing since my heat pump currently has “only” 29,679 hours, which still fits within the int16 range. Once the value exceeds that range it would be displayed as negative.

This is now fixed — operating hours are handled as unsigned 16-bit integers.

Hi, I tested the integration on an WT32-ETH01 board with a Rego 636MBK unit, and everything—including the controls—works. I just have a problem with the registers; the rego 636mbk has some different registers. Maybe it would be good to add some kind of switching mechanism (rego 600, 636…) or a basic option to edit the registers used in the integration?

I was thinking of rewriting the registers manually, but if there’s an update, the registers might get overwritten back to their original state.

Hey, great to hear it’s working!

Do you have a list of registers? Adding a rego-unit-selector shouldn’t be a problem, especially if the only difference is the list of registers.

Hi, In my current integration, I am not yet reading all the data; for now, I am only using and have identified the following registries:

I just don’t know which approach to take that would be the most versatile for improving integration

  • HP Standby ?? - 0x0206
  • Compressor - 0x0200
  • P1 Floor Pump - 0x0205
  • P3 Ground Collector Pump - 0x01FF
  • 3-Way Valve - DHW - 0x0207
  • Fault - 0x0208

  • GT1 Return - 0x020B
  • GT2 Outdoor - 0x020C
  • GT3 DHW - Boiler - 0x020D
  • GT6 Compressor - 0x0210
  • GT8 Hot Circuit Out - 0x0211
  • GT9 Hot Circuit In - 0x0212
  • GT10 Cold Circuit In - 0x0213
  • GT11 Cold Circuit Out - 0x0214

  • REGO Heat Curve RAW - 0x0000
  • REGO Heat Curve Fine RAW - 0x0001
  • REGO Heating Hours - 0x0048
  • REGO DHW Hours - 0x004A
  • REGO Compressor Starts - 0x0046
  • REGO Compressor Run 0-9 - 0x0049
  • REGO Target Return Temperature - 0x006E

Below is register_repository.py that was generated with help of AI - a list of registers for Rego 636. I haven’t validated it so cannot confirm it’s correctness, but you can replace register_repository.py within your HA installation at homeassistant/custom_components/regoheatpump/rego600 and restart HA in order to take affect and check the outcome. Keep the original so you can restore.

Or use it as a starting point if you are not willing to test directly.

"""Register definitions for Rego 636 / 636MBK style mappings.

This repository is based on the existing rego600 layout, with the sensor and
device-value blocks shifted to match the reported WT32-ETH01 + Rego 636MBK
register map.
"""

from .identifiers import Identifiers
from .register import Register
from .register_factory import RegisterFactory


class RegisterRepository:
    """Register repository for Rego 636-style controllers."""

    @staticmethod
    def version() -> Register:
        """Return the version register."""
        return RegisterFactory.version(identifier=Identifiers.VERSION)

    @staticmethod
    def registers() -> list[Register]:
        """Return all supported registers."""
        return [
            # Last error
            RegisterFactory.last_error(identifier=Identifiers.LAST_ERROR),
            # Front Panel
            RegisterFactory.front_panel_switch(
                identifier=Identifiers.FRONT_PANEL_POWER_LAMP,
                address=0x0012,
            ),
            RegisterFactory.front_panel_switch(
                identifier=Identifiers.FRONT_PANEL_PUMP_LAMP,
                address=0x0013,
            ),
            RegisterFactory.front_panel_switch(
                identifier=Identifiers.FRONT_PANEL_ADDITIONAL_HEAT_LAMP,
                address=0x0014,
            ),
            RegisterFactory.front_panel_switch(
                identifier=Identifiers.FRONT_PANEL_WATER_HEATER_LAMP,
                address=0x0015,
            ),
            RegisterFactory.front_panel_switch(
                identifier=Identifiers.FRONT_PANEL_ALARM_LAMP,
                address=0x0016,
            ),
            # System registers, sensor values
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_RADIATOR_RETURN,
                address=0x020B,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_OUTDOOR,
                address=0x020C,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_HOTWATER,
                address=0x020D,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_RADIATOR_FORWARD,
                address=0x020E,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_INDOOR,
                address=0x020F,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_COMPRESSOR,
                address=0x0210,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_HEATFLUID_OUT,
                address=0x0211,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_HEATFLUID_IN,
                address=0x0212,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_COLDFLUID_IN,
                address=0x0213,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SENSOR_VALUES_COLDFLUID_OUT,
                address=0x0214,
            ),
            # External hotwater not yet confirmed for 636MBK.
            # RegisterFactory.system_temperature(
            #     identifier=Identifiers.SENSOR_VALUES_EXTERNAL_HOTWATER,
            #     address=0x0215,
            # ),
            # System registers, control data
            # Verify correct scaling and unit conversion for this register.
            # Disabled until correct register type and scaling are confirmed.
            # RegisterFactory.system_temperature(
            #     identifier=Identifiers.CONTROL_DATA_ADDHEAT_POWER_PERCENT,
            #     address=0x006D,
            # ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.CONTROL_DATA_RADIATOR_FORWARD_TARGET,
                address=0x006E,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.CONTROL_DATA_RADIATOR_RETURN_TARGET,
                address=0x006F,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.CONTROL_DATA_RADIATOR_RETURN_ON,
                address=0x0070,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.CONTROL_DATA_RADIATOR_RETURN_OFF,
                address=0x0071,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.CONTROL_DATA_HOTWATER_ON,
                address=0x0074,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.CONTROL_DATA_HOTWATER_OFF,
                address=0x0075,
            ),
            # System registers, device values
            RegisterFactory.system_switch(
                identifier=Identifiers.DEVICE_VALUES_COLD_FLUID_PUMP,
                address=0x01FF,
            ),
            RegisterFactory.system_switch(
                identifier=Identifiers.DEVICE_VALUES_COMPRESSOR,
                address=0x0200,
            ),
            RegisterFactory.system_switch(
                identifier=Identifiers.DEVICE_VALUES_ADDITIONAL_HEAT_3KW,
                address=0x0201,
            ),
            RegisterFactory.system_switch(
                identifier=Identifiers.DEVICE_VALUES_ADDITIONAL_HEAT_6KW,
                address=0x0202,
            ),
            RegisterFactory.system_switch(
                identifier=Identifiers.DEVICE_VALUES_RADIATOR_PUMP,
                address=0x0205,
            ),
            RegisterFactory.system_switch(
                identifier=Identifiers.DEVICE_VALUES_HEATFLUID_PUMP,
                address=0x0206,
            ),
            RegisterFactory.system_switch(
                identifier=Identifiers.DEVICE_VALUES_SWITCH_VALVE,
                address=0x0207,
            ),
            RegisterFactory.system_switch(
                identifier=Identifiers.DEVICE_VALUES_ALARM,
                address=0x0208,
            ),
            # System registers, settings
            RegisterFactory.system_unitless(
                identifier=Identifiers.SETTINGS_HEAT_CURVE,
                address=0x0000,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_HEAT_CURVE_FINE_ADJ,
                address=0x0001,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_HEAT_CURVE_COUPLING_DIFF,
                address=0x0002,
                is_writable=True,
            ),
            RegisterFactory.system_unitless(
                identifier=Identifiers.SETTINGS_HEAT_CURVE_2,
                address=0x0003,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_HEAT_CURVE_2_FINE_ADJ,
                address=0x0004,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_20,
                address=0x001E,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_15,
                address=0x001C,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_10,
                address=0x001A,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_5,
                address=0x0018,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_0,
                address=0x0016,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_MINUS_5,
                address=0x0014,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_MINUS_10,
                address=0x0012,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_MINUS_15,
                address=0x0010,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_MINUS_20,
                address=0x000E,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_MINUS_25,
                address=0x000C,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_MINUS_30,
                address=0x000A,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_ADJ_CURVE_AT_MINUS_35,
                address=0x0008,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_INDOOR_TEMP_SETTING,
                address=0x0021,
                is_writable=True,
            ),
            RegisterFactory.system_unitless(
                identifier=Identifiers.SETTINGS_CURVE_INFL_BY_IN_TEMP,
                address=0x0022,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_SUMMER_DISCONNECTION,
                address=0x0024,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_HOTWATER_TARGET,
                address=0x002B,
                is_writable=True,
            ),
            RegisterFactory.system_temperature(
                identifier=Identifiers.SETTINGS_HOTWATER_TARGET_HYSTERESIS,
                address=0x002C,
                is_writable=True,
            ),
            # System registers, operating times
            RegisterFactory.system_hours(
                identifier=Identifiers.OPERATING_TIMES_HP_IN_OPERATION_RAD,
                address=0x0048,
            ),
            RegisterFactory.system_hours(
                identifier=Identifiers.OPERATING_TIMES_HP_IN_OPERATION_DHW,
                address=0x004A,
            ),
            RegisterFactory.system_hours(
                identifier=Identifiers.OPERATING_TIMES_ADD_HEAT_IN_OPERATION_RAD,
                address=0x004C,
            ),
            RegisterFactory.system_hours(
                identifier=Identifiers.OPERATING_TIMES_ADD_HEAT_IN_OPERATION_DHW,
                address=0x004E,
            ),
        ]

Hope it helps.

EDIT: Once we nail-down the list of registers (register_repository.py) for Rego 636, we can add it to the repo + add a config option to select rego version. IMHO the easiest way to do so is to replace the register_repository.py as described above until you are satisfied with the result and than share it so it can be added.

Thank you for sending it. I’ve been testing the modified registries for about two weeks now. And everything seems to be working perfectly.

In the meantime, I’ve also been working on the Czech translation. I’m still fine-tuning the details, then I’ll send the JSON file.

1 Like

Added option to select rego controller, please update to latest version.

Following the recent Home Assistant developer change from pyserial to serialx, I replaced the serial communication layer with serialx and am able to communicate with my HP through ESPHome using serial_proxy.

The new URI scheme works nicely:

esphome://<ip>:<port>/?port_name=...

Example:

esphome://192.168.2.50:6053/?port_name=hp

So I successfully migrated from my existing ESP8266 + ser2net (running ESPEasy) setup to ESPHome using only “official” components.