Hello everyone.
I am trying to connect my Baxi aerothermal to Home Assistant. (When this is done I will publish the project on GitHub but it is still very raw)
To do this, I have connected a GTW-08 Gateway to convert the R-Bus signal into Modbus.
I have connected an ESP32 with a TTL converter to the modbus and that’s it, we now have communication between HA and the aerothermal system :).
Here the GTW-08 connected to the R-Bus:
Here the ESP32 connected to the Gateway:
My system has 2 zones. Zone 1 is the heating/cooling and Zone 2 is the water heater.
To simplify things I have started with zone 2, the water heater.
Here is the yaml that I have made for now:
substitutions:
settings_skipped_updates: "30"
devicename: "baxi"
esphome:
name: $devicename
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
time:
- platform: homeassistant
id: homeassistant_time
uart:
id: mod_bus
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 9600
stop_bits: 1
modbus:
id: baxi_modbus
flow_control_pin: 5
modbus_controller:
- id: baxi
address: 0x64
modbus_id: baxi_modbus
setup_priority: -10
update_interval: "15s"
command_throttle: "50ms"
############################## ENTITIES ##############################
############################## SENSORS ##############################
sensor:
- platform: modbus_controller #1631 varDhwTankTemperature 8-1
modbus_controller_id: $devicename
name: "ACS Temperatura"
address: 1631
register_type: holding
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 2
device_class: temperature
state_class: measurement
filters:
- multiply: 0.01
############################## NUMBER ##############################
number:
- platform: modbus_controller #1177 parZoneDhwComfortSetpoint 8-1
modbus_controller_id: $devicename
name: "ACS Temperatura de Confort"
address: 1177
use_write_multiple: false
unit_of_measurement: "°C"
device_class: temperature
min_value: 0
max_value: 100
value_type: U_WORD
multiply: 100
- platform: modbus_controller #1178 parZoneDhwReducedSetpoint 8-1
modbus_controller_id: $devicename
name: "ACS Temperatura ECO"
address: 1178
use_write_multiple: false
unit_of_measurement: "°C"
device_class: temperature
min_value: 0
max_value: 100
value_type: U_WORD
multiply: 100
############################## SELECT ##############################
select:
- platform: modbus_controller #1161 parZoneMode 2
modbus_controller_id: $devicename
name: "ACS Modo"
address: 1161
use_write_multiple: false
value_type: U_WORD
optionsmap:
"Auto": 0
"Manual": 1
"Off": 2
skip_updates: 10
############################## TEXT SENSOR ##############################
text_sensor:
- platform: modbus_controller #411 varApStatus
modbus_controller_id: $devicename
name: "Estado del aparato RAW"
address: 411
register_type: holding
bitmask: 0
raw_encode: HEXBYTES
- platform: modbus_controller #411 varApStatus
modbus_controller_id: $devicename
name: "Estado del aparato"
address: 411
register_type: holding
bitmask: 0
raw_encode: HEXBYTES
lambda: |-
uint8_t value = modbus_controller::word_from_hex_str(x, 0);
switch (value) {
case 0: return std::string("En espera");
case 1: return std::string("Demanda calor");
case 3: return std::string("Calentando calefaccion");
case 4: return std::string("Calentando ACS");
case 6: return std::string("Postcirculacion bomba de calor");
case 7: return std::string("Refrigeracion activa");
case 8: return std::string("Parada controlada del compresor");
case 9: return std::string("Bloqueado");
case 10: return std::string("Bloqueo temporal");
case 11: return std::string("Test carga minima");
case 12: return std::string("Test carga maxima CC");
case 16: return std::string("Proteccion antiheladas");
case 17: return std::string("Purgago activado");
default: return std::string("Desconocido");
}
return x;
- platform: modbus_controller #412 varApSubStatus
modbus_controller_id: $devicename
name: "Subestado del aparato raw"
address: 412
register_type: holding
bitmask: 0
raw_encode: HEXBYTES
- platform: modbus_controller #412 varApSubStatus
modbus_controller_id: $devicename
name: "Subestado del aparato"
address: 412
register_type: holding
bitmask: 0
raw_encode: HEXBYTES
lambda: |-
uint8_t value = modbus_controller::word_from_hex_str(x, 0);
switch (value) {
case 0: return std::string("Parado");
case 1: return std::string("Ciclo anticorto");
case 2: return std::string("Cambio de valvula de inversion a calefaccion");
case 3: return std::string("Alimentacion de la bomba del sistema hibrido");
case 4: return std::string("Condiciones de arranque pendientes en bomba y respaldo");
case 30: return std::string("Funcionamiento normal");
case 31: return std::string("Punto de consigna interno limitado");
case 60: return std::string("Posfuncionamiento de la bomba");
case 62: return std::string("Cambio de valvula de 3 vias a ACS");
case 65: return std::string("Derivacion del compresor");
case 66: return std::string("Temperatura superior a temperatura maxima de funcionamiento del compresor");
case 67: return std::string("Temperatura exterior inferior a temperatura maxima de funcionamiento del compresor");
case 68: return std::string("El funcionamiento hibrido solicita la desactivacion del compresor");
case 69: return std::string("Deshielo en curso");
case 70: return std::string("No se reunen las condiciones para deshielo");
case 71: return std::string("Deshielo en curso");
case 75: return std::string("Apagado del compresor por condensacion");
case 78: return std::string("Correccion del punto de consigna de temperatura");
case 82: return std::string("Temperatura inferior a temperatura minima de refrigeracion");
case 88: return std::string("BL-respaldo limitado");
case 89: return std::string("BL-bomba de calor limitada");
case 90: return std::string("BL-bomba de calor y respaldo limitados");
case 91: return std::string("BL-tarifa reducida");
case 92: return std::string("PV-con bomba de calor");
case 93: return std::string("PV-con bomba de calor y respaldo");
case 94: return std::string("BL-red electrica inteligente");
default: return std::string("Desconocido");
}
return x;
- platform: modbus_controller #1619 varZoneCurrentActivities 2
modbus_controller_id: $devicename
name: "ACS Actividad raw"
address: 1619
register_type: holding
bitmask: 0
raw_encode: HEXBYTES
- platform: modbus_controller #1619 varZoneCurrentActivities 2
modbus_controller_id: $devicename
name: "ACS Actividad"
address: 1619
register_type: holding
bitmask: 0
raw_encode: HEXBYTES
lambda: |-
uint8_t value = modbus_controller::word_from_hex_str(x, 0);
switch (value) {
case 0: return std::string("Off");
case 1: return std::string("ECO");
case 2: return std::string("Confort");
case 3: return std::string("Antilegionella");
default: return std::string("Desconocido");
}
return x;
- platform: modbus_controller #1620 varZoneCurrentMode 2
modbus_controller_id: $devicename
name: "ACS Modo de funcionamiento raw"
address: 1620
register_type: holding
bitmask: 0
raw_encode: HEXBYTES
- platform: modbus_controller #1620 varZoneCurrentMode 2
modbus_controller_id: $devicename
name: "ACS Modo de funcionamiento"
address: 1620
register_type: holding
bitmask: 0
raw_encode: HEXBYTES
lambda: |-
uint8_t value = modbus_controller::word_from_hex_str(x, 0);
switch (value) {
case 0: return std::string("Auto");
case 1: return std::string("Manual");
case 2: return std::string("Off");
case 3: return std::string("Temporal");
case 4: return std::string("Vacaciones");
default: return std::string("Desconocido");
}
return x;
And the result is this:
Well, that’s what I want to do from now on:
1 - Define a Climate entity to see better the information.
How I think it should work:
- Be able to select the work mode: Automatic (Scheduled) / Manual / Off.
- When the Scheduled mode is selected, the machine will change between ECO and COMFORT according to its program, the target temperature should change between ECO and COMFORT according to the state it is in, and that temperature should be able to be changed.
- When Manual mode is selected, it should work with the comfort temperature.
And I think this is it for the DHW. I don’t think it is a good idea to act on the heater, what I want is for the system to decide when to heat and when not, I will only select the Work Mode and the Temperatures of those modes.
2 - Do the same for Heating/Cooling. Here we will act on the machine. But once the DHW has been installed, the Heating/Cooling will be the same.
My first attempt was to do it all at once and I already managed to get almost all the parameters. But I preferred to do it slower and finish the DHW.
This is what I got:
But first let’s finish the DHW and then move on to Heating/Cooling
Well, the post is a bit long but I wanted to explain everything well.
This system will be valid for any machine from the Baxi/Dietrich/Remeha group…
What do I need from the community? Well, a help
- If anyone sees a way to improve the code, it would be welcome.
- If someone helps me with the Climates, it would be welcome, I am not able to do it.
I also attach the Modbus addresses in Excel, it is easier to work with than with the PDF (I also attach the PDF)
Any help will be welcome!
Thank you so much!