esphome 2025.2.1__py3-none-any.whl → 2025.3.0b1__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 (140) hide show
  1. esphome/__main__.py +9 -1
  2. esphome/components/api/api_connection.cpp +426 -70
  3. esphome/components/api/api_connection.h +117 -25
  4. esphome/components/api/api_pb2.cpp +9 -0
  5. esphome/components/api/api_pb2.h +1 -0
  6. esphome/components/api/api_server.cpp +2 -2
  7. esphome/components/api/list_entities.cpp +76 -22
  8. esphome/components/api/list_entities.h +1 -0
  9. esphome/components/api/subscribe_state.h +2 -0
  10. esphome/components/audio/audio_reader.cpp +7 -7
  11. esphome/components/audio/audio_reader.h +1 -1
  12. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -0
  13. esphome/components/bmp085/bmp085.cpp +1 -1
  14. esphome/components/chsc6x/__init__.py +2 -0
  15. esphome/components/chsc6x/chsc6x_touchscreen.cpp +47 -0
  16. esphome/components/chsc6x/chsc6x_touchscreen.h +34 -0
  17. esphome/components/chsc6x/touchscreen.py +33 -0
  18. esphome/components/climate/__init__.py +0 -1
  19. esphome/components/cst816/binary_sensor/__init__.py +2 -25
  20. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +3 -14
  21. esphome/components/cst816/touchscreen/cst816_touchscreen.h +0 -4
  22. esphome/components/esp32_ble_beacon/__init__.py +3 -1
  23. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -2
  24. esphome/components/esp8266/gpio.py +1 -2
  25. esphome/components/font/__init__.py +185 -185
  26. esphome/components/font/font.cpp +4 -4
  27. esphome/components/font/font.h +1 -0
  28. esphome/components/haier/climate.py +11 -10
  29. esphome/components/hbridge/switch/hbridge_switch.cpp +2 -2
  30. esphome/components/heatpumpir/climate.py +2 -1
  31. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  32. esphome/components/heatpumpir/heatpumpir.h +1 -0
  33. esphome/components/i2c/__init__.py +6 -6
  34. esphome/components/i2c/i2c_bus_esp_idf.cpp +6 -2
  35. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  36. esphome/components/ili9xxx/display.py +1 -0
  37. esphome/components/ili9xxx/ili9xxx_display.h +5 -0
  38. esphome/components/ili9xxx/ili9xxx_init.h +59 -0
  39. esphome/components/ld2450/__init__.py +51 -0
  40. esphome/components/ld2450/binary_sensor.py +47 -0
  41. esphome/components/ld2450/button/__init__.py +45 -0
  42. esphome/components/ld2450/button/reset_button.cpp +9 -0
  43. esphome/components/ld2450/button/reset_button.h +18 -0
  44. esphome/components/ld2450/button/restart_button.cpp +9 -0
  45. esphome/components/ld2450/button/restart_button.h +18 -0
  46. esphome/components/ld2450/ld2450.cpp +876 -0
  47. esphome/components/ld2450/ld2450.h +234 -0
  48. esphome/components/ld2450/number/__init__.py +121 -0
  49. esphome/components/ld2450/number/presence_timeout_number.cpp +12 -0
  50. esphome/components/ld2450/number/presence_timeout_number.h +18 -0
  51. esphome/components/ld2450/number/zone_coordinate_number.cpp +14 -0
  52. esphome/components/ld2450/number/zone_coordinate_number.h +19 -0
  53. esphome/components/ld2450/select/__init__.py +56 -0
  54. esphome/components/ld2450/select/baud_rate_select.cpp +12 -0
  55. esphome/components/ld2450/select/baud_rate_select.h +18 -0
  56. esphome/components/ld2450/select/zone_type_select.cpp +12 -0
  57. esphome/components/ld2450/select/zone_type_select.h +18 -0
  58. esphome/components/ld2450/sensor.py +156 -0
  59. esphome/components/ld2450/switch/__init__.py +45 -0
  60. esphome/components/ld2450/switch/bluetooth_switch.cpp +12 -0
  61. esphome/components/ld2450/switch/bluetooth_switch.h +18 -0
  62. esphome/components/ld2450/switch/multi_target_switch.cpp +12 -0
  63. esphome/components/ld2450/switch/multi_target_switch.h +18 -0
  64. esphome/components/ld2450/text_sensor.py +62 -0
  65. esphome/components/ltr390/ltr390.cpp +7 -7
  66. esphome/components/ltr390/ltr390.h +0 -1
  67. esphome/components/lvgl/defines.py +0 -2
  68. esphome/components/lvgl/font.cpp +1 -1
  69. esphome/components/lvgl/lvgl_esphome.cpp +27 -19
  70. esphome/components/lvgl/widgets/img.py +1 -3
  71. esphome/components/mcp2515/mcp2515.cpp +1 -0
  72. esphome/components/mlx90393/sensor.py +53 -33
  73. esphome/components/mlx90393/sensor_mlx90393.cpp +4 -0
  74. esphome/components/mlx90393/sensor_mlx90393.h +8 -3
  75. esphome/components/mqtt/__init__.py +2 -2
  76. esphome/components/msa3xx/__init__.py +189 -0
  77. esphome/components/msa3xx/binary_sensor.py +40 -0
  78. esphome/components/msa3xx/msa3xx.cpp +417 -0
  79. esphome/components/msa3xx/msa3xx.h +311 -0
  80. esphome/components/msa3xx/sensor.py +42 -0
  81. esphome/components/msa3xx/text_sensor.py +38 -0
  82. esphome/components/nfc/binary_sensor/__init__.py +4 -4
  83. esphome/components/opentherm/binary_sensor/__init__.py +4 -4
  84. esphome/components/opentherm/generate.py +6 -6
  85. esphome/components/opentherm/sensor/__init__.py +5 -6
  86. esphome/components/packages/__init__.py +35 -11
  87. esphome/components/pn532/binary_sensor.py +4 -4
  88. esphome/components/rc522/binary_sensor.py +4 -4
  89. esphome/components/socket/bsd_sockets_impl.cpp +1 -0
  90. esphome/components/socket/lwip_sockets_impl.cpp +1 -0
  91. esphome/components/socket/socket.h +3 -1
  92. esphome/components/ssd1306_base/__init__.py +7 -7
  93. esphome/components/thermostat/climate.py +1 -1
  94. esphome/components/tmp1075/tmp1075.cpp +7 -11
  95. esphome/components/tmp1075/tmp1075.h +1 -2
  96. esphome/components/tormatic/__init__.py +1 -0
  97. esphome/components/tormatic/cover.py +47 -0
  98. esphome/components/tormatic/tormatic_cover.cpp +355 -0
  99. esphome/components/tormatic/tormatic_cover.h +60 -0
  100. esphome/components/tormatic/tormatic_protocol.h +211 -0
  101. esphome/components/touchscreen/binary_sensor/__init__.py +3 -0
  102. esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.cpp +7 -1
  103. esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.h +3 -1
  104. esphome/components/touchscreen/touchscreen.cpp +3 -4
  105. esphome/components/udp/udp_component.h +4 -1
  106. esphome/components/web_server/list_entities.cpp +70 -66
  107. esphome/components/web_server/list_entities.h +43 -22
  108. esphome/components/web_server/web_server.cpp +345 -68
  109. esphome/components/web_server/web_server.h +138 -6
  110. esphome/components/web_server_base/__init__.py +1 -1
  111. esphome/components/web_server_idf/__init__.py +2 -0
  112. esphome/components/web_server_idf/web_server_idf.cpp +177 -30
  113. esphome/components/web_server_idf/web_server_idf.h +53 -4
  114. esphome/config_validation.py +23 -125
  115. esphome/const.py +5 -1
  116. esphome/core/config.py +12 -4
  117. esphome/core/defines.h +1 -1
  118. esphome/core/helpers.h +5 -3
  119. esphome/core/time.cpp +1 -0
  120. esphome/cpp_generator.py +3 -3
  121. esphome/dashboard/core.py +30 -21
  122. esphome/dashboard/dns.py +7 -1
  123. esphome/dashboard/entries.py +83 -16
  124. esphome/dashboard/settings.py +0 -4
  125. esphome/dashboard/status/mdns.py +43 -14
  126. esphome/dashboard/status/mqtt.py +22 -9
  127. esphome/dashboard/status/ping.py +54 -10
  128. esphome/dashboard/web_server.py +56 -24
  129. esphome/storage_json.py +4 -0
  130. esphome/wizard.py +13 -17
  131. esphome/writer.py +1 -3
  132. esphome/yaml_util.py +36 -33
  133. esphome/zeroconf.py +9 -21
  134. {esphome-2025.2.1.dist-info → esphome-2025.3.0b1.dist-info}/METADATA +5 -5
  135. {esphome-2025.2.1.dist-info → esphome-2025.3.0b1.dist-info}/RECORD +139 -99
  136. esphome/components/cst816/binary_sensor/cst816_button.h +0 -27
  137. {esphome-2025.2.1.dist-info → esphome-2025.3.0b1.dist-info}/LICENSE +0 -0
  138. {esphome-2025.2.1.dist-info → esphome-2025.3.0b1.dist-info}/WHEEL +0 -0
  139. {esphome-2025.2.1.dist-info → esphome-2025.3.0b1.dist-info}/entry_points.txt +0 -0
  140. {esphome-2025.2.1.dist-info → esphome-2025.3.0b1.dist-info}/top_level.txt +0 -0
