aio_remeha_modbus.api package

Submodules

aio_remeha_modbus.api.api module

Implementation of the Remeha Modbus API.

class aio_remeha_modbus.api.api.DeviceBoardCategory(type: DeviceBoardType, generation: int)

Bases: object

The category of the device located on the appliance.

generation: int

The category generation

type: DeviceBoardType

The device type

class aio_remeha_modbus.api.api.DeviceBoardType(*values)

Bases: Enum

Defines the type of device located on the device instance.

CU_GH = 0

Motherboard for central heating boilers like Tzerra Ace

CU_OH = 1

Motherboard for condensing oil boilers like Calora Tower Oil LS

EEC = 27

Motherboard for gas boilers like GAS 120 Ace

EHC = 2

Motherboard for (hybrid) heat pumps like Mercuria Ace

EHC_ALT = 33

Unknown/alternate heatpump mainboard (seen on Confida)

GATEWAY = 30

A gateway, for example GTW-08 (modbus gateway)

MK = 20

Appliance control panel like eTwist

SCB = 25

Circuit control board

is_mainboard() bool

Return whether this value represents a mainboard, a.k.a. the main device.

class aio_remeha_modbus.api.api.DeviceInstance(id: int, board_category: DeviceBoardCategory, sw_version: tuple[int, int], hw_version: tuple[int, int], article_number: int)

Bases: object

A device (electronic board) somewhere on the Remeha appliance.

article_number: int

The article number of the device

board_category: DeviceBoardCategory

The board category on this instance.

hw_version: tuple[int, int]

The hardware version as (major,minor)

id: int

The device sequence id.

is_mainboard() bool

Return whether this device is a mainboard.

sw_version: tuple[int, int]

The software version as (major,minor)

class aio_remeha_modbus.api.api.RemehaApi(name: str, connection_type: ConnectionType, client: ModbusBaseClient, device_address: int = 1, time_zone: tzinfo | None = None)

Bases: object

Use instances of this class to interact with the Remeha device through Modbus.

async async_close() None

Close the connection to the configured modbus device.

async async_connect() bool

Connect to the configured modbus device.

async async_health_check() None

Attempt to check the system health by reading a single register (128 - numberOfDevices).

Raises:

RemehaModbusError – If the health check failed.

property async_is_connected: bool

Return whether we’re connected to the modbus device.

async async_read_appliance() Appliance

Read the appliance status registers.

Returns:

The appliance with its status fields.

Return type:

Appliance

Raises:
  • RemehaModbusError – If the appliance status fields cannot be obtained.

  • ValueError – If the retrieved modbus data cannot be successfully deserialized.

async async_read_device_instance(id: int) DeviceInstance

Read a single device instance from the modbus interface.

This reads the registers as described in the table below. Only the base zone registers are mentioned here; add 6 * id to get the discrete register number of the zone. For details, refer to the Remeha GTW-08 parameter list.

Base address | Variable name | Description | Modbus type | HA type |

|---------------|——————————-|-------------------------------------------------------|—————|---------------------------| | 129 | DeviceTypeBoard | Type of the device located on the instance. | UINT16 | DeviceBoardCategory | | 130 | sw_version | Software version (ex. 0x2001 = SW02.01) | UINT16 | tuple[int, int] | | 132 | hw_version | Hardware version (ex. 0x2001 = HW02.01) | UINT16 | tuple[int, int] | | 133 | ArticleNumber | Article number of the device located on the instance. | UINT32 | int |

Parameters:

id (int) – The one-based instance id.

Returns:

The requested device instance

Return type:

DeviceInst4ance

Raises:
  • RemehaModbusError – If the instance registers cannot be read.

  • ValueException – If deserializing the registers to a DeviceInstance fails.

async async_read_device_instances() list[DeviceInstance]

Retrieve the available devices instances of the Remeha appliance.

Returns:

A list of all discovered device instances.

Return type:

list[DeviceInstance]

Raises:

RemehaModbusError – If the list of device instances cannot be obtained.

async async_read_number_of_device_instances() int

Retrieve the number of available device instances in the appliance.

Returns:

The number of instances.

Return type:

int

Raises:
  • RemehaModbusError – If the number of instances cannot be obtained.

  • ValueError – If the retrieved modbus data cannot be deserialized successfully.

async async_read_number_of_zones() int | None

Retrieve the number of zones defined in the appliance.

Returns

int | None: The number of zones, or None if the modbus address is empty.

Raises

RemehaModbusError: If the number of zones cannot be obtained. ValueError: If the retrieved modbus data cannot be deserialized successfully.

async async_read_registers(start_register: int, register_count: int = 1, struct_format: str | bytes = '=H') tuple[Any, ...]

Read registers from the modbus interface for debugging purposes.

Parameters:
  • start_register (int) – The register to start reading at.

  • register_count (int) – The amount of registers to read.

  • struct_format (str | bytes) – The struct format to convert the register bytes to.

Returns:

A tuple containing values unpacked according to the format string.

Raises:
  • RemehaModbusError – if a modbus error occurred while reading the registers.

  • struct.error – if struct_format is an illegal struct format.

async async_read_sensor_values(descriptions: list[ModbusVariableDescription]) dict[ModbusVariableDescription, Any]

Read the values of the given list of variable descriptions.

Parameters:

descriptions (list[ModbusVariableDescription]) – The list of modbus variables to retrieve.

Returns:

A mapping from modbus variables to their values.

Return type:

dict[ModbusVariableDescription, Any]

async async_read_zone(id: int, appliance: Appliance) ClimateZone | None

Read a single climate zone from the modbus interface.

This reads the registers as described in the table below. Only the base zone registers are mentioned here; add 512 * id to get the discrete register number of the zone. For details, refer to the Remeha GTW-08 parameter list.

Base address | Variable name | Description | Modbus type | HA type |

|---------------|———————————–|-------------------------------------------------------|—————|---------------------------| | 640 | varZoneType | Zone type. | ENUM8 | ClimateZoneType | | 641 | parZoneFunction | Zone function. | ENUM8 | ClimateZoneFunction | | 642 | parZoneFriendlyNameShort | Zone short name. | STRING | str | | 646 | instance | Device instance owning the zone. | UINT8 | int | | 649 | parZoneMode | Mode zone working. | ENUM8 | ClimateZoneMode | | 656 | parZoneCoolingSetpoint1 | Zone cooling setpoint in ECO mode. | UINT16 | float | | 657 | parZoneCoolingSetpoint2 | Zone cooling setpoint in COMFORT mode. | UINT16 | float | | 658 | parZoneCoolingSetpoint3 | Zone cooling setpoint in AWAY mode. | UINT16 | float | | 659 | parZoneCoolingSetpoint4 | Zone cooling setpoint in MORNING mode. | UINT16 | float | | 660 | parZoneCoolingSetpoint5 | Zone cooling setpoint in EVENING mode. | UINT16 | float | | 664 | parZoneRoomManualSetpoint | Manually set wished room temperature of the zone. | UINT16 | float | | 665 | parZoneDhwComfortSetpoint | Wished comfort domestic hot water temperature. | UINT16 | float | | 666 | parZoneDhwReducedSetpoint | Wished reduced domestic hot water temperature. | UINT16 | float | | 686 | parZoneDhwCalorifierHysteresis | Hysteresis to start DHW tank load | UINT16 | float | | 688 | parZoneTimeProgramSelected | Time program selected by the user. | ENUM8 | ClimateZoneScheduleId | | 1104 | varZoneTRoom | Current room temperature for zone. | INT16 | float | | 1109 | varZoneCurrentHeatingMode | Current mode the zone is functioning in. | ENUM8 | ClimateZoneHeatingMode | | 1110 | varZonePumpRunning | Whether the zone pump is ruinning. | ENUM8 | bool | | 1119 | varDhwTankTemperature | Tank temperature DHW tank (bottom or single sensor) | INT16 | float |

Parameters:
  • id (int) – The one-based zone id.

  • appliance (Appliance) – The appliance to which the zone belongs.

Returns:

The requested zone, or None if zone.type == ClimateZoneType.NOT_PRESENT.

Return type:

ClimateZone

Raises:
  • InvalidZoneSchedule – If the zone is in scheduling mode and parsing the schedule fails.

  • RemehaModbusError – If the zone registers cannot be read.

  • ValueError – If deserializing the registers to a ClimateZone fails.

async async_read_zone_schedule(zone: ClimateZone | int, schedule_id: ClimateZoneScheduleId, day: Weekday) ZoneSchedule | None

Read a single climate zone schedule from the modbus interface.

Parameters:
  • zone (ClimateZone | int) – The ClimateZone or its one-based id the time program is for.

  • schedule_id (ClimateZoneScheduleId) – The id of the schedule to read.

  • day (Weekday) – The weekday of the requested schedule.

Returns:

The requested zone schedule, or None if it has not been configured.

Return type:

ZoneSchedule

Raises:
  • RemehaModbusError – If the required registers cannot be read.

  • ValueError – If deserializing the registers to a ZoneSchedule fails.

async async_read_zone_update(zone: ClimateZone, appliance: Appliance) ClimateZone

