9 static const char *
const TAG =
"opentherm";
10 namespace message_data {
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;
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);
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, )
111 switch (request_id) {
112 OPENTHERM_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_READ_MESSAGE, OPENTHERM_IGNORE, , , )
116 switch (request_id) {
117 OPENTHERM_BINARY_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_READ_MESSAGE, OPENTHERM_IGNORE, , , )
125 ESP_LOGE(TAG,
"Tried to create a request with unknown id %d. This should never happen, so please open an issue.",
133 ESP_LOGD(TAG,
"Received OpenTherm response with id %d (%s)", data.
id,
134 this->opentherm_->message_id_to_str((
MessageId) data.
id));
138 OPENTHERM_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_RESPONSE_MESSAGE, OPENTHERM_MESSAGE_RESPONSE_ENTITY, ,
139 OPENTHERM_MESSAGE_RESPONSE_POSTSCRIPT, )
142 OPENTHERM_BINARY_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_RESPONSE_MESSAGE, OPENTHERM_MESSAGE_RESPONSE_ENTITY, ,
143 OPENTHERM_MESSAGE_RESPONSE_POSTSCRIPT, )
148 ESP_LOGD(TAG,
"Setting up OpenTherm component");
151 ESP_LOGE(TAG,
"Failed to initialize OpenTherm protocol. See previous log messages for details.");
168 std::vector<std::pair<MessageId, uint8_t>> 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;
177 std::transform(sorted.begin(), sorted.end(), std::back_inserter(target),
178 [](
const std::pair<MessageId, uint8_t> &pair) {
return pair.first; });
185 if (pair.second == REPEATING_MESSAGE_ORDER) {
186 target.push_back(pair.first);
198 auto const cur_mode = this->
opentherm_->get_mode();
250 ESP_LOGE(TAG,
"OpenTherm is not idle at the start of the loop");
270 ESP_LOGE(TAG,
"Hub timeout triggered during send");
279 ESP_LOGW(TAG,
"Unexpected state after sending request: %s",
280 this->
opentherm_->operation_mode_to_str(this->opentherm_->get_mode()));
294 ESP_LOGE(TAG,
"Hub timeout triggered during receive");
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()));
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.",
323 ESP_LOGV(TAG,
"Less than 100 ms elapsed since last convo, skipping this iteration");
332 if (this->sending_initial_) {
333 this->sending_initial_ =
false;
343 ESP_LOGD(TAG,
"Sending request with id %d (%s)", request.id,
344 this->opentherm_->message_id_to_str((
MessageId) request.id));
353 if (!this->
opentherm_->get_message(response)) {
354 ESP_LOGW(TAG,
"Couldn't get the response, but flags indicated success. This is a bug.");
375 ESP_LOGW(TAG,
"Protocol error occured while receiving response: %s",
382 ESP_LOGW(TAG,
"Timeout while waiting for response from device");
387 this->
opentherm_->report_and_reset_timer_error();
394 std::vector<MessageId> initial_messages;
395 std::vector<MessageId> repeating_messages;
399 ESP_LOGCONFIG(TAG,
"OpenTherm:");
400 LOG_PIN(
" In: ", this->
in_pin_);
402 ESP_LOGCONFIG(TAG,
" Sync mode: %s", YESNO(this->
sync_mode_));
404 ESP_LOGCONFIG(TAG,
" Binary sensors: %s", SHOW(OPENTHERM_BINARY_SENSOR_LIST(ID, )));
406 ESP_LOGCONFIG(TAG,
" Input sensors: %s", SHOW(OPENTHERM_INPUT_SENSOR_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) {
413 ESP_LOGCONFIG(TAG,
" Repeating requests:");
414 for (
auto type : repeating_messages) {
void write_flag8_lb_2(const bool value, OpenthermData &data)
bool should_skip_loop_(uint32_t cur_time) const
uint16_t parse_u8_lb_60(OpenthermData &data)
uint16_t parse_u16(OpenthermData &data)
constexpr T read_bit(T value, uint8_t bit)
void check_timings_(uint32_t cur_time)
bool parse_flag8_hb_3(OpenthermData &data)
int8_t parse_s8_lb(OpenthermData &data)
void write_u16(const uint16_t value, OpenthermData &data)
void write_flag8_lb_1(const bool value, OpenthermData &data)
int16_t parse_s16(OpenthermData &data)
void write_s8_lb(const int8_t value, OpenthermData &data)
float parse_f88(OpenthermData &data)
void write_flag8_lb_7(const bool value, OpenthermData &data)
bool parse_flag8_lb_4(OpenthermData &data)
void write_s8_hb(const int8_t value, OpenthermData &data)
bool parse_flag8_lb_3(OpenthermData &data)
uint32_t last_conversation_start_
std::vector< MessageId >::const_iterator message_iterator_
uint16_t parse_u8_hb_60(OpenthermData &data)
void handle_protocol_error_()
void write_flag8_lb_3(const bool value, OpenthermData &data)
void process_response(OpenthermData &data)
std::unordered_map< MessageId, uint8_t > configured_messages_
ProtocolErrorType error_type
timeout while waiting to receive bytes
void write_f88(const float value, OpenthermData &data)
InternalGPIOPin * in_pin_
constexpr T write_bit(T value, uint8_t bit, uint8_t bit_value)
OPENTHERM_OUTPUT_LIST(OPENTHERM_DECLARE_OUTPUT,) OPENTHERM_INPUT_SENSOR_LIST(OPENTHERM_DECLARE_INPUT_SENSOR
std::unique_ptr< OpenTherm > opentherm_
bool parse_flag8_hb_1(OpenthermData &data)
void write_flag8_hb_4(const bool value, OpenthermData &data)
uint32_t IRAM_ATTR HOT millis()
bool parse_flag8_hb_2(OpenthermData &data)
bool parse_flag8_lb_0(OpenthermData &data)
bool spin_wait_(uint32_t timeout, F func)
void write_s16(const int16_t value, OpenthermData &data)
bool parse_flag8_lb_5(OpenthermData &data)
CallbackManager< void(OpenthermData &)> before_process_response_callback_
void write_flag8_hb_6(const bool value, OpenthermData &data)
bool parse_flag8_lb_7(OpenthermData &data)
bool parse_flag8_lb_6(OpenthermData &data)
void start_conversation_()
void write_flag8_hb_0(const bool value, OpenthermData &data)
void write_flag8_lb_4(const bool value, OpenthermData &data)
BedjetMode mode
BedJet operating mode.
int8_t parse_s8_hb(OpenthermData &data)
uint32_t last_conversation_end_
InternalGPIOPin * out_pin_
CallbackManager< void(OpenthermData &)> before_send_callback_
bool parse_flag8_lb_1(OpenthermData &data)
bool parse_flag8_hb_0(OpenthermData &data)
void write_flag8_lb_6(const bool value, OpenthermData &data)
bool parse_flag8_hb_7(OpenthermData &data)
uint8_t parse_u8_lb(OpenthermData &data)
void write_flag8_hb_5(const bool value, OpenthermData &data)
void handle_timer_error_()
void write_initial_messages_(std::vector< MessageId > &target)
void write_flag8_hb_1(const bool value, OpenthermData &data)
bool parse_flag8_hb_4(OpenthermData &data)
void write_flag8_hb_2(const bool value, OpenthermData &data)
void dump_config() override
bool parse_flag8_hb_6(OpenthermData &data)
bool parse_flag8_lb_2(OpenthermData &data)
virtual void mark_failed()
Mark this component as failed.
void write_flag8_hb_3(const bool value, OpenthermData &data)
OPENTHERM_SWITCH_LIST(OPENTHERM_DECLARE_SWITCH,) OPENTHERM_NUMBER_LIST(OPENTHERM_DECLARE_NUMBER
void write_flag8_hb_7(const bool value, OpenthermData &data)
Implementation of SPI Controller mode.
std::vector< MessageId > messages_
void write_repeating_messages_(std::vector< MessageId > &target)
void write_u8_lb(const uint8_t value, OpenthermData &data)
void write_u8_hb(const uint8_t value, OpenthermData &data)
void add_repeating_message(MessageId message_id)
Structure to hold Opentherm data packet content.
void handle_timeout_error_()
OPENTHERM_SENSOR_LIST(OPENTHERM_DECLARE_SENSOR,) OPENTHERM_BINARY_SENSOR_LIST(OPENTHERM_DECLARE_BINARY_SENSOR
uint8_t parse_u8_hb(OpenthermData &data)
void write_flag8_lb_5(const bool value, OpenthermData &data)
void on_shutdown() override
OpenthermData build_request_(MessageId request_id) const
void write_flag8_lb_0(const bool value, OpenthermData &data)
bool parse_flag8_hb_5(OpenthermData &data)
bool handle_error_(OperationMode mode)