Integracja z kotłem Valliant VC 186 oraz sterownikiem pogodowym VC400 korzysta z protokołu eBUS. Jako adapter eBUS wykorzystywana jest płytka w wersji 2.2 zbudowana na podstawie strony eBus Adapter 3. Od czasu jego zlutowania (2020) pojawiło się kilka nowszych wersji adaptera, ale nie zamierzam zmieniać, bo działa bardzo skutecznie. Komunikacja z HA jest za pomocą serwera MQTT.
Schemat blokowy

Wygląd płytki adaptera eBus z UART

Oprogramowanie
Korzystam z ebusd uruchomionego na Linuxie (Debian) jako serwis.
Instalacja
Instalacja pakietu ebusd wg instrukcji: link.
Konfiguracja
Konfiguracja w pliku /etc/default/ebusd
#tryb standardowy
#EBUSD_OPTS="--scanconfig -l/var/log/ebusd.log --device=/dev/ttyUSB0 --mqtthost=192.168.0.2 --mqttport=1883 --mqttjson --mqttuser=user_mqtt --mqttpass=pass_mqtt --mqttint=/etc/ebusd/mqtt-hassio.cfg"
#tryb instalatora wi
EBUSD_OPTS="--scanconfig -l/var/log/ebusd.log --device=/dev/ttyUSB0 --mqtthost=192.168.0.2 --mqttport=1883 --mqttjson --mqttuser=user_mqtt --mqttpass=pass_mqtt --mqttint=/etc/ebusd/mqtt-hassio.cfg --accesslevel=install"
Oczywiście wartości mqtthost, mqttport, mqttuser, mqttpass należy ustawić na poprawne.
Aby zmieniać niektóre wartości (krzywa grzewcza, stany liczników gazu) ebusd musi działać w trybie instalatora. Weryfikację, czy dany parametr jest modyfikowalny można sprawdzić w projekcie GIT https://github.com/john30/ebusd-configuration wyszukując odpowieni plik dla instalacji.
Weryfikacja działania ebusd
ebusctl info
dla mojej instalacji komenda zwraca
version: ebusd 24.1.24.1
update check: OK
device: /dev/ttyUSB0, serial
access: install
signal: acquired
symbol rate: 22
max symbol rate: 1441
min arbitration micros: 0
max arbitration micros: 3168
min symbol latency: 0
max symbol latency: 15
scan: finished
reconnects: 0
masters: 3
messages: 432
conditional: 7
poll: 110
update: 16
address 03: master #11
address 08: slave #11, scanned "MF=Vaillant;ID=BAI00;SW=0516;HW=7401", loaded "vaillant/bai.308523.inc" ([id_hw=7401]), "vaillant/08.bai.csv"
address 10: master #2
address 15: slave #2, scanned "MF=Vaillant;ID=40000;SW=0139;HW=7301", loaded "vaillant/15.400.csv"
address 31: master #8, ebusd
address 36: slave #8, ebusd
Problemy
Ponieważ rozwiązanie działało już przez kilka lat nastąpiło przepełnienie liczników (ebusd/bai/PrEnergyXXX) odpowiedzialnych za zliczanie zużycia gazu.
Poniżej komendy do zresetowania odpowiednich liczników:
#odczyt
ebusctl read -V -c bai PrEnergyCountHwc1
#zapis
ebusctl write -c bai PrEnergySumHc1 0
ebusctl write -c bai PrEnergySumHwc1 0
ebusctl write -c bai PrEnergyCountHc1 0
ebusctl write -c bai PrEnergyCountHwc1 0
Jeżeli przy zapisie są błędy „ERR: element not found” powyższe komendy należy wykonać w trybie instalatora (parametr „–accesslevel=install”).
Home Assistant
Karta ogrzewania w HA