Retrieve updates for a single ClimateZone.

In attempt to reduce the amount of calls over the network, this only reads updatable fields from modbus and merges zone with the updates in a new returned ClimateZone. Only the base zone registers are mentioned here; add 512 * id to get the discrete register number of the zone. For details, refer to the Remeha GTW-08 parameter list.

Base address | Variable name | Description | Modbus type | HA type |

|---------------|———————————–|-------------------------------------------------------|—————|---------------------------| | 649 | parZoneMode | Mode zone working. | ENUM8 | ClimateZoneMode | | 656 | parZoneCoolingSetpoint1 | Zone cooling setpoint in ECO mode. | UINT16 | float | | 657 | parZoneCoolingSetpoint2 | Zone cooling setpoint in COMFORT mode. | UINT16 | float | | 658 | parZoneCoolingSetpoint3 | Zone cooling setpoint in AWAY mode. | UINT16 | float | | 659 | parZoneCoolingSetpoint4 | Zone cooling setpoint in MORNING mode. | UINT16 | float | | 660 | parZoneCoolingSetpoint5 | Zone cooling setpoint in EVENING mode. | UINT16 | float | | 664 | parZoneRoomManualSetpoint | Manually set wished room temperature of the zone. | UINT16 | float | | 665 | parZoneDhwComfortSetpoint | Wished comfort domestic hot water temperature. | UINT16 | float | | 666 | parZoneDhwReducedSetpoint | Wished reduced domestic hot water temperature. | UINT16 | float | | 686 | parZoneDhwCalorifierHysteresis | Hysteresis to start DHW tank load | `UINT16 | float | | 688 | parZoneTimeProgramSelected | Time program selected by the user. | ENUM8 | ClimateZoneScheduleId | | 1104 | varZoneTRoom | Current room temperature for zone. | INT16 | float | | 1109 | varZoneCurrentHeatingMode | Current mode the zone is functioning in. | ENUM8 | ClimateZoneHeatingMode | | 1110 | varZonePumpRunning | Whether the zone pump is ruinning. | ENUM8 | bool | | 1119 | varDhwTankTemperature | Tank temperature DHW tank (bottom or single sensor) | INT16 | float |

Parameters:
  • zone (ClimateZone) – The zone to update.

  • appliance (Appliance) – The appliance to which this zone belongs.

Returns:

The updated zone.

Return type:

ClimateZone

Raises:
  • InvalidZoneSchedule – If the zone is in scheduling mode and parsing the schedule fails.

  • RemehaModbusError – If the zone update registers cannot be read.

  • ValueError – If deserializing any register fails.

async async_read_zones(appliance: Appliance) list[ClimateZone]

Retrieve the available zones of the modbus device.

This method returns the all zones having a supported ClimateZoneFunction. Whether a zone function is supported can be queried using ClimateZoneFunction.is_supported()

Parameters:

appliance (Appliance) – The appliance to which the zones belong.

Returns:

A list of all discovered zones.

Return type:

list[ClimateZone]

Raises:
  • DiscoveryTableCorruptedError – If the modbus discovery table has been corrupted.

  • InvalidZoneSchedule – If the climate zone is in scheduling mode but reading the schedule fails.

  • RemehaModbusError – If the list of zones cannot be obtained.

  • ValueError – If the retrieved modbus data cannot be successfully deserialized.

async async_write_variable(variable: ModbusVariableDescription, value: str | float | bool | tuple[int, int] | datetime | Enum | ZoneSchedule | None, offset: int = 0) None

Write a single variable to the modbus device.

### Notes:
  • If value is a tuple, the whole tuple must fit in a single register, contain exactly two elements that are both treated as unsigned bytes.

    Therefore the individual values cannot exceed 2^8.

  • Values of type datatype are only allowed when variable.data_type == DataType.CIA_301_TIME_OF_DAY.

Parameters:
  • variable (ModbusVariableDescription) – The description of the variable to write.

  • value (str|float|bool|tuple[int,int]|datetime|Enum|ZoneSchedule|None) – The value to write. If None, the GTW-08 NULL value is written instead.

  • offset (int) – The offset in registers of variable.start_address. Used for zone-, device and schedule objects.

Raises:
  • RemehaModbusError – If the connection to the modbus device is lost or if the write request fails.

  • ValueError

    • If no conversion path exists between variable.data_type and value * If conversion to a numeric type fails. * If value is a tuple which does not contain exactly two elements. * If value is a datetime but variable.data_type is not DataType.CIA_301_TIME_OF_DAY.

property connection_type: ConnectionType

Return the modbus connection type.

classmethod create(name: str, config: Configuration, time_zone: tzinfo | None = None) Self

Create a new RemehaApi instance.

Parameters:
  • name (str) – The name of the modbus hub name.

  • config (Configuration) – A typed dict containing the configuration.

  • time_zone (tzinfo|None) – The time zone of the Remeha appliance. If None, local system time is used.

get_device_register_offset(device: DeviceInstance | int) int

Get the offset in registers for the given DeviceInfo | int.

get_schedule_register_offset(schedule: ClimateZoneScheduleId | int) int

Get the offset in registers for the given `ClimateZoneScheduleId | int.

get_zone_register_offset(zone: ClimateZone | int) int

Get the offset in registers for the given ClimateZone | int.

property name: str

Return the modbus hub name.

class aio_remeha_modbus.api.api.SerialConnectionMethod(*values)

Bases: StrEnum

Defines the serial connection method.

ASCII = 'ascii'

ASCII data transmission preceded by slave id and followed by a crc. Used for new devices.

RTU = 'rtu'

Binary data transmission preceded by slave it and followed by a crc. Standard.

aio_remeha_modbus.api.appliance module

Implementation of appliance-scoped functionality.

class aio_remeha_modbus.api.appliance.Appliance(silent_mode: SilentMode, silent_mode_start_time: time, silent_mode_end_time: time, ch_enabled: bool, cooling_type: CoolingType, current_error: int | None, error_priority: ApplianceErrorPriority, cooling_forced: bool, status: ApplianceStatus, season_mode: SeasonalMode | None, summer_winter: float, neutral_band_summer_winter: float = 0.0, force_summer: bool = False)

Bases: object

Represents a Remeha appliance.

An Appliance stores information about the appliance that cannot be linked to any of the other available api types, like appliance error status or burning hours counters.

ch_enabled: bool

Whether central heating demand processing is enabled.

cooling_forced: bool

Whether the appliance is in forced cooling mode.

cooling_type: CoolingType

The type of cooling.

current_error: int | None

The current error, encoded in two unsigned bytes. None means no error.

The joined bytes show the error that can be looked up in the manual , e.g. 0x0207 is error 02.07.

error_as_str() str

Return a user-friendly string representing the error.

error_priority: ApplianceErrorPriority

Shows the current appliance error priority.

force_summer: bool = False

Whether forced summer mode is active (parameter AP074).

is_cooling_required() bool

Whether the appliance cooling mode is required.

This can be forced (cooling_forced == True) or derived (season_mode is in a summer variant).

neutral_band_summer_winter: float = 0.0

Temperature band below the summer/winter limit within which the appliance neither heats nor cools (parameter AP075).

season_mode: SeasonalMode | None

The current seasonal mode of the appliance.

silent_mode: SilentMode

The silent mode level of the appliance.

silent_mode_end_time: time

The time of day at which the silent mode ends.

silent_mode_start_time: time

The time of day at which the silent mode starts.

status: ApplianceStatus

Shows various status fields.

summer_winter: float

The upper limit for heating.

class aio_remeha_modbus.api.appliance.ApplianceErrorPriority(*values)

Bases: Enum

Defines the current error state of the appliance.

BLOCKING = 3

This error type has high priority. The appliance is blocked because of multiple prior warnings.

LOCKING = 0

This error type has the highest priority. The appliance is locked because of a physical defect or missing configuration unit, to prevent further damage.

NO_ERROR = 255

This error type has low priority. No action required.

WARNING = 6

This error type has medium priority. If ignored, the appliance will block the water flow to prevent damage.

class aio_remeha_modbus.api.appliance.ApplianceStatus(bits: tuple[int, int])

Bases: object

The appliance status shows various boolean status fields about the applliance.

appliance_pump_on: bool

Whether the main pump is on.

ch_active: bool

Whether the CH system is active.

cooling_active: bool

Whether the cooling system is active.

dhw_active: bool

Whether the DHW system is active.

dhw_electrical_backup_on: bool

Whether the DHW electrical backup is on.

electrical_backup2_on: bool

Whether the 2nd central heating electrical backup is on.

electrical_backup_on: bool

Whether the central heating electrical backup is on.

flame_on: bool

Whether the appliance flame is on.

heat_pump_on: bool

Whether the appliance heat pump is on.

power_down_reset_needed: bool

Whether the appliance must be powered down and reset. Leave it powered off at least 20 seconds.

service_required: bool

Whether the appliance requires service.

three_way_valve: bool

Unknown, but relate to 3-way valve obviously.

three_way_valve_closed: bool

Whether the 3-way valve is closed.

three_way_valve_open: bool