@@ -14,6 +14,46 @@
14
14
  namespace esphome {
15
15
  namespace api {
16
16
 
17
+ using send_message_t = bool(APIConnection *, void *);
18
+
19
+ /*
20
+ This class holds a pointer to the source component that wants to publish a message, and a pointer to a function that
21
+ will lazily publish that message. The two pointers allow dedup in the deferred queue if multiple publishes for the
22
+ same component are backed up, and take up only 8 bytes of memory. The entry in the deferred queue (a std::vector) is
23
+ the DeferredMessage instance itself (not a pointer to one elsewhere in heap) so still only 8 bytes per entry. Even
24
+ 100 backed up messages (you'd have to have at least 100 sensors publishing because of dedup) would take up only 0.8
25
+ kB.
26
+ */
27
+ class DeferredMessageQueue {
28
+ struct DeferredMessage {
29
+ friend class DeferredMessageQueue;
30
+
31
+ protected:
32
+ void *source_;
33
+ send_message_t *send_message_;
34
+
35
+ public:
36
+ DeferredMessage(void *source, send_message_t *send_message) : source_(source), send_message_(send_message) {}
37
+ bool operator==(const DeferredMessage &test) const {
38
+ return (source_ == test.source_ && send_message_ == test.send_message_);
39
+ }
40
+ } __attribute__((packed));
41
+
42
+ protected:
43
+ // vector is used very specifically for its zero memory overhead even though items are popped from the front (memory
44
+ // footprint is more important than speed here)
45
+ std::vector<DeferredMessage> deferred_queue_;
46
+ APIConnection *api_connection_;
47
+
48
+ // helper for allowing only unique entries in the queue
49
+ void dmq_push_back_with_dedup_(void *source, send_message_t *send_message);
50
+
51
+ public:
52
+ DeferredMessageQueue(APIConnection *api_connection) : api_connection_(api_connection) {}
53
+ void process_queue();
54
+ void defer(void *source, send_message_t *send_message);
55
+ };
56
+
17
57
  class APIConnection : public APIServerConnection {
18
58
  public:
19
59
  APIConnection(std::unique_ptr<socket::Socket> socket, APIServer *parent);
@@ -28,96 +68,140 @@ class APIConnection : public APIServerConnection {
28
68
  }
29
69
  #ifdef USE_BINARY_SENSOR
30
70
  bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state);
31
- bool send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor);
71
+ void send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor);
72
+ static bool try_send_binary_sensor_state(APIConnection *api, void *v_binary_sensor);
73
+ static bool try_send_binary_sensor_state(APIConnection *api, binary_sensor::BinarySensor *binary_sensor, bool state);
74
+ static bool try_send_binary_sensor_info(APIConnection *api, void *v_binary_sensor);
32
75
  #endif
