This commit is contained in:
2026-02-23 17:19:16 +01:00
commit 5ace382c3f
5 changed files with 6435 additions and 0 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 elgatho
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

12
README.md Normal file
View File

@@ -0,0 +1,12 @@
# Openkospel
Project for implementing kospel heater to Home Assistant using ESPHOME integration.
It is under heavy developement, you are using it at your own risk!
# Wiring
Tested on modules HW-0519,
![hw-0519 wiring](https://github.com/user-attachments/assets/b32596c1-1ebe-492b-9a8d-2f6e50492b6a)
HW-97
![HW97_bb](https://github.com/user-attachments/assets/e09532f6-d848-43f7-8c6e-4e25ddc8e041)

680
esphome.yaml Normal file
View File

@@ -0,0 +1,680 @@
logger:
baud_rate: 0
status_led:
pin: GPIO2
uart:
id: mod_bus
tx_pin: TX
rx_pin: RX
baud_rate: 9600
stop_bits: 1
parity: NONE
modbus:
id: modbus1
modbus_controller:
- id: kospel
address: 101
modbus_id: modbus1
setup_priority: -11
update_interval: 20s
command_throttle: 1s
allow_duplicate_commands: true
select:
- platform: modbus_controller
id: tryb_pracy
name: "Tryb pracy"
address: 0x0b55
value_type: U_WORD
entity_category: config
icon: "mdi:toggle-switch"
optionsmap:
"Wyłączony": 0
"Lato": 1
"Zima": 2
"Wakacje": 3
"Party": 4
lambda: |-
uint16_t value = int(id(wbrwf1).state);
int zima = ((value >> 13) & 1);
int lato = ((value >> 11) & 1);
int wakacje = ((value >> 15) & 1);
int party = ((value >> 14) & 1);
if (zima == 1 && lato == 0 && wakacje == 0 && party == 0) {
return std::string("Zima");
} else if (lato == 1 && zima == 0 && wakacje == 0 && party == 0) {
return std::string("Lato");
} else if (wakacje == 1) {
return std::string("Wakacje");
} else if (party == 1) {
return std::string("Party");
} else {
return std::string("Wyłączony");
}
write_lambda: |-
uint16_t reg = int(id(wbrwf1).state);
if (value == 0) {
reg &= ~(1 << 11);
reg &= ~(1 << 13);
reg &= ~(1 << 14);
reg &= ~(1 << 15);
} else if (value == 1) {
reg |= (1 << 11);
reg &= ~(1 << 13);
reg &= ~(1 << 14);
reg &= ~(1 << 15);
} else if (value == 2) {
reg &= ~(1 << 11);
reg |= (1 << 13);
reg &= ~(1 << 14);
reg &= ~(1 << 15);
}
else if (value == 3) {
reg |= (1 << 15);
reg &= ~(1 << 14);
}
else if (value == 4) {
reg &= ~(1 << 15);
reg |= (1 << 14);
}
return reg;
- platform: modbus_controller
id: config_pump_lift
name: "Wysokość podnoszenia pompy"
address: 0x0b83
value_type: U_WORD
entity_category: config
icon: "mdi:pump"
optionsmap:
"3m": 0
"4m": 256
"5m": 512
"6m": 768
"7m": 1024
"7.5m": 1280
number:
- platform: modbus_controller
icon: mdi:water-boiler
id: config_temp_boil_komf
name: "Ustaw temp komfortowa boilera"
address: 0x0b67
value_type: U_WORD
entity_category: config
min_value: 35
max_value: 50
lambda: |-
int value = data[3] << 8 | data[2];
value = value / 10;
return value ;
write_lambda: |-
int int_value = static_cast<int>(x * 10);
return (int_value << 8) | (int_value >> 8);
- platform: modbus_controller
id: config_temp_boil_eko
icon: mdi:water-boiler
name: "Ustaw temp ekonomiczna boilera"
address: 0x0b66
value_type: U_WORD
entity_category: config
min_value: 30
max_value: 45
lambda: |-
int value = data[1] << 8 | data[0];
value = value / 10;
return value ;
write_lambda: |-
int int_value = static_cast<int>(x * 10);
return (int_value << 8) | (int_value >> 8);
- platform: modbus_controller
id: config_temp_co_manual
icon: mdi:heating-coil
name: "Ustaw temp CO ręczna"
address: 0x0b73
value_type: U_WORD
entity_category: config
min_value: 30
max_value: 55
lambda: |-
int value = data[1] << 8 | data[0];
value = value / 10;
return value ;
write_lambda: |-
int int_value = static_cast<int>(x * 10);
return (int_value << 8) | (int_value >> 8);
sensor:
- platform: total_daily_energy
name: "Kospel zużycie energii dzienne"
id: kospel_daily_power_usage
power_id: power_main
restore: true
unit_of_measurement: kWh
device_class: energy
icon: mdi:calendar-clock
- platform: total_daily_energy
name: "Kospel zużycie energii dzienne CO"
id: kospel_daily_power_usage_co
power_id: power_co
restore: true
unit_of_measurement: kWh
icon: mdi:calendar-clock
device_class: energy
- platform: total_daily_energy
name: "Kospel zużycie energii dzienne CWU"
id: kospel_daily_power_usage_cwu
power_id: power_cwu
restore: true
device_class: energy
unit_of_measurement: kWh
icon: mdi:calendar-clock
################################### TIME
- platform: modbus_controller
modbus_controller_id: kospel
name: "Time Data (Hours)"
id: time_date
register_type: holding
address: 0x0AF7
lambda: |-
uint8_t minutes = data[0];
uint8_t hours = data[2];
return hours * 100 + minutes;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura na zewnątrz"
id: temperature_outside
register_type: holding
address: 0x0b4c
device_class: temperature
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int16_t value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura wewnątrz"
id: temperature_inside
register_type: holding
unit_of_measurement: "°C"
accuracy_decimals: 1
address: 0x0b4b
device_class: temperature
value_type: S_WORD
lambda: |-
uint16_t value = int(id(wbrwf1).state);
if (((value >> 10) & 1) == 0){
return NAN;
}
else
{
int16_t sens_value = data[item->offset+1] << 8 | data[item->offset];
return sens_value;
}
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boiler"
id: temperature_boil
register_type: holding
address: 0x0b4a
device_class: temperature
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura zasilania co min"
id: temp_zas_min
register_type: holding
address: 0x0bba
device_class: temperature
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura zasilania co max"
id: temp_zas_max
register_type: holding
address: 0x0bbb
device_class: temperature
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura zasilania co ręczna"
id: temp_zas_man
register_type: holding
address: 0x0b73
device_class: temperature
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura Wejścia"
id: temperature_in
register_type: holding
address: 0x0b48
value_type: S_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura Wyjścia"
id: temperature_out
register_type: holding
address: 0x0b49
value_type: S_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[3] << 8 | data[2];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura zadana układu"
id: temperature_factor
register_type: holding
address: 0x0b44
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boilera min"
id: temperature_boil_min
register_type: holding
address: 0x0bbe
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boilera max"
id: temperature_boil_max
register_type: holding
address: 0x0bbf
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boilera komfortowa"
id: temperature_boil_komfort
register_type: holding
address: 0x0b67
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[3] << 8 | data[2];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boilera ekonomiczna"
id: temperature_boil_ekonomiczna
register_type: holding
address: 0x0b66
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Ciśnienie w układzie"
id: presaure
register_type: holding
address: 0x0b4e
value_type: S_WORD
unit_of_measurement: "bar"
accuracy_decimals: 1
device_class: pressure
filters:
- multiply: 0.01
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Przepływ"
id: flow
register_type: holding
address: 0x0b4f
value_type: U_WORD
device_class: volume_flow_rate
unit_of_measurement: "l/min"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: template
name: "Moc"
id: power_main
unit_of_measurement: "kW"
device_class: power
lambda: |-
int value = id(wb_power).state;
if (value > 0 && value <= 24)
{
return value ;
}
else
{ return 0; }
- platform: template
name: "Moc CO"
internal: true
id: power_co
unit_of_measurement: "kW"
device_class: power
accuracy_decimals: 1
lambda: |-
int value = id(wb_power).state;
if (id(sensor_wb_co).state == 1 && id(tdr).state == "co") {
return value;
} else {
return 0;
}
- platform: template
name: "Moc CWU"
internal: true
id: power_cwu
unit_of_measurement: "kW"
device_class: power
lambda: |-
int value = id(wb_power).state;
if (id(sensor_wb_cwu).state == 1 && id(tdr).state == "cwu") {
return value;
} else {
return 0;
}
- platform: modbus_controller
modbus_controller_id: kospel
name: "Maksymalna moc kotła"
id: max_power
register_type: holding
address: 0x0b34
value_type: S_WORD
unit_of_measurement: "kW"
device_class: power
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] Wejścia binarne"
internal: true
id: wb
register_type: holding
address: 0x0b51
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] Wejścia binarne temperatury pokojowe"
internal: true
id: buff
register_type: holding
address: 0x0b8a
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] MOC"
internal: false
id: wb_power
register_type: holding
accuracy_decimals: 1
filters:
- multiply: 0.1
address: 0x0b46
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
on_value:
- component.update: power_main
- component.update: power_co
- component.update: power_cwu
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] Wejścia binarne rw_flagi_1"
internal: true
id: wbrwf1
register_type: holding
address: 0x0b55
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] Błędy"
internal: true
id: errorcode
register_type: holding
address: 0x0b52
binary_sensor:
- platform: template
name: "[WB] CO_YES_NO"
lambda: |-
uint16_t value = (int(id(wbrwf1).state) & 0xFF00) >> 8 | (int(id(wbrwf1).state) & 0x00FF);
return ((value >> 4) & 1);
- platform: template
name: "[WB] Pompa"
icon: mdi:pump
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return (value & 1);
- platform: template
name: "[WB] Pompa cyrkulacyjna"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 1) & 1);
- platform: template
name: "[WB] Wejscie sygnału nadrzędnego"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 3) & 1);
- platform: template
name: "[WB] Wejście regulatora pokojowego"
icon: mdi:thermostat
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 4) & 1);
- platform: template
name: "[WB] Fun"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 6) & 1);
- platform: template
name: "[WB] CO"
id: sensor_wb_co
icon: mdi:heating-coil
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 7) & 1);
- platform: template
name: "[WB] CWU"
icon: mdi:faucet-variant
id: sensor_wb_cwu
lambda: |-
return ((int(id(wb).state) >> 8) & 1);
#Konfiguracja
text_sensor:
- platform: modbus_controller
modbus_controller_id: kospel
name: "Tryb pracy boilera"
id: tryb_pracy_boilera
register_type: holding
address: 0x0b30
raw_encode: HEXBYTES
lambda: |-
uint16_t value = data[1] << 8 | data[0];
switch (value) {
case 0: return std::string("Ekonomiczny");
case 1: return std::string("Przeciw zamarzanie");
case 2: return std::string("Komfortowy");
default: return std::string("Unknown");
}
return x;
- platform: modbus_controller
modbus_controller_id: kospel
name: "CO Regulacja"
id: tryb_pracy_co
register_type: holding
address: 0x0b55
raw_encode: HEXBYTES
lambda: |-
uint16_t value = int(id(wbrwf1).state);
switch (((value >> 6) & 1) == 0) {
case 0: return std::string("Krzywa grzania");
case 1: return std::string("Nastawa ręczna");
}
return x;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Tryb pracy kotła"
id: tryb_pracy_kotla
register_type: holding
address: 0x0b32
raw_encode: HEXBYTES
lambda: |-
uint16_t value = data[1] << 8 | data[0];
switch (value) {
case 0: return std::string("Ekonomiczny");
case 1: return std::string("Przeciwzamarzanie");
case 2: return std::string("Komfortowy");
case 3: return std::string("Komfortowy minus");
case 4: return std::string("Komfortowy plus");
case 64: return std::string("Grzanie pokoju");
default: return std::string("Unknown");
}
return x;
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] Zawór TDR"
icon: mdi:pipe-valve
id: tdr
register_type: holding
address: 0x0b51
raw_encode: HEXBYTES
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
value = ((value >> 2) & 1);
switch (value) {
case 0: return std::string("co");
case 1: return std::string("cwu");
default: return std::string("Unknown");
}
return x;

5722
module_scrap.html Normal file

File diff suppressed because one or more lines are too long

BIN
rejestry.ods Normal file

Binary file not shown.