Whether the 3-way valve is open.

water_pressure_low: bool

Whether the water pressure is low.

class aio_remeha_modbus.api.appliance.CoolingType(*values)

Bases: Enum

Defines the type of cooling used by the appliance (if any).

ACTIVE_COOLING = 1

The appliance uses active cooling.

This type of cooling is used by all air-sourced heat pumps.

FREE_COOLING = 2

The appliance uses free cooling.

This type of cooling is used by geothermal and water-source heat pumps.

OFF = 0

Cooling is off.

class aio_remeha_modbus.api.appliance.SeasonalMode(*values)

Bases: Enum

Defines the current seasonal mode of the appliance.

SUMMER = 3
SUMMER_NEUTRAL_BAND = 2
WINTER = 0
WINTER_FROST_PROTECTION = 1
class aio_remeha_modbus.api.appliance.SilentMode(*values)

Bases: Enum

Defines the silent mode of the appliance.

LEVEL_1 = 1

Silent mode.

LEVEL_2 = 2

Extra silent mode.

OFF = 0

Normal operation.

aio_remeha_modbus.api.climate_zone module

Implementation of climate zones within the Remeha Modbus integration.

class aio_remeha_modbus.api.climate_zone.ClimateZone(id: int, type: ClimateZoneType, function: ClimateZoneFunction, short_name: str, owning_device: int | None, mode: ClimateZoneMode, selected_schedule: ClimateZoneScheduleId | None, current_schedule: dict[Weekday, ZoneSchedule | None], heating_mode: ClimateZoneHeatingMode | None, temporary_setpoint: float | None, room_setpoint: float | None, dhw_comfort_setpoint: float | None, dhw_reduced_setpoint: float | None, dhw_calorifier_hysteresis: float | None, temporary_setpoint_end_time: datetime | None, room_temperature: float | None, room_cooling_setpoint_1: float | None, room_cooling_setpoint_2: float | None, room_cooling_setpoint_3: float | None, room_cooling_setpoint_4: float | None, room_cooling_setpoint_5: float | None, dhw_tank_temperature: float | None, pump_running: bool, time_zone: tzinfo | None, appliance_requires_cooling: bool = False)

Bases: object

Defines a climate zone following the GTW-08 parameter list.

In the GTW-08 parameter list, a climate zone contains all fields for all zone types. The API must stay as close as possible to the original mapping and therefore a ClimateZone does not differentiate between zone types. However, the entities created from ClimateZone instances have distinct types for all supported zone types.

appliance_requires_cooling: bool = False

Whether the related appliance requires cooling

current_schedule: dict[Weekday, ZoneSchedule | None]

If selected_schedule has a value, current_schedule contains the schedule for all week days.

property current_setpoint: float | None

Return the current setpoint of this zone.

The actual returned setpoint field depends on the type of zone and the current zone mode.

Returns:

The current zone setpoint, or -1 if zone type or mode does not support a current setpoint.

Return type:

float

property current_temparature: float

Return the current temperature of this zone.

The actual returned temperature field depends on the type of zone.

dhw_calorifier_hysteresis: float | None

Hysteresis to start DHW tank load

dhw_comfort_setpoint: float | None

The setpoint for DHW in comfort mode

dhw_reduced_setpoint: float | None

The setpoint for DHW in reduced (eco) mode

dhw_tank_temperature: float | None

The current DHW tank temperature

function: ClimateZoneFunction

The climate zone function

has_cooling_capability() bool

Whether this type of climate zone is capable of cooling.

heating_mode: ClimateZoneHeatingMode | None

The current heating mode of the climate zone

id: int

The one-based climate zone id

is_central_heating() bool

Determine if this zone is a CH (central heating) zone.

is_domestic_hot_water() bool

Determine if this zone is a DHW (domestic hot water) zone.

property max_temp: float

The highest allowed setpoint for this zone.

The maximum temperature differs per zone type: * For DHW (Domestinc Hot Water) it’s 65 degrees C * For CH (Central Heating) or mixing circuits it’s 30 degrees C * For all others it’s the lowest value of the above. This is to ensure unknown zone types won’t get a flow temperature they can’t handle.

property min_temp: float

The lowest allowed setpoint for this zone.

The minimum temperature differs per zone type: * For DHW (Domestinc Hot Water) it’s 6 degrees C * For CH (Central Heating) or mixing circuits it’s 10 degrees C * For all others it’s the highest value of the above. This is to ensure unknown zone types won’t get a flow temperature they can’t handle.

mode: ClimateZoneMode

The current mode the zone is in

owning_device: int | None

The id of the device owning the zone.

pump_running: bool

Whether the zone pump is currently running

room_cooling_setpoint_1: float | None

Cooling setpoint in ECO mode

room_cooling_setpoint_2: float | None

Cooling setpoint in COMFORT mode

room_cooling_setpoint_3: float | None

Cooling setpoint in AWAY mode

room_cooling_setpoint_4: float | None

Cooling setpoint in MORNING mode

room_cooling_setpoint_5: float | None

Cooling setpoint in EVENING mode

room_setpoint: float | None

The current room temperature setpoint

room_temperature: float | None

The current room temperature

selected_schedule: ClimateZoneScheduleId | None

The currently selected schedule.

Although this property is optional, it needn’t be None if mode != ClimateZoneMode.SCHEDULING.

short_name: str

The climate zone short name

temporary_setpoint: float | None

Temporary room setpoint override. Only available when mode is SCHEDULING.

temporary_setpoint_end_time: datetime | None

End time of temporary setpoint override

time_zone: tzinfo | None

The time zone of the related appliance

type: ClimateZoneType

The type of climate zone

aio_remeha_modbus.api.climate_zone.is_central_heating(type: ClimateZoneType, function: ClimateZoneFunction) bool

Return whether the given type and function resolve to a CH zone type.

This method is meant to be used by the API, in situations where no ClimateZone is available (yet).

aio_remeha_modbus.api.climate_zone.is_domestic_hot_water(type: ClimateZoneType, function: ClimateZoneFunction) bool

Return whether the given type and function resolve to a DHW zone type.

aio_remeha_modbus.api.config module

Configuration classes.

class aio_remeha_modbus.api.config.Configuration(connection_type: ConnectionType, device_address: int, port: str | int)

Bases: object

The configuration to use when creating new RemehaApi instances.

connection_type: ConnectionType

The type of connection required to connect to the modbus device.

device_address: int

The modbus slave id.

port: str | int

The port to connect to.

Examples: * /dev/ttyUSB0 for a serial connection * 502 for a TCP connection

class aio_remeha_modbus.api.config.SerialConfiguration(connection_type: ConnectionType, device_address: int, port: str | int, framer: Literal[FramerType.RTU, FramerType.ASCII], baudrate: int = 9600, bytesize: Literal[5, 6, 7, 8] = 8, parity: Literal['E', 'O', 'N'] = 'N', stopbits: Literal[1, 2] = 2)

Bases: Configuration

Configuration for serial connections.

baudrate: int = 9600

The speed of the connection.

bytesize: Literal[5, 6, 7, 8] = 8

Data size in bits of each byte.

connection_type: ConnectionType = 'serial'

The type of connection required to connect to the modbus device.

framer: Literal[FramerType.RTU, FramerType.ASCII]

The type of framer to use.

parity: Literal['E', 'O', 'N'] = 'N'

Parity if the data bytes.

stopbits: Literal[1, 2] = 2

Stopbits of the data bytes.

class aio_remeha_modbus.api.config.TcpConfiguration(connection_type: ConnectionType, device_address: int, port: str | int, framer: Literal[FramerType.SOCKET, FramerType.RTU], host: str, timeout: int = 120)

Bases: Configuration

Configuration for TCP connection types.

framer: Literal[FramerType.SOCKET, FramerType.RTU]
host: str

The IP-address or hostname of the modbus device.

timeout: int = 120

Response timeout in seconds.

class aio_remeha_modbus.api.config.UdpConfiguration(connection_type: ConnectionType, device_address: int, port: str | int, framer: Literal[FramerType.SOCKET], host: str, timeout: int = 120)

Bases: Configuration

Configuration for UDP connection types.

framer: Literal[FramerType.SOCKET]
host: str

The IP-address or hostname of the modbus device.

timeout: int = 120

Response timeout in seconds.

aio_remeha_modbus.api.const module

Constants for the Remeha Modbus API.

aio_remeha_modbus.api.const.AUTO_SCHEDULE_DEFAULT_ID: Final[ClimateZoneScheduleId] = ClimateZoneScheduleId.SCHEDULE_1

The default schedule id for auto scheduling.

aio_remeha_modbus.api.const.AUTO_SCHEDULE_MINIMAL_END_HOUR: Final[int] = 21

The minimal latest hour required to create a useful auto schedule.

This means that if a schedule is planned before this hour, it cannot succeed because then no full day can be planned ahead.

aio_remeha_modbus.api.const.BOILER_MAX_ALLOWED_HEAT_DURATION: Final[int] = 3

The maximum amount of hours the boiler will get to heat up.