33
76
  #ifdef USE_COVER
34
77
  bool send_cover_state(cover::Cover *cover);
35
- bool send_cover_info(cover::Cover *cover);
78
+ void send_cover_info(cover::Cover *cover);
79
+ static bool try_send_cover_state(APIConnection *api, void *v_cover);
80
+ static bool try_send_cover_info(APIConnection *api, void *v_cover);
36
81
  void cover_command(const CoverCommandRequest &msg) override;
37
82
  #endif
38
83
  #ifdef USE_FAN
39
84
  bool send_fan_state(fan::Fan *fan);
40
- bool send_fan_info(fan::Fan *fan);
85
+ void send_fan_info(fan::Fan *fan);
86
+ static bool try_send_fan_state(APIConnection *api, void *v_fan);
87
+ static bool try_send_fan_info(APIConnection *api, void *v_fan);
41
88
  void fan_command(const FanCommandRequest &msg) override;
42
89
  #endif
43
90
  #ifdef USE_LIGHT
44
91
  bool send_light_state(light::LightState *light);
45
- bool send_light_info(light::LightState *light);
92
+ void send_light_info(light::LightState *light);
93
+ static bool try_send_light_state(APIConnection *api, void *v_light);
94
+ static bool try_send_light_info(APIConnection *api, void *v_light);
46
95
  void light_command(const LightCommandRequest &msg) override;
47
96
  #endif
48
97
  #ifdef USE_SENSOR
49
98
  bool send_sensor_state(sensor::Sensor *sensor, float state);
50
- bool send_sensor_info(sensor::Sensor *sensor);
99
+ void send_sensor_info(sensor::Sensor *sensor);
100
+ static bool try_send_sensor_state(APIConnection *api, void *v_sensor);
101
+ static bool try_send_sensor_state(APIConnection *api, sensor::Sensor *sensor, float state);
102
+ static bool try_send_sensor_info(APIConnection *api, void *v_sensor);
51
103
  #endif
52
104
  #ifdef USE_SWITCH
53
105
  bool send_switch_state(switch_::Switch *a_switch, bool state);
54
- bool send_switch_info(switch_::Switch *a_switch);
106
+ void send_switch_info(switch_::Switch *a_switch);
107
+ static bool try_send_switch_state(APIConnection *api, void *v_a_switch);
108
+ static bool try_send_switch_state(APIConnection *api, switch_::Switch *a_switch, bool state);
109
+ static bool try_send_switch_info(APIConnection *api, void *v_a_switch);
55
110
  void switch_command(const SwitchCommandRequest &msg) override;
56
111
  #endif
57
112
  #ifdef USE_TEXT_SENSOR
58
113
  bool send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state);
59
- bool send_text_sensor_info(text_sensor::TextSensor *text_sensor);
114
+ void send_text_sensor_info(text_sensor::TextSensor *text_sensor);
115
+ static bool try_send_text_sensor_state(APIConnection *api, void *v_text_sensor);
116
+ static bool try_send_text_sensor_state(APIConnection *api, text_sensor::TextSensor *text_sensor, std::string state);
117
+ static bool try_send_text_sensor_info(APIConnection *api, void *v_text_sensor);
60
118
  #endif
61
119
  #ifdef USE_ESP32_CAMERA
62
- void send_camera_state(std::shared_ptr<esp32_camera::CameraImage> image);
63
- bool send_camera_info(esp32_camera::ESP32Camera *camera);
120
+ void set_camera_state(std::shared_ptr<esp32_camera::CameraImage> image);
121
+ void send_camera_info(esp32_camera::ESP32Camera *camera);
122
+ static bool try_send_camera_info(APIConnection *api, void *v_camera);
64
123
  void camera_image(const CameraImageRequest &msg) override;
65
124
  #endif
66
125
  #ifdef USE_CLIMATE
67
126
  bool send_climate_state(climate::Climate *climate);
68
- bool send_climate_info(climate::Climate *climate);
127
+ void send_climate_info(climate::Climate *climate);
128
+ static bool try_send_climate_state(APIConnection *api, void *v_climate);
129
+ static bool try_send_climate_info(APIConnection *api, void *v_climate);
69
130
  void climate_command(const ClimateCommandRequest &msg) override;
70
131
  #endif
