Skip to content

Commit c0d9724

Browse files
committed
* Improved configuration routine to better support new connection methods
* Update README.md and translations
1 parent e79af41 commit c0d9724

File tree

6 files changed

+142
-25
lines changed

6 files changed

+142
-25
lines changed

README.md

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1-
# Systemair Modbus Integration for Home Assistant
1+
# Systemair Integration for Home Assistant
22

33
[![HACS Default](https://img.shields.io/badge/HACS-Default-blue.svg?style=for-the-badge)](https://github.com/hacs/integration)
44
[![GitHub Release](https://img.shields.io/github/v/release/AN3Orik/systemair?style=for-the-badge)](https://github.com/AN3Orik/systemair/releases)
55
[![GitHub License](https://img.shields.io/github/license/AN3Orik/systemair?style=for-the-badge)](https://github.com/AN3Orik/systemair/blob/main/LICENSE)
66
[![TIP](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=for-the-badge)](https://dalink.to/an3orik)
77

8-
This Home Assistant integration allows you to monitor and control **Systemair SAVE** ventilation units through your local network. It communicates directly with the **Systemair IAM ([Internet Access Module](https://www.systemair.com/en-gb/p/internet-access-module-iam-110534))** or any other ModBus TCP-RTU module via the Modbus TCP protocol.
8+
This Home Assistant integration allows you to monitor and control **Systemair SAVE** ventilation units through multiple connection methods. It supports communication via **Modbus TCP**, **Modbus Serial (RS485)**, and **Web API**, providing flexibility for different hardware configurations.
99

10-
This integration was tested with SAVE VSR 300 and VSR 500 models but should be compatible with other units that use the IAM module.
10+
This integration was tested with SAVE VSR 300 and VSR 500 models but should be compatible with other units that support Modbus protocol.
1111

1212
## Overview
1313

1414
[Systemair SAVE](https://www.systemair.com/en-gb/products/residential-ventilation-systems/air-handling-units/save) units are residential ventilation systems designed for heat recovery. This integration brings your ventilation unit into Home Assistant, allowing you to create advanced automations and gain deep insights into your home's air quality and energy consumption.
1515

1616
## Features
1717

18+
* **Multiple Connection Methods:** Support for three different connection types:
19+
* **Modbus TCP** - via Systemair SAVECONNECT 1.0 or compatible Modbus TCP modules
20+
* **Modbus Serial (RS485)** - via USB-to-Modbus converters
21+
* **Web API (HTTP)** - via Systemair SAVECONNECT 2.0 IAM module
1822
* **Climate Control:** Full control over HVAC modes (Off, Fan Only, Heat, Cool), target temperature, fan speed, and preset modes (Auto, Manual, Away, Holiday, etc.).
1923
* **Calculated Power Consumption:** Monitor the estimated power usage of the supply fan, extract fan, and the total power consumption of the unit, including the re-heater. Essential for energy tracking in Home Assistant's Energy Dashboard.
2024
* **Advanced Configuration Controls:** Directly configure key operational parameters from Home Assistant, including:
@@ -28,14 +32,29 @@ This integration was tested with SAVE VSR 300 and VSR 500 models but should be c
2832
* Current Defrosting State
2933
* **Sensor Monitoring:** Track key environmental data, including outdoor, supply, and extract air temperatures, as well as relative humidity.
3034
* **Device Status:** Monitor fan RPM, fan speed percentages, and heater output.
31-
* **Diagnostics:** Keep an eye on filter lifetime and view detailed alarm statuses.
32-
* **Calculated Power Consumption:** Monitor the estimated power usage of the supply fan, extract fan, and the total power consumption of the unit, including the re-heater. This feature relies on selecting the correct unit model during configuration.
35+
* **Diagnostics:** Keep an eye on filter lifetime and view detailed alarm statuses.
3336

3437
## Prerequisites
3538

36-
1. A Systemair SAVE ventilation unit equipped with an **IAM (Internet Access Module)**.
39+
### Connection Method 1: Modbus TCP (SAVECONNECT 1.0)
40+
41+
1. A Systemair SAVE ventilation unit equipped with a **[SAVECONNECT 1.0 (IAM)](https://www.systemair.com/en-gb/p/internet-access-module-iam-110534)** module or any other Modbus TCP-to-RTU converter.
42+
2. The module must be connected to the same local network as your Home Assistant instance.
43+
3. You need to know the IP address of the module. You can typically find this in your router's client list.
44+
45+
### Connection Method 2: Modbus Serial (RS485)
46+
47+
1. A Systemair SAVE ventilation unit with accessible Modbus RS485 port.
48+
2. A **USB-to-Modbus RS485 converter** connected to your Home Assistant server.
49+
3. The serial port path (e.g., `/dev/ttyUSB0` on Linux, `COM3` on Windows).
50+
4. Communication parameters (usually 19200 baud, 8 data bits, no parity, 1 stop bit).
51+
52+
### Connection Method 3: Web API (SAVECONNECT 2.0)
53+
54+
1. A Systemair SAVE ventilation unit equipped with a **[SAVECONNECT 2.0](https://www.systemair.com/en/products/residential-ventilation-systems/accessories/accessories-for-residential-units/control/save-connect)** module.
3755
2. The IAM module must be connected to the same local network as your Home Assistant instance.
3856
3. You need to know the IP address of the IAM module. You can typically find this in your router's client list.
57+
4. The IAM module's web interface should be accessible via HTTP.
3958

4059
## Installation
4160

@@ -61,12 +80,37 @@ Configuration is done entirely through the Home Assistant user interface.
6180
1. Navigate to **Settings > Devices & Services**.
6281
2. Click the **+ Add Integration** button in the bottom right corner.
6382
3. Search for "**Systemair**" and select it.
64-
4. A configuration dialog will appear, asking for connection details:
83+
4. Select your **connection type**:
84+
85+
### Option A: Modbus TCP
86+
87+
Configure connection to SAVECONNECT 1.0 or compatible Modbus TCP module:
88+
89+
* **Host:** The IP address of your Systemair module (e.g., `192.168.1.50`).
90+
* **Port:** The Modbus TCP port for the module. The default is `502`.
91+
* **Slave ID:** The Modbus slave ID of the unit. The default is `1`.
92+
* **Ventilation Unit Model:** Select your specific SAVE unit model from the dropdown list (e.g., `VSR 300`, `VSR 500`). **This is crucial for accurate power consumption calculations.**
93+
94+
### Option B: Modbus Serial (RS485)
95+
96+
Configure connection via USB-to-Modbus RS485 converter:
97+
98+
* **Serial Port:** The serial port path (e.g., `/dev/ttyUSB0` on Linux, `COM3` on Windows).
99+
* **Baud Rate:** Communication speed. Default is `19200`.
100+
* **Data Bits:** Number of data bits. Options: `7` or `8` (default: `8`).
101+
* **Parity:** Parity checking. Options: `N` (None), `E` (Even), `O` (Odd). Default is `N`.
102+
* **Stop Bits:** Number of stop bits. Options: `1` or `2` (default: `1`).
103+
* **Slave ID:** The Modbus slave ID of the unit. The default is `1`.
104+
* **Ventilation Unit Model:** Select your specific SAVE unit model from the dropdown list (e.g., `VSR 300`, `VSR 500`).
105+
106+
### Option C: Web API (SAVECONNECT 2.0)
107+
108+
Configure connection to SAVECONNECT 2.0 IAM module:
109+
110+
* **IP Address:** The IP address of your SAVECONNECT 2.0 IAM module (e.g., `192.168.1.50`).
111+
* **Ventilation Unit Model (Optional):** You can manually select your unit model, or leave it empty to auto-detect from the device.
65112

66-
* **Host:** The IP address of your Systemair IAM module (e.g., `192.168.1.50`).
67-
* **Port:** The Modbus TCP port for the IAM module. The default is `502`.
68-
* **Slave ID:** The ModBus slave ID of the unit. The default is `1`.
69-
* **Ventilation Unit Model:** Select your specific SAVE unit model from the dropdown list (e.g., `VSR 300`, `VSR 500`). **This is crucial for accurate power consumption calculations.**
113+
---
70114

71115
5. Click **Submit**. The integration will test the connection and add the Systemair device and its entities to Home Assistant.
72116

custom_components/systemair/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: SystemairConfigEntry) ->
9595
return True
9696

9797

98-
async def async_options_update_listener(_hass: HomeAssistant, entry: ConfigEntry) -> None:
98+
async def async_options_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
9999
"""Handle options update."""
100-
entry.runtime_data.model = entry.options[CONF_MODEL]
100+
await hass.config_entries.async_reload(entry.entry_id)
101101

102102

103103
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:

custom_components/systemair/config_flow.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,10 @@ async def async_step_modbus_tcp(self, user_input: dict | None = None) -> config_
149149
self._abort_if_unique_id_configured()
150150

151151
user_input[CONF_API_TYPE] = API_TYPE_MODBUS_TCP
152-
return self.async_create_entry(title=user_input[CONF_HOST], data=user_input)
152+
return self.async_create_entry(
153+
title=user_input.get(CONF_MODEL, user_input[CONF_HOST]),
154+
data=user_input,
155+
)
153156

154157
return self.async_show_form(
155158
step_id="modbus_tcp",
@@ -193,7 +196,7 @@ async def async_step_modbus_serial(self, user_input: dict | None = None) -> conf
193196
user_input[CONF_STOPBITS] = int(user_input[CONF_STOPBITS])
194197

195198
return self.async_create_entry(
196-
title=f"Serial {user_input[CONF_SERIAL_PORT]}",
199+
title=user_input.get(CONF_MODEL, f"Serial {user_input[CONF_SERIAL_PORT]}"),
197200
data=user_input,
198201
)
199202

@@ -254,12 +257,14 @@ async def async_step_modbus_webapi(self, user_input: dict | None = None) -> conf
254257
self._abort_if_unique_id_configured()
255258

256259
user_input[CONF_API_TYPE] = API_TYPE_MODBUS_WEBAPI
257-
# Set model from device if not manually selected
260+
261+
# Use device model if user didn't select one manually
258262
if CONF_MODEL not in user_input or not user_input[CONF_MODEL]:
259263
user_input[CONF_MODEL] = device_info.get("model", next(iter(MODEL_SPECS)))
260-
264+
265+
# Title is always the selected/detected model
261266
return self.async_create_entry(
262-
title=device_info.get("model", user_input[CONF_IP_ADDRESS]),
267+
title=user_input[CONF_MODEL],
263268
data=user_input,
264269
)
265270

@@ -295,6 +300,13 @@ def config_entry(self) -> config_entries.ConfigEntry:
295300
async def async_step_init(self, user_input: dict | None = None) -> config_entries.ConfigFlowResult:
296301
"""Manage the options."""
297302
if user_input is not None:
303+
# Update the integration title to match selected model
304+
new_model = user_input.get(CONF_MODEL)
305+
if new_model:
306+
self.hass.config_entries.async_update_entry(
307+
self.config_entry,
308+
title=new_model,
309+
)
298310
return self.async_create_entry(title="", data=user_input)
299311

300312
default_model = self.config_entry.options.get(CONF_MODEL, self.config_entry.data.get(CONF_MODEL, "VSR 300"))

custom_components/systemair/entity.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,20 @@ class SystemairEntity(CoordinatorEntity[SystemairDataUpdateCoordinator]):
1313
"""SystemairEntity class."""
1414

1515
_attr_attribution = ATTRIBUTION
16+
_attr_has_entity_name = True
1617

1718
def __init__(self, coordinator: SystemairDataUpdateCoordinator) -> None:
1819
"""Initialize."""
1920
super().__init__(coordinator)
2021
self._attr_unique_id = coordinator.config_entry.entry_id
2122

23+
# Get model from user selection or device info
24+
model = coordinator.config_entry.runtime_data.model or coordinator.config_entry.runtime_data.mb_model
25+
2226
device_info_dict = {
27+
"name": f"Systemair {model}" if model else "Systemair VSR",
2328
"manufacturer": "Systemair",
24-
"model": coordinator.config_entry.runtime_data.mb_model,
29+
"model": model,
2530
"hw_version": coordinator.config_entry.runtime_data.mb_hw_version,
2631
"sw_version": coordinator.config_entry.runtime_data.mb_sw_version,
2732
"serial_number": coordinator.config_entry.runtime_data.serial_number,

custom_components/systemair/translations/en.json

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,45 @@
33
"step": {
44
"user": {
55
"title": "Connect to Systemair Unit",
6-
"description": "Enter the connection details for your Systemair IAM module. Press Submit to check the connection.",
6+
"description": "Select the connection type for your Systemair ventilation unit.",
7+
"data": {
8+
"api_type": "Connection Type"
9+
}
10+
},
11+
"modbus_tcp": {
12+
"title": "Modbus TCP Configuration",
13+
"description": "Enter the IP address of your Systemair IAM module. The device must be accessible via Modbus TCP.",
714
"data": {
815
"host": "IP Address",
916
"port": "Port",
1017
"slave_id": "Slave ID",
1118
"model": "Ventilation Unit Model"
1219
}
20+
},
21+
"modbus_serial": {
22+
"title": "Modbus Serial (RS485) Configuration",
23+
"description": "Enter the serial port details for your USB-RS485 converter connected to the Systemair unit.",
24+
"data": {
25+
"port": "Serial Port",
26+
"baudrate": "Baud Rate",
27+
"bytesize": "Data Bits",
28+
"parity": "Parity",
29+
"stopbits": "Stop Bits",
30+
"slave_id": "Slave ID",
31+
"model": "Ventilation Unit Model"
32+
}
33+
},
34+
"modbus_webapi": {
35+
"title": "Modbus WebAPI Configuration",
36+
"description": "Enter the IP address of your Systemair SAVECONNECT 2.0 module. The device info will be retrieved automatically.",
37+
"data": {
38+
"ip_address": "IP Address",
39+
"model": "Ventilation Unit Model (optional)"
40+
}
1341
}
1442
},
1543
"error": {
16-
"cannot_connect": "Unable to connect to the device. Please check the IP address, port, and that the device is online.",
44+
"cannot_connect": "Unable to connect to the device. Please check the connection details and ensure the device is online.",
1745
"unknown": "An unknown error occurred.",
1846
"already_configured": "This device is already configured."
1947
}
@@ -45,7 +73,7 @@
4573
},
4674
"climate": {
4775
"saveconnect": {
48-
"name": "Unit",
76+
"name": "Climate",
4977
"state_attributes": {
5078
"preset_mode": {
5179
"state": {

custom_components/systemair/translations/ru.json

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,45 @@
33
"step": {
44
"user": {
55
"title": "Подключение к устройству Systemair",
6-
"description": "Введите данные подключения для модуля Systemair IAM. Нажмите «Подтвердить», чтобы проверить соединение.",
6+
"description": "Выберите тип подключения для вашей вентиляционной установки Systemair.",
7+
"data": {
8+
"api_type": "Тип подключения"
9+
}
10+
},
11+
"modbus_tcp": {
12+
"title": "Настройка Modbus TCP",
13+
"description": "Введите сетевые параметры для подключения к модулю Systemair IAM. Устройство должно быть доступно по Modbus TCP.",
714
"data": {
815
"host": "IP-адрес",
916
"port": "Порт",
1017
"slave_id": "Slave ID",
1118
"model": "Модель устройства"
1219
}
20+
},
21+
"modbus_serial": {
22+
"title": "Настройка Modbus Serial (RS485)",
23+
"description": "Введите параметры последовательного порта для USB-RS485 конвертера, подключенного к устройству Systemair.",
24+
"data": {
25+
"port": "Последовательный порт",
26+
"baudrate": "Скорость передачи",
27+
"bytesize": "Биты данных",
28+
"parity": "Четность",
29+
"stopbits": "Стоп-биты",
30+
"slave_id": "Slave ID",
31+
"model": "Модель устройства"
32+
}
33+
},
34+
"modbus_webapi": {
35+
"title": "Настройка Modbus WebAPI",
36+
"description": "Введите IP-адрес модуля Systemair SAVECONNECT 2.0. Информация об устройстве будет получена автоматически.",
37+
"data": {
38+
"ip_address": "IP-адрес",
39+
"model": "Модель устройства (необязательно)"
40+
}
1341
}
1442
},
1543
"error": {
16-
"cannot_connect": "Не удалось подключиться к устройству. Проверьте IP-адрес, порт и убедитесь, что устройство в сети.",
44+
"cannot_connect": "Не удалось подключиться к устройству. Проверьте параметры подключения и убедитесь, что устройство в сети.",
1745
"unknown": "Произошла неизвестная ошибка.",
1846
"already_configured": "Это устройство уже настроено."
1947
}
@@ -45,7 +73,7 @@
4573
},
4674
"climate": {
4775
"saveconnect": {
48-
"name": "Блок",
76+
"name": "Климат",
4977
"state_attributes": {
5078
"preset_mode": {
5179
"state": {

0 commit comments

Comments
 (0)