If the central heating- the heat pump unit can modulate, this is the estimated amount of time required since that is most energy-efficient. When the unit is unable to modulate, this time is much shorter, but it will cost more energy.

class aio_remeha_modbus.api.const.BoilerConfiguration(volume: Final[float | None], heat_loss_rate: Final[float | None], energy_label: Final[BoilerEnergyLabel | None])

Bases: object

The configuration of a DHW boiler.

energy_label: Final[BoilerEnergyLabel | None]

The boiler energy label, if the heat loss rate is not available.

heat_loss_rate: Final[float | None]

The heat loss rate in Watt

volume: Final[float | None]

The volume of the boiler in m³

class aio_remeha_modbus.api.const.BoilerEnergyLabel(*values)

Bases: StrEnum

Energy label for DHW boiler.

The energy label is used to provide an alternative method of calculating heat loss rate. See also https://www.energielabel.nl/apparaten/boiler-en-geiser (Dutch)

A = 'A'
A_PLUS = 'A+'
B = 'B'
C = 'C'
D = 'D'
E = 'E'
F = 'F'
class aio_remeha_modbus.api.const.ClimateZoneFunction(*values)

Bases: Enum

Enumerates the available zone functions.

DHW_BIC = 11
DHW_COMMERCIAL_TANK = 12
DHW_LAYERED = 10
DHW_PRIMARY = 254
DHW_TANK = 6
DIRECT = 1
DISABLED = 0
ELECTRICAL_DHW_TANK = 7
FAN_CONVECTOR = 5
HIGH_TEMPERATURE = 4
MIXING_CIRCUIT = 2
PROCESS_HEAT = 9
SWIMMING_POOL = 3
TIME_PROGRAM = 8
has_cooling_capability() bool

Return whether this ClimateZoneFunction supports cooling.

is_supported() bool

Return whether this ClimateZoneFunction is currently supported within this integration.

class aio_remeha_modbus.api.const.ClimateZoneHeatingMode(*values)

Bases: Enum

The mode the zone is currently functioning in.

COOLING = 2
HEATING = 1
STANDBY = 0
class aio_remeha_modbus.api.const.ClimateZoneMode(*values)

Bases: Enum

Enumerates the modes a zone can be in.

ANTI_FROST = 2
MANUAL = 1
SCHEDULING = 0
class aio_remeha_modbus.api.const.ClimateZoneScheduleId(*values)

Bases: Enum

The climate zone time program selected by the user.

Note: After updating the enum values, ALWAYS update the mapping to _attr_preset_modes of RemehaModbusClimateEntity!

SCHEDULE_1 = 0
SCHEDULE_2 = 1
SCHEDULE_3 = 2
SCHEDULE_4 = 3
class aio_remeha_modbus.api.const.ClimateZoneType(*values)

Bases: Enum

Enumerates the available zone types.

CH_AND_COOLING = 2
CH_ONLY = 1
DHW = 3
NOT_PRESENT = 0
OTHER = 254
PROCESS_HEAT = 4
SWIMMING_POOL = 5
class aio_remeha_modbus.api.const.ConnectionType(*values)

Bases: StrEnum

Defines the type of modbus connection.

RTU_OVER_TCP = 'rtuovertcp'

TCP/IP connection with RTU framer, used when connecting to modbus forwarders.

SERIAL = 'serial'

Serial connection with RTU framer, used with TTY port or USB rs485 converter.

TCP = 'tcp'

TCP/IP connection with socket framer, used with Ethernet enabled devices.

UDP = 'udp'

UDP connection with socker framer.

class aio_remeha_modbus.api.const.DataType(*values)

Bases: StrEnum

Data types for GTW-08 modbus.

#### Notes The HA modbus component also provides a DataType enum, but it has a deprecated UINT8 variant, which is used extensively by the GTW-08 parameter list. Not providing an UINT8 variant would require a more generic approach while reading/writing registers, that is more complex than adding a new variant and handling it specifically.

CIA_301_TIME_OF_DAY = 'cia301_time_of_day'

A time of day, encoded as defined in the CAN301 par 9.1.6.4, ‘Time of Day’.

FLOAT32 = 'float32'
FLOAT64 = 'float64'
INT16 = 'int16'
INT32 = 'int32'
INT64 = 'int64'
STRING = 'string'
TUPLE16 = 'tuple16'

A tuple[int, int] read from a single register.

UINT16 = 'uint16'
UINT32 = 'uint32'
UINT64 = 'uint64'
UINT8 = 'uint8'

A single byte, read from a 2-byte register with struct format of xB. Also used for ENUM8

ZONE_TIME_PROGRAM = 'zone_time_program'

A zone time program for a single day, encoded in bytes as defined in the GTW-08 parameter list.

class aio_remeha_modbus.api.const.DeviceInstanceRegisters

Bases: object

The register mappings for device instances.

ARTICLE_NUMBER: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=133, name='ArticleNumber', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
HW_VERSION: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=132, name='hw_version', data_type=<DataType.TUPLE16: 'tuple16'>, scale=None, count=1, friendly_name=None)
SW_VERSION: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=130, name='sw_version', data_type=<DataType.TUPLE16: 'tuple16'>, scale=None, count=1, friendly_name=None)
TYPE_BOARD: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=129, name='DeviceTypeBoard', data_type=<DataType.TUPLE16: 'tuple16'>, scale=None, count=1, friendly_name=None)
class aio_remeha_modbus.api.const.ForecastField(*values)

Bases: StrEnum

Describe the weather forecast action response field names that are relevant for this integration.

CONDITION = 'condition'
DATETIME = 'datetime'
PRECIPITATION = 'precipitation'
SOLAR_IRRADIANCE = 'solar_irradiance'

Solar irradiance is not a field that’s available by default

TEMPERATURE = 'temperature'
class aio_remeha_modbus.api.const.HybridRegisters

Bases: object

Registers for hybrid appliances.

COP_CALCULATED: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=9230, name='varHpCOPCalculated', data_type=<DataType.UINT16: 'uint16'>, scale=0.001, count=1, friendly_name=None)
class aio_remeha_modbus.api.const.Limits(*values)

Bases: float, Enum

Forced limits users must not exceed.

CH_MAX_TEMP = 30.0

Central heating maximum temperature.

CH_MIN_TEMP = 6.0

Central heating minimum temperature.

DHW_MAX_TEMP = 65.0

Domestic hot water maximum temperature.

DHW_MIN_TEMP = 10.0

Domestic hot water minimum temperature.

DHW_SCHEDULING_SETPOINT_OVERRIDE_DURATION = 2.0

The duration in hours of a temporary setpoint override in DHW scheduling.

HYSTERESIS_MAX_TEMP = 40.0

The maximum allowed hysteresis.

HYSTERESIS_MIN_TEMP = 0.0

The minimum required hysteresis.

aio_remeha_modbus.api.const.MAXIMUM_NORMAL_SURFACE_IRRADIANCE_NL: Final[int] = 1000

The maximum normal surface irradiance in The Netherlands, in W/m²

class aio_remeha_modbus.api.const.MetaRegisters

Bases: object

Register mappings for meta data.

ACTUAL_PRODUCED_POWER: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=460, name='varApActualProducerPower', data_type=<DataType.UINT32: 'uint32'>, scale=0.01, count=2, friendly_name=None)
APPLIANCE_STATUS_1: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=279, name='applilanceStatus1', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
APPLIANCE_STATUS_2: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=280, name='applilanceStatus2', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
BACKUP1_HOURS: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=425, name='varApBackup1Hours', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
BACKUP1_STARTS: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=423, name='varApBackup1Starts', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
BACKUP2_HOURS: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=429, name='varApBackup2Hours', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
BACKUP2_STARTS: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=427, name='varApBackup2Starts', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
BACKUP_ENERGY_CONSUMPTION: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=441, name='varApBackupEnergyConsumption', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
BACKUP_ENERGY_DELIVERY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=451, name='varApBackupEnergyDelivery', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
CH_ENABLED: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=500, name='parApChEnabled', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='AP016')
CH_ENERGY_CONSUMPTION: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=433, name='varApChEnergyConsumption', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
CH_ENERGY_DELIVERY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=445, name='varApChEnergyDelivery', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
COOLING_ENABLED: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=502, name='parApCoolingEnabled', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='AP028')
COOLING_ENERGY_CONSUMPTION: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=437, name='varApCoolingEnergyConsumption', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
COOLING_ENERGY_DELIVERY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=449, name='varApCoolingEnergyDelivery', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
COOLING_FORCED: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=503, name='parApCoolingForced', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='AP015')
CURRENT_ERROR: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=277, name='applianceCurrentError', data_type=<DataType.UINT16: 'uint16'>, scale=None, count=1, friendly_name=None)
DHW_ENERGY_CONSUMPTION: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=435, name='varApDhwEnergyConsumption', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
DHW_ENERGY_DELIVERY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=447, name='varApDhwEnergyDelivery', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
ERROR_PRIORITY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=278, name='applianceErrorPriority', data_type=<DataType.INT16: 'int16'>, scale=None, count=1, friendly_name=None)
FLOW_METER: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=410, name='varApFlowmeter', data_type=<DataType.UINT16: 'uint16'>, scale=0.01, count=1, friendly_name=None)
FLOW_TEMPERATURE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=400, name='varApTFlow', data_type=<DataType.INT16: 'int16'>, scale=0.01, count=1, friendly_name=None)
FORCE_SUMMER: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=389, name='parApForceSummer', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='AP074')