71
132
  #ifdef USE_NUMBER
72
133
  bool send_number_state(number::Number *number, float state);
73
- bool send_number_info(number::Number *number);
134
+ void send_number_info(number::Number *number);
135
+ static bool try_send_number_state(APIConnection *api, void *v_number);
136
+ static bool try_send_number_state(APIConnection *api, number::Number *number, float state);
137
+ static bool try_send_number_info(APIConnection *api, void *v_number);
74
138
  void number_command(const NumberCommandRequest &msg) override;
75
139
  #endif
76
140
  #ifdef USE_DATETIME_DATE
77
141
  bool send_date_state(datetime::DateEntity *date);
78
- bool send_date_info(datetime::DateEntity *date);
142
+ void send_date_info(datetime::DateEntity *date);
143
+ static bool try_send_date_state(APIConnection *api, void *v_date);
144
+ static bool try_send_date_info(APIConnection *api, void *v_date);
79
145
  void date_command(const DateCommandRequest &msg) override;
80
146
  #endif
81
147
  #ifdef USE_DATETIME_TIME
82
148
  bool send_time_state(datetime::TimeEntity *time);
83
- bool send_time_info(datetime::TimeEntity *time);
149
+ void send_time_info(datetime::TimeEntity *time);
150
+ static bool try_send_time_state(APIConnection *api, void *v_time);
151
+ static bool try_send_time_info(APIConnection *api, void *v_time);
84
152
  void time_command(const TimeCommandRequest &msg) override;
85
153
  #endif
86
154
  #ifdef USE_DATETIME_DATETIME
87
155
  bool send_datetime_state(datetime::DateTimeEntity *datetime);
88
- bool send_datetime_info(datetime::DateTimeEntity *datetime);
156
+ void send_datetime_info(datetime::DateTimeEntity *datetime);
157
+ static bool try_send_datetime_state(APIConnection *api, void *v_datetime);
158
+ static bool try_send_datetime_info(APIConnection *api, void *v_datetime);
89
159
  void datetime_command(const DateTimeCommandRequest &msg) override;
90
160
  #endif
91
161
  #ifdef USE_TEXT
92
162
  bool send_text_state(text::Text *text, std::string state);
93
- bool send_text_info(text::Text *text);
163
+ void send_text_info(text::Text *text);
164
+ static bool try_send_text_state(APIConnection *api, void *v_text);
165
+ static bool try_send_text_state(APIConnection *api, text::Text *text, std::string state);
166
+ static bool try_send_text_info(APIConnection *api, void *v_text);
94
167
  void text_command(const TextCommandRequest &msg) override;
95
168
  #endif
96
169
  #ifdef USE_SELECT
97
170
  bool send_select_state(select::Select *select, std::string state);
98
- bool send_select_info(select::Select *select);
171
+ void send_select_info(select::Select *select);
172
+ static bool try_send_select_state(APIConnection *api, void *v_select);
173
+ static bool try_send_select_state(APIConnection *api, select::Select *select, std::string state);
174
+ static bool try_send_select_info(APIConnection *api, void *v_select);
99
175
  void select_command(const SelectCommandRequest &msg) override;
100
176
  #endif
101
177
  #ifdef USE_BUTTON
102
- bool send_button_info(button::Button *button);
178
+ void send_button_info(button::Button *button);
179
+ static bool try_send_button_info(APIConnection *api, void *v_button);
103
180
  void button_command(const ButtonCommandRequest &msg) override;
104
181
  #endif
105
182
  #ifdef USE_LOCK
106
183
  bool send_lock_state(lock::Lock *a_lock, lock::LockState state);
107
- bool send_lock_info(lock::Lock *a_lock);
184
+ void send_lock_info(lock::Lock *a_lock);
185
+ static bool try_send_lock_state(APIConnection *api, void *v_a_lock);
186
+ static bool try_send_lock_state(APIConnection *api, lock::Lock *a_lock, lock::LockState state);
187
+ static bool try_send_lock_info(APIConnection *api, void *v_a_lock);
108
188
  void lock_command(const LockCommandRequest &msg) override;
109
189
  #endif
110
190
  #ifdef USE_VALVE
111
191
  bool send_valve_state(valve::Valve *valve);
112
- bool send_valve_info(valve::Valve *valve);
192
+ void send_valve_info(valve::Valve *valve);
193
+ static bool try_send_valve_state(APIConnection *api, void *v_valve);
194
+ static bool try_send_valve_info(APIConnection *api, void *v_valve);
113
195
  void valve_command(const ValveCommandRequest &msg) override;
114
196
  #endif
115
197
  #ifdef USE_MEDIA_PLAYER
116
198
  bool send_media_player_state(media_player::MediaPlayer *media_player);
117
- bool send_media_player_info(media_player::MediaPlayer *media_player);
199
+ void send_media_player_info(media_player::MediaPlayer *media_player);
200
+ static bool try_send_media_player_state(APIConnection *api, void *v_media_player);
201
+ static bool try_send_media_player_info(APIConnection *api, void *v_media_player);
118
202
  void media_player_command(const MediaPlayerCommandRequest &msg) override;
119
203
  #endif
120
- bool send_log_message(int level, const char *tag, const char *line);
204
+ bool try_send_log_message(int level, const char *tag, const char *line);
121
205
  void send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
122
206
  if (!this->service_call_subscription_)
123
207
  return;
