Initial commit

This commit is contained in:
Constantin Pascal
2026-01-21 16:51:02 +02:00
commit d1f068e7fc
15 changed files with 1673 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
# RDZ HMI Control - Home Assistant Integration
A custom Home Assistant integration for controlling RDZ HMI thermostats via Modbus TCP.
## Overview
This integration connects to RDZ HMI HVAC control systems over Modbus TCP and exposes thermostats as Home Assistant climate entities. The system supports up to 64 zones with separate heating (winter) and cooling (summer) setpoints.
## Key Concepts
### Season Mode (Global)
The system operates in one of two modes controlled by a global season switch:
- **Winter Mode**: System is in heating mode, thermostats show heating action
- **Summer Mode**: System is in cooling mode, thermostats show cooling action
The season switch controls Modbus coil 2 and affects all thermostats globally. Individual thermostats cannot override the season - their HVAC mode/action is derived from this switch.
### Thermostat Types
Zones can be configured as one of three types:
1. **Real Thermostat** (`real`): Physical thermostat with temperature sensor
- Supports setting target temperature
- HVAC mode is read-only (derived from season switch)
- Can be linked to a virtual thermostat for setpoint syncing
2. **Virtual Thermostat** (`virtual`): Software-controlled zone without physical thermostat
- Read-only (no direct control)
- Can be linked from a real thermostat to auto-sync setpoints
3. **Unconfigured** (`unconfigured`): Detected zone not yet configured
- Shows as OFF, no control available
### Setpoints
Each zone has two temperature setpoints stored in separate Modbus registers:
- **Winter Setpoint** (registers 300-363): Used when system is in heating mode
- **Summer Setpoint** (registers 364-427): Used when system is in cooling mode
When you change the target temperature, it writes to the appropriate setpoint based on the current season.
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ Home Assistant │
├─────────────────────────────────────────────────────────────┤
│ __init__.py Entry point, platform setup │
│ coordinator.py Data polling, setpoint syncing │
│ climate.py Climate entities (thermostats) │
│ switch.py Season switch entity │
│ sensor.py Setpoint diagnostic sensors │
│ modbus_client.py Async Modbus TCP communication │
│ config_flow.py UI configuration wizard │
│ const.py Constants and register addresses │
└─────────────────────────────────────────────────────────────┘
│
│ Modbus TCP (default port 8000)
▼
┌─────────────────┐
│ RDZ HMI │
│ Controller │
└─────────────────┘
```
## File Structure
| File | Purpose |
|------|---------|
| `__init__.py` | Integration setup, platform loading, lifecycle management |
| `coordinator.py` | `RDZDataUpdateCoordinator` - polls Modbus every 30s, syncs linked thermostats |
| `climate.py` | `RDZClimateEntity` - thermostat entities with season-based HVAC mode |
| `switch.py` | `RDZSeasonSwitch` - global summer/winter mode control |
| `sensor.py` | `RDZSetpointSensor` - diagnostic sensors showing both setpoints |
| `modbus_client.py` | `RDZModbusClient` - async Modbus TCP wrapper with connection management |
| `config_flow.py` | Configuration UI for adding/configuring the integration |
| `const.py` | Constants: register addresses, defaults, config keys |
## Modbus Register Map
| Register/Coil | Address | Description |
|---------------|---------|-------------|
| Coil 2 | 2 | Season (0=winter, 1=summer) |
| Registers 300-363 | 300 + zone_id | Winter setpoints (value * 10) |
| Registers 364-427 | 364 + zone_id | Summer setpoints (value * 10) |
| Registers 2700-2763 | 2700 + zone_id | Current temperatures (value * 10, read-only) |
| Registers 2892-2895 | 2892 + (zone_id / 16) | Zone activity bitmasks (16-bit, read-only) |
Temperature values are stored as integers with a scale factor of 10 (e.g., 21.5°C = 215).
### Zone Activity Bitmasks
Registers 2892-2895 contain 16-bit bitmasks indicating which zones are actively heating/cooling:
- **Register 2892**: Zones 0-15 (bit 0 = zone 0, bit 15 = zone 15)
- **Register 2893**: Zones 16-31 (bit 0 = zone 16, bit 15 = zone 31)
- **Register 2894**: Zones 32-47 (bit 0 = zone 32, bit 15 = zone 47)
- **Register 2895**: Zones 48-63 (bit 0 = zone 48, bit 15 = zone 63)
Bit = 1: Zone is actively heating/cooling
Bit = 0: Zone is idle
## Data Flow
### Reading Data (Coordinator)
1. Every 30 seconds, coordinator polls:
- All temperature registers (2700-2763)
- Winter setpoints (300-363)
- Summer setpoints (364-427)
- Season coil (2)
- Zone activity bitmasks (2892-2895)
2. Data stored in `coordinator.data` dictionary
3. Entities update via `_handle_coordinator_update()`
### Setting Temperature
1. User changes target temperature on climate entity
2. `async_set_temperature()` determines current season from coordinator data
3. Writes to winter (HEAT) or summer (COOL) setpoint register
4. If real thermostat is linked to virtual, coordinator syncs on next poll
### Changing Season
1. User toggles season switch
2. `async_turn_on()`/`async_turn_off()` writes to coil 2
3. All climate entities update their HVAC mode accordingly
### HVAC Action Detection
The HVAC action (heating/cooling/idle) is determined from the zone activity bitmasks:
For **real thermostats**:
- **HEATING**: The zone's bit is set (1) in the activity bitmask
- **COOLING**: The linked virtual zone's bit is set (1) in the activity bitmask
- **IDLE**: Neither this zone nor linked virtual zone is active
For **virtual/unconfigured thermostats**: Always shows OFF
## Entities Created
For each configured zone:
- 1x Climate entity (thermostat)
- 1x Winter setpoint sensor (diagnostic)
- 1x Summer setpoint sensor (diagnostic)
System-level:
- 1x Season switch
## Configuration
The integration is configured through the Home Assistant UI:
1. Add integration, enter Modbus host/port
2. Integration discovers active zones (non-zero temperature readings)
3. Configure each zone: name, type (real/virtual/unconfigured)
4. Optionally link real thermostats to virtual zones for setpoint syncing