Whether forced summer mode is active. Heating is switched off, DHW stays active.

GENERATOR_HOURS_TOTAL: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=421, name='varApGeneratorHoursTotal', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
GENERATOR_STARTS_TOTAL: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=419, name='varApGeneratorStartsTotal', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
HEAT_PUMP_FLOW_TEMPERATURE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=403, name='varHpHeatPumpTF', data_type=<DataType.INT16: 'int16'>, scale=0.01, count=1, friendly_name=None)
HEAT_PUMP_RETURN_TEMPERATURE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=404, name='varHpHeatPumpTR', data_type=<DataType.INT16: 'int16'>, scale=0.01, count=1, friendly_name=None)
NEUTRAL_BAND_SUMMER_WINTER: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=387, name='parApNeutralBandSummerWinter', data_type=<DataType.UINT16: 'uint16'>, scale=0.01, count=1, friendly_name='AP075')

Temperature band below the summer/winter limit within which the appliance neither heats nor cools (transition season).

NUMBER_OF_DEVICES: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=128, name='numberOfDevices', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
NUMBER_OF_ZONES: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=189, name='NumberOfZones', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
OUTSIDE_TEMPERATURE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=384, name='varApTOutside', data_type=<DataType.INT16: 'int16'>, scale=0.01, count=1, friendly_name=None)
POWER_ACTUAL: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=413, name='varApPowerActual', data_type=<DataType.UINT16: 'uint16'>, scale=0.01, count=1, friendly_name=None)
POWER_ON_HOURS: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=431, name='varApPowerOnHours', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
PUMP_SPEED: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=459, name='varApPumpSpeed', data_type=<DataType.UINT16: 'uint16'>, scale=0.01, count=1, friendly_name=None)
RESET_DISCOVERY_TABLE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=200, name='Reset discovery table', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
RETURN_TEMPERATURE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=401, name='varApTReturn', data_type=<DataType.INT16: 'int16'>, scale=0.01, count=1, friendly_name=None)
SEASON_MODE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=385, name='varApSeasonMode', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
SILENT_MODE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=490, name='enabling_heat_pump_silent_mode', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='HP058')
SILENT_MODE_END_TIME: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=492, name='silent_mode_end_time', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='HP095')
SILENT_MODE_START_TIME: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=491, name='silent_mode_start_time', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='HP094')
STATUS: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=411, name='varApStatus', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
SUBSTATUS: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=412, name='varApSubStatus', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
SUMMER_WINTER: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=386, name='varApSummerWinter', data_type=<DataType.UINT16: 'uint16'>, scale=0.01, count=1, friendly_name='AP073')

Upper limit for heating.

Factory default is 22°C. Above this temperature, the appliance won’t heat anymore. Setting it to 30.5°C will disable it and cause the appliance to stay in winter mode.

TOTAL_ENERGY_CONSUMPTION: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=439, name='varApTotalEnergyConsumption', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
TOTAL_ENERGY_DELIVERY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=443, name='varApTotalEnergyDelivery', data_type=<DataType.UINT32: 'uint32'>, scale=None, count=2, friendly_name=None)
WATER_PRESSURE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=409, name='varApWaterPressure', data_type=<DataType.UINT8: 'uint8'>, scale=0.1, count=1, friendly_name=None)
class aio_remeha_modbus.api.const.ModbusVariableDescription(start_address: ModbusVariableRef, name: str, data_type: DataType, scale: float | None = None, count: int | None = None, friendly_name: str | None = None)

Bases: object

Modbus register description.

start_address

The register index as specified in the GTW-08 parameter list.

Type:

ModbusRegisterRef

name

The name as shown in the ‘Data’ field in the GTW-08 parameter list.

Type:

str

data_type

The data type of the variable.

Type:

DataType

scale

Multiply the ‘raw’ variable value by this.

Type:

float

count

The amount of registers to read/write. Required, and calculated for all types except DataType.STRING.

Type:

int

friendly_name

The optional parameter name as shown in the Remeha installation manual of the appliance.

Type:

str | None

count: int | None = None
data_type: DataType
ensure_mandatory_fields() Self

Ensure the fields count and struct_format have a value when they are required.

Additionally, if count has no value, it is calculated for data types other than DataType.STRING.

  • count is required if data_type == DataType.STRING

  • scale must be None if data_type == DataType.TUPLE16

friendly_name: str | None = None
name: str
scale: float | None = None
start_address: ModbusVariableRef
type aio_remeha_modbus.api.const.ModbusVariableRef = int
class aio_remeha_modbus.api.const.PVSystem(nominal_power: Final[int], orientation: Final[PVSystemOrientation], tilt: Final[float | None], annual_efficiency_decrease: Final[float | None], installation_date: Final[date | None])

Bases: object

Parameters that describe a PV system.

annual_efficiency_decrease: Final[float | None]

The annual decrease of efficiency, in percent.

installation_date: Final[date | None]

The installation date

nominal_power: Final[int]

The total Wp of the system.

orientation: Final[PVSystemOrientation]

The direction the PV system faces.

tilt: Final[float | None]

The tilt of the PV system, in degrees.

class aio_remeha_modbus.api.const.PVSystemOrientation(*values)

Bases: StrEnum

Describe the PV system orientations.

EAST = 'E'
EAST_NORTH_EAST = 'ENE'
EAST_SOUTH_EAST = 'ESE'
EAST_WEST = 'EW'

East/West evenly distributes total PV power over east and west.

NORTH = 'N'
NORTH_EAST = 'NE'
NORTH_NORTH_EAST = 'NNE'
NORTH_NORTH_WEST = 'NNW'
NORTH_WEST = 'NW'
SOUTH = 'S'
SOUTH_EAST = 'SE'
SOUTH_SOUTH_EAST = 'SSE'
SOUTH_SOUTH_WEST = 'SSW'
SOUTH_WEST = 'SW'
WEST = 'W'
WEST_NORTH_WEST = 'WNW'
WEST_SOUTH_WEST = 'WSW'
aio_remeha_modbus.api.const.PV_MAX_TILT_DEGREES: Final[int] = 90

The maximum supported PV system tilt

aio_remeha_modbus.api.const.PV_MIN_TILT_DEGREES: Final[int] = 10

The minimum supported PV system tilt

class aio_remeha_modbus.api.const.UnitOfTemperature(*values)

Bases: StrEnum

Temperature units.

CELSIUS = '°C'
FAHRENHEIT = '°F'
KELVIN = 'K'
aio_remeha_modbus.api.const.WATER_SPECIFIC_HEAT_CAPACITY_KJ: Final[float] = 4.18

The amount of energy required to warm 1 kilogram of water by one degree K

class aio_remeha_modbus.api.const.Weekday(*values)

Bases: Enum

Enumeration for days of the week.

FRIDAY = 4
MONDAY = 0
SATURDAY = 5
SUNDAY = 6
THURSDAY = 3
TUESDAY = 1
WEDNESDAY = 2
class aio_remeha_modbus.api.const.ZoneRegisters

Bases: object

The register mappings for a climate zone.