@@ -160,18 +244,25 @@ class APIConnection : public APIServerConnection {
160
244
 
161
245
  #ifdef USE_ALARM_CONTROL_PANEL
162
246
  bool send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
163
- bool send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
247
+ void send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel);
248
+ static bool try_send_alarm_control_panel_state(APIConnection *api, void *v_a_alarm_control_panel);
249
+ static bool try_send_alarm_control_panel_info(APIConnection *api, void *v_a_alarm_control_panel);
164
250
  void alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) override;
165
251
  #endif
166
252
 
167
253
  #ifdef USE_EVENT
168
- bool send_event(event::Event *event, std::string event_type);
169
- bool send_event_info(event::Event *event);
254
+ void send_event(event::Event *event, std::string event_type);
255
+ void send_event_info(event::Event *event);
256
+ static bool try_send_event(APIConnection *api, void *v_event);
257
+ static bool try_send_event(APIConnection *api, event::Event *event, std::string event_type);
258
+ static bool try_send_event_info(APIConnection *api, void *v_event);
170
259
  #endif
171
260
 
172
261
  #ifdef USE_UPDATE
173
262
  bool send_update_state(update::UpdateEntity *update);
174
- bool send_update_info(update::UpdateEntity *update);
263
+ void send_update_info(update::UpdateEntity *update);
264
+ static bool try_send_update_state(APIConnection *api, void *v_update);
265
+ static bool try_send_update_info(APIConnection *api, void *v_update);
175
266
  void update_command(const UpdateCommandRequest &msg) override;
176
267
  #endif
177
268
 
@@ -262,6 +353,7 @@ class APIConnection : public APIServerConnection {
262
353
  bool service_call_subscription_{false};
263
354
  bool next_close_ = false;
264
355
  APIServer *parent_;
356
+ DeferredMessageQueue deferred_message_queue_;
265
357
  InitialStateIterator initial_state_iterator_;
266
358
  ListEntitiesIterator list_entities_iterator_;
267
359
  int state_subs_at_ = -1;
@@ -838,6 +838,10 @@ bool DeviceInfoResponse::decode_length(uint32_t field_id, ProtoLengthDelimited v
838
838
  this->suggested_area = value.as_string();
839
839
  return true;
840
840
  }
841
+ case 18: {
842
+ this->bluetooth_mac_address = value.as_string();
843
+ return true;
844
+ }
841
845
  default:
842
846
  return false;
843
847
  }
@@ -860,6 +864,7 @@ void DeviceInfoResponse::encode(ProtoWriteBuffer buffer) const {
860
864
  buffer.encode_uint32(14, this->legacy_voice_assistant_version);
861
865
  buffer.encode_uint32(17, this->voice_assistant_feature_flags);
862
866
  buffer.encode_string(16, this->suggested_area);
867
+ buffer.encode_string(18, this->bluetooth_mac_address);
863
868
  }
864
869
  #ifdef HAS_PROTO_MESSAGE_DUMP
865
870
  void DeviceInfoResponse::dump_to(std::string &out) const {
@@ -937,6 +942,10 @@ void DeviceInfoResponse::dump_to(std::string &out) const {
937
942
  out.append(" suggested_area: ");
938
943
  out.append("'").append(this->suggested_area).append("'");
939
944
  out.append("\n");
945
+
946
+ out.append(" bluetooth_mac_address: ");
947
+ out.append("'").append(this->bluetooth_mac_address).append("'");
948
+ out.append("\n");
940
949
  out.append("}");
941
950
  }
942
951
  #endif
@@ -354,6 +354,7 @@ class DeviceInfoResponse : public ProtoMessage {
354
354
  uint32_t legacy_voice_assistant_version{0};
355
355
  uint32_t voice_assistant_feature_flags{0};
356
356
  std::string suggested_area{};
357
+ std::string bluetooth_mac_address{};
357
358
  void encode(ProtoWriteBuffer buffer) const override;
358
359
  #ifdef HAS_PROTO_MESSAGE_DUMP
359
360
  void dump_to(std::string &out) const override;
@@ -72,7 +72,7 @@ void APIServer::setup() {
72
72
  logger::global_logger->add_on_log_callback([this](int level, const char *tag, const char *message) {
73
73
  for (auto &c : this->clients_) {
74
74
  if (!c->remove_)
75
- c->send_log_message(level, tag, message);
75
+ c->try_send_log_message(level, tag, message);
76
76
  }
77
77
  });
78
78
  }
@@ -86,7 +86,7 @@ void APIServer::setup() {
86
86
  [this](const std::shared_ptr<esp32_camera::CameraImage> &image) {
87
87
  for (auto &c : this->clients_) {
88
88
  if (!c->remove_)
89
- c->send_camera_state(image);
89
+ c->set_camera_state(image);
90
90
  }
91
91
  });
92
92
  }
@@ -10,37 +10,63 @@ namespace api {
10
10
 
11
11
  #ifdef USE_BINARY_SENSOR
12
12
  bool ListEntitiesIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) {
13
- return this->client_->send_binary_sensor_info(binary_sensor);
13
+ this->client_->send_binary_sensor_info(binary_sensor);
14
+ return true;
14
15
  }
15
16
  #endif
16
17
  #ifdef USE_COVER
17
- bool ListEntitiesIterator::on_cover(cover::Cover *cover) { return this->client_->send_cover_info(cover); }
18
+ bool ListEntitiesIterator::on_cover(cover::Cover *cover) {
19
+ this->client_->send_cover_info(cover);
20
+ return true;
21
+ }
18
22
  #endif
19
23
  #ifdef USE_FAN
20
- bool ListEntitiesIterator::on_fan(fan::Fan *fan) { return this->client_->send_fan_info(fan); }
24
+ bool ListEntitiesIterator::on_fan(fan::Fan *fan) {
25
+ this->client_->send_fan_info(fan);
26
+ return true;
27
+ }
21
28
  #endif
22
29
  #ifdef USE_LIGHT
23
- bool ListEntitiesIterator::on_light(light::LightState *light) { return this->client_->send_light_info(light); }
30
+ bool ListEntitiesIterator::on_light(light::LightState *light) {
31
+ this->client_->send_light_info(light);
32
+ return true;
33
+ }
24
34
  #endif
25
35
  #ifdef USE_SENSOR
26
- bool ListEntitiesIterator::on_sensor(sensor::Sensor *sensor) { return this->client_->send_sensor_info(sensor); }
36
+ bool ListEntitiesIterator::on_sensor(sensor::Sensor *sensor) {
37
+ this->client_->send_sensor_info(sensor);
38
+ return true;
39
+ }
27
40
  #endif
28
41
  #ifdef USE_SWITCH
29
- bool ListEntitiesIterator::on_switch(switch_::Switch *a_switch) { return this->client_->send_switch_info(a_switch); }
42
+ bool ListEntitiesIterator::on_switch(switch_::Switch *a_switch) {
43
+ this->client_->send_switch_info(a_switch);
44
+ return true;
45
+ }
30
46
  #endif
31
47
  #ifdef USE_BUTTON
32
- bool ListEntitiesIterator::on_button(button::Button *button) { return this->client_->send_button_info(button); }
48
+ bool ListEntitiesIterator::on_button(button::Button *button) {
49
+ this->client_->send_button_info(button);
50
+ return true;
51
+ }
33
52
  #endif
34
53
  #ifdef USE_TEXT_SENSOR
35
54
  bool ListEntitiesIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) {
36
- return this->client_->send_text_sensor_info(text_sensor);
55
+ this->client_->send_text_sensor_info(text_sensor);
56
+ return true;
37
57
  }
