ESPHome 2025.5.0
Loading...
Searching...
No Matches
hub.cpp
Go to the documentation of this file.
1#include "hub.h"
3
4#include <string>
5
6namespace esphome {
7namespace opentherm {
8
9static const char *const TAG = "opentherm";
10namespace message_data {
11bool parse_flag8_lb_0(OpenthermData &data) { return read_bit(data.valueLB, 0); }
12bool parse_flag8_lb_1(OpenthermData &data) { return read_bit(data.valueLB, 1); }
13bool parse_flag8_lb_2(OpenthermData &data) { return read_bit(data.valueLB, 2); }
14bool parse_flag8_lb_3(OpenthermData &data) { return read_bit(data.valueLB, 3); }
15bool parse_flag8_lb_4(OpenthermData &data) { return read_bit(data.valueLB, 4); }
16bool parse_flag8_lb_5(OpenthermData &data) { return read_bit(data.valueLB, 5); }
17bool parse_flag8_lb_6(OpenthermData &data) { return read_bit(data.valueLB, 6); }
18bool parse_flag8_lb_7(OpenthermData &data) { return read_bit(data.valueLB, 7); }
19bool parse_flag8_hb_0(OpenthermData &data) { return read_bit(data.valueHB, 0); }
20bool parse_flag8_hb_1(OpenthermData &data) { return read_bit(data.valueHB, 1); }
21bool parse_flag8_hb_2(OpenthermData &data) { return read_bit(data.valueHB, 2); }
22bool parse_flag8_hb_3(OpenthermData &data) { return read_bit(data.valueHB, 3); }
23bool parse_flag8_hb_4(OpenthermData &data) { return read_bit(data.valueHB, 4); }
24bool parse_flag8_hb_5(OpenthermData &data) { return read_bit(data.valueHB, 5); }
25bool parse_flag8_hb_6(OpenthermData &data) { return read_bit(data.valueHB, 6); }
26bool parse_flag8_hb_7(OpenthermData &data) { return read_bit(data.valueHB, 7); }
27uint8_t parse_u8_lb(OpenthermData &data) { return data.valueLB; }
28uint8_t parse_u8_hb(OpenthermData &data) { return data.valueHB; }
29int8_t parse_s8_lb(OpenthermData &data) { return (int8_t) data.valueLB; }
30int8_t parse_s8_hb(OpenthermData &data) { return (int8_t) data.valueHB; }
31uint16_t parse_u16(OpenthermData &data) { return data.u16(); }
32uint16_t parse_u8_lb_60(OpenthermData &data) { return data.valueLB * 60; }
33uint16_t parse_u8_hb_60(OpenthermData &data) { return data.valueHB * 60; }
34int16_t parse_s16(OpenthermData &data) { return data.s16(); }
35float parse_f88(OpenthermData &data) { return data.f88(); }
36
37void write_flag8_lb_0(const bool value, OpenthermData &data) { data.valueLB = write_bit(data.valueLB, 0, value); }
38void write_flag8_lb_1(const bool value, OpenthermData &data) { data.valueLB = write_bit(data.valueLB, 1, value); }
39void write_flag8_lb_2(const bool value, OpenthermData &data) { data.valueLB = write_bit(data.valueLB, 2, value); }
40void write_flag8_lb_3(const bool value, OpenthermData &data) { data.valueLB = write_bit(data.valueLB, 3, value); }
41void write_flag8_lb_4(const bool value, OpenthermData &data) { data.valueLB = write_bit(data.valueLB, 4, value); }
42void write_flag8_lb_5(const bool value, OpenthermData &data) { data.valueLB = write_bit(data.valueLB, 5, value); }
43void write_flag8_lb_6(const bool value, OpenthermData &data) { data.valueLB = write_bit(data.valueLB, 6, value); }
44void write_flag8_lb_7(const bool value, OpenthermData &data) { data.valueLB = write_bit(data.valueLB, 7, value); }
45void write_flag8_hb_0(const bool value, OpenthermData &data) { data.valueHB = write_bit(data.valueHB, 0, value); }
46void write_flag8_hb_1(const bool value, OpenthermData &data) { data.valueHB = write_bit(data.valueHB, 1, value); }
47void write_flag8_hb_2(const bool value, OpenthermData &data) { data.valueHB = write_bit(data.valueHB, 2, value); }
48void write_flag8_hb_3(const bool value, OpenthermData &data) { data.valueHB = write_bit(data.valueHB, 3, value); }
49void write_flag8_hb_4(const bool value, OpenthermData &data) { data.valueHB = write_bit(data.valueHB, 4, value); }
50void write_flag8_hb_5(const bool value, OpenthermData &data) { data.valueHB = write_bit(data.valueHB, 5, value); }
51void write_flag8_hb_6(const bool value, OpenthermData &data) { data.valueHB = write_bit(data.valueHB, 6, value); }
52void write_flag8_hb_7(const bool value, OpenthermData &data) { data.valueHB = write_bit(data.valueHB, 7, value); }
53void write_u8_lb(const uint8_t value, OpenthermData &data) { data.valueLB = value; }
54void write_u8_hb(const uint8_t value, OpenthermData &data) { data.valueHB = value; }
55void write_s8_lb(const int8_t value, OpenthermData &data) { data.valueLB = (uint8_t) value; }
56void write_s8_hb(const int8_t value, OpenthermData &data) { data.valueHB = (uint8_t) value; }
57void write_u16(const uint16_t value, OpenthermData &data) { data.u16(value); }
58void write_s16(const int16_t value, OpenthermData &data) { data.s16(value); }
59void write_f88(const float value, OpenthermData &data) { data.f88(value); }
60
61} // namespace message_data
62
64 OpenthermData data;
65 data.type = 0;
66 data.id = request_id;
67 data.valueHB = 0;
68 data.valueLB = 0;
69
70 // We need this special logic for STATUS message because we have two options for specifying boiler modes:
71 // with static config values in the hub, or with separate switches.
72 if (request_id == MessageId::STATUS) {
73 // NOLINTBEGIN
74 bool const ch_enabled = this->ch_enable && OPENTHERM_READ_ch_enable && OPENTHERM_READ_t_set > 0.0;
75 bool const dhw_enabled = this->dhw_enable && OPENTHERM_READ_dhw_enable;
76 bool const cooling_enabled =
77 this->cooling_enable && OPENTHERM_READ_cooling_enable && OPENTHERM_READ_cooling_control > 0.0;
78 bool const otc_enabled = this->otc_active && OPENTHERM_READ_otc_active;
79 bool const ch2_enabled = this->ch2_active && OPENTHERM_READ_ch2_active && OPENTHERM_READ_t_set_ch2 > 0.0;
80 bool const summer_mode_is_active = this->summer_mode_active && OPENTHERM_READ_summer_mode_active;
81 bool const dhw_blocked = this->dhw_block && OPENTHERM_READ_dhw_block;
82 // NOLINTEND
83
85 data.valueHB = ch_enabled | (dhw_enabled << 1) | (cooling_enabled << 2) | (otc_enabled << 3) | (ch2_enabled << 4) |
86 (summer_mode_is_active << 5) | (dhw_blocked << 6);
87
88 return data;
89 }
90
91 // Next, we start with write requests from switches and other inputs,
92 // because we would want to write that data if it is available, rather than
93 // request a read for that type (in the case that both read and write are
94 // supported).
95 switch (request_id) {
96 OPENTHERM_SWITCH_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_WRITE_MESSAGE, OPENTHERM_MESSAGE_WRITE_ENTITY, ,
97 OPENTHERM_MESSAGE_WRITE_POSTSCRIPT, )
98 OPENTHERM_NUMBER_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_WRITE_MESSAGE, OPENTHERM_MESSAGE_WRITE_ENTITY, ,
99 OPENTHERM_MESSAGE_WRITE_POSTSCRIPT, )
100 OPENTHERM_OUTPUT_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_WRITE_MESSAGE, OPENTHERM_MESSAGE_WRITE_ENTITY, ,
101 OPENTHERM_MESSAGE_WRITE_POSTSCRIPT, )
102 OPENTHERM_INPUT_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_WRITE_MESSAGE, OPENTHERM_MESSAGE_WRITE_ENTITY, ,
103 OPENTHERM_MESSAGE_WRITE_POSTSCRIPT, )
104 OPENTHERM_SETTING_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_WRITE_MESSAGE, OPENTHERM_MESSAGE_WRITE_SETTING, ,
105 OPENTHERM_MESSAGE_WRITE_POSTSCRIPT, )
106 default:
107 break;
108 }
109
110 // Finally, handle the simple read requests, which only change with the message id.
111 switch (request_id) {
112 OPENTHERM_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_READ_MESSAGE, OPENTHERM_IGNORE, , , )
113 default:
114 break;
115 }
116 switch (request_id) {
117 OPENTHERM_BINARY_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_READ_MESSAGE, OPENTHERM_IGNORE, , , )
118 default:
119 break;
120 }
121
122 // And if we get here, a message was requested which somehow wasn't handled.
123 // This shouldn't happen due to the way the defines are configured, so we
124 // log an error and just return a 0 message.
125 ESP_LOGE(TAG, "Tried to create a request with unknown id %d. This should never happen, so please open an issue.",
126 request_id);
127 return {};
128}
129
130OpenthermHub::OpenthermHub() : Component(), in_pin_{}, out_pin_{} {}
131
133 ESP_LOGD(TAG, "Received OpenTherm response with id %d (%s)", data.id,
134 this->opentherm_->message_id_to_str((MessageId) data.id));
135 this->opentherm_->debug_data(data);
136
137 switch (data.id) {
138 OPENTHERM_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_RESPONSE_MESSAGE, OPENTHERM_MESSAGE_RESPONSE_ENTITY, ,
139 OPENTHERM_MESSAGE_RESPONSE_POSTSCRIPT, )
140 }
141 switch (data.id) {
142 OPENTHERM_BINARY_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_RESPONSE_MESSAGE, OPENTHERM_MESSAGE_RESPONSE_ENTITY, ,
143 OPENTHERM_MESSAGE_RESPONSE_POSTSCRIPT, )
144 }
145}
146
148 ESP_LOGD(TAG, "Setting up OpenTherm component");
150 if (!this->opentherm_->initialize()) {
151 ESP_LOGE(TAG, "Failed to initialize OpenTherm protocol. See previous log messages for details.");
152 this->mark_failed();
153 return;
154 }
155
156 // Ensure that there is at least one request, as we are required to
157 // communicate at least once every second. Sending the status request is
158 // good practice anyway.
161 this->message_iterator_ = this->messages_.begin();
162}
163
164void OpenthermHub::on_shutdown() { this->opentherm_->stop(); }
165
166// Disabling clang-tidy for this particular line since it keeps removing the trailing underscore (bug?)
167void OpenthermHub::write_initial_messages_(std::vector<MessageId> &target) { // NOLINT
168 std::vector<std::pair<MessageId, uint8_t>> sorted;
169 std::copy_if(this->configured_messages_.begin(), this->configured_messages_.end(), std::back_inserter(sorted),
170 [](const std::pair<MessageId, uint8_t> &pair) { return pair.second < REPEATING_MESSAGE_ORDER; });
171 std::sort(sorted.begin(), sorted.end(),
172 [](const std::pair<MessageId, uint8_t> &a, const std::pair<MessageId, uint8_t> &b) {
173 return a.second < b.second;
174 });
175
176 target.clear();
177 std::transform(sorted.begin(), sorted.end(), std::back_inserter(target),
178 [](const std::pair<MessageId, uint8_t> &pair) { return pair.first; });
179}
180
181// Disabling clang-tidy for this particular line since it keeps removing the trailing underscore (bug?)
182void OpenthermHub::write_repeating_messages_(std::vector<MessageId> &target) { // NOLINT
183 target.clear();
184 for (auto const &pair : this->configured_messages_) {
185 if (pair.second == REPEATING_MESSAGE_ORDER) {
186 target.push_back(pair.first);
187 }
188 }
189}
190
192 if (this->sync_mode_) {
193 this->sync_loop_();
194 return;
195 }
196
197 auto cur_time = millis();
198 auto const cur_mode = this->opentherm_->get_mode();
199
200 if (this->handle_error_(cur_mode)) {
201 return;
202 }
203
204 switch (cur_mode) {
208 break;
210 this->check_timings_(cur_time);
211 if (this->should_skip_loop_(cur_time)) {
212 break;
213 }
214 this->start_conversation_();
215 break;
217 // Message sent, now listen for the response.
218 this->opentherm_->listen();
219 break;
221 this->read_response_();
222 break;
223 default:
224 break;
225 }
226 this->last_mode_ = cur_mode;
227}
228
230 switch (mode) {
232 // Protocol error can happen only while reading boiler response.
234 return true;
236 // Timeout error might happen while we wait for device to respond.
237 this->handle_timeout_error_();
238 return true;
240 // Timer error can happen only on ESP32.
241 this->handle_timer_error_();
242 return true;
243 default:
244 return false;
245 }
246}
247
249 if (!this->opentherm_->is_idle()) {
250 ESP_LOGE(TAG, "OpenTherm is not idle at the start of the loop");
251 return;
252 }
253
254 auto cur_time = millis();
255
256 this->check_timings_(cur_time);
257
258 if (this->should_skip_loop_(cur_time)) {
259 return;
260 }
261
262 this->start_conversation_();
263 // There may be a timer error at this point
264 if (this->handle_error_(this->opentherm_->get_mode())) {
265 return;
266 }
267
268 // Spin while message is being sent to device
269 if (!this->spin_wait_(1150, [&] { return this->opentherm_->is_active(); })) {
270 ESP_LOGE(TAG, "Hub timeout triggered during send");
271 this->stop_opentherm_();
272 return;
273 }
274
275 // Check for errors and ensure we are in the right state (message sent successfully)
276 if (this->handle_error_(this->opentherm_->get_mode())) {
277 return;
278 } else if (!this->opentherm_->is_sent()) {
279 ESP_LOGW(TAG, "Unexpected state after sending request: %s",
280 this->opentherm_->operation_mode_to_str(this->opentherm_->get_mode()));
281 this->stop_opentherm_();
282 return;
283 }
284
285 // Listen for the response
286 this->opentherm_->listen();
287 // There may be a timer error at this point
288 if (this->handle_error_(this->opentherm_->get_mode())) {
289 return;
290 }
291
292 // Spin while response is being received
293 if (!this->spin_wait_(1150, [&] { return this->opentherm_->is_active(); })) {
294 ESP_LOGE(TAG, "Hub timeout triggered during receive");
295 this->stop_opentherm_();
296 return;
297 }
298
299 // Check for errors and ensure we are in the right state (message received successfully)
300 if (this->handle_error_(this->opentherm_->get_mode())) {
301 return;
302 } else if (!this->opentherm_->has_message()) {
303 ESP_LOGW(TAG, "Unexpected state after receiving response: %s",
304 this->opentherm_->operation_mode_to_str(this->opentherm_->get_mode()));
305 this->stop_opentherm_();
306 return;
307 }
308
309 this->read_response_();
310}
311
312void OpenthermHub::check_timings_(uint32_t cur_time) {
313 if (this->last_conversation_start_ > 0 && (cur_time - this->last_conversation_start_) > 1150) {
314 ESP_LOGW(TAG,
315 "%d ms elapsed since the start of the last convo, but 1150 ms are allowed at maximum. Look at other "
316 "components that might slow the loop down.",
317 (int) (cur_time - this->last_conversation_start_));
318 }
319}
320
321bool OpenthermHub::should_skip_loop_(uint32_t cur_time) const {
322 if (this->last_conversation_end_ > 0 && (cur_time - this->last_conversation_end_) < 100) {
323 ESP_LOGV(TAG, "Less than 100 ms elapsed since last convo, skipping this iteration");
324 return true;
325 }
326
327 return false;
328}
329
331 if (this->message_iterator_ == this->messages_.end()) {
332 if (this->sending_initial_) {
333 this->sending_initial_ = false;
335 }
336 this->message_iterator_ = this->messages_.begin();
337 }
338
339 auto request = this->build_request_(*this->message_iterator_);
340
341 this->before_send_callback_.call(request);
342
343 ESP_LOGD(TAG, "Sending request with id %d (%s)", request.id,
344 this->opentherm_->message_id_to_str((MessageId) request.id));
345 this->opentherm_->debug_data(request);
346 // Send the request
348 this->opentherm_->send(request);
349}
350
352 OpenthermData response;
353 if (!this->opentherm_->get_message(response)) {
354 ESP_LOGW(TAG, "Couldn't get the response, but flags indicated success. This is a bug.");
355 this->stop_opentherm_();
356 return;
357 }
358
359 this->stop_opentherm_();
360
361 this->before_process_response_callback_.call(response);
362 this->process_response(response);
363
364 this->message_iterator_++;
365}
366
368 this->opentherm_->stop();
370}
371
373 OpenThermError error;
374 this->opentherm_->get_protocol_error(error);
375 ESP_LOGW(TAG, "Protocol error occured while receiving response: %s",
376 this->opentherm_->protocol_error_to_str(error.error_type));
377 this->opentherm_->debug_error(error);
378 this->stop_opentherm_();
379}
380
382 ESP_LOGW(TAG, "Timeout while waiting for response from device");
383 this->stop_opentherm_();
384}
385
387 this->opentherm_->report_and_reset_timer_error();
388 this->stop_opentherm_();
389 // Timer error is critical, there is no point in retrying.
390 this->mark_failed();
391}
392
394 std::vector<MessageId> initial_messages;
395 std::vector<MessageId> repeating_messages;
396 this->write_initial_messages_(initial_messages);
397 this->write_repeating_messages_(repeating_messages);
398
399 ESP_LOGCONFIG(TAG, "OpenTherm:");
400 LOG_PIN(" In: ", this->in_pin_);
401 LOG_PIN(" Out: ", this->out_pin_);
402 ESP_LOGCONFIG(TAG, " Sync mode: %s", YESNO(this->sync_mode_));
403 ESP_LOGCONFIG(TAG, " Sensors: %s", SHOW(OPENTHERM_SENSOR_LIST(ID, )));
404 ESP_LOGCONFIG(TAG, " Binary sensors: %s", SHOW(OPENTHERM_BINARY_SENSOR_LIST(ID, )));
405 ESP_LOGCONFIG(TAG, " Switches: %s", SHOW(OPENTHERM_SWITCH_LIST(ID, )));
406 ESP_LOGCONFIG(TAG, " Input sensors: %s", SHOW(OPENTHERM_INPUT_SENSOR_LIST(ID, )));
407 ESP_LOGCONFIG(TAG, " Outputs: %s", SHOW(OPENTHERM_OUTPUT_LIST(ID, )));
408 ESP_LOGCONFIG(TAG, " Numbers: %s", SHOW(OPENTHERM_NUMBER_LIST(ID, )));
409 ESP_LOGCONFIG(TAG, " Initial requests:");
410 for (auto type : initial_messages) {
411 ESP_LOGCONFIG(TAG, " - %d (%s)", type, this->opentherm_->message_id_to_str(type));
412 }
413 ESP_LOGCONFIG(TAG, " Repeating requests:");
414 for (auto type : repeating_messages) {
415 ESP_LOGCONFIG(TAG, " - %d (%s)", type, this->opentherm_->message_id_to_str(type));
416 }
417}
418
419} // namespace opentherm
420} // namespace esphome
BedjetMode mode
BedJet operating mode.
virtual void mark_failed()
Mark this component as failed.
OPENTHERM_SENSOR_LIST(OPENTHERM_DECLARE_SENSOR,) OPENTHERM_BINARY_SENSOR_LIST(OPENTHERM_DECLARE_BINARY_SENSOR
void check_timings_(uint32_t cur_time)
Definition hub.cpp:312
void dump_config() override
Definition hub.cpp:393
void on_shutdown() override
Definition hub.cpp:164
std::vector< MessageId > messages_
Definition hub.h:68
OpenthermData build_request_(MessageId request_id) const
Definition hub.cpp:63
OperationMode last_mode_
Definition hub.h:73
void add_repeating_message(MessageId message_id)
Definition hub.h:146
InternalGPIOPin * out_pin_
Definition hub.h:48
std::unordered_map< MessageId, uint8_t > configured_messages_
Definition hub.h:67
void process_response(OpenthermData &data)
Definition hub.cpp:132
OPENTHERM_SWITCH_LIST(OPENTHERM_DECLARE_SWITCH,) OPENTHERM_NUMBER_LIST(OPENTHERM_DECLARE_NUMBER
InternalGPIOPin * in_pin_
Definition hub.h:48
CallbackManager< void(OpenthermData &)> before_send_callback_
Definition hub.h:81
bool handle_error_(OperationMode mode)
Definition hub.cpp:229
CallbackManager< void(OpenthermData &)> before_process_response_callback_
Definition hub.h:82
bool spin_wait_(uint32_t timeout, F func)
Definition hub.h:100
std::vector< MessageId >::const_iterator message_iterator_
Definition hub.h:69
uint32_t last_conversation_start_
Definition hub.h:71
void write_initial_messages_(std::vector< MessageId > &target)
Definition hub.cpp:167
void write_repeating_messages_(std::vector< MessageId > &target)
Definition hub.cpp:182
bool should_skip_loop_(uint32_t cur_time) const
Definition hub.cpp:321
OPENTHERM_OUTPUT_LIST(OPENTHERM_DECLARE_OUTPUT,) OPENTHERM_INPUT_SENSOR_LIST(OPENTHERM_DECLARE_INPUT_SENSOR
std::unique_ptr< OpenTherm > opentherm_
Definition hub.h:50
uint8_t type
void write_flag8_lb_4(const bool value, OpenthermData &data)
Definition hub.cpp:41
bool parse_flag8_lb_3(OpenthermData &data)
Definition hub.cpp:14
bool parse_flag8_lb_2(OpenthermData &data)
Definition hub.cpp:13
bool parse_flag8_lb_5(OpenthermData &data)
Definition hub.cpp:16
void write_flag8_lb_7(const bool value, OpenthermData &data)
Definition hub.cpp:44
uint16_t parse_u16(OpenthermData &data)
Definition hub.cpp:31
bool parse_flag8_hb_7(OpenthermData &data)
Definition hub.cpp:26
int8_t parse_s8_hb(OpenthermData &data)
Definition hub.cpp:30
bool parse_flag8_lb_0(OpenthermData &data)
Definition hub.cpp:11
void write_flag8_lb_5(const bool value, OpenthermData &data)
Definition hub.cpp:42
bool parse_flag8_hb_3(OpenthermData &data)
Definition hub.cpp:22
void write_flag8_hb_7(const bool value, OpenthermData &data)
Definition hub.cpp:52
bool parse_flag8_lb_6(OpenthermData &data)
Definition hub.cpp:17
bool parse_flag8_hb_5(OpenthermData &data)
Definition hub.cpp:24
void write_s8_lb(const int8_t value, OpenthermData &data)
Definition hub.cpp:55
uint8_t parse_u8_hb(OpenthermData &data)
Definition hub.cpp:28
void write_flag8_lb_2(const bool value, OpenthermData &data)
Definition hub.cpp:39
void write_flag8_hb_4(const bool value, OpenthermData &data)
Definition hub.cpp:49
void write_u16(const uint16_t value, OpenthermData &data)
Definition hub.cpp:57
void write_s8_hb(const int8_t value, OpenthermData &data)
Definition hub.cpp:56
bool parse_flag8_hb_4(OpenthermData &data)
Definition hub.cpp:23
void write_flag8_hb_5(const bool value, OpenthermData &data)
Definition hub.cpp:50
void write_flag8_lb_1(const bool value, OpenthermData &data)
Definition hub.cpp:38
void write_u8_lb(const uint8_t value, OpenthermData &data)
Definition hub.cpp:53
void write_flag8_lb_3(const bool value, OpenthermData &data)
Definition hub.cpp:40
float parse_f88(OpenthermData &data)
Definition hub.cpp:35
void write_s16(const int16_t value, OpenthermData &data)
Definition hub.cpp:58
bool parse_flag8_hb_6(OpenthermData &data)
Definition hub.cpp:25
void write_flag8_hb_2(const bool value, OpenthermData &data)
Definition hub.cpp:47
bool parse_flag8_hb_1(OpenthermData &data)
Definition hub.cpp:20
int16_t parse_s16(OpenthermData &data)
Definition hub.cpp:34
void write_flag8_hb_3(const bool value, OpenthermData &data)
Definition hub.cpp:48
bool parse_flag8_lb_4(OpenthermData &data)
Definition hub.cpp:15
uint16_t parse_u8_hb_60(OpenthermData &data)
Definition hub.cpp:33
bool parse_flag8_hb_0(OpenthermData &data)
Definition hub.cpp:19
void write_flag8_lb_0(const bool value, OpenthermData &data)
Definition hub.cpp:37
uint16_t parse_u8_lb_60(OpenthermData &data)
Definition hub.cpp:32
void write_f88(const float value, OpenthermData &data)
Definition hub.cpp:59
void write_flag8_hb_6(const bool value, OpenthermData &data)
Definition hub.cpp:51
bool parse_flag8_lb_7(OpenthermData &data)
Definition hub.cpp:18
void write_u8_hb(const uint8_t value, OpenthermData &data)
Definition hub.cpp:54
void write_flag8_hb_1(const bool value, OpenthermData &data)
Definition hub.cpp:46
void write_flag8_hb_0(const bool value, OpenthermData &data)
Definition hub.cpp:45
int8_t parse_s8_lb(OpenthermData &data)
Definition hub.cpp:29
void write_flag8_lb_6(const bool value, OpenthermData &data)
Definition hub.cpp:43
uint8_t parse_u8_lb(OpenthermData &data)
Definition hub.cpp:27
bool parse_flag8_lb_1(OpenthermData &data)
Definition hub.cpp:12
bool parse_flag8_hb_2(OpenthermData &data)
Definition hub.cpp:21
constexpr T write_bit(T value, uint8_t bit, uint8_t bit_value)
Definition opentherm.h:28
constexpr T read_bit(T value, uint8_t bit)
Definition opentherm.h:22
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::unique_ptr< T > make_unique(Args &&...args)
Definition helpers.h:85
uint32_t IRAM_ATTR HOT millis()
Definition core.cpp:27
Structure to hold Opentherm data packet content.
Definition opentherm.h:184