CURRENT_HEATING_MODE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=1109, name='varZoneCurrentHeatingMode', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='CM200')
CURRENT_ROOM_TEMPERATURE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=1104, name='varZoneTRoom', data_type=<DataType.INT16: 'int16'>, scale=0.1, count=1, friendly_name='CM030')
DHW_CALORIFIER_HYSTERESIS: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=686, name='parZoneDhwCalorifierHysterisis', data_type=<DataType.UINT16: 'uint16'>, scale=0.01, count=1, friendly_name='CP420')
DHW_COMFORT_SETPOINT: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=665, name='parZoneDhwComfortSetpoint', data_type=<DataType.UINT16: 'uint16'>, scale=0.01, count=1, friendly_name='CP350')
DHW_REDUCED_SETPOINT: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=666, name='parZoneDhwReducedSetpoint', data_type=<DataType.UINT16: 'uint16'>, scale=0.01, count=1, friendly_name='CP360')
DHW_TANK_TEMPERATURE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=1119, name='varDhwTankTemperature', data_type=<DataType.INT16: 'int16'>, scale=0.01, count=1, friendly_name='CM040')
END_TIME_MODE_CHANGE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=978, name='parZoneEndTimeModeChange', data_type=<DataType.CIA_301_TIME_OF_DAY: 'cia301_time_of_day'>, scale=None, count=3, friendly_name=None)
FUNCTION: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=641, name='parZoneFunction', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='CP020')
MODE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=649, name='parZoneMode', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='CP320')
OWNING_DEVICE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=646, name='instance', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)
PUMP_RUNNING: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=1110, name='varZonePumpRunning', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='CM050')
ROOM_COOLING_SETPOINT_1: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=656, name='parZoneRoomCoolingSetpoint1', data_type=<DataType.UINT16: 'uint16'>, scale=0.1, count=1, friendly_name='CP140')
ROOM_COOLING_SETPOINT_2: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=657, name='parZoneRoomCoolingSetpoint2', data_type=<DataType.UINT16: 'uint16'>, scale=0.1, count=1, friendly_name='CP141')
ROOM_COOLING_SETPOINT_3: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=658, name='parZoneRoomCoolingSetpoint3', data_type=<DataType.UINT16: 'uint16'>, scale=0.1, count=1, friendly_name='CP142')
ROOM_COOLING_SETPOINT_4: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=659, name='parZoneRoomCoolingSetpoint4', data_type=<DataType.UINT16: 'uint16'>, scale=0.1, count=1, friendly_name='CP143')
ROOM_COOLING_SETPOINT_5: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=660, name='parZoneRoomCoolingSetpoint5', data_type=<DataType.UINT16: 'uint16'>, scale=0.1, count=1, friendly_name='CP144')
ROOM_MANUAL_SETPOINT: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=664, name='parZoneRoomManualSetpoint', data_type=<DataType.UINT16: 'uint16'>, scale=0.1, count=1, friendly_name='CP200')
SELECTED_TIME_PROGRAM: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=688, name='parZoneTimeProgramSelected', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name='CP570')
SHORT_NAME: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=642, name='parZoneFriendlyNameShort', data_type=<DataType.STRING: 'string'>, scale=None, count=3, friendly_name=None)
TEMPORARY_SETPOINT: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=663, name='parZoneTemporaryRoomSetpoint', data_type=<DataType.UINT16: 'uint16'>, scale=0.1, count=1, friendly_name='CP510')
TIME_PROGRAM_FRIDAY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=729, name='parZoneTimeProgramFriday', data_type=<DataType.ZONE_TIME_PROGRAM: 'zone_time_program'>, scale=None, count=10, friendly_name=None)
TIME_PROGRAM_MONDAY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=689, name='parZoneTimeProgramMonday', data_type=<DataType.ZONE_TIME_PROGRAM: 'zone_time_program'>, scale=None, count=10, friendly_name=None)
TIME_PROGRAM_SATURDAY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=739, name='parZoneTimeProgramSaturday', data_type=<DataType.ZONE_TIME_PROGRAM: 'zone_time_program'>, scale=None, count=10, friendly_name=None)
TIME_PROGRAM_SUNDAY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=749, name='parZoneTimeProgramSunday', data_type=<DataType.ZONE_TIME_PROGRAM: 'zone_time_program'>, scale=None, count=10, friendly_name=None)
TIME_PROGRAM_THURSDAY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=719, name='parZoneTimeProgramThursday', data_type=<DataType.ZONE_TIME_PROGRAM: 'zone_time_program'>, scale=None, count=10, friendly_name=None)
TIME_PROGRAM_TUESDAY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=699, name='parZoneTimeProgramTuesday', data_type=<DataType.ZONE_TIME_PROGRAM: 'zone_time_program'>, scale=None, count=10, friendly_name=None)
TIME_PROGRAM_WEDNESDAY: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=709, name='parZoneTimeProgramWednesday', data_type=<DataType.ZONE_TIME_PROGRAM: 'zone_time_program'>, scale=None, count=10, friendly_name=None)
TYPE: Final[ModbusVariableDescription] = ModbusVariableDescription(start_address=640, name='varZoneType', data_type=<DataType.UINT8: 'uint8'>, scale=None, count=1, friendly_name=None)

aio_remeha_modbus.api.errors module

Remeha Modbus API exceptions.

exception aio_remeha_modbus.api.errors.AutoSchedulingError(translation_key: str, translation_placeholders: Placeholders = {})

Bases: RemehaApiError

Exception to indicate an error occurred while auto scheduling.

exception aio_remeha_modbus.api.errors.DiscoveryTableCorruptedError(translation_key: str, translation_placeholders: Placeholders = {})

Bases: RemehaModbusError

Exception to indicate the modbus discovery table seems corrupted.

This happens for example if the number of devices is 0 or None. This can be fixed by calling the force_system_rediscovery service.

exception aio_remeha_modbus.api.errors.InvalidZoneSchedule(*args: object, zone: int, schedule_id: ClimateZoneScheduleId, is_dhw: bool)

Bases: RemehaApiError

API exception to indicate that an invalid zone schedule was read from modbus.

This exception is raised when the encoded zone schedule bytes are read from modbus successfully, but parsing them into a ZoneSchedule failed.

property is_dhw: bool

Whether the related climate zone is a DHW zone.

property schedule_id: ClimateZoneScheduleId

The name of the schedule that was attempted to read.

property zone: int

The index of the zone that was attempted to read.

type aio_remeha_modbus.api.errors.Placeholders = dict[str, str | int | bool | Enum | Placeholders]

Type declaration for placeholders in a translateable error.

exception aio_remeha_modbus.api.errors.RemehaApiError(translation_key: str, translation_placeholders: Placeholders = {})

Bases: Exception

Base class for Remeha Modbus API exceptions.

translation_key: str

The key used to look up translations of this error.

translation_placeholders: Placeholders

Placeholders for values within the error message.

exception aio_remeha_modbus.api.errors.RemehaModbusError(translation_key: str, translation_placeholders: Placeholders = {})

Bases: RemehaApiError

Base class for translateable modbus exceptions.

aio_remeha_modbus.api.schedule module

Implementation of time programs in the Remeha Modbus device.

class aio_remeha_modbus.api.schedule.HourlyForecast(start_time: datetime, temperature: float, solar_irradiance: int | None)

Bases: object

An hourly weather forecast entry.

classmethod from_dict(data: dict[str, Any]) Self

Create a new HourlyForecast based on a dict containing weather forecast attributes.

solar_irradiance: int | None

The global horizontal irradiance, in W/m2.

start_time: datetime

The start time of the forecast.

temperature: float

The temperature in temperature_unit.

At temperatures above 25 °C, the PV panel efficiency decreases with 4 percent every 10 degrees.

class aio_remeha_modbus.api.schedule.Timeslot(setpoint_type: TimeslotSetpointType, activity: TimeslotActivity, switch_time: time)

Bases: object

A zone schedule time slot.

activity: TimeslotActivity

The type of activity for this time slot.

classmethod decode(encoded_time_slot: bytes) Self

Decode a bytes object intoa a Timeslot.

Parameters:

encoded_time_slot (bytes) – The encoded time slot. Must be 3 bytes.

Raises:

ValueError – If encoded_time_slot is not exactly 3 bytes.

encode() bytes

Encode this time slot into a bytes object.

setpoint_type: TimeslotSetpointType

The type of setpoint for this time slot.

switch_time: time

The start time of this time slot.

class aio_remeha_modbus.api.schedule.TimeslotActivity(*values)

Bases: Enum

The type of activity that must run during the containing TimeSlot.

DHW = 0
HEAT_COOL = 200
class aio_remeha_modbus.api.schedule.TimeslotSetpointType(*values)

Bases: Enum

The setpoint that must be reached during the containing TimeSlot.

The names used here are the default names as shown in the Remeha Home app. In the app, these names can be changed.

AWAY = 32

Setpoint in ‘away’ mode.

COMFORT = 16

Comfort setpoint. For TimeslotActivity.HEAT_COOL this is named ‘At home’ in the Remeha Home app.

ECO = 0

Reduced setpoint. For TimeslotActivity.HEAT_COOL this is named ‘Sleeping’ in the Remeha Home app.

EVENING = 64

Setpoint in ‘evening’ mode.

MORNING = 48

Setpoint in ‘morning’ mode.

class aio_remeha_modbus.api.schedule.WeatherForecast(unit_of_temperature: UnitOfTemperature, forecasts: list[HourlyForecast])

Bases: object

A forecasted weather condition containing the necessary attributes to calculate a schedule.

forecasts: list[HourlyForecast]

A list containing the hourly forecasts for the next 24 hours.

unit_of_temperature: UnitOfTemperature

The unit of temperature used in the forecast entries.

class aio_remeha_modbus.api.schedule.ZoneSchedule(id: ClimateZoneScheduleId, zone_id: int, day: Weekday, time_slots: list[Timeslot])

Bases: object

Implementation of the Remeha Modbus scheduling format.

The GTW-08 parameter list shows that a user can choose from 3 distinct heating schedules for a given zone. For cooling, one schedule can be used. All schedules are divided in 7 time programs, one for each weekday.

### Time program encoding A time program is encoded in a binary string, and is 20 bytes (10 registers) in size. It is encoded as follows:

Byte index | Contents | Data type |

|:-----------:|:—————————-|:----------| | 0 | Number of switches (max 6) | UINT8 | | 1 | Temperature 1 | UINT16 | | 3 | Switch time 1 | UINT8 | | 4 | Temperature 2 | UINT16 | | 6 | Switch time 2 | UINT8 | | … | … | … | | 16 | Temperature 6 | UINT16 | | 18 | Switch time 6 | UINT8 |

#### Temperature encoding The switch temperature is encoded into activities (heat/cool, dhw, dhw primary). The setpoints of these activities are defined elsewhere. The activities are defined as follows:

Name | MSB | LSB |

|:----------|:——-:|------------------------:| | At home | 0x10 | 0xc8 (heat/cool) | | Morning | 0x30 | 0xc8 (heat/cool) | | Away | 0x20 | 0xc8 (heat/cool) | | Evening | 0x40 | 0xc8 (heat/cool) | | Sleeping | 0x00 | 0xc8 (heat/cool) | | Eco | 0x00 | 0x00 (DHW primary) | | Comfort | 0x10 | 0x00 (DHW primary) |

#### Switch time encoding The switch time is encoded as a number, indicating the amount of 10-minute steps from 00:00 local time. This means that a value of 10 stands for 01:40AM.

classmethod create_default(id: ClimateZoneScheduleId, zone_id: int, day: Weekday, is_dhw: bool) Self

Create a default ZoneSchedule.

A default schedule puts the zone in ECO mode for that given day. Default schedules are used to repair an issue where the zone schedule cannot be parsed although it has been selected. This can mean that there are missing options in our implementation or that the data has been corrupted in transit or on the GTW-08.

Parameters:
  • id (ClimateZoneScheduleId) – The schedule id.

  • zone_id (int) – The one-based id of the ClimateZone containing the schedule.

  • day (Weekday) – The day of the week this schedule is active in.

  • is_dhw (bool) – Whether this schedule is for a DHW zone.

Returns:

The zone schedule.

day: Weekday

The weekday of this program

classmethod decode(id: ClimateZoneScheduleId, zone_id: int, day: Weekday, encoded_schedule: bytes) Self

Decode a bytes object containing the schedule into a ZoneSchedule.

Parameters:
  • id (int) – The one-based id of the schedule.

  • zone_id (int) – The one-based id of the ClimateZone containing the schedule.

  • day (Weekday) – The day of the week this schedule is active in.

  • encoded_schedule (bytes) – The binary data containing the encoded schedule. Must be exactly 20 bytes.

Raises:

ValueError

encode() bytes

Encode this ZoneSchedule into bytes.

Note The resulting bytes do not encode id, zone_id and day. These attributes are used to find the correct modbus register to put the schedule in.

classmethod generate(weather_forecast: WeatherForecast, pv_system: PVSystem, boiler_config: BoilerConfiguration, boiler_zone: ClimateZone, appliance_seasonal_mode: SeasonalMode | None, schedule_id: ClimateZoneScheduleId) Self

Generate a ZoneSchedule for the next day, based on the weather forecast.

Parameters:
Returns:

The generated ZoneSchedule.

id: ClimateZoneScheduleId

The one-based id of the time program.

time_slots: list[Timeslot]

The defined time slots for this schedule.

zone_id: int

The one-based id of the containing zone.

aio_remeha_modbus.api.schedule.get_current_timeslot(schedule: dict[Weekday, ZoneSchedule | None] | None, time_zone: tzinfo | None) Timeslot | None

Retrieve the current schedule time slot.

Parameters:
  • schedule (dict[Weekday, ZoneSchedule]) – The selected schedule

  • time_zone (datetime.tzinfo) – The appliance time zone

Returns:

The current schedule time slot, or None if schedule is None.

aio_remeha_modbus.api.schedule.is_cooling_schedule(schedule: dict[Weekday, ZoneSchedule | None], time_zone: tzinfo | None) bool

Return whether the given schedule is a cooling schedule.

Parameters:
  • schedule – The weekly schedule to test.

  • time_zone (datetime.tzinfo) – The appliance time zone

Returns:

True if the schedule for the current day is a cooling schedule, False otherwise.

Module contents

Package containing all Remeha Modbus API classes.

class aio_remeha_modbus.api.DeviceBoardCategory(type: DeviceBoardType, generation: int)

Bases: object

The category of the device located on the appliance.

generation: int

The category generation

type: DeviceBoardType

The device type

class aio_remeha_modbus.api.DeviceBoardType(*values)

Bases: Enum

Defines the type of device located on the device instance.

CU_GH = 0

Motherboard for central heating boilers like Tzerra Ace

CU_OH = 1

Motherboard for condensing oil boilers like Calora Tower Oil LS

EEC = 27

Motherboard for gas boilers like GAS 120 Ace

EHC = 2

Motherboard for (hybrid) heat pumps like Mercuria Ace

EHC_ALT = 33

Unknown/alternate heatpump mainboard (seen on Confida)

GATEWAY = 30

A gateway, for example GTW-08 (modbus gateway)

MK = 20

Appliance control panel like eTwist

SCB = 25

Circuit control board

is_mainboard() bool

Return whether this value represents a mainboard, a.k.a. the main device.

class aio_remeha_modbus.api.DeviceInstance(id: int, board_category: DeviceBoardCategory, sw_version: tuple[int, int], hw_version: tuple[int, int], article_number: int)

Bases: object

A device (electronic board) somewhere on the Remeha appliance.

article_number: int

The article number of the device

board_category: DeviceBoardCategory

The board category on this instance.

hw_version: tuple[int, int]

The hardware version as (major,minor)

id: int

The device sequence id.

is_mainboard() bool

Return whether this device is a mainboard.

sw_version: tuple[int, int]

The software version as (major,minor)

class aio_remeha_modbus.api.RemehaApi(name: str, connection_type: ConnectionType, client: ModbusBaseClient, device_address: int = 1, time_zone: tzinfo | None = None)

Bases: object

Use instances of this class to interact with the Remeha device through Modbus.

async async_close() None

Close the connection to the configured modbus device.

async async_connect() bool

Connect to the configured modbus device.

async async_health_check() None

Attempt to check the system health by reading a single register (128 - numberOfDevices).

Raises:

RemehaModbusError – If the health check failed.

property async_is_connected: bool

Return whether we’re connected to the modbus device.

async async_read_appliance() Appliance

Read the appliance status registers.

Returns:

The appliance with its status fields.

Return type:

Appliance

Raises:
  • RemehaModbusError – If the appliance status fields cannot be obtained.

  • ValueError – If the retrieved modbus data cannot be successfully deserialized.

async async_read_device_instance(id: int) DeviceInstance

Read a single device instance from the modbus interface.

This reads the registers as described in the table below. Only the base zone registers are mentioned here; add 6 * id to get the discrete register number of the zone. For details, refer to the Remeha GTW-08 parameter list.

Base address | Variable name | Description | Modbus type | HA type |

|---------------|——————————-|-------------------------------------------------------|—————|---------------------------| | 129 | DeviceTypeBoard | Type of the device located on the instance. | UINT16 | DeviceBoardCategory | | 130 | sw_version | Software version (ex. 0x2001 = SW02.01) | UINT16 | tuple[int, int] | | 132 | hw_version | Hardware version (ex. 0x2001 = HW02.01) | UINT16 | tuple[int, int] | | 133 | ArticleNumber | Article number of the device located on the instance. | UINT32 | int |

Parameters:

id (int) – The one-based instance id.

Returns:

The requested device instance

Return type:

DeviceInst4ance

Raises:
  • RemehaModbusError – If the instance registers cannot be read.

  • ValueException – If deserializing the registers to a DeviceInstance fails.

async async_read_device_instances() list[DeviceInstance]

Retrieve the available devices instances of the Remeha appliance.

Returns:

A list of all discovered device instances.

Return type:

list[DeviceInstance]

Raises:

RemehaModbusError – If the list of device instances cannot be obtained.

async async_read_number_of_device_instances() int

Retrieve the number of available device instances in the appliance.

Returns:

The number of instances.

Return type:

int

Raises:
  • RemehaModbusError – If the number of instances cannot be obtained.

  • ValueError – If the retrieved modbus data cannot be deserialized successfully.

async async_read_number_of_zones() int | None

Retrieve the number of zones defined in the appliance.

Returns

int | None: The number of zones, or None if the modbus address is empty.

Raises

RemehaModbusError: If the number of zones cannot be obtained. ValueError: If the retrieved modbus data cannot be deserialized successfully.

async async_read_registers(start_register: int, register_count: int = 1, struct_format: str | bytes = '=H') tuple[Any, ...]

Read registers from the modbus interface for debugging purposes.

Parameters:
  • start_register (int) – The register to start reading at.

  • register_count (int) – The amount of registers to read.

  • struct_format (str | bytes) – The struct format to convert the register bytes to.

Returns:

A tuple containing values unpacked according to the format string.

Raises:
  • RemehaModbusError – if a modbus error occurred while reading the registers.

  • struct.error – if struct_format is an illegal struct format.

async async_read_sensor_values(descriptions: list[ModbusVariableDescription]) dict[ModbusVariableDescription, Any]

Read the values of the given list of variable descriptions.

Parameters:

descriptions (list[ModbusVariableDescription]) – The list of modbus variables to retrieve.

Returns:

A mapping from modbus variables to their values.

Return type:

dict[ModbusVariableDescription, Any]

async async_read_zone(id: int, appliance: Appliance) ClimateZone | None

Read a single climate zone from the modbus interface.