38
58
  #endif
39
59
  #ifdef USE_LOCK
40
- bool ListEntitiesIterator::on_lock(lock::Lock *a_lock) { return this->client_->send_lock_info(a_lock); }
60
+ bool ListEntitiesIterator::on_lock(lock::Lock *a_lock) {
61
+ this->client_->send_lock_info(a_lock);
62
+ return true;
63
+ }
41
64
  #endif
42
65
  #ifdef USE_VALVE
43
- bool ListEntitiesIterator::on_valve(valve::Valve *valve) { return this->client_->send_valve_info(valve); }
66
+ bool ListEntitiesIterator::on_valve(valve::Valve *valve) {
67
+ this->client_->send_valve_info(valve);
68
+ return true;
69
+ }
44
70
  #endif
45
71
 
46
72
  bool ListEntitiesIterator::on_end() { return this->client_->send_list_info_done(); }
@@ -52,55 +78,83 @@ bool ListEntitiesIterator::on_service(UserServiceDescriptor *service) {
52
78
 
53
79
  #ifdef USE_ESP32_CAMERA
54
80
  bool ListEntitiesIterator::on_camera(esp32_camera::ESP32Camera *camera) {
55
- return this->client_->send_camera_info(camera);
81
+ this->client_->send_camera_info(camera);
82
+ return true;
56
83
  }
57
84
  #endif
58
85
 
59
86
  #ifdef USE_CLIMATE
60
- bool ListEntitiesIterator::on_climate(climate::Climate *climate) { return this->client_->send_climate_info(climate); }
87
+ bool ListEntitiesIterator::on_climate(climate::Climate *climate) {
88
+ this->client_->send_climate_info(climate);
89
+ return true;
90
+ }
61
91
  #endif
62
92
 
63
93
  #ifdef USE_NUMBER
64
- bool ListEntitiesIterator::on_number(number::Number *number) { return this->client_->send_number_info(number); }
94
+ bool ListEntitiesIterator::on_number(number::Number *number) {
95
+ this->client_->send_number_info(number);
96
+ return true;
97
+ }
65
98
  #endif
66
99
 
67
100
  #ifdef USE_DATETIME_DATE
68
- bool ListEntitiesIterator::on_date(datetime::DateEntity *date) { return this->client_->send_date_info(date); }
101
+ bool ListEntitiesIterator::on_date(datetime::DateEntity *date) {
102
+ this->client_->send_date_info(date);
103
+ return true;
104
+ }
69
105
  #endif
70
106
 
71
107
  #ifdef USE_DATETIME_TIME
72
- bool ListEntitiesIterator::on_time(datetime::TimeEntity *time) { return this->client_->send_time_info(time); }
108
+ bool ListEntitiesIterator::on_time(datetime::TimeEntity *time) {
109
+ this->client_->send_time_info(time);
110
+ return true;
111
+ }
73
112
  #endif
74
113
 
75
114
  #ifdef USE_DATETIME_DATETIME
76
115
  bool ListEntitiesIterator::on_datetime(datetime::DateTimeEntity *datetime) {
77
- return this->client_->send_datetime_info(datetime);
116
+ this->client_->send_datetime_info(datetime);
117
+ return true;
78
118
  }
79
119
  #endif
80
120
 
81
121
  #ifdef USE_TEXT
82
- bool ListEntitiesIterator::on_text(text::Text *text) { return this->client_->send_text_info(text); }
122
+ bool ListEntitiesIterator::on_text(text::Text *text) {
123
+ this->client_->send_text_info(text);
124
+ return true;
125
+ }
83
126
  #endif
84
127
 
85
128
  #ifdef USE_SELECT
86
- bool ListEntitiesIterator::on_select(select::Select *select) { return this->client_->send_select_info(select); }
129
+ bool ListEntitiesIterator::on_select(select::Select *select) {
130
+ this->client_->send_select_info(select);
131
+ return true;
132
+ }
87
133
  #endif
88
134
 
89
135
  #ifdef USE_MEDIA_PLAYER
90
136
  bool ListEntitiesIterator::on_media_player(media_player::MediaPlayer *media_player) {
91
- return this->client_->send_media_player_info(media_player);
137
+ this->client_->send_media_player_info(media_player);
138
+ return true;
92
139
  }
93
140
  #endif
94
141
  #ifdef USE_ALARM_CONTROL_PANEL
95
142
  bool ListEntitiesIterator::on_alarm_control_panel(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
96
- return this->client_->send_alarm_control_panel_info(a_alarm_control_panel);
143
+ this->client_->send_alarm_control_panel_info(a_alarm_control_panel);
144
+ return true;
97
145
  }
98
146
  #endif
99
147
  #ifdef USE_EVENT
100
- bool ListEntitiesIterator::on_event(event::Event *event) { return this->client_->send_event_info(event); }
148
+ bool ListEntitiesIterator::on_event(event::Event *event) {
149
+ this->client_->send_event_info(event);
150
+ return true;
151
+ }
101
152
  #endif
102
153
  #ifdef USE_UPDATE
103
- bool ListEntitiesIterator::on_update(update::UpdateEntity *update) { return this->client_->send_update_info(update); }
154
+ bool ListEntitiesIterator::on_update(update::UpdateEntity *update) {
155
+ this->client_->send_update_info(update);
156
+ return true;
157
+ }
104
158
  #endif
105
159
 
106
160
  } // namespace api