Rozwiązanie bazuje na cyklicznym odczycie danych przez MQTT. Aby oczytać jakąś wartość należy najpierw wysłać wiadomość odpowiedni topic MQTT. Do testowania najlepiej użyć klienta umożliwiającego podłączenie się bezpośrednio do serwera MQTT, np. MQTT Explorer
Skrypty wymuszające pobieranie danych:
script:
ebus_refresh_2m:
alias: "Pobierz dane ebus"
sequence:
- service: mqtt.publish
data_template:
topic: 'ebusd/400/RoomTemp/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/WaterPressure/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/CirPump/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/IsInHoliday/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/IsInParty/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/IsInSingleHwcLoadingMode/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/ActualRoomTempDesired/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/HwcTempDesired/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/PrEnergySumHwc1/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/PrEnergySumHc1/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/PrEnergyCountHwc1/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/PrEnergyCountHc1/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/StorageTemp/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/OperatingMode/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/OperatingModeHwc/get'
payload: ''
ebus_refresh_30m:
alias: "Pobierz dane ebus"
sequence:
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/HcHours/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/HwcHours/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/FlowSetPotmeter/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/HwcSetPotmeter/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/HeatingCurve/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/PrEnergySumHwc2/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/PrEnergySumHwc3/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/PrEnergySumHc2/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/bai/PrEnergySumHc3/get'
payload: ''
- service: mqtt.publish
data_template:
topic: 'ebusd/400/ReducedNightTemp/get'
payload: ''
i odpowiednie automatyzacje, dodatkowo automatyzacja powiadamiająca o zbyt niskim ciśnieniu w instalacji
automation:
- alias: "Ebusd - update after start"
trigger:
platform: homeassistant
event: start
action:
- delay: 00:01:00
- service: script.ebus_refresh_2m
- service: script.ebus_refresh_30m
- id: 'update_ebusd_1'
alias: Ebusd - update 5min
trigger:
platform: time_pattern
minutes: '/2'
condition:
- condition: state
entity_id: sensor.ebusd_running
state: 'true'
action:
- service: script.ebus_refresh_2m
- id: 'update_ebusd_2'
alias: Ebusd - update 30min
trigger:
platform: time_pattern
minutes: /30
condition:
- condition: state
entity_id: sensor.ebusd_running
state: 'true'
action:
- service: script.ebus_refresh_30m
- id: waterpressure_low_notification
alias: "Ebusd - Waterpressure Low Notification"
initial_state: 'on'
trigger:
platform: numeric_state
entity_id: sensor.cisnienie_wody
below: 0.75
action:
- service: notify.gmail_notifier
data:
message: "Ciśnienie wody za niskie: {{ states('sensor.cisnienie_wody') }}"
title: "[HA] Ciśnienie wody"
- service: persistent_notification.create
data:
title: "Ciśnienie wody"
message: >
Ciśnienie wody za niskie: {{ states('sensor.cisnienie_wody') }}
notification_id: "waterpressure_error"
Poniżej ustawienia mqtt (ustawienie w pliku configuration.yaml oraz mqtt.yaml)
configuration.yaml
...
mqtt: !include mqtt.yaml
...
mqtt.yaml
sensor:
#########
# EBUSD #
#########
- state_topic: "ebusd/global/running"
name: "ebusd_running"
- state_topic: "ebusd/global/signal"
name: "ebusd_signal"
- state_topic: "ebusd/global/uptime"
name: "ebusd_uptime"
- state_topic: "ebusd/global/version"
name: "ebusd_version"
- state_topic: "ebusd/bai/Status01"
name: "ebus_FlowTemp"
value_template: "{{ value_json['temp']['value'] }}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/Status01"
name: "ebus_ReturnTemp"
value_template: "{{ value_json['temp_1']['value'] | round(1)}}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/Status01"
name: "Temperatura zewnętrzna"
value_template: "{{ value_json['temp_2']['value'] | round(1)}}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/Status01"
name: "Temperatura c.w."
value_template: "{{ value_json['temp_4']['value'] }}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/Status01"
name: "Płomień"
value_template: "{{ value_json['pumpstate']['value'] }}"
##z automatyzacji
- state_topic: "ebusd/400/RoomTemp"
name: "Temperatura Jadalnia"
value_template: "{{ ((value_json['temp']['value']|float)-1) | round(1)}}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/400/ActualRoomTempDesired"
name: "Temperatura zadana"
value_template: "{{ value_json['value']['value'] | round(1)}}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/HcHours"
name: "Liczba godzin pracy ogrzewania"
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'h'
- state_topic: "ebusd/bai/HwcHours"
name: "Liczba godzin pracy c.w.u."
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'h'
- state_topic: "ebusd/bai/FlowSetPotmeter"
name: "Ustawienie ogrzewania"
value_template: "{{ value_json['value']['value'] | round(1)}}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/HwcSetPotmeter"
name: "Ustawienie c.w.u"
value_template: "{{ value_json['value']['value'] | round(1)}}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/WaterPressure"
name: "Ciśnienie wody"
value_template: "{{ value_json['press']['value'] }}"
unit_of_measurement: 'Pa'
device_class: pressure
- state_topic: "ebusd/bai/CirPump"
name: "Pompa cyrkulacyjna"
value_template: "{{ value_json['value']['value'] }}"
- state_topic: "ebusd/400/HeatingCurve"
name: "Krzywa grzewcza"
value_template: "{{ value_json['value']['value'] }}"
- state_topic: "ebusd/400/IsInHoliday"
name: "Tryb wakacyjny"
value_template: "{{ value_json['value']['value'] }}"
- state_topic: "ebusd/400/IsInParty"
name: "Tryb impreza"
value_template: "{{ value_json['value']['value'] }}"
- state_topic: "ebusd/400/IsInSingleHwcLoadingMode"
name: "Tryb ładowania zasobnika"
value_template: "{{ value_json['value']['value'] }}"
- state_topic: "ebusd/bai/Status02"
name: "ebusd_hwcmode"
value_template: "{{ value_json['hwcmode']['value'] }}"
- state_topic: "ebusd/bai/Status02"
name: "ebusd_st2_1"
value_template: "{{ value_json['temp_1']['value'] }}"
- state_topic: "ebusd/bai/Status02"
name: "ebusd_st2_2"
value_template: "{{ value_json['temp_2']['value'] }}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/Status02"
name: "ebusd_st2_3"
value_template: "{{ value_json['temp_3']['value'] }}"
- state_topic: "ebusd/bai/Status02"
name: "ebusd_st2_4"
value_template: "{{ value_json['temp_4']['value'] }}"
unit_of_measurement: '°C'
device_class: temperature
- state_topic: "ebusd/bai/PrEnergySumHwc1"
name: "ebusd_PrEnergySumHwc1"
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'W'
device_class: power
- state_topic: "ebusd/bai/PrEnergySumHwc2"
name: "ebusd_PrEnergySumHwc2"
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'W'
device_class: power
- state_topic: "ebusd/bai/PrEnergySumHwc3"
name: "ebusd_PrEnergySumHwc3"
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'W'
device_class: power
- state_topic: "ebusd/bai/PrEnergySumHc1"
name: "ebusd_PrEnergySumHc1"
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'W'
device_class: power
- state_topic: "ebusd/bai/PrEnergySumHc2"
name: "ebusd_PrEnergySumHc2"
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'W'
device_class: power
- state_topic: "ebusd/bai/PrEnergySumHc3"
name: "ebusd_PrEnergySumHc3"
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'W'
device_class: power
- state_topic: "ebusd/bai/PrEnergyCountHwc1"
name: "ebusd_PrEnergyCountHwc1"
value_template: "{{ value_json['value']['value'] }}"
unit_of_measurement: 'W'
device_class: power
- state_topic: "ebusd/400/OperatingModeHwc"
name: "ebusd_OperatingModeHwc"
value_template: "{{ value_json.value.value }}"
- state_topic: "ebusd/400/OperatingMode"
name: "ebusd_OperatingMode"
value_template: "{{ value_json.value.value }}"
Konfiguracja dodatkowych obiektów w pliku mqtt.yaml
climate:
- name: "Ogrzewanie"
max_temp: 25
min_temp: 15
precision: 0.1
temp_step: 0.5
modes:
- "heat"
- "off"
mode_state_template: >-
{% set values = { 'auto':'auto', 'on':'heat', 'hwc':'cool', 'off':'off'} %}
{% set state = value_json['pumpstate']['value'] %}
{{ values[state] if state in values.keys() else 'off' }}
mode_state_topic: "ebusd/bai/Status01"
current_temperature_topic: "ebusd/400/RoomTemp"
current_temperature_template: '{{value_json["temp"].value|float -1.25 }}'
temperature_state_topic: "ebusd/400/ActualRoomTempDesired"
temperature_state_template: '{{value_json.value.value}}'
- name: "Ciepła woda"
max_temp: 65
min_temp: 40
precision: 1
temp_step: 1
modes:
- "heat"
- "off"
mode_state_template: >-
{% set values = { 'hwc':'heat', 'off':'off'} %}
{% set state = value_json['pumpstate']['value'] %}
{{ values[state] if state in values.keys() else 'off' }}
mode_state_topic: "ebusd/bai/Status01"
temperature_state_topic: "ebusd/400/HwcTempDesired"
temperature_state_template: '{{value_json.value.value}}'
temperature_command_topic: "ebusd/400/HwcTempDesired/set"
current_temperature_topic: "ebusd/bai/StorageTemp"
current_temperature_template: '{{value_json["temp"].value}}'
number:
- name: mqtt_tryb_wakacyjny
icon: mdi:caravan
min: 0
max: 20
step: 1
mode: slider
command_topic: ebusd/400/IsInHoliday/set
state_topic: "ebusd/400/IsInHoliday"
value_template: '{{value_json.value.value | int}}'
- name: mqtt_krzywa_grzewcza
icon: mdi:chart-bell-curve-cumulative
min: 0.2
max: 4
step: 0.1
mode: slider
command_topic: ebusd/400/HeatingCurve/set
state_topic: ebusd/400/HeatingCurve
value_template: '{{value_json.value.value | float}}'
switch:
- name: mqtt_tryb_impreza
icon: mdi:glass-cocktail
command_topic: "ebusd/400/IsInParty/set"
state_topic: "ebusd/400/IsInParty"
value_template: '{{value_json.value.value }}'
payload_on: "on"
payload_off: "off"
- name: mqtt_tryb_ladowania_zasobnika
icon: mdi:heat-pump
command_topic: "ebusd/400/IsInSingleHwcLoadingMode/set"
state_topic: "ebusd/400/IsInSingleHwcLoadingMode"
value_template: '{{value_json.value.value }}'
payload_on: "on"
payload_off: "off"
Zużycie gazu
Zużycie gazu można wyliczyć na podstawie liczników PrEnergySumHwc1 oraz PrEnergySumHw1. Na podstawie pomiarów należy wyliczyć stosunek zużycia gazu do sumy PrEnergySumHwc1 i PrEnergySumHw1.
Komponent do wprowadzenia poprzednich wartości odczytanych

type: entities
entities:
- entity: input_number.gas_last_measure
- entity: input_number.gas_prenergysumhc1
- entity: input_number.gas_prenergysumhwc1
- entity: input_number.wspolczynnik_gazu
- entity: sensor.licznik_gazu
title: Zużycie gazu
show_header_toggle: false
Wyliczenie bieżącej wartości zużycia gazu (plik sensors.yaml)
licznik_gazu:
friendly_name: "Licznik gazu"
unit_of_measurement: "m³"
device_class: gas
icon_template:
mdi:gas-burner
value_template: '{{ ((states.input_number.gas_last_measure.state | float) +
((states.sensor.ebusd_prenergysumhc1.state | int + states.sensor.ebusd_prenergysumhwc1.state | int) -
(states.input_number.gas_prenergysumhc1.state | int + states.input_number.gas_prenergysumhwc1.state | int)) /
(states.input_number.wspolczynnik_gazu.state | float)
) |round(3)
}}