khenderick / esphome-opentherm Goto Github PK
View Code? Open in Web Editor NEWOpenTherm support for ESPHome
License: MIT License
OpenTherm support for ESPHome
License: MIT License
MessageID::Status enableOutsideTemperatureCompensation << 3
Temperatures changed on the boiler, are not reflected on gateway without restart
Looks like they are read once during boot.
Add ch2_enabled, for boilers with indirect heating, the inclusion of a second heating circuit is required (Baxi Nuvola-3 b40)
Good afternoon, some boilers require messaging, otherwise they cannot be controlled:
OpenThermMessageType::READ_DATA, OpenThermMessageID::BOILER_CONFIGURATION, 0xFFFF);
uint8_t SlaveMemberIDcode = respons3 >> 0 & 0xFF;
OpenThermMessageType::WRITE_DATA, OpenThermMessageID::DEVICE_CONFIGURATION, SlaveMemberIDcode);
OpenThermMessageType::READ_DATA, OpenThermMessageID::BOILER_VERSION, 0);
OpenThermMessageType::WRITE_DATA, OpenThermMessageID::DEVICE_VERSION, 0x013F);
Hi,
Awesome work, best esphome opentherm implementation i have seen yet!
The only issue i have is that a couple times per hour bit errors occur, i tried to make a really solid connection between the boiler and my diyless opentherm shield but the bit errors still occur. Anyone else with the same issue?
Is it maybe possible to implement some sort of error checking?
Thx
Hi,
I'm trying to make a PID climate thermostat using your code. As far as i know the homeassistant generic thermostat is just a basic on/off thermostat. I tried to use the esphome PID climate component but i am struggling with the heat_output parameter. This expects an output. I tried to set the ch_setpoint_temperature, but this is a number so it's not compatible with the output component.
How would i implement a PID climate using the ch_setpoint_temperature number?
Thanks
Hi @khenderick! @Alexwijn and I created a HACS custom component called Smart Autotune Thermostat. At the moment we are able to control an Opentherm Gas boiler through an OTGW ( MQTT or Serial ). We would like to expand the compatibility of supported devices to DIYLess and Ihor Melnyk boards and I came across your work. It looks that your ESPhome component is the perfect solution in order to support these boards. But in order to achive it, we need your help. Your component is missing the Max Modulation
sensor ( ID14
) and an input number for max_modulation management. These 2 sensors will be used in order to implement the native Low-Load control operation like most modern thermostats do. If you can help us it will be amazing! Then we will be able to create a new coordinator for your component.
P.S. This is the MQTT coordinator as an example.
Thanks in advance.
In OT3.0 the HB flag8 have these description:
bit:description {clear/0, set/1}
0: CH enable [CH is disabled, CH is enabled]
1: DHW enable [DHW is disabled, DHW is enabled]
2: Cooling enable [Cooling is disabled, Cooling is enabled]
3: OTC active [OTC not active, OTC is active]
4: CH2 enable [CH2 is disabled, CH2 is enabled]
5: Summer/winter mode [winter mode active, summer mode active]
6: DHW blocking [DHW unblocked, DHW blocked]
BAXI bowlers neet BLOR comand to reset an error
Now I use template button with lambda, but it need to remove private: section from your header. It's better to include this button to component
Is there an easy way to add entities? For example I can read MSG_DHW_FLOW_RATE from my boiler, but no MSG_CH_PRESSURE or MSG_TRET (just removed them from yaml).
.
upd>
I can see continous
[10:35:22][W][opentherm:206]: Received invalid response: UNKNOWN_DATA_ID(28, 0x0000)
[10:35:23][W][opentherm:206]: Received invalid response: UNKNOWN_DATA_ID(18, 0x0000)
in the log.
Removing\commenting in yaml is not enoght, absent entities must be disabled deeper
With an example config:
esphome:
name: climatest
friendly_name: climatest
esp8266:
board: d1_mini
logger:
api:
ota:
wifi:
ssid: !secret ssid
password: !secret PWD
external_components:
source: github://khenderick/esphome-opentherm
components: [opentherm]
opentherm:
read_pin: 4
write_pin: 5
**The rest is from Example entry for config.yaml:**
I have this compilation error:
INFO ESPHome 2023.5.5
INFO Reading configuration /config/climatest.yaml...
INFO Generating C++ source...
INFO Compiling app...
Processing climatest (board: d1_mini; framework: arduino; platform: platformio/[email protected])
--------------------------------------------------------------------------------
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
Dependency Graph
|-- ESPAsyncTCP-esphome @ 1.2.3
|-- ESPAsyncWebServer-esphome @ 2.1.0
| |-- ESPAsyncTCP-esphome @ 1.2.3
| |-- Hash @ 1.0
| |-- ESP8266WiFi @ 1.0
|-- DNSServer @ 1.1.1
|-- ESP8266WiFi @ 1.0
|-- ESP8266mDNS @ 1.2
|-- noise-c @ 0.1.4
| |-- libsodium @ 1.10018.1
Compiling .pioenvs/climatest/src/esphome/components/opentherm/number/custom_number.cpp.o
Compiling .pioenvs/climatest/src/esphome/components/ota/ota_backend_arduino_esp8266.cpp.o
Compiling .pioenvs/climatest/src/esphome/components/ota/ota_backend_arduino_rp2040.cpp.o
Compiling .pioenvs/climatest/src/esphome/components/ota/ota_backend_esp_idf.cpp.o
Compiling .pioenvs/climatest/src/esphome/components/ota/ota_component.cpp.o
Compiling .pioenvs/climatest/src/esphome/components/sensor/automation.cpp.o
In file included from src/esphome/components/opentherm/number/custom_number.cpp:1:
src/esphome/components/opentherm/number/custom_number.cpp: In member function 'void esphome::opentherm::CustomNumber::dump_custom_config(const char*, const char*)':
src/esphome/components/opentherm/number/custom_number.cpp:31:22: error: initializer fails to determine size of '__pstr__'
31 | LOG_NUMBER(prefix, type, this);
src/esphome/core/log.h:94:90: note: in definition of macro 'esph_log_config'
94 | esp_log_printf_(ESPHOME_LOG_LEVEL_CONFIG, tag, __LINE__, ESPHOME_LOG_FORMAT(format), ##__VA_ARGS__)
| ^~~~~~~~~~~
src/esphome/components/number/number.h:14:5: note: in expansion of macro 'ESP_LOGCONFIG'
14 | ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
| ^~~~~~~~~~~~~
src/esphome/core/log.h:185:28: note: in expansion of macro 'LOG_STR_ARG'
185 | #define LOG_STR_LITERAL(s) LOG_STR_ARG(LOG_STR(s))
| ^~~~~~~~~~~
src/esphome/core/log.h:185:40: note: in expansion of macro 'LOG_STR'
185 | #define LOG_STR_LITERAL(s) LOG_STR_ARG(LOG_STR(s))
| ^~~~~~~
src/esphome/components/number/number.h:14:45: note: in expansion of macro 'LOG_STR_LITERAL'
14 | ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
| ^~~~~~~~~~~~~~~
src/esphome/components/opentherm/number/custom_number.cpp:31:3: note: in expansion of macro 'LOG_NUMBER'
31 | LOG_NUMBER(prefix, type, this);
| ^~~~~~~~~~
src/esphome/components/opentherm/number/custom_number.cpp:31:22: error: array must be initialized with a brace-enclosed initializer
31 | LOG_NUMBER(prefix, type, this);
src/esphome/core/log.h:94:90: note: in definition of macro 'esph_log_config'
94 | esp_log_printf_(ESPHOME_LOG_LEVEL_CONFIG, tag, __LINE__, ESPHOME_LOG_FORMAT(format), ##__VA_ARGS__)
| ^~~~~~~~~~~
src/esphome/components/number/number.h:14:5: note: in expansion of macro 'ESP_LOGCONFIG'
14 | ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
| ^~~~~~~~~~~~~
src/esphome/core/log.h:185:28: note: in expansion of macro 'LOG_STR_ARG'
185 | #define LOG_STR_LITERAL(s) LOG_STR_ARG(LOG_STR(s))
| ^~~~~~~~~~~
src/esphome/core/log.h:185:40: note: in expansion of macro 'LOG_STR'
185 | #define LOG_STR_LITERAL(s) LOG_STR_ARG(LOG_STR(s))
| ^~~~~~~
src/esphome/components/number/number.h:14:45: note: in expansion of macro 'LOG_STR_LITERAL'
14 | ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
| ^~~~~~~~~~~~~~~
src/esphome/components/opentherm/number/custom_number.cpp:31:3: note: in expansion of macro 'LOG_NUMBER'
31 | LOG_NUMBER(prefix, type, this);
| ^~~~~~~~~~
*** [.pioenvs/climatest/src/esphome/components/opentherm/number/custom_number.cpp.o] Error 1
========================== [FAILED] Took 3.52 seconds ==========================
Hovewer esp32 compiles OK.
My bowler need small pause (about 1-2 seconds) to send ch enabe, temperature etc after an opetherm initialisation. Now I make it using delay in on_boot automation. Wait and set value that I need from saved globals
on_boot:
then:
- delay: 2s
- lambda: |-
if( id(ch_sw_save) ) id(ch_sw).turn_on();
if( id(ch2_sw_save) ) id(ch2_sw).turn_on();
if( id(dhw_sw_save) ) id(dhw_sw).turn_on();
It's better to have simple init_delay settings in opentherm component
I would really like to thank the author of the development. This is the only development that works with idf framework without arduino. This ability have to be shown on the top of the readme.
Nevertheless I have errors listed below.
[23:47:19][W][opentherm:374]: Queue full. Discarded request: READ_DATA(119, 0x0000)
[23:47:19][W][opentherm:374]: Queue full. Discarded request: READ_DATA(123, 0x0000)
[23:47:19][W][opentherm:374]: Queue full. Discarded request: READ_DATA(5, 0x0000)
[23:47:19][W][opentherm:374]: Queue full. Discarded request: READ_DATA(3, 0x0000)
[23:47:20][W][opentherm:374]: Queue full. Discarded request: READ_DATA(6, 0x0000)
[23:47:20][W][opentherm:642]: Request timeout
[23:47:20][D][opentherm:370]: Sending request: READ_DATA(33, 0x0000)
[23:47:20][D][opentherm:370]: Enqueued request: READ_DATA(28, 0x0000)
[23:47:20][W][opentherm:374]: Queue full. Discarded request: WRITE_DATA(1, 0x0A00)
[23:47:20][W][opentherm:374]: Queue full. Discarded request: WRITE_DATA(56, 0x2600)
[23:47:20][W][opentherm:374]: Queue full. Discarded request: READ_DATA(25, 0x0000)
[23:47:20][W][opentherm:374]: Queue full. Discarded request: READ_DATA(31, 0x0000)
[23:47:20][W][opentherm:374]: Queue full. Discarded request: READ_DATA(19, 0x0000)
[23:47:21][W][opentherm:374]: Queue full. Discarded request: READ_DATA(18, 0x0000)
[23:47:21][W][opentherm:374]: Queue full. Discarded request: READ_DATA(17, 0x0000)
[23:47:21][W][opentherm:642]: Request timeout
[23:47:21][D][opentherm:370]: Sending request: READ_DATA(48, 0x0000)
[23:47:21][D][opentherm:370]: Enqueued request: READ_DATA(26, 0x0000)
[23:47:21][W][opentherm:374]: Received invalid response: DATA_INVALID(48, 0x0000)
[23:47:21][W][opentherm:374]: Queue full. Discarded request: READ_DATA(32, 0x0000)
[23:47:21][D][opentherm:370]: Sending request: WRITE_DATA(1, 0x0A00)
[23:47:22][D][opentherm:370]: Enqueued request: READ_DATA(27, 0x0000)
[23:47:22][W][opentherm:374]: Queue full. Discarded request: READ_DATA(33, 0x0000)
[23:47:22][D][opentherm:370]: Received response: WRITE_ACK(1, 0x0A00)
[23:47:22][D][opentherm:370]: Sending request: WRITE_DATA(56, 0x2600)
[23:47:22][D][opentherm:370]: Enqueued request: WRITE_DATA(1, 0x0A00)
[23:47:22][W][opentherm:374]: Queue full. Discarded request: WRITE_DATA(56, 0x2600)
[23:47:23][W][opentherm:374]: Queue full. Discarded request: READ_DATA(48, 0x0000)
[23:47:23][W][opentherm:374]: Queue full. Discarded request: READ_DATA(49, 0x0000)
[23:47:23][W][opentherm:374]: Queue full. Discarded request: READ_DATA(115, 0x0000)
[23:47:23][W][opentherm:374]: Received invalid response: DATA_INVALID(56, 0x0000)
[23:47:23][W][opentherm:374]: Queue full. Discarded request: READ_DATA(116, 0x0000)
[23:47:23][D][opentherm:370]: Sending request: READ_DATA(49, 0x0000)
[23:47:23][D][opentherm:370]: Enqueued request: READ_DATA(120, 0x0000)
[23:47:23][W][opentherm:374]: Queue full. Discarded request: READ_DATA(117, 0x0000)
[23:47:23][W][opentherm:374]: Received invalid response: DATA_INVALID(49, 0x0000)
[23:47:23][W][opentherm:374]: Queue full. Discarded request: READ_DATA(121, 0x0000)
[23:47:23][D][opentherm:370]: Sending request: READ_DATA(115, 0x0000)
[23:47:23][D][opentherm:370]: Enqueued request: READ_DATA(0, 0x0000)
[23:47:24][W][opentherm:374]: Queue full. Discarded request: READ_DATA(118, 0x0000)
[23:47:24][W][opentherm:374]: Queue full. Discarded request: READ_DATA(122, 0x0000)
[23:47:24][W][opentherm:374]: Queue full. Discarded request: READ_DATA(119, 0x0000)
[23:47:24][W][opentherm:374]: Queue full. Discarded request: READ_DATA(123, 0x0000)
My boiler is Baxi Slim 1400.
I do not modify the code. I just use the example.
What can I do with this errors?
I have tried to use
restore_mode: ALWAYS_ON
on
ch_enabled
dhwenabled
otc_active
but it doesn't seem to do anything.
switch:
- platform: opentherm
ch_enabled:
name: "CH enabled"
restore_mode: ALWAYS_ON
dhw_enabled:
name: "DHW enabled"
restore_mode: ALWAYS_ON
otc_active:
name: "OTC active"
restore_mode: ALWAYS_ON
Is this something that I am doing wrong, or is it something that needs to be implented?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.