This reads the registers as described in the table below. Only the base zone registers are mentioned here; add 512 * id to get the discrete register number of the zone. For details, refer to the Remeha GTW-08 parameter list.

Base address | Variable name | Description | Modbus type | HA type |

|---------------|———————————–|-------------------------------------------------------|—————|---------------------------| | 640 | varZoneType | Zone type. | ENUM8 | ClimateZoneType | | 641 | parZoneFunction | Zone function. | ENUM8 | ClimateZoneFunction | | 642 | parZoneFriendlyNameShort | Zone short name. | STRING | str | | 646 | instance | Device instance owning the zone. | UINT8 | int | | 649 | parZoneMode | Mode zone working. | ENUM8 | ClimateZoneMode | | 656 | parZoneCoolingSetpoint1 | Zone cooling setpoint in ECO mode. | UINT16 | float | | 657 | parZoneCoolingSetpoint2 | Zone cooling setpoint in COMFORT mode. | UINT16 | float | | 658 | parZoneCoolingSetpoint3 | Zone cooling setpoint in AWAY mode. | UINT16 | float | | 659 | parZoneCoolingSetpoint4 | Zone cooling setpoint in MORNING mode. | UINT16 | float | | 660 | parZoneCoolingSetpoint5 | Zone cooling setpoint in EVENING mode. | UINT16 | float | | 664 | parZoneRoomManualSetpoint | Manually set wished room temperature of the zone. | UINT16 | float | | 665 | parZoneDhwComfortSetpoint | Wished comfort domestic hot water temperature. | UINT16 | float | | 666 | parZoneDhwReducedSetpoint | Wished reduced domestic hot water temperature. | UINT16 | float | | 686 | parZoneDhwCalorifierHysteresis | Hysteresis to start DHW tank load | UINT16 | float | | 688 | parZoneTimeProgramSelected | Time program selected by the user. | ENUM8 | ClimateZoneScheduleId | | 1104 | varZoneTRoom | Current room temperature for zone. | INT16 | float | | 1109 | varZoneCurrentHeatingMode | Current mode the zone is functioning in. | ENUM8 | ClimateZoneHeatingMode | | 1110 | varZonePumpRunning | Whether the zone pump is ruinning. | ENUM8 | bool | | 1119 | varDhwTankTemperature | Tank temperature DHW tank (bottom or single sensor) | INT16 | float |

Parameters:
  • id (int) – The one-based zone id.

  • appliance (Appliance) – The appliance to which the zone belongs.

Returns:

The requested zone, or None if zone.type == ClimateZoneType.NOT_PRESENT.

Return type:

ClimateZone

Raises:
  • InvalidZoneSchedule – If the zone is in scheduling mode and parsing the schedule fails.

  • RemehaModbusError – If the zone registers cannot be read.

  • ValueError – If deserializing the registers to a ClimateZone fails.

async async_read_zone_schedule(zone: ClimateZone | int, schedule_id: ClimateZoneScheduleId, day: Weekday) ZoneSchedule | None

Read a single climate zone schedule from the modbus interface.

Parameters:
  • zone (ClimateZone | int) – The ClimateZone or its one-based id the time program is for.

  • schedule_id (ClimateZoneScheduleId) – The id of the schedule to read.

  • day (Weekday) – The weekday of the requested schedule.

Returns:

The requested zone schedule, or None if it has not been configured.

Return type:

ZoneSchedule

Raises:
  • RemehaModbusError – If the required registers cannot be read.

  • ValueError – If deserializing the registers to a ZoneSchedule fails.

async async_read_zone_update(zone: ClimateZone, appliance: Appliance) ClimateZone

Retrieve updates for a single ClimateZone.

In attempt to reduce the amount of calls over the network, this only reads updatable fields from modbus and merges zone with the updates in a new returned ClimateZone. Only the base zone registers are mentioned here; add 512 * id to get the discrete register number of the zone. For details, refer to the Remeha GTW-08 parameter list.

Base address | Variable name | Description | Modbus type | HA type |

|---------------|———————————–|-------------------------------------------------------|—————|---------------------------| | 649 | parZoneMode | Mode zone working. | ENUM8 | ClimateZoneMode | | 656 | parZoneCoolingSetpoint1 | Zone cooling setpoint in ECO mode. | UINT16 | float | | 657 | parZoneCoolingSetpoint2 | Zone cooling setpoint in COMFORT mode. | UINT16 | float | | 658 | parZoneCoolingSetpoint3 | Zone cooling setpoint in AWAY mode. | UINT16 | float | | 659 | parZoneCoolingSetpoint4 | Zone cooling setpoint in MORNING mode. | UINT16 | float | | 660 | parZoneCoolingSetpoint5 | Zone cooling setpoint in EVENING mode. | UINT16 | float | | 664 | parZoneRoomManualSetpoint | Manually set wished room temperature of the zone. | UINT16 | float | | 665 | parZoneDhwComfortSetpoint | Wished comfort domestic hot water temperature. | UINT16 | float | | 666 | parZoneDhwReducedSetpoint | Wished reduced domestic hot water temperature. | UINT16 | float | | 686 | parZoneDhwCalorifierHysteresis | Hysteresis to start DHW tank load | `UINT16 | float | | 688 | parZoneTimeProgramSelected | Time program selected by the user. | ENUM8 | ClimateZoneScheduleId | | 1104 | varZoneTRoom | Current room temperature for zone. | INT16 | float | | 1109 | varZoneCurrentHeatingMode | Current mode the zone is functioning in. | ENUM8 | ClimateZoneHeatingMode | | 1110 | varZonePumpRunning | Whether the zone pump is ruinning. | ENUM8 | bool | | 1119 | varDhwTankTemperature | Tank temperature DHW tank (bottom or single sensor) | INT16 | float |

Parameters:
  • zone (ClimateZone) – The zone to update.

  • appliance (Appliance) – The appliance to which this zone belongs.

Returns:

The updated zone.

Return type:

ClimateZone

Raises:
  • InvalidZoneSchedule – If the zone is in scheduling mode and parsing the schedule fails.

  • RemehaModbusError – If the zone update registers cannot be read.

  • ValueError – If deserializing any register fails.

async async_read_zones(appliance: Appliance) list[ClimateZone]

Retrieve the available zones of the modbus device.

This method returns the all zones having a supported ClimateZoneFunction. Whether a zone function is supported can be queried using ClimateZoneFunction.is_supported()

Parameters:

appliance (Appliance) – The appliance to which the zones belong.

Returns:

A list of all discovered zones.

Return type:

list[ClimateZone]

Raises:
  • DiscoveryTableCorruptedError – If the modbus discovery table has been corrupted.

  • InvalidZoneSchedule – If the climate zone is in scheduling mode but reading the schedule fails.

  • RemehaModbusError – If the list of zones cannot be obtained.

  • ValueError – If the retrieved modbus data cannot be successfully deserialized.

async async_write_variable(variable: ModbusVariableDescription, value: str | float | bool | tuple[int, int] | datetime | Enum | ZoneSchedule | None, offset: int = 0) None

Write a single variable to the modbus device.

### Notes:
  • If value is a tuple, the whole tuple must fit in a single register, contain exactly two elements that are both treated as unsigned bytes.

    Therefore the individual values cannot exceed 2^8.

  • Values of type datatype are only allowed when variable.data_type == DataType.CIA_301_TIME_OF_DAY.

Parameters:
  • variable (ModbusVariableDescription) – The description of the variable to write.

  • value (str|float|bool|tuple[int,int]|datetime|Enum|ZoneSchedule|None) – The value to write. If None, the GTW-08 NULL value is written instead.

  • offset (int) – The offset in registers of variable.start_address. Used for zone-, device and schedule objects.

Raises:
  • RemehaModbusError – If the connection to the modbus device is lost or if the write request fails.

  • ValueError

    • If no conversion path exists between variable.data_type and value * If conversion to a numeric type fails. * If value is a tuple which does not contain exactly two elements. * If value is a datetime but variable.data_type is not DataType.CIA_301_TIME_OF_DAY.

property connection_type: ConnectionType

Return the modbus connection type.

classmethod create(name: str, config: Configuration, time_zone: tzinfo | None = None) Self

Create a new RemehaApi instance.

Parameters:
  • name (str) – The name of the modbus hub name.

  • config (Configuration) – A typed dict containing the configuration.

  • time_zone (tzinfo|None) – The time zone of the Remeha appliance. If None, local system time is used.

get_device_register_offset(device: DeviceInstance | int) int

Get the offset in registers for the given DeviceInfo | int.

get_schedule_register_offset(schedule: ClimateZoneScheduleId | int) int

Get the offset in registers for the given `ClimateZoneScheduleId | int.

get_zone_register_offset(zone: ClimateZone | int) int

Get the offset in registers for the given ClimateZone | int.

property name: str

Return the modbus hub name.

class aio_remeha_modbus.api.SerialConnectionMethod(*values)

Bases: StrEnum

Defines the serial connection method.

ASCII = 'ascii'

ASCII data transmission preceded by slave id and followed by a crc. Used for new devices.

RTU = 'rtu'

Binary data transmission preceded by slave it and followed by a crc. Standard.