@@ -80,6 +80,7 @@ class ListEntitiesIterator : public ComponentIterator {
80
80
  bool on_update(update::UpdateEntity *update) override;
81
81
  #endif
82
82
  bool on_end() override;
83
+ bool completed() { return this->state_ == IteratorState::NONE; }
83
84
 
84
85
  protected:
85
86
  APIConnection *client_;
@@ -76,6 +76,8 @@ class InitialStateIterator : public ComponentIterator {
76
76
  #ifdef USE_UPDATE
77
77
  bool on_update(update::UpdateEntity *update) override;
78
78
  #endif
79
+ bool completed() { return this->state_ == IteratorState::NONE; }
80
+
79
81
  protected:
80
82
  APIConnection *client_;
81
83
  };
@@ -15,6 +15,8 @@ namespace audio {
15
15
 
16
16
  static const uint32_t READ_WRITE_TIMEOUT_MS = 20;
17
17
 
18
+ static const uint32_t CONNECTION_TIMEOUT_MS = 5000;
19
+
18
20
  // The number of times the http read times out with no data before throwing an error
19
21
  static const uint32_t ERROR_COUNT_NO_DATA_READ_TIMEOUT = 100;
20
22
 
@@ -97,7 +99,7 @@ esp_err_t AudioReader::start(const std::string &uri, AudioFileType &file_type) {
97
99
  client_config.user_data = this;
98
100
  client_config.buffer_size = HTTP_STREAM_BUFFER_SIZE;
99
101
  client_config.keep_alive_enable = true;
100
- client_config.timeout_ms = 5000; // Shouldn't trigger watchdog resets if caller runs in a task
102
+ client_config.timeout_ms = CONNECTION_TIMEOUT_MS; // Shouldn't trigger watchdog resets if caller runs in a task
101
103
 
102
104
  #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
103
105
  if (uri.find("https:") != std::string::npos) {
@@ -189,7 +191,7 @@ esp_err_t AudioReader::start(const std::string &uri, AudioFileType &file_type) {
189
191
  file_type = this->audio_file_type_;
190
192
  }
191
193
 
192
- this->no_data_read_count_ = 0;
194
+ this->last_data_read_ms_ = millis();
193
195
 
194
196
  this->output_transfer_buffer_ = AudioSinkTransferBuffer::create(this->buffer_size_);
195
197
  if (this->output_transfer_buffer_ == nullptr) {
@@ -271,8 +273,7 @@ AudioReaderState AudioReader::http_read_() {
271
273
 
272
274
  if (received_len > 0) {
273
275
  this->output_transfer_buffer_->increase_buffer_length(received_len);
274
-
275
- this->no_data_read_count_ = 0;
276
+ this->last_data_read_ms_ = millis();
276
277
  } else if (received_len < 0) {
277
278
  // HTTP read error
278
279
  this->cleanup_connection_();
@@ -280,12 +281,11 @@ AudioReaderState AudioReader::http_read_() {
280
281
  } else {
281
282
  if (bytes_to_read > 0) {
282
283
  // Read timed out
283
- ++this->no_data_read_count_;
284
- if (this->no_data_read_count_ >= ERROR_COUNT_NO_DATA_READ_TIMEOUT) {
285
- // Timed out with no data read too many times, so the http read has failed
284
+ if ((millis() - this->last_data_read_ms_) > CONNECTION_TIMEOUT_MS) {
286
285
  this->cleanup_connection_();
287
286
  return AudioReaderState::FAILED;
288
287
  }
288
+
289
289
  delay(READ_WRITE_TIMEOUT_MS);
290
290
  }
291
291
  }
@@ -71,7 +71,7 @@ class AudioReader {
71
71
  void cleanup_connection_();
72
72
 
73
73
  size_t buffer_size_;
74
- uint32_t no_data_read_count_;
74
+ uint32_t last_data_read_ms_;
75
75
 
76
76
  esp_http_client_handle_t client_{nullptr};
77
77
 
@@ -15,6 +15,9 @@
15
15
 
16
16
  #include "bluetooth_connection.h"
17
17
 
18
+ #include <esp_bt.h>
19
+ #include <esp_bt_device.h>
20
+
18
21
  namespace esphome {
19
22
  namespace bluetooth_proxy {
20
23
 
@@ -114,6 +117,11 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
114
117
  return flags;
115
118
  }
116
119
 
120
+ std::string get_bluetooth_mac_address_pretty() {
121
+ const uint8_t *mac = esp_bt_dev_get_address();
122
+ return str_snprintf("%02X:%02X:%02X:%02X:%02X:%02X", 17, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
123
+ }
124
+
117
125
  protected:
118
126
  void send_api_packet_(const esp32_ble_tracker::ESPBTDevice &device);
119
127
 
@@ -95,7 +95,7 @@ void BMP085Component::read_pressure_() {
95
95
  return;
96
96
  }
97
97
 
98
- uint32_t value = (uint32_t(buffer[0]) << 16) | (uint32_t(buffer[1]) << 8) | uint32_t(buffer[0]);
98
+ uint32_t value = (uint32_t(buffer[0]) << 16) | (uint32_t(buffer[1]) << 8) | uint32_t(buffer[2]);
99
99
  if ((value >> 5) == 0) {
100
100
  ESP_LOGW(TAG, "Invalid pressure!");
101
101
  this->status_set_warning();
@@ -0,0 +1,2 @@
1
+ CODEOWNERS = ["@kkosik20"]
2
+ DEPENDENCIES = ["i2c"]
@@ -0,0 +1,47 @@
1
+ #include "chsc6x_touchscreen.h"
2
+
3
+ namespace esphome {
4
+ namespace chsc6x {
5
+
6
+ void CHSC6XTouchscreen::setup() {
7
+ ESP_LOGCONFIG(TAG, "Setting up CHSC6X Touchscreen...");
8
+ if (this->interrupt_pin_ != nullptr) {
9
+ this->interrupt_pin_->setup();
10
+ this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE);
11
+ }
12
+ if (this->x_raw_max_ == this->x_raw_min_) {
13
+ this->x_raw_max_ = this->display_->get_native_width();
14
+ }
15
+ if (this->y_raw_max_ == this->y_raw_min_) {
16
+ this->y_raw_max_ = this->display_->get_native_height();
17
+ }
18
+
19
+ ESP_LOGCONFIG(TAG, "CHSC6X Touchscreen setup complete");
20
+ }
21
+
22
+ void CHSC6XTouchscreen::update_touches() {
23
+ uint8_t data[CHSC6X_REG_STATUS_LEN];
24
+ if (!this->read_bytes(CHSC6X_REG_STATUS, data, sizeof(data))) {
25
+ return;
26
+ }
27
+
28
+ uint8_t num_of_touches = data[CHSC6X_REG_STATUS_TOUCH];
29
+
30
+ if (num_of_touches == 1) {
31
+ uint16_t x = data[CHSC6X_REG_STATUS_X_COR];
32
+ uint16_t y = data[CHSC6X_REG_STATUS_Y_COR];
33
+ this->add_raw_touch_position_(0, x, y);
34
+ }
35
+ }
36
+
37
+ void CHSC6XTouchscreen::dump_config() {
38
+ ESP_LOGCONFIG(TAG, "CHSC6X Touchscreen:");
39
+ LOG_I2C_DEVICE(this);
40
+ LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
41
+ ESP_LOGCONFIG(TAG, " Touch timeout: %d", this->touch_timeout_);
42
+ ESP_LOGCONFIG(TAG, " x_raw_max_: %d", this->x_raw_max_);
43
+ ESP_LOGCONFIG(TAG, " y_raw_max_: %d", this->y_raw_max_);
44
+ }
45
+
46
+ } // namespace chsc6x
47
+ } // namespace esphome
@@ -0,0 +1,34 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/i2c/i2c.h"
4
+ #include "esphome/components/touchscreen/touchscreen.h"
5
+ #include "esphome/core/component.h"
6
+ #include "esphome/core/hal.h"
7
+ #include "esphome/core/log.h"
8
+
9
+ namespace esphome {
10
+ namespace chsc6x {
11
+
12
+ static const char *const TAG = "chsc6x.touchscreen";
13
+
14
+ static const uint8_t CHSC6X_REG_STATUS = 0x00;
15
+ static const uint8_t CHSC6X_REG_STATUS_TOUCH = 0x00;
16
+ static const uint8_t CHSC6X_REG_STATUS_X_COR = 0x02;
17
+ static const uint8_t CHSC6X_REG_STATUS_Y_COR = 0x04;
18
+ static const uint8_t CHSC6X_REG_STATUS_LEN = 0x05;
19
+ static const uint8_t CHSC6X_CHIP_ID = 0x2e;
20
+
21
+ class CHSC6XTouchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice {
22
+ public:
23
+ void setup() override;
24
+ void update_touches() override;
25
+ void dump_config() override;
26
+
27
+ void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; }
28
+
29
+ protected:
30
+ InternalGPIOPin *interrupt_pin_{};
31
+ };
32
+
33
+ } // namespace chsc6x
34
+ } // namespace esphome