Hej,
Nie widziałem nigdzie takiego tematu, więc postanowiłem założyć nowy i opisać jak zintegrować rekuperację na Defro. Wzorowałem się na wiedzy dostępnej w Internecie o rekuperatorze Thessli - podziękowania dla wszystkich użytkowników zaangażowanych w ten projekt bo było mi po prostu dużo łatwiej. Dodatkowo też skorzystałem z dokumentacji od samego producenta. Przejdźmy do konkretów.
Dashboard:
Co potrzebujemy?
- Konwerter MODBUS RS485 TCP przez Ethernet lub Wifi - ja skorzystałem z Elfin EW11A
- Zasilacz do konwertera: w moim przypadku 5-36V 5W - patrz komentarz poniżej
Problemy:
- Producent płytki Tech Sterowniki dla rekuperatora Defro przygotował jedynie komunikację (A/B) i nie ma wyprowadzonego zasilania, więc zgodnie z oficjalną informacją jaką uzyskałem należy zastosować osobny zasilacz…
- Brakuje obsługi jednego przypadku użycia - jeśli na ekranie sterownika zostanie zmieniony bieg (funkcja na 1-4 godziny), to takie ustawienie bierze priorytet i z ze strony MODBUS nie ma żadnego rejestru, który by, po pierwsze, pozwolił odczytać to ustawienie (brak informacji poza biegiem), oraz po drugie pozwolił nadpisać rejestr (zmiana biegu przez integrację nie będzie zaakceptowana). Zgłosiłem to do Defro. Drobna sprawa ale jednak dobrze by było mieć to obsłużone.
Pierwsze kroki:
Jak już mamy konwerter to trzeba go podpiąć do płytki rekuperatora. Można kupić gotowy przewód lub zarobić samemu. W moim przypadku wykorzystałem zwykłą skrętkę utp 5e. Następnie musimy się połączyć z konwerterem i skonfigurować ustawienia sieciowe. Szczegóły pomijam bo jest dużo informacji w internecie jak to poprawnie zrobić.
Konwerter konfigurujemy zgodnie z ustawieniami na sterowniku Defro (domyślne ustawienia):
Do tego potrzebujemy ustawienia serwera TCP:
Konfiguracja w Home Assistant:
Ustawiamy integrację MODBUS (można jedynie przez YAML):
# Modbus through TCP
# Elfin EW11A - Defro DRX V
- name: DefroBMS
host: 192.168.1.xxx
port: 9999
type: tcp
delay: 5
timeout: 15
sensors:
- name: "Defro - Wydatek Nawiewu"
address: 100
slave: 1
device_class: volume_flow_rate
unit_of_measurement: m³/h
state_class: measurement
scan_interval: 15
unique_id: "defro_wydatek_nawiewu"
- name: "Defro - Wydatek Wywiewu"
slave: 1
address: 101
device_class: volume_flow_rate
unit_of_measurement: m³/h
state_class: measurement
scan_interval: 15
unique_id: "defro_wydatek_wywiewu"
- name: "Defro - Bieg Nawiewu"
address: 102
slave: 1
input_type: holding
unique_id: "defro_bieg_nawiewu"
- name: "Defro - Bieg Wywiewu"
slave: 1
address: 103
input_type: holding
unique_id: "defro_bieg_wywiewu"
- name: "Defro - Bieg Zadany"
address: 157
slave: 1
input_type: holding
scan_interval: 15
unique_id: "defro_bieg_zadany"
- name: "Defro - Stan Filtrów"
slave: 1
address: 170
unique_id: "defro_stan_filtrow"
- name: "Defro - Temperatura Czerpnia"
address: 104
slave: 1
unit_of_measurement: °C
scale: 0.1
precision: 1
device_class: temperature
state_class: measurement
unique_id: "defro_temperatura_czerpnia"
- name: "Defro - Temperatura Wyrzutnia"
address: 105
slave: 1
unit_of_measurement: °C
scale: 0.1
precision: 1
device_class: temperature
state_class: measurement
unique_id: "defro_temperatura_wyrzutnia"
- name: "Defro - Temperatura Nawiew"
address: 106
slave: 1
unit_of_measurement: °C
scale: 0.1
precision: 1
device_class: temperature
state_class: measurement
unique_id: "defro_temperatura_nawiew"
- name: "Defro - Temperatura Wywiew"
address: 107
slave: 1
unit_of_measurement: °C
scale: 0.1
precision: 1
device_class: temperature
state_class: measurement
unique_id: "defro_temperatura_wywiew"
- name: "Defro - Temperatura Kontroli Nagrzewnicy"
address: 109
slave: 1
unit_of_measurement: °C
scale: 0.1
precision: 1
device_class: temperature
state_class: measurement
unique_id: "defro_temperatura_kontroli_nagrzewnicy"
- name: "Defro - Przepływ Biegu 1"
address: 164
slave: 1
input_type: holding
unique_id: "defro_przeplyw_biegu_1"
- name: "Defro - Przepływ Biegu 2"
address: 165
slave: 1
input_type: holding
unique_id: "defro_przeplyw_biegu_2"
- name: "Defro - Przepływ Biegu 3"
address: 166
slave: 1
input_type: holding
unique_id: "defro_przeplyw_biegu_3"
- name: "Defro - Błędy"
address: 139
slave: 1
input_type: holding
data_type: uint16
unique_id: "defro_bledy"
- name: "Defro - Bypass Dolna Temperatura"
address: 173
slave: 1
input_type: holding
unique_id: "defro_dolna_temperatura"
- name: "Defro - Bypass Temperatura Komfortu"
address: 174
slave: 1
input_type: holding
unique_id: "defro_temperatura_komfortu"
binary_sensors:
- name: "Defro - Bypass Stan"
address: 133
slave: 1
input_type: holding
unique_id: "defro_bypass_stan"
- name: "Defro - Urlop Stan"
address: 137
slave: 1
input_type: holding
unique_id: "defro_urlop_stan"
switches:
- name: "Defro - Bypass"
address: 141
slave: 1
write_type: holding
command_on: 1
command_off: 0
verify:
address: 141
input_type: holding
state_on: 1
state_off: 0
unique_id: "defro_bypass"
- name: "Defro - Tygodniówka"
address: 156
slave: 1
write_type: holding
command_on: 1
command_off: 0
verify:
address: 156
input_type: holding
state_on: 1
state_off: 0
unique_id: "defro_tygodniowka"
- name: "Defro - Flow Balancing"
address: 168
slave: 1
write_type: holding
command_on: 1
command_off: 0
verify:
address: 168
input_type: holding
state_on: 1
state_off: 0
unique_id: "defro_flow_balancing"
- name: "Defro - Urlop"
address: 145
slave: 1
write_type: holding
command_on: 60
command_off: 0
verify:
address: 137
input_type: holding
state_on: 1
state_off: 0
unique_id: "defro_urlop"
- name: "Defro - Okna"
address: 158
slave: 1
write_type: holding
command_on: 1
command_off: 0
verify:
address: 158
input_type: holding
state_on: 1
state_off: 0
unique_id: "defro_okna"
Brakuje kilku funkcji, z których po prostu nie korzystam ale jak ktoś chce to może łatwo dodać: palenisko, tryb tygodniowy, GWC, jakieś dodatkowe ustawienia na przykład przy bypassie.
Dla głównego sensora od wentylatorów zrobiłem osobny YAML: /homeassistant/template/defro_fan_sensor.yaml
- fan:
- name: "Defro - Fan Mode"
unique_id: "fan.defro_fan_mode"
state: >-
{{ is_state('binary_sensor.defro_status', 'on') }}
percentage: >-
{% set gear = states('sensor.defro_bieg_zadany_max') | int(0) %}
{% if gear == 1 %}
{{ (states('sensor.defro_przeplyw_biegu_1') | float(0) / 450 * 100) | round(1) }}
{% elif gear == 2 %}
{{ (states('sensor.defro_przeplyw_biegu_2') | float(0) / 450 * 100) | round(1) }}
{% elif gear == 3 %}
{{ (states('sensor.defro_przeplyw_biegu_3') | float(0) / 450 * 100) | round(1) }}
{% else %}
0
{% endif %}
speed_count: 3
turn_on:
- action: modbus.write_register
data:
slave: 1
address: 157
value: >-
{% set p = percentage | int %}
{% if p <= 0 %} 0
{% elif p <= 33 %} 1
{% elif p <= 66 %} 2
{% else %} 3
{% endif %}
hub: DefroBMS
turn_off:
- action: modbus.write_register
data:
slave: 1
address: 157
value: 0
hub: DefroBMS
set_percentage:
- action: modbus.write_register
data:
slave: 1
address: 157
value: >-
{% set p = percentage | int %}
{% if p <= 0 %} 0
{% elif p <= 33 %} 1
{% elif p <= 66 %} 2
{% else %} 3
{% endif %}
hub: DefroBMS
preset_modes:
- "normalny"
- "urlop"
- "okna"
preset_mode: >-
{% if is_state('switch.defro_urlop', 'on') %}
urlop
{% elif is_state('switch.defro_okna', 'on') %}
okna
{% else %}
normalny
{% endif %}
set_preset_mode:
- choose:
- conditions: "{{ preset_mode == 'urlop' }}"
sequence:
- action: switch.turn_off
target:
entity_id:
- switch.defro_okna
- action: switch.turn_on
target:
entity_id: switch.defro_urlop
- conditions: "{{ preset_mode == 'okna' }}"
sequence:
- action: switch.turn_off
target:
entity_id:
- switch.defro_urlop
- action: switch.turn_on
target:
entity_id: switch.defro_okna
- conditions: "{{ preset_mode == 'normalny' }}"
sequence:
- action: switch.turn_off
target:
entity_id:
- switch.defro_urlop
- switch.defro_okna
Pozostałe sensory są w kolejnym YAML: /homeassistant/template/defro_template_sensors.yaml
- sensor:
- name: "Defro - Sprawność"
unique_id: "sensor.defro_sprawnosc"
unit_of_measurement: "%"
state_class: "measurement"
state: >-
{% if is_state('binary_sensor.defro_bypass_stan', 'off') %}
{% set t1 = states('sensor.defro_temperatura_czerpnia') | float(0) %}
{% set t2 = states('sensor.defro_temperatura_nawiew') | float(0) %}
{% set t3 = states('sensor.defro_temperatura_wywiew') | float(0) %}
{% if (t3 - t1) != 0 %}
{{ ((t2 - t1) / (t3 - t1) * 100) | round(1, default=0) }}
{% else %}
0
{% endif %}
{% else %}
0
{% endif %}
- name: "Defro - Odzyskana Moc"
unique_id: "sensor.defro_odzyskana_moc"
unit_of_measurement: "W"
state_class: "measurement"
state: >-
{% if is_state('binary_sensor.defro_bypass_stan', 'off') %}
{% set strumienN = states('sensor.defro_wydatek_nawiewu') | float(0) %}
{% set tcz = states('sensor.defro_temperatura_czerpnia') | float(0) %}
{% set tn = states('sensor.defro_temperatura_nawiew') | float(0) %}
{% set odzysk = ((tn - tcz) * strumienN * 1200) / 3600 %}
{% if tcz < strumienN %}
{{ odzysk | float | round(1, default=0) }}
{% else %}
{{ (odzysk * -1) | float | round(1, default=0) }}
{% endif %}
{% else %}
0
{% endif %}
- name: "Defro - Wysterowanie Wywiew"
unique_id: "sensor.defro_wysterowanie_wywiew"
unit_of_measurement: "%"
state_class: "measurement"
state: >-
{% set flowW = states('sensor.defro_wydatek_wywiewu') | float(0) %}
{{ ((flowW * 100) / 450) | float | round(1, default=0) }}
- name: "Defro - Wysterowanie Nawiew"
unique_id: "sensor.defro_wysterowanie_nawiew"
unit_of_measurement: "%"
state_class: "measurement"
state: >-
{% set flowN = states('sensor.defro_wydatek_nawiewu') | float(0) %}
{{ ((flowN * 100) / 450) | float | round(1, default=0) }}
- name: "Defro - Błedy Stan"
unique_id: "sensor.defro_bledy_stan"
state: >-
{% set val = states('sensor.defro_bledy') | int(0) %}
{% set binary = '{0:b}'.format(val) %}
{% set data = namespace(positions=[]) %}
{% for i in range(binary | length) %}
{% if binary[-1 - i] == '1' %}
{% set data.positions = data.positions + [i + 1] %}
{% endif %}
{% endfor %}
{% set errors = {
1: "Błąd wentylatora wywiewu",
2: "Błąd wentylatora nawiewu",
3: "Błąd czujnika temperatury zewnętrznej",
4: "Błąd czujnika temperatury wywiewu",
5: "Błąd czujnika temperatury nawiewu",
6: "Błąd czujnika temperatury wyrzut",
7: "Błąd czujnika temperatury nawilżacza",
10: "Błąd czujnika przepływu wywiewu",
11: "Błąd czujnika przepływu nawiewu",
12: "Błąd czujnika nawilżacza",
13: "Błąd czujnika nagrzewnicy GWC",
14: "Błąd czujnika temperatury nagrzewnicy nawilżacza",
15: "Błąd wentylatora wywiewu przepływ",
16: "Błąd wentylatora nawiewu przepływ"
} %}
{% set ns = namespace(active_errors=[]) %}
{% for pos in data.positions %}
{% if errors[pos] is defined %}
{% set ns.active_errors = ns.active_errors + [errors[pos]] %}
{% endif %}
{% endfor %}
{{ ns.active_errors if ns.active_errors else "OK" }}
- name: "Defro - Bieg Zadany Max"
unique_id: "defro_bieg_zadany_max"
state: >-
{{ [
states('sensor.defro_bieg_nawiewu') | int(0),
states('sensor.defro_bieg_wywiewu') | int(0)
] | max }}
- binary_sensor:
- name: "Defro - Status"
unique_id: "binary_sensor.defro_status"
state: >-
{% set val = states('sensor.defro_bieg_zadany') | int(0) %}
{{ 'off' if val == 0 else 'on' }}
- name: "Defro - Okna Stan"
unique_id: "binary_sensor.defro_okna_stan"
state: >-
{{ is_state('switch.defro_okna', 'on') }}
- name: "Defro - Awaria"
unique_id: "binary_sensor.defro_awaria"
state: >-
{{ states('sensor.defro_bledy') | int(0) != 0 }}
Oczywiście do głównego pliku konfiguracyjnego /homeassistant/configuration.yaml musimy dodać odpowiednio:
template: !include_dir_merge_list template/
modbus: !include modbus.yaml
Kod dla vertical stack card:
type: vertical-stack
cards:
- type: picture-elements
elements:
- type: state-label
entity: sensor.defro_temperatura_czerpnia
style:
top: 33%
left: 7%
color: black
font-family: system-ui
- type: state-label
entity: sensor.defro_temperatura_wywiew
style:
top: 33%
left: 93%
color: black
font-family: system-ui
- type: state-label
entity: sensor.defro_temperatura_wyrzutnia
style:
top: 66.8%
left: 7%
color: black
font-family: system-ui
- type: state-label
entity: sensor.defro_temperatura_nawiew
style:
top: 66.8%
left: 93%
color: black
font-family: system-ui
- type: state-label
entity: sensor.defro_temperatura_kontroli_nagrzewnicy
style:
top: 21%
left: 37%
color: black
font-family: system-ui
font-size: smaller
- type: state-label
entity: sensor.defro_wydatek_nawiewu
style:
top: 82%
left: 92%
- type: state-label
entity: sensor.defro_wysterowanie_nawiew
style:
top: 82%
left: 66%
color: black
font-family: system-ui
font-size: smaller
- type: state-label
entity: sensor.defro_wydatek_wywiewu
style:
top: 18%
left: 92%
- type: state-label
entity: sensor.defro_wysterowanie_wywiew
style:
top: 82%
left: 35%
color: black
font-family: system-ui
font-size: smaller
- type: state-label
entity: sensor.defro_sprawnosc
style:
top: 72%
left: 50%
color: black
font-family: system-ui
font-size: smaller
- type: state-label
entity: sensor.defro_odzyskana_moc
style:
top: 29%
left: 50%
color: black
font-family: system-ui
font-size: smaller
- type: state-label
entity: sensor.defro_bieg_nawiewu
style:
top: 52%
left: 65.5%
color: black
font-weight: bold
- type: state-label
entity: sensor.defro_bieg_wywiewu
style:
top: 52%
left: 34.5%
color: black
font-weight: bold
- type: state-label
entity: sensor.shellyemminig4_7c2c6777361c_moc
style:
top: 19%
left: 50%
color: black
font-family: system-ui
font-size: smaller
image: /local/defro/defro1v.png
Chciałbym jeszcze w przyszłości usprawnić działanie karty i pokazać bypass oraz może kilka innych ustawień na wzór integracji z Thessli ale to może kiedyś. ![]()
Pozdrawiam,
Piotr




