ESPHome  2024.10.2
hub.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "esphome/core/defines.h"
4 #include "esphome/core/hal.h"
6 #include "esphome/core/log.h"
7 
8 #include "opentherm.h"
9 
10 #include <memory>
11 #include <unordered_map>
12 #include <unordered_set>
13 #include <functional>
14 
15 namespace esphome {
16 namespace opentherm {
17 
18 // OpenTherm component for ESPHome
19 class OpenthermHub : public Component {
20  protected:
21  // Communication pins for the OpenTherm interface
23  // The OpenTherm interface
24  std::unique_ptr<OpenTherm> opentherm_;
25 
26  // The set of initial messages to send on starting communication with the boiler
27  std::unordered_set<MessageId> initial_messages_;
28  // and the repeating messages which are sent repeatedly to update various sensors
29  // and boiler parameters (like the setpoint).
30  std::unordered_set<MessageId> repeating_messages_;
31  // Indicates if we are still working on the initial requests or not
32  bool sending_initial_ = true;
33  // Index for the current request in one of the _requests sets.
34  std::unordered_set<MessageId>::const_iterator current_message_iterator_;
35 
37  uint32_t last_conversation_end_ = 0;
40 
41  // Synchronous communication mode prevents other components from disabling interrupts while
42  // we are talking to the boiler. Enable if you experience random intermittent invalid response errors.
43  // Very likely to happen while using Dallas temperature sensors.
44  bool sync_mode_ = false;
45 
46  // Create OpenTherm messages based on the message id
50  void handle_timeout_error_();
51  void stop_opentherm_();
52  void start_conversation_();
53  void read_response_();
54  bool check_timings_(uint32_t cur_time);
55  bool should_skip_loop_(uint32_t cur_time) const;
56  void sync_loop_();
57 
58  template<typename F> bool spin_wait_(uint32_t timeout, F func) {
59  auto start_time = millis();
60  while (func()) {
61  yield();
62  auto cur_time = millis();
63  if (cur_time - start_time >= timeout) {
64  return false;
65  }
66  }
67  return true;
68  }
69 
70  public:
71  // Constructor with references to the global interrupt handlers
72  OpenthermHub();
73 
74  // Handle responses from the OpenTherm interface
75  void process_response(OpenthermData &data);
76 
77  // Setters for the input and output OpenTherm interface pins
78  void set_in_pin(InternalGPIOPin *in_pin) { this->in_pin_ = in_pin; }
79  void set_out_pin(InternalGPIOPin *out_pin) { this->out_pin_ = out_pin; }
80 
81  // Add a request to the set of initial requests
82  void add_initial_message(MessageId message_id) { this->initial_messages_.insert(message_id); }
83  // Add a request to the set of repeating requests. Note that a large number of repeating
84  // requests will slow down communication with the boiler. Each request may take up to 1 second,
85  // so with all sensors enabled, it may take about half a minute before a change in setpoint
86  // will be processed.
87  void add_repeating_message(MessageId message_id) { this->repeating_messages_.insert(message_id); }
88 
89  // There are five status variables, which can either be set as a simple variable,
90  // or using a switch. ch_enable and dhw_enable default to true, the others to false.
91  bool ch_enable = true, dhw_enable = true, cooling_enable = false, otc_active = false, ch2_active = false;
92 
93  // Setters for the status variables
94  void set_ch_enable(bool value) { this->ch_enable = value; }
95  void set_dhw_enable(bool value) { this->dhw_enable = value; }
96  void set_cooling_enable(bool value) { this->cooling_enable = value; }
97  void set_otc_active(bool value) { this->otc_active = value; }
98  void set_ch2_active(bool value) { this->ch2_active = value; }
99  void set_sync_mode(bool sync_mode) { this->sync_mode_ = sync_mode; }
100 
101  float get_setup_priority() const override { return setup_priority::HARDWARE; }
102 
103  void setup() override;
104  void on_shutdown() override;
105  void loop() override;
106  void dump_config() override;
107 };
108 
109 } // namespace opentherm
110 } // namespace esphome
bool should_skip_loop_(uint32_t cur_time) const
Definition: hub.cpp:193
bool check_timings_(uint32_t cur_time)
Definition: hub.cpp:180
uint32_t last_conversation_start_
Definition: hub.h:36
std::unordered_set< MessageId > initial_messages_
Definition: hub.h:27
void process_response(OpenthermData &data)
Definition: hub.cpp:50
std::unordered_set< MessageId > repeating_messages_
Definition: hub.h:30
InternalGPIOPin * in_pin_
Definition: hub.h:22
void set_out_pin(InternalGPIOPin *out_pin)
Definition: hub.h:79
std::unique_ptr< OpenTherm > opentherm_
Definition: hub.h:24
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
OperationMode last_mode_
Definition: hub.h:38
OpenthermData build_request_(MessageId request_id)
Definition: hub.cpp:11
bool spin_wait_(uint32_t timeout, F func)
Definition: hub.h:58
void set_sync_mode(bool sync_mode)
Definition: hub.h:99
uint32_t last_conversation_end_
Definition: hub.h:37
InternalGPIOPin * out_pin_
Definition: hub.h:22
void set_in_pin(InternalGPIOPin *in_pin)
Definition: hub.h:78
void set_cooling_enable(bool value)
Definition: hub.h:96
std::unordered_set< MessageId >::const_iterator current_message_iterator_
Definition: hub.h:34
void dump_config() override
Definition: hub.cpp:261
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition: component.cpp:18
float get_setup_priority() const override
Definition: hub.h:101
void add_initial_message(MessageId message_id)
Definition: hub.h:82
void IRAM_ATTR HOT yield()
Definition: core.cpp:24
void loop() override
Definition: hub.cpp:75
void set_dhw_enable(bool value)
Definition: hub.h:95
void set_otc_active(bool value)
Definition: hub.h:97
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void set_ch_enable(bool value)
Definition: hub.h:94
void setup() override
Definition: hub.cpp:56
void add_repeating_message(MessageId message_id)
Definition: hub.h:87
Structure to hold Opentherm data packet content.
Definition: opentherm.h:144
void on_shutdown() override
Definition: hub.cpp:73
void set_ch2_active(bool value)
Definition: hub.h:98
OpenthermData last_request_
Definition: hub.h:39