esphome 2024.10.2__py3-none-any.whl → 2024.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. esphome/__main__.py +22 -4
  2. esphome/automation.py +29 -2
  3. esphome/components/animation/__init__.py +5 -8
  4. esphome/components/animation/animation.cpp +1 -1
  5. esphome/components/audio/__init__.py +9 -0
  6. esphome/components/audio/audio.h +21 -0
  7. esphome/components/axs15231/__init__.py +6 -0
  8. esphome/components/axs15231/touchscreen/__init__.py +36 -0
  9. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +64 -0
  10. esphome/components/axs15231/touchscreen/axs15231_touchscreen.h +27 -0
  11. esphome/components/bme68x_bsec2/__init__.py +1 -1
  12. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +50 -47
  13. esphome/components/bme68x_bsec2/bme68x_bsec2.h +0 -2
  14. esphome/components/bytebuffer/__init__.py +5 -0
  15. esphome/components/bytebuffer/bytebuffer.h +421 -0
  16. esphome/components/climate/__init__.py +14 -13
  17. esphome/components/datetime/__init__.py +3 -3
  18. esphome/components/debug/debug_esp32.cpp +16 -8
  19. esphome/components/dfplayer/dfplayer.cpp +132 -6
  20. esphome/components/dfplayer/dfplayer.h +19 -53
  21. esphome/components/display/display.cpp +142 -0
  22. esphome/components/display/display.h +7 -0
  23. esphome/components/es8311/__init__.py +0 -0
  24. esphome/components/es8311/audio_dac.py +70 -0
  25. esphome/components/es8311/es8311.cpp +227 -0
  26. esphome/components/es8311/es8311.h +135 -0
  27. esphome/components/es8311/es8311_const.h +195 -0
  28. esphome/components/esp32/boards.py +199 -1
  29. esphome/components/esp32/gpio.py +3 -1
  30. esphome/components/esp32_ble/const_esp32c6.h +7 -0
  31. esphome/components/esp32_ble_client/ble_client_base.h +1 -1
  32. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +3 -0
  33. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -1
  34. esphome/components/esp32_rmt_led_strip/led_strip.cpp +2 -2
  35. esphome/components/esp32_rmt_led_strip/led_strip.h +2 -0
  36. esphome/components/esp32_rmt_led_strip/light.py +3 -1
  37. esphome/components/esp8266/gpio.py +7 -5
  38. esphome/components/ethernet/__init__.py +55 -1
  39. esphome/components/ethernet/ethernet_component.cpp +14 -1
  40. esphome/components/ethernet/ethernet_component.h +7 -1
  41. esphome/components/font/__init__.py +213 -108
  42. esphome/components/gp8403/output/__init__.py +1 -1
  43. esphome/components/host/gpio.py +6 -4
  44. esphome/components/http_request/__init__.py +12 -0
  45. esphome/components/http_request/http_request.h +65 -3
  46. esphome/components/http_request/http_request_arduino.cpp +4 -3
  47. esphome/components/http_request/http_request_idf.cpp +12 -14
  48. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  49. esphome/components/http_request/update/http_request_update.cpp +1 -1
  50. esphome/components/i2c_device/__init__.py +26 -0
  51. esphome/components/i2c_device/i2c_device.cpp +17 -0
  52. esphome/components/i2c_device/i2c_device.h +18 -0
  53. esphome/components/i2s_audio/__init__.py +1 -3
  54. esphome/components/i2s_audio/speaker/__init__.py +12 -4
  55. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +426 -200
  56. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +92 -33
  57. esphome/components/ili9xxx/display.py +5 -1
  58. esphome/components/image/__init__.py +5 -8
  59. esphome/components/image/image.cpp +14 -14
  60. esphome/components/image/image.h +20 -24
  61. esphome/components/internal_temperature/internal_temperature.cpp +51 -2
  62. esphome/components/internal_temperature/internal_temperature.h +1 -0
  63. esphome/components/ld2420/ld2420.cpp +1 -1
  64. esphome/components/libretiny/gpio.py +4 -2
  65. esphome/components/light/__init__.py +32 -1
  66. esphome/components/light/automation.py +39 -32
  67. esphome/components/light/effects.py +36 -36
  68. esphome/components/light/light_state.cpp +6 -16
  69. esphome/components/light/light_state.h +34 -0
  70. esphome/components/light/types.py +3 -1
  71. esphome/components/logger/logger_esp32.cpp +15 -0
  72. esphome/components/lvgl/__init__.py +202 -95
  73. esphome/components/lvgl/automation.py +42 -40
  74. esphome/components/lvgl/binary_sensor/__init__.py +8 -15
  75. esphome/components/lvgl/defines.py +14 -8
  76. esphome/components/lvgl/encoders.py +11 -8
  77. esphome/components/lvgl/keypads.py +77 -0
  78. esphome/components/lvgl/light/__init__.py +6 -8
  79. esphome/components/lvgl/lv_validation.py +2 -4
  80. esphome/components/lvgl/lvcode.py +3 -9
  81. esphome/components/lvgl/lvgl_esphome.cpp +210 -89
  82. esphome/components/lvgl/lvgl_esphome.h +113 -30
  83. esphome/components/lvgl/lvgl_proxy.h +17 -0
  84. esphome/components/lvgl/number/__init__.py +10 -15
  85. esphome/components/lvgl/schemas.py +4 -2
  86. esphome/components/lvgl/select/__init__.py +12 -37
  87. esphome/components/lvgl/select/lvgl_select.h +27 -33
  88. esphome/components/lvgl/sensor/__init__.py +8 -14
  89. esphome/components/lvgl/styles.py +3 -4
  90. esphome/components/lvgl/switch/__init__.py +8 -13
  91. esphome/components/lvgl/text/__init__.py +5 -6
  92. esphome/components/lvgl/text_sensor/__init__.py +15 -15
  93. esphome/components/lvgl/touchscreens.py +2 -3
  94. esphome/components/lvgl/trigger.py +7 -9
  95. esphome/components/lvgl/types.py +9 -3
  96. esphome/components/lvgl/widgets/__init__.py +32 -21
  97. esphome/components/lvgl/widgets/animimg.py +4 -3
  98. esphome/components/lvgl/widgets/dropdown.py +22 -10
  99. esphome/components/lvgl/widgets/img.py +2 -0
  100. esphome/components/lvgl/widgets/msgbox.py +6 -5
  101. esphome/components/lvgl/widgets/obj.py +4 -2
  102. esphome/components/lvgl/widgets/page.py +3 -2
  103. esphome/components/lvgl/widgets/qrcode.py +54 -0
  104. esphome/components/lvgl/widgets/roller.py +21 -14
  105. esphome/components/lvgl/widgets/tileview.py +2 -1
  106. esphome/components/max17043/__init__.py +1 -0
  107. esphome/components/max17043/automation.h +20 -0
  108. esphome/components/max17043/max17043.cpp +98 -0
  109. esphome/components/max17043/max17043.h +29 -0
  110. esphome/components/max17043/sensor.py +77 -0
  111. esphome/components/media_player/__init__.py +11 -0
  112. esphome/components/media_player/automation.h +10 -0
  113. esphome/components/media_player/media_player.cpp +4 -0
  114. esphome/components/midea/air_conditioner.cpp +17 -1
  115. esphome/components/mlx90393/sensor.py +1 -1
  116. esphome/components/modbus/modbus.cpp +24 -12
  117. esphome/components/modbus_controller/__init__.py +31 -1
  118. esphome/components/modbus_controller/automation.h +16 -0
  119. esphome/components/modbus_controller/const.py +2 -0
  120. esphome/components/modbus_controller/modbus_controller.cpp +14 -2
  121. esphome/components/modbus_controller/modbus_controller.h +9 -0
  122. esphome/components/mopeka_pro_check/mopeka_pro_check.cpp +40 -21
  123. esphome/components/mopeka_pro_check/mopeka_pro_check.h +9 -2
  124. esphome/components/mopeka_pro_check/sensor.py +41 -0
  125. esphome/components/mqtt/__init__.py +36 -0
  126. esphome/components/mqtt/mqtt_client.cpp +27 -3
  127. esphome/components/mqtt/mqtt_client.h +27 -2
  128. esphome/components/mqtt/mqtt_climate.cpp +4 -2
  129. esphome/components/mqtt/mqtt_component.cpp +6 -0
  130. esphome/components/mqtt/mqtt_component.h +4 -0
  131. esphome/components/mqtt/mqtt_const.h +6 -0
  132. esphome/components/online_image/online_image.cpp +2 -8
  133. esphome/components/online_image/online_image.h +2 -6
  134. esphome/components/opentherm/__init__.py +35 -9
  135. esphome/components/opentherm/binary_sensor/__init__.py +33 -0
  136. esphome/components/opentherm/const.py +11 -0
  137. esphome/components/opentherm/generate.py +142 -0
  138. esphome/components/opentherm/hub.cpp +130 -24
  139. esphome/components/opentherm/hub.h +62 -9
  140. esphome/components/opentherm/input.h +18 -0
  141. esphome/components/opentherm/input.py +51 -0
  142. esphome/components/opentherm/number/__init__.py +74 -0
  143. esphome/components/opentherm/number/number.cpp +40 -0
  144. esphome/components/opentherm/number/number.h +31 -0
  145. esphome/components/opentherm/opentherm.cpp +30 -0
  146. esphome/components/opentherm/opentherm.h +34 -2
  147. esphome/components/opentherm/opentherm_macros.h +151 -0
  148. esphome/components/opentherm/output/__init__.py +47 -0
  149. esphome/components/opentherm/output/output.cpp +18 -0
  150. esphome/components/opentherm/output/output.h +33 -0
  151. esphome/components/opentherm/schema.py +814 -0
  152. esphome/components/opentherm/sensor/__init__.py +51 -0
  153. esphome/components/opentherm/switch/__init__.py +43 -0
  154. esphome/components/opentherm/switch/switch.cpp +28 -0
  155. esphome/components/opentherm/switch/switch.h +20 -0
  156. esphome/components/opentherm/validate.py +31 -0
  157. esphome/components/pcd8544/display.py +8 -4
  158. esphome/components/prometheus/prometheus_handler.cpp +176 -14
  159. esphome/components/prometheus/prometheus_handler.h +25 -7
  160. esphome/components/qspi_amoled/display.py +1 -141
  161. esphome/components/qspi_dbi/display.py +185 -0
  162. esphome/components/qspi_dbi/models.py +64 -0
  163. esphome/components/{qspi_amoled/qspi_amoled.cpp → qspi_dbi/qspi_dbi.cpp} +95 -46
  164. esphome/components/{qspi_amoled/qspi_amoled.h → qspi_dbi/qspi_dbi.h} +26 -15
  165. esphome/components/rp2040/__init__.py +6 -3
  166. esphome/components/rp2040/gpio.py +5 -3
  167. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +20 -0
  168. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h +3 -2
  169. esphome/components/rtttl/rtttl.cpp +4 -1
  170. esphome/components/rtttl/rtttl.h +1 -0
  171. esphome/components/sdl/sdl_esphome.cpp +22 -5
  172. esphome/components/sdl/sdl_esphome.h +1 -0
  173. esphome/components/sdm_meter/sdm_meter.cpp +1 -1
  174. esphome/components/sensor/__init__.py +18 -8
  175. esphome/components/sensor/filter.cpp +19 -18
  176. esphome/components/sensor/filter.h +9 -10
  177. esphome/components/sgp4x/sgp4x.cpp +40 -74
  178. esphome/components/sgp4x/sgp4x.h +5 -3
  179. esphome/components/speaker/__init__.py +51 -5
  180. esphome/components/speaker/automation.h +25 -0
  181. esphome/components/speaker/speaker.h +72 -1
  182. esphome/components/spi/__init__.py +15 -14
  183. esphome/components/spi_device/__init__.py +4 -15
  184. esphome/components/ssd1306_spi/display.py +6 -2
  185. esphome/components/ssd1322_spi/display.py +6 -2
  186. esphome/components/ssd1325_spi/display.py +6 -2
  187. esphome/components/ssd1327_spi/display.py +6 -2
  188. esphome/components/ssd1331_spi/display.py +6 -2
  189. esphome/components/ssd1351_spi/display.py +6 -2
  190. esphome/components/st7567_spi/display.py +6 -2
  191. esphome/components/st7701s/display.py +5 -1
  192. esphome/components/st7735/display.py +10 -5
  193. esphome/components/st7789v/display.py +12 -7
  194. esphome/components/statsd/statsd.cpp +2 -0
  195. esphome/components/statsd/statsd.h +2 -0
  196. esphome/components/sun/sun.h +3 -0
  197. esphome/components/tc74/__init__.py +1 -0
  198. esphome/components/tc74/sensor.py +32 -0
  199. esphome/components/tc74/tc74.cpp +68 -0
  200. esphome/components/tc74/tc74.h +28 -0
  201. esphome/components/touchscreen/__init__.py +41 -50
  202. esphome/components/touchscreen/touchscreen.h +4 -8
  203. esphome/components/tuya/fan/tuya_fan.cpp +1 -1
  204. esphome/components/udp/udp_component.cpp +6 -3
  205. esphome/components/udp/udp_component.h +4 -2
  206. esphome/components/waveshare_epaper/display.py +6 -2
  207. esphome/components/web_server/web_server.cpp +22 -0
  208. esphome/components/web_server/web_server.h +3 -0
  209. esphome/components/weikai/weikai.h +2 -2
  210. esphome/components/wifi/wifi_component.cpp +2 -2
  211. esphome/components/wifi/wifi_component_esp32_arduino.cpp +4 -4
  212. esphome/components/wifi/wifi_component_esp8266.cpp +4 -4
  213. esphome/components/wifi/wifi_component_esp_idf.cpp +2 -2
  214. esphome/components/xpt2046/touchscreen/__init__.py +7 -32
  215. esphome/config_validation.py +3 -1
  216. esphome/const.py +9 -2
  217. esphome/core/defines.h +8 -2
  218. esphome/core/helpers.cpp +32 -17
  219. esphome/core/helpers.h +32 -16
  220. esphome/core/ring_buffer.cpp +2 -2
  221. esphome/core/ring_buffer.h +2 -2
  222. esphome/dashboard/core.py +25 -0
  223. esphome/dashboard/status/mdns.py +3 -4
  224. esphome/dashboard/web_server.py +54 -19
  225. esphome/espota2.py +36 -35
  226. esphome/helpers.py +68 -16
  227. esphome/mqtt.py +9 -2
  228. esphome/storage_json.py +4 -0
  229. esphome/writer.py +7 -18
  230. esphome/zeroconf.py +8 -6
  231. {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/METADATA +7 -5
  232. {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/RECORD +237 -191
  233. esphome/core/bytebuffer.cpp +0 -167
  234. esphome/core/bytebuffer.h +0 -144
  235. /esphome/components/{qspi_amoled → qspi_dbi}/__init__.py +0 -0
  236. {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/LICENSE +0 -0
  237. {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/WHEEL +0 -0
  238. {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/entry_points.txt +0 -0
  239. {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/top_level.txt +0 -0
@@ -4,14 +4,37 @@
4
4
  #include "esphome/core/hal.h"
5
5
  #include "esphome/core/component.h"
6
6
  #include "esphome/core/log.h"
7
+ #include <vector>
7
8
 
8
9
  #include "opentherm.h"
9
10
 
11
+ #ifdef OPENTHERM_USE_SENSOR
12
+ #include "esphome/components/sensor/sensor.h"
13
+ #endif
14
+
15
+ #ifdef OPENTHERM_USE_BINARY_SENSOR
16
+ #include "esphome/components/binary_sensor/binary_sensor.h"
17
+ #endif
18
+
19
+ #ifdef OPENTHERM_USE_SWITCH
20
+ #include "esphome/components/opentherm/switch/switch.h"
21
+ #endif
22
+
23
+ #ifdef OPENTHERM_USE_OUTPUT
24
+ #include "esphome/components/opentherm/output/output.h"
25
+ #endif
26
+
27
+ #ifdef OPENTHERM_USE_NUMBER
28
+ #include "esphome/components/opentherm/number/number.h"
29
+ #endif
30
+
10
31
  #include <memory>
11
32
  #include <unordered_map>
12
33
  #include <unordered_set>
13
34
  #include <functional>
14
35
 
36
+ #include "opentherm_macros.h"
37
+
15
38
  namespace esphome {
16
39
  namespace opentherm {
17
40
 
@@ -23,15 +46,27 @@ class OpenthermHub : public Component {
23
46
  // The OpenTherm interface
24
47
  std::unique_ptr<OpenTherm> opentherm_;
25
48
 
49
+ OPENTHERM_SENSOR_LIST(OPENTHERM_DECLARE_SENSOR, )
50
+
51
+ OPENTHERM_BINARY_SENSOR_LIST(OPENTHERM_DECLARE_BINARY_SENSOR, )
52
+
53
+ OPENTHERM_SWITCH_LIST(OPENTHERM_DECLARE_SWITCH, )
54
+
55
+ OPENTHERM_NUMBER_LIST(OPENTHERM_DECLARE_NUMBER, )
56
+
57
+ OPENTHERM_OUTPUT_LIST(OPENTHERM_DECLARE_OUTPUT, )
58
+
59
+ OPENTHERM_INPUT_SENSOR_LIST(OPENTHERM_DECLARE_INPUT_SENSOR, )
60
+
26
61
  // The set of initial messages to send on starting communication with the boiler
27
- std::unordered_set<MessageId> initial_messages_;
62
+ std::vector<MessageId> initial_messages_;
28
63
  // and the repeating messages which are sent repeatedly to update various sensors
29
64
  // and boiler parameters (like the setpoint).
30
- std::unordered_set<MessageId> repeating_messages_;
65
+ std::vector<MessageId> repeating_messages_;
31
66
  // Indicates if we are still working on the initial requests or not
32
67
  bool sending_initial_ = true;
33
68
  // Index for the current request in one of the _requests sets.
34
- std::unordered_set<MessageId>::const_iterator current_message_iterator_;
69
+ std::vector<MessageId>::const_iterator current_message_iterator_;
35
70
 
36
71
  uint32_t last_conversation_start_ = 0;
37
72
  uint32_t last_conversation_end_ = 0;
@@ -43,8 +78,10 @@ class OpenthermHub : public Component {
43
78
  // Very likely to happen while using Dallas temperature sensors.
44
79
  bool sync_mode_ = false;
45
80
 
81
+ float opentherm_version_ = 0.0f;
82
+
46
83
  // Create OpenTherm messages based on the message id
47
- OpenthermData build_request_(MessageId request_id);
84
+ OpenthermData build_request_(MessageId request_id) const;
48
85
  void handle_protocol_write_error_();
49
86
  void handle_protocol_read_error_();
50
87
  void handle_timeout_error_();
@@ -78,17 +115,30 @@ class OpenthermHub : public Component {
78
115
  void set_in_pin(InternalGPIOPin *in_pin) { this->in_pin_ = in_pin; }
79
116
  void set_out_pin(InternalGPIOPin *out_pin) { this->out_pin_ = out_pin; }
80
117
 
81
- // Add a request to the set of initial requests
82
- void add_initial_message(MessageId message_id) { this->initial_messages_.insert(message_id); }
118
+ OPENTHERM_SENSOR_LIST(OPENTHERM_SET_SENSOR, )
119
+
120
+ OPENTHERM_BINARY_SENSOR_LIST(OPENTHERM_SET_BINARY_SENSOR, )
121
+
122
+ OPENTHERM_SWITCH_LIST(OPENTHERM_SET_SWITCH, )
123
+
124
+ OPENTHERM_NUMBER_LIST(OPENTHERM_SET_NUMBER, )
125
+
126
+ OPENTHERM_OUTPUT_LIST(OPENTHERM_SET_OUTPUT, )
127
+
128
+ OPENTHERM_INPUT_SENSOR_LIST(OPENTHERM_SET_INPUT_SENSOR, )
129
+
130
+ // Add a request to the vector of initial requests
131
+ void add_initial_message(MessageId message_id) { this->initial_messages_.push_back(message_id); }
83
132
  // Add a request to the set of repeating requests. Note that a large number of repeating
84
133
  // requests will slow down communication with the boiler. Each request may take up to 1 second,
85
134
  // so with all sensors enabled, it may take about half a minute before a change in setpoint
86
135
  // will be processed.
87
- void add_repeating_message(MessageId message_id) { this->repeating_messages_.insert(message_id); }
136
+ void add_repeating_message(MessageId message_id) { this->repeating_messages_.push_back(message_id); }
88
137
 
89
- // There are five status variables, which can either be set as a simple variable,
138
+ // There are seven status variables, which can either be set as a simple variable,
90
139
  // 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;
140
+ bool ch_enable = true, dhw_enable = true, cooling_enable = false, otc_active = false, ch2_active = false,
141
+ summer_mode_active = false, dhw_block = false;
92
142
 
93
143
  // Setters for the status variables
94
144
  void set_ch_enable(bool value) { this->ch_enable = value; }
@@ -96,7 +146,10 @@ class OpenthermHub : public Component {
96
146
  void set_cooling_enable(bool value) { this->cooling_enable = value; }
97
147
  void set_otc_active(bool value) { this->otc_active = value; }
98
148
  void set_ch2_active(bool value) { this->ch2_active = value; }
149
+ void set_summer_mode_active(bool value) { this->summer_mode_active = value; }
150
+ void set_dhw_block(bool value) { this->dhw_block = value; }
99
151
  void set_sync_mode(bool sync_mode) { this->sync_mode_ = sync_mode; }
152
+ void set_opentherm_version(float value) { this->opentherm_version_ = value; }
100
153
 
101
154
  float get_setup_priority() const override { return setup_priority::HARDWARE; }
102
155
 
@@ -0,0 +1,18 @@
1
+ #pragma once
2
+
3
+ namespace esphome {
4
+ namespace opentherm {
5
+
6
+ class OpenthermInput {
7
+ public:
8
+ bool auto_min_value, auto_max_value;
9
+
10
+ virtual void set_min_value(float min_value) = 0;
11
+ virtual void set_max_value(float max_value) = 0;
12
+
13
+ virtual void set_auto_min_value(bool auto_min_value) { this->auto_min_value = auto_min_value; }
14
+ virtual void set_auto_max_value(bool auto_max_value) { this->auto_max_value = auto_max_value; }
15
+ };
16
+
17
+ } // namespace opentherm
18
+ } // namespace esphome
@@ -0,0 +1,51 @@
1
+ from typing import Any
2
+
3
+ import esphome.codegen as cg
4
+ import esphome.config_validation as cv
5
+ from . import schema, generate
6
+
7
+ CONF_min_value = "min_value"
8
+ CONF_max_value = "max_value"
9
+ CONF_auto_min_value = "auto_min_value"
10
+ CONF_auto_max_value = "auto_max_value"
11
+ CONF_step = "step"
12
+
13
+ OpenthermInput = generate.opentherm_ns.class_("OpenthermInput")
14
+
15
+
16
+ def validate_min_value_less_than_max_value(conf):
17
+ if (
18
+ CONF_min_value in conf
19
+ and CONF_max_value in conf
20
+ and conf[CONF_min_value] > conf[CONF_max_value]
21
+ ):
22
+ raise cv.Invalid(f"{CONF_min_value} must be less than {CONF_max_value}")
23
+ return conf
24
+
25
+
26
+ def input_schema(entity: schema.InputSchema) -> cv.Schema:
27
+ result = cv.Schema(
28
+ {
29
+ cv.Optional(CONF_min_value, entity.range[0]): cv.float_range(
30
+ entity.range[0], entity.range[1]
31
+ ),
32
+ cv.Optional(CONF_max_value, entity.range[1]): cv.float_range(
33
+ entity.range[0], entity.range[1]
34
+ ),
35
+ }
36
+ )
37
+ result = result.add_extra(validate_min_value_less_than_max_value)
38
+ result = result.extend({cv.Optional(CONF_step, False): cv.float_})
39
+ if entity.auto_min_value is not None:
40
+ result = result.extend({cv.Optional(CONF_auto_min_value, False): cv.boolean})
41
+ if entity.auto_max_value is not None:
42
+ result = result.extend({cv.Optional(CONF_auto_max_value, False): cv.boolean})
43
+
44
+ return result
45
+
46
+
47
+ def generate_setters(entity: cg.MockObj, conf: dict[str, Any]) -> None:
48
+ generate.add_property_set(entity, CONF_min_value, conf)
49
+ generate.add_property_set(entity, CONF_max_value, conf)
50
+ generate.add_property_set(entity, CONF_auto_min_value, conf)
51
+ generate.add_property_set(entity, CONF_auto_max_value, conf)
@@ -0,0 +1,74 @@
1
+ from typing import Any
2
+
3
+ import esphome.codegen as cg
4
+ import esphome.config_validation as cv
5
+ from esphome.components import number
6
+ from esphome.const import (
7
+ CONF_ID,
8
+ CONF_UNIT_OF_MEASUREMENT,
9
+ CONF_STEP,
10
+ CONF_INITIAL_VALUE,
11
+ CONF_RESTORE_VALUE,
12
+ )
13
+ from .. import const, schema, validate, input, generate
14
+
15
+ DEPENDENCIES = [const.OPENTHERM]
16
+ COMPONENT_TYPE = const.NUMBER
17
+
18
+ OpenthermNumber = generate.opentherm_ns.class_(
19
+ "OpenthermNumber", number.Number, cg.Component, input.OpenthermInput
20
+ )
21
+
22
+
23
+ async def new_openthermnumber(config: dict[str, Any]) -> cg.Pvariable:
24
+ var = cg.new_Pvariable(config[CONF_ID])
25
+ await cg.register_component(var, config)
26
+ await number.register_number(
27
+ var,
28
+ config,
29
+ min_value=config[input.CONF_min_value],
30
+ max_value=config[input.CONF_max_value],
31
+ step=config[input.CONF_step],
32
+ )
33
+ input.generate_setters(var, config)
34
+
35
+ if CONF_INITIAL_VALUE in config:
36
+ cg.add(var.set_initial_value(config[CONF_INITIAL_VALUE]))
37
+ if CONF_RESTORE_VALUE in config:
38
+ cg.add(var.set_restore_value(config[CONF_RESTORE_VALUE]))
39
+
40
+ return var
41
+
42
+
43
+ def get_entity_validation_schema(entity: schema.InputSchema) -> cv.Schema:
44
+ return (
45
+ number.NUMBER_SCHEMA.extend(
46
+ {
47
+ cv.GenerateID(): cv.declare_id(OpenthermNumber),
48
+ cv.Optional(
49
+ CONF_UNIT_OF_MEASUREMENT, entity.unit_of_measurement
50
+ ): cv.string_strict,
51
+ cv.Optional(CONF_STEP, entity.step): cv.float_,
52
+ cv.Optional(CONF_INITIAL_VALUE): cv.float_,
53
+ cv.Optional(CONF_RESTORE_VALUE): cv.boolean,
54
+ }
55
+ )
56
+ .extend(input.input_schema(entity))
57
+ .extend(cv.COMPONENT_SCHEMA)
58
+ )
59
+
60
+
61
+ CONFIG_SCHEMA = validate.create_component_schema(
62
+ schema.INPUTS, get_entity_validation_schema
63
+ )
64
+
65
+
66
+ async def to_code(config: dict[str, Any]) -> None:
67
+ keys = await generate.component_to_code(
68
+ COMPONENT_TYPE,
69
+ schema.INPUTS,
70
+ OpenthermNumber,
71
+ generate.create_only_conf(new_openthermnumber),
72
+ config,
73
+ )
74
+ generate.define_readers(COMPONENT_TYPE, keys)
@@ -0,0 +1,40 @@
1
+ #include "number.h"
2
+
3
+ namespace esphome {
4
+ namespace opentherm {
5
+
6
+ static const char *const TAG = "opentherm.number";
7
+
8
+ void OpenthermNumber::control(float value) {
9
+ this->publish_state(value);
10
+
11
+ if (this->restore_value_)
12
+ this->pref_.save(&value);
13
+ }
14
+
15
+ void OpenthermNumber::setup() {
16
+ float value;
17
+ if (!this->restore_value_) {
18
+ value = this->initial_value_;
19
+ } else {
20
+ this->pref_ = global_preferences->make_preference<float>(this->get_object_id_hash());
21
+ if (!this->pref_.load(&value)) {
22
+ if (!std::isnan(this->initial_value_)) {
23
+ value = this->initial_value_;
24
+ } else {
25
+ value = this->traits.get_min_value();
26
+ }
27
+ }
28
+ }
29
+ this->publish_state(value);
30
+ }
31
+
32
+ void OpenthermNumber::dump_config() {
33
+ LOG_NUMBER("", "OpenTherm Number", this);
34
+ ESP_LOGCONFIG(TAG, " Restore value: %d", this->restore_value_);
35
+ ESP_LOGCONFIG(TAG, " Initial value: %.2f", this->initial_value_);
36
+ ESP_LOGCONFIG(TAG, " Current value: %.2f", this->state);
37
+ }
38
+
39
+ } // namespace opentherm
40
+ } // namespace esphome
@@ -0,0 +1,31 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/number/number.h"
4
+ #include "esphome/core/preferences.h"
5
+ #include "esphome/core/log.h"
6
+ #include "esphome/components/opentherm/input.h"
7
+
8
+ namespace esphome {
9
+ namespace opentherm {
10
+
11
+ // Just a simple number, which stores the number
12
+ class OpenthermNumber : public number::Number, public Component, public OpenthermInput {
13
+ protected:
14
+ void control(float value) override;
15
+ void setup() override;
16
+ void dump_config() override;
17
+
18
+ float initial_value_{NAN};
19
+ bool restore_value_{false};
20
+
21
+ ESPPreferenceObject pref_;
22
+
23
+ public:
24
+ void set_min_value(float min_value) override { this->traits.set_min_value(min_value); }
25
+ void set_max_value(float max_value) override { this->traits.set_max_value(max_value); }
26
+ void set_initial_value(float initial_value) { initial_value_ = initial_value; }
27
+ void set_restore_value(bool restore_value) { this->restore_value_ = restore_value; }
28
+ };
29
+
30
+ } // namespace opentherm
31
+ } // namespace esphome
@@ -283,6 +283,9 @@ bool OpenTherm::init_esp32_timer_() {
283
283
  .clk_src = TIMER_SRC_CLK_DEFAULT,
284
284
  #endif
285
285
  .divider = 80,
286
+ #if defined(SOC_TIMER_GROUP_SUPPORT_XTAL) && ESP_IDF_VERSION_MAJOR < 5
287
+ .clk_src = TIMER_SRC_CLK_APB
288
+ #endif
286
289
  };
287
290
 
288
291
  esp_err_t result;
@@ -480,6 +483,8 @@ const char *OpenTherm::message_id_to_str(MessageId id) {
480
483
  TO_STRING_MEMBER(EXHAUST_TEMP)
481
484
  TO_STRING_MEMBER(FAN_SPEED)
482
485
  TO_STRING_MEMBER(FLAME_CURRENT)
486
+ TO_STRING_MEMBER(ROOM_TEMP_CH2)
487
+ TO_STRING_MEMBER(REL_HUMIDITY)
483
488
  TO_STRING_MEMBER(DHW_BOUNDS)
484
489
  TO_STRING_MEMBER(CH_BOUNDS)
485
490
  TO_STRING_MEMBER(OTC_CURVE_BOUNDS)
@@ -489,14 +494,39 @@ const char *OpenTherm::message_id_to_str(MessageId id) {
489
494
  TO_STRING_MEMBER(HVAC_STATUS)
490
495
  TO_STRING_MEMBER(REL_VENT_SETPOINT)
491
496
  TO_STRING_MEMBER(DEVICE_VENT)
497
+ TO_STRING_MEMBER(HVAC_VER_ID)
492
498
  TO_STRING_MEMBER(REL_VENTILATION)
493
499
  TO_STRING_MEMBER(REL_HUMID_EXHAUST)
500
+ TO_STRING_MEMBER(EXHAUST_CO2)
494
501
  TO_STRING_MEMBER(SUPPLY_INLET_TEMP)
495
502
  TO_STRING_MEMBER(SUPPLY_OUTLET_TEMP)
496
503
  TO_STRING_MEMBER(EXHAUST_INLET_TEMP)
497
504
  TO_STRING_MEMBER(EXHAUST_OUTLET_TEMP)
505
+ TO_STRING_MEMBER(EXHAUST_FAN_SPEED)
506
+ TO_STRING_MEMBER(SUPPLY_FAN_SPEED)
507
+ TO_STRING_MEMBER(REMOTE_VENTILATION_PARAM)
498
508
  TO_STRING_MEMBER(NOM_REL_VENTILATION)
509
+ TO_STRING_MEMBER(HVAC_NUM_TSP)
510
+ TO_STRING_MEMBER(HVAC_IDX_TSP)
511
+ TO_STRING_MEMBER(HVAC_FHB_SIZE)
512
+ TO_STRING_MEMBER(HVAC_FHB_IDX)
513
+ TO_STRING_MEMBER(RF_SIGNAL)
514
+ TO_STRING_MEMBER(DHW_MODE)
499
515
  TO_STRING_MEMBER(OVERRIDE_FUNC)
516
+ TO_STRING_MEMBER(SOLAR_MODE_FLAGS)
517
+ TO_STRING_MEMBER(SOLAR_ASF)
518
+ TO_STRING_MEMBER(SOLAR_VERSION_ID)
519
+ TO_STRING_MEMBER(SOLAR_PRODUCT_ID)
520
+ TO_STRING_MEMBER(SOLAR_NUM_TSP)
521
+ TO_STRING_MEMBER(SOLAR_IDX_TSP)
522
+ TO_STRING_MEMBER(SOLAR_FHB_SIZE)
523
+ TO_STRING_MEMBER(SOLAR_FHB_IDX)
524
+ TO_STRING_MEMBER(SOLAR_STARTS)
525
+ TO_STRING_MEMBER(SOLAR_HOURS)
526
+ TO_STRING_MEMBER(SOLAR_ENERGY)
527
+ TO_STRING_MEMBER(SOLAR_TOTAL_ENERGY)
528
+ TO_STRING_MEMBER(FAILED_BURNER_STARTS)
529
+ TO_STRING_MEMBER(BURNER_FLAME_LOW)
500
530
  TO_STRING_MEMBER(OEM_DIAGNOSTIC)
501
531
  TO_STRING_MEMBER(BURNER_STARTS)
502
532
  TO_STRING_MEMBER(CH_PUMP_STARTS)
@@ -20,7 +20,6 @@
20
20
  namespace esphome {
21
21
  namespace opentherm {
22
22
 
23
- // TODO: Account for immutable semantics change in hub.cpp when doing later installments of OpenTherm PR
24
23
  template<class T> constexpr T read_bit(T value, uint8_t bit) { return (value >> bit) & 0x01; }
25
24
 
26
25
  template<class T> constexpr T set_bit(T value, uint8_t bit) { return value |= (1UL << bit); }
@@ -28,7 +27,7 @@ template<class T> constexpr T set_bit(T value, uint8_t bit) { return value |= (1
28
27
  template<class T> constexpr T clear_bit(T value, uint8_t bit) { return value &= ~(1UL << bit); }
29
28
 
30
29
  template<class T> constexpr T write_bit(T value, uint8_t bit, uint8_t bit_value) {
31
- return bit_value ? setBit(value, bit) : clearBit(value, bit);
30
+ return bit_value ? set_bit(value, bit) : clear_bit(value, bit);
32
31
  }
33
32
 
34
33
  enum OperationMode {
@@ -100,6 +99,8 @@ enum MessageId {
100
99
  EXHAUST_TEMP = 33,
101
100
  FAN_SPEED = 35,
102
101
  FLAME_CURRENT = 36,
102
+ ROOM_TEMP_CH2 = 37,
103
+ REL_HUMIDITY = 38,
103
104
  DHW_BOUNDS = 48,
104
105
  CH_BOUNDS = 49,
105
106
  OTC_CURVE_BOUNDS = 50,
@@ -111,15 +112,46 @@ enum MessageId {
111
112
  HVAC_STATUS = 70,
112
113
  REL_VENT_SETPOINT = 71,
113
114
  DEVICE_VENT = 74,
115
+ HVAC_VER_ID = 75,
114
116
  REL_VENTILATION = 77,
115
117
  REL_HUMID_EXHAUST = 78,
118
+ EXHAUST_CO2 = 79,
116
119
  SUPPLY_INLET_TEMP = 80,
117
120
  SUPPLY_OUTLET_TEMP = 81,
118
121
  EXHAUST_INLET_TEMP = 82,
119
122
  EXHAUST_OUTLET_TEMP = 83,
123
+ EXHAUST_FAN_SPEED = 84,
124
+ SUPPLY_FAN_SPEED = 85,
125
+ REMOTE_VENTILATION_PARAM = 86,
120
126
  NOM_REL_VENTILATION = 87,
127
+ HVAC_NUM_TSP = 88,
128
+ HVAC_IDX_TSP = 89,
129
+ HVAC_FHB_SIZE = 90,
130
+ HVAC_FHB_IDX = 91,
121
131
 
132
+ RF_SIGNAL = 98,
133
+ DHW_MODE = 99,
122
134
  OVERRIDE_FUNC = 100,
135
+
136
+ // Solar Specific Message IDs
137
+ SOLAR_MODE_FLAGS = 101, // hb0-2 Controller storage mode
138
+ // lb0 Device fault
139
+ // lb1-3 Device mode status
140
+ // lb4-5 Device status
141
+ SOLAR_ASF = 102,
142
+ SOLAR_VERSION_ID = 103,
143
+ SOLAR_PRODUCT_ID = 104,
144
+ SOLAR_NUM_TSP = 105,
145
+ SOLAR_IDX_TSP = 106,
146
+ SOLAR_FHB_SIZE = 107,
147
+ SOLAR_FHB_IDX = 108,
148
+ SOLAR_STARTS = 109,
149
+ SOLAR_HOURS = 110,
150
+ SOLAR_ENERGY = 111,
151
+ SOLAR_TOTAL_ENERGY = 112,
152
+
153
+ FAILED_BURNER_STARTS = 113,
154
+ BURNER_FLAME_LOW = 114,
123
155
  OEM_DIAGNOSTIC = 115,
124
156
  BURNER_STARTS = 116,
125
157
  CH_PUMP_STARTS = 117,
@@ -0,0 +1,151 @@
1
+ #pragma once
2
+ namespace esphome {
3
+ namespace opentherm {
4
+
5
+ // ===== hub.h macros =====
6
+
7
+ // *_LIST macros will be generated in defines.h if at least one sensor from each platform is used.
8
+ // These lists will look like this:
9
+ // #define OPENTHERM_BINARY_SENSOR_LIST(F, sep) F(sensor_1) sep F(sensor_2)
10
+ // These lists will be used in hub.h to define sensor fields (passing macros like OPENTHERM_DECLARE_SENSOR as F)
11
+ // and setters (passing macros like OPENTHERM_SET_SENSOR as F) (see below)
12
+ // In order for things not to break, we define empty lists here in case some platforms are not used in config.
13
+ #ifndef OPENTHERM_SENSOR_LIST
14
+ #define OPENTHERM_SENSOR_LIST(F, sep)
15
+ #endif
16
+ #ifndef OPENTHERM_BINARY_SENSOR_LIST
17
+ #define OPENTHERM_BINARY_SENSOR_LIST(F, sep)
18
+ #endif
19
+ #ifndef OPENTHERM_SWITCH_LIST
20
+ #define OPENTHERM_SWITCH_LIST(F, sep)
21
+ #endif
22
+ #ifndef OPENTHERM_NUMBER_LIST
23
+ #define OPENTHERM_NUMBER_LIST(F, sep)
24
+ #endif
25
+ #ifndef OPENTHERM_OUTPUT_LIST
26
+ #define OPENTHERM_OUTPUT_LIST(F, sep)
27
+ #endif
28
+ #ifndef OPENTHERM_INPUT_SENSOR_LIST
29
+ #define OPENTHERM_INPUT_SENSOR_LIST(F, sep)
30
+ #endif
31
+
32
+ // Use macros to create fields for every entity specified in the ESPHome configuration
33
+ #define OPENTHERM_DECLARE_SENSOR(entity) sensor::Sensor *entity;
34
+ #define OPENTHERM_DECLARE_BINARY_SENSOR(entity) binary_sensor::BinarySensor *entity;
35
+ #define OPENTHERM_DECLARE_SWITCH(entity) OpenthermSwitch *entity;
36
+ #define OPENTHERM_DECLARE_NUMBER(entity) OpenthermNumber *entity;
37
+ #define OPENTHERM_DECLARE_OUTPUT(entity) OpenthermOutput *entity;
38
+ #define OPENTHERM_DECLARE_INPUT_SENSOR(entity) sensor::Sensor *entity;
39
+
40
+ // Setter macros
41
+ #define OPENTHERM_SET_SENSOR(entity) \
42
+ void set_##entity(sensor::Sensor *sensor) { this->entity = sensor; }
43
+
44
+ #define OPENTHERM_SET_BINARY_SENSOR(entity) \
45
+ void set_##entity(binary_sensor::BinarySensor *binary_sensor) { this->entity = binary_sensor; }
46
+
47
+ #define OPENTHERM_SET_SWITCH(entity) \
48
+ void set_##entity(OpenthermSwitch *sw) { this->entity = sw; }
49
+
50
+ #define OPENTHERM_SET_NUMBER(entity) \
51
+ void set_##entity(OpenthermNumber *number) { this->entity = number; }
52
+
53
+ #define OPENTHERM_SET_OUTPUT(entity) \
54
+ void set_##entity(OpenthermOutput *output) { this->entity = output; }
55
+
56
+ #define OPENTHERM_SET_INPUT_SENSOR(entity) \
57
+ void set_##entity(sensor::Sensor *sensor) { this->entity = sensor; }
58
+
59
+ // ===== hub.cpp macros =====
60
+
61
+ // *_MESSAGE_HANDLERS are generated in defines.h and look like this:
62
+ // OPENTHERM_NUMBER_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep) MESSAGE(COOLING_CONTROL)
63
+ // ENTITY(cooling_control_number, f88) postscript msg_sep They contain placeholders for message part and entities parts,
64
+ // since one message can contain multiple entities. MESSAGE part is substituted with OPENTHERM_MESSAGE_WRITE_MESSAGE,
65
+ // OPENTHERM_MESSAGE_READ_MESSAGE or OPENTHERM_MESSAGE_RESPONSE_MESSAGE. ENTITY part is substituted with
66
+ // OPENTHERM_MESSAGE_WRITE_ENTITY or OPENTHERM_MESSAGE_RESPONSE_ENTITY. OPENTHERM_IGNORE is used for sensor read
67
+ // requests since no data needs to be sent or processed, just the data id.
68
+
69
+ // In order for things not to break, we define empty lists here in case some platforms are not used in config.
70
+ #ifndef OPENTHERM_SENSOR_MESSAGE_HANDLERS
71
+ #define OPENTHERM_SENSOR_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)
72
+ #endif
73
+ #ifndef OPENTHERM_BINARY_SENSOR_MESSAGE_HANDLERS
74
+ #define OPENTHERM_BINARY_SENSOR_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)
75
+ #endif
76
+ #ifndef OPENTHERM_SWITCH_MESSAGE_HANDLERS
77
+ #define OPENTHERM_SWITCH_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)
78
+ #endif
79
+ #ifndef OPENTHERM_NUMBER_MESSAGE_HANDLERS
80
+ #define OPENTHERM_NUMBER_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)
81
+ #endif
82
+ #ifndef OPENTHERM_OUTPUT_MESSAGE_HANDLERS
83
+ #define OPENTHERM_OUTPUT_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)
84
+ #endif
85
+ #ifndef OPENTHERM_INPUT_SENSOR_MESSAGE_HANDLERS
86
+ #define OPENTHERM_INPUT_SENSOR_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)
87
+ #endif
88
+
89
+ // Write data request builders
90
+ #define OPENTHERM_MESSAGE_WRITE_MESSAGE(msg) \
91
+ case MessageId::msg: { \
92
+ data.type = MessageType::WRITE_DATA; \
93
+ data.id = request_id;
94
+ #define OPENTHERM_MESSAGE_WRITE_ENTITY(key, msg_data) message_data::write_##msg_data(this->key->state, data);
95
+ #define OPENTHERM_MESSAGE_WRITE_POSTSCRIPT \
96
+ return data; \
97
+ }
98
+
99
+ // Read data request builder
100
+ #define OPENTHERM_MESSAGE_READ_MESSAGE(msg) \
101
+ case MessageId::msg: \
102
+ data.type = MessageType::READ_DATA; \
103
+ data.id = request_id; \
104
+ return data;
105
+
106
+ // Data processing builders
107
+ #define OPENTHERM_MESSAGE_RESPONSE_MESSAGE(msg) case MessageId::msg:
108
+ #define OPENTHERM_MESSAGE_RESPONSE_ENTITY(key, msg_data) this->key->publish_state(message_data::parse_##msg_data(data));
109
+ #define OPENTHERM_MESSAGE_RESPONSE_POSTSCRIPT break;
110
+
111
+ #define OPENTHERM_IGNORE(x, y)
112
+
113
+ // Default macros for STATUS entities
114
+ #ifndef OPENTHERM_READ_ch_enable
115
+ #define OPENTHERM_READ_ch_enable true
116
+ #endif
117
+ #ifndef OPENTHERM_READ_dhw_enable
118
+ #define OPENTHERM_READ_dhw_enable true
119
+ #endif
120
+ #ifndef OPENTHERM_READ_t_set
121
+ #define OPENTHERM_READ_t_set 0.0
122
+ #endif
123
+ #ifndef OPENTHERM_READ_cooling_enable
124
+ #define OPENTHERM_READ_cooling_enable false
125
+ #endif
126
+ #ifndef OPENTHERM_READ_cooling_control
127
+ #define OPENTHERM_READ_cooling_control 0.0
128
+ #endif
129
+ #ifndef OPENTHERM_READ_otc_active
130
+ #define OPENTHERM_READ_otc_active false
131
+ #endif
132
+ #ifndef OPENTHERM_READ_ch2_active
133
+ #define OPENTHERM_READ_ch2_active false
134
+ #endif
135
+ #ifndef OPENTHERM_READ_t_set_ch2
136
+ #define OPENTHERM_READ_t_set_ch2 0.0
137
+ #endif
138
+ #ifndef OPENTHERM_READ_summer_mode_active
139
+ #define OPENTHERM_READ_summer_mode_active false
140
+ #endif
141
+ #ifndef OPENTHERM_READ_dhw_block
142
+ #define OPENTHERM_READ_dhw_block false
143
+ #endif
144
+
145
+ // These macros utilize the structure of *_LIST macros in order
146
+ #define ID(x) x
147
+ #define SHOW_INNER(x) #x
148
+ #define SHOW(x) SHOW_INNER(x)
149
+
150
+ } // namespace opentherm
151
+ } // namespace esphome
@@ -0,0 +1,47 @@
1
+ from typing import Any
2
+
3
+ import esphome.codegen as cg
4
+ import esphome.config_validation as cv
5
+ from esphome.components import output
6
+ from esphome.const import CONF_ID
7
+ from .. import const, schema, validate, input, generate
8
+
9
+ DEPENDENCIES = [const.OPENTHERM]
10
+ COMPONENT_TYPE = const.OUTPUT
11
+
12
+ OpenthermOutput = generate.opentherm_ns.class_(
13
+ "OpenthermOutput", output.FloatOutput, cg.Component, input.OpenthermInput
14
+ )
15
+
16
+
17
+ async def new_openthermoutput(
18
+ config: dict[str, Any], key: str, _hub: cg.MockObj
19
+ ) -> cg.Pvariable:
20
+ var = cg.new_Pvariable(config[CONF_ID])
21
+ await cg.register_component(var, config)
22
+ await output.register_output(var, config)
23
+ cg.add(getattr(var, "set_id")(cg.RawExpression(f'"{key}_{config[CONF_ID]}"')))
24
+ input.generate_setters(var, config)
25
+ return var
26
+
27
+
28
+ def get_entity_validation_schema(entity: schema.InputSchema) -> cv.Schema:
29
+ return (
30
+ output.FLOAT_OUTPUT_SCHEMA.extend(
31
+ {cv.GenerateID(): cv.declare_id(OpenthermOutput)}
32
+ )
33
+ .extend(input.input_schema(entity))
34
+ .extend(cv.COMPONENT_SCHEMA)
35
+ )
36
+
37
+
38
+ CONFIG_SCHEMA = validate.create_component_schema(
39
+ schema.INPUTS, get_entity_validation_schema
40
+ )
41
+
42
+
43
+ async def to_code(config: dict[str, Any]) -> None:
44
+ keys = await generate.component_to_code(
45
+ COMPONENT_TYPE, schema.INPUTS, OpenthermOutput, new_openthermoutput, config
46
+ )
47
+ generate.define_readers(COMPONENT_TYPE, keys)