esphome 2025.6.0b1__py3-none-any.whl → 2025.6.0b3__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 (78) hide show
  1. esphome/components/api/api_connection.cpp +53 -33
  2. esphome/components/api/api_connection.h +24 -25
  3. esphome/components/api/api_pb2.cpp +1 -0
  4. esphome/components/api/api_pb2.h +65 -226
  5. esphome/components/api/client.py +1 -3
  6. esphome/components/api/proto.h +1 -1
  7. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
  8. esphome/components/bluetooth_proxy/bluetooth_proxy.h +1 -1
  9. esphome/components/bme280_base/bme280_base.cpp +2 -3
  10. esphome/components/datetime/date_entity.cpp +5 -5
  11. esphome/components/datetime/datetime_base.h +0 -5
  12. esphome/components/datetime/datetime_entity.cpp +8 -8
  13. esphome/components/datetime/time_entity.cpp +4 -4
  14. esphome/components/esp32/__init__.py +30 -3
  15. esphome/components/esp32_ble/ble.cpp +90 -45
  16. esphome/components/esp32_ble/ble.h +24 -5
  17. esphome/components/esp32_ble/ble_event.h +172 -32
  18. esphome/components/esp32_ble/ble_scan_result.h +24 -0
  19. esphome/components/esp32_ble/queue.h +53 -27
  20. esphome/components/esp32_ble_tracker/__init__.py +1 -0
  21. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +95 -66
  22. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +16 -16
  23. esphome/components/esp32_camera/esp32_camera.cpp +1 -1
  24. esphome/components/fan/fan.cpp +26 -17
  25. esphome/components/i2s_audio/i2s_audio.cpp +1 -1
  26. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +47 -29
  27. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +2 -0
  28. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +28 -10
  29. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +1 -0
  30. esphome/components/kmeteriso/kmeteriso.cpp +2 -3
  31. esphome/components/light/light_state.h +15 -15
  32. esphome/components/logger/logger.cpp +2 -15
  33. esphome/components/logger/logger.h +1 -2
  34. esphome/components/mqtt/mqtt_component.cpp +1 -1
  35. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  36. esphome/components/nextion/nextion_upload_arduino.cpp +12 -9
  37. esphome/components/nextion/nextion_upload_idf.cpp +11 -9
  38. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  39. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  40. esphome/components/number/number.cpp +1 -1
  41. esphome/components/number/number.h +0 -4
  42. esphome/components/prometheus/__init__.py +0 -1
  43. esphome/components/select/select.cpp +1 -1
  44. esphome/components/select/select.h +0 -4
  45. esphome/components/sensor/sensor.cpp +8 -4
  46. esphome/components/sensor/sensor.h +3 -6
  47. esphome/components/spi/spi_arduino.cpp +22 -9
  48. esphome/components/status_led/light/status_led_light.cpp +2 -2
  49. esphome/components/status_led/light/status_led_light.h +1 -1
  50. esphome/components/switch/switch.h +13 -7
  51. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +14 -9
  52. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +1 -0
  53. esphome/components/text/text.cpp +1 -1
  54. esphome/components/text/text.h +0 -4
  55. esphome/components/text_sensor/text_sensor.cpp +8 -4
  56. esphome/components/text_sensor/text_sensor.h +6 -6
  57. esphome/components/update/update_entity.cpp +1 -1
  58. esphome/components/update/update_entity.h +0 -3
  59. esphome/components/uptime/sensor/uptime_timestamp_sensor.cpp +1 -1
  60. esphome/components/web_server_idf/__init__.py +0 -2
  61. esphome/components/web_server_idf/web_server_idf.cpp +6 -2
  62. esphome/components/web_server_idf/web_server_idf.h +7 -0
  63. esphome/components/weikai/weikai.cpp +1 -1
  64. esphome/const.py +1 -1
  65. esphome/core/application.cpp +14 -8
  66. esphome/core/application.h +7 -7
  67. esphome/core/component.cpp +36 -15
  68. esphome/core/component.h +30 -13
  69. esphome/core/entity_base.cpp +4 -16
  70. esphome/core/entity_base.h +27 -13
  71. esphome/core/helpers.h +1 -1
  72. esphome/wizard.py +0 -16
  73. {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b3.dist-info}/METADATA +2 -2
  74. {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b3.dist-info}/RECORD +78 -77
  75. {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b3.dist-info}/WHEEL +0 -0
  76. {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b3.dist-info}/entry_points.txt +0 -0
  77. {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b3.dist-info}/licenses/LICENSE +0 -0
  78. {esphome-2025.6.0b1.dist-info → esphome-2025.6.0b3.dist-info}/top_level.txt +0 -0
@@ -337,23 +337,26 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
337
337
 
338
338
  bool Nextion::upload_end_(bool successful) {
339
339
  ESP_LOGD(TAG, "TFT upload done: %s", YESNO(successful));
340
- this->is_updating_ = false;
341
- this->ignore_is_setup_ = false;
342
-
343
- uint32_t baud_rate = this->parent_->get_baud_rate();
344
- if (baud_rate != this->original_baud_rate_) {
345
- ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
346
- this->parent_->set_baud_rate(this->original_baud_rate_);
347
- this->parent_->load_settings();
348
- }
349
340
 
350
341
  if (successful) {
351
342
  ESP_LOGD(TAG, "Restart");
352
343
  delay(1500); // NOLINT
353
344
  App.safe_reboot();
345
+ delay(1500); // NOLINT
354
346
  } else {
355
347
  ESP_LOGE(TAG, "TFT upload failed");
348
+
349
+ this->is_updating_ = false;
350
+ this->ignore_is_setup_ = false;
351
+
352
+ uint32_t baud_rate = this->parent_->get_baud_rate();
353
+ if (baud_rate != this->original_baud_rate_) {
354
+ ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
355
+ this->parent_->set_baud_rate(this->original_baud_rate_);
356
+ this->parent_->load_settings();
357
+ }
356
358
  }
359
+
357
360
  return successful;
358
361
  }
359
362
 
@@ -337,15 +337,6 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) {
337
337
 
338
338
  bool Nextion::upload_end_(bool successful) {
339
339
  ESP_LOGD(TAG, "TFT upload done: %s", YESNO(successful));
340
- this->is_updating_ = false;
341
- this->ignore_is_setup_ = false;
342
-
343
- uint32_t baud_rate = this->parent_->get_baud_rate();
344
- if (baud_rate != this->original_baud_rate_) {
345
- ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
346
- this->parent_->set_baud_rate(this->original_baud_rate_);
347
- this->parent_->load_settings();
348
- }
349
340
 
350
341
  if (successful) {
351
342
  ESP_LOGD(TAG, "Restart");
@@ -353,7 +344,18 @@ bool Nextion::upload_end_(bool successful) {
353
344
  App.safe_reboot();
354
345
  } else {
355
346
  ESP_LOGE(TAG, "TFT upload failed");
347
+
348
+ this->is_updating_ = false;
349
+ this->ignore_is_setup_ = false;
350
+
351
+ uint32_t baud_rate = this->parent_->get_baud_rate();
352
+ if (baud_rate != this->original_baud_rate_) {
353
+ ESP_LOGD(TAG, "Baud back: %" PRIu32 "->%" PRIu32, baud_rate, this->original_baud_rate_);
354
+ this->parent_->set_baud_rate(this->original_baud_rate_);
355
+ this->parent_->load_settings();
356
+ }
356
357
  }
358
+
357
359
  return successful;
358
360
  }
359
361
 
@@ -88,7 +88,7 @@ void NextionSensor::set_state(float state, bool publish, bool send_to_nextion) {
88
88
  } else {
89
89
  this->raw_state = state;
90
90
  this->state = state;
91
- this->has_state_ = true;
91
+ this->set_has_state(true);
92
92
  }
93
93
  }
94
94
  this->update_component_settings();
@@ -37,7 +37,7 @@ void NextionTextSensor::set_state(const std::string &state, bool publish, bool s
37
37
  this->publish_state(state);
38
38
  } else {
39
39
  this->state = state;
40
- this->has_state_ = true;
40
+ this->set_has_state(true);
41
41
  }
42
42
 
43
43
  this->update_component_settings();
@@ -7,7 +7,7 @@ namespace number {
7
7
  static const char *const TAG = "number";
8
8
 
9
9
  void Number::publish_state(float state) {
10
- this->has_state_ = true;
10
+ this->set_has_state(true);
11
11
  this->state = state;
12
12
  ESP_LOGD(TAG, "'%s': Sending state %f", this->get_name().c_str(), state);
13
13
  this->state_callback_.call(state);
@@ -48,9 +48,6 @@ class Number : public EntityBase {
48
48
 
49
49
  NumberTraits traits;
50
50
 
51
- /// Return whether this number has gotten a full state yet.
52
- bool has_state() const { return has_state_; }
53
-
54
51
  protected:
55
52
  friend class NumberCall;
56
53
 
@@ -63,7 +60,6 @@ class Number : public EntityBase {
63
60
  virtual void control(float value) = 0;
64
61
 
65
62
  CallbackManager<void(float)> state_callback_;
66
- bool has_state_{false};
67
63
  };
68
64
 
69
65
  } // namespace number
@@ -31,7 +31,6 @@ CONFIG_SCHEMA = cv.Schema(
31
31
  }
32
32
  ),
33
33
  },
34
- cv.only_with_arduino,
35
34
  ).extend(cv.COMPONENT_SCHEMA)
36
35
 
37
36
 
@@ -10,7 +10,7 @@ void Select::publish_state(const std::string &state) {
10
10
  auto index = this->index_of(state);
11
11
  const auto *name = this->get_name().c_str();
12
12
  if (index.has_value()) {
13
- this->has_state_ = true;
13
+ this->set_has_state(true);
14
14
  this->state = state;
15
15
  ESP_LOGD(TAG, "'%s': Sending state %s (index %zu)", name, state.c_str(), index.value());
16
16
  this->state_callback_.call(state, index.value());
@@ -35,9 +35,6 @@ class Select : public EntityBase {
35
35
 
36
36
  void publish_state(const std::string &state);
37
37
 
38
- /// Return whether this select component has gotten a full state yet.
39
- bool has_state() const { return has_state_; }
40
-
41
38
  /// Instantiate a SelectCall object to modify this select component's state.
42
39
  SelectCall make_call() { return SelectCall(this); }
43
40
 
@@ -73,7 +70,6 @@ class Select : public EntityBase {
73
70
  virtual void control(const std::string &value) = 0;
74
71
 
75
72
  CallbackManager<void(std::string, size_t)> state_callback_;
76
- bool has_state_{false};
77
73
  };
78
74
 
79
75
  } // namespace select
@@ -38,7 +38,9 @@ StateClass Sensor::get_state_class() {
38
38
 
39
39
  void Sensor::publish_state(float state) {
40
40
  this->raw_state = state;
41
- this->raw_callback_.call(state);
41
+ if (this->raw_callback_) {
42
+ this->raw_callback_->call(state);
43
+ }
42
44
 
43
45
  ESP_LOGV(TAG, "'%s': Received new state %f", this->name_.c_str(), state);
44
46
 
@@ -51,7 +53,10 @@ void Sensor::publish_state(float state) {
51
53
 
52
54
  void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); }
53
55
  void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) {
54
- this->raw_callback_.add(std::move(callback));
56
+ if (!this->raw_callback_) {
57
+ this->raw_callback_ = make_unique<CallbackManager<void(float)>>();
58
+ }
59
+ this->raw_callback_->add(std::move(callback));
55
60
  }
56
61
 
57
62
  void Sensor::add_filter(Filter *filter) {
@@ -88,13 +93,12 @@ float Sensor::get_raw_state() const { return this->raw_state; }
88
93
  std::string Sensor::unique_id() { return ""; }
89
94
 
90
95
  void Sensor::internal_send_state_to_frontend(float state) {
91
- this->has_state_ = true;
96
+ this->set_has_state(true);
92
97
  this->state = state;
93
98
  ESP_LOGD(TAG, "'%s': Sending state %.5f %s with %d decimals of accuracy", this->get_name().c_str(), state,
94
99
  this->get_unit_of_measurement().c_str(), this->get_accuracy_decimals());
95
100
  this->callback_.call(state);
96
101
  }
97
- bool Sensor::has_state() const { return this->has_state_; }
98
102
 
99
103
  } // namespace sensor
100
104
  } // namespace esphome
@@ -7,6 +7,7 @@
7
7
  #include "esphome/components/sensor/filter.h"
8
8
 
9
9
  #include <vector>
10
+ #include <memory>
10
11
 
11
12
  namespace esphome {
12
13
  namespace sensor {
@@ -140,9 +141,6 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
140
141
  */
141
142
  float raw_state;
142
143
 
143
- /// Return whether this sensor has gotten a full state (that passed through all filters) yet.
144
- bool has_state() const;
145
-
146
144
  /** Override this method to set the unique ID of this sensor.
147
145
  *
148
146
  * @deprecated Do not use for new sensors, a suitable unique ID is automatically generated (2023.4).
@@ -152,15 +150,14 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
152
150
  void internal_send_state_to_frontend(float state);
153
151
 
154
152
  protected:
155
- CallbackManager<void(float)> raw_callback_; ///< Storage for raw state callbacks.
156
- CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
153
+ std::unique_ptr<CallbackManager<void(float)>> raw_callback_; ///< Storage for raw state callbacks (lazy allocated).
154
+ CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
157
155
 
158
156
  Filter *filter_list_{nullptr}; ///< Store all active filters.
159
157
 
160
158
  optional<int8_t> accuracy_decimals_; ///< Accuracy in decimals override
161
159
  optional<StateClass> state_class_{STATE_CLASS_NONE}; ///< State class override
162
160
  bool force_update_{false}; ///< Force update mode
163
- bool has_state_{false};
164
161
  };
165
162
 
166
163
  } // namespace sensor
@@ -3,7 +3,6 @@
3
3
 
4
4
  namespace esphome {
5
5
  namespace spi {
6
-
7
6
  #ifdef USE_ARDUINO
8
7
 
9
8
  static const char *const TAG = "spi-esp-arduino";
@@ -38,17 +37,31 @@ class SPIDelegateHw : public SPIDelegate {
38
37
 
39
38
  void write16(uint16_t data) override { this->channel_->transfer16(data); }
40
39
 
41
- #ifdef USE_RP2040
42
40
  void write_array(const uint8_t *ptr, size_t length) override {
43
- // avoid overwriting the supplied buffer
44
- uint8_t *rxbuf = new uint8_t[length]; // NOLINT(cppcoreguidelines-owning-memory)
45
- memcpy(rxbuf, ptr, length);
46
- this->channel_->transfer((void *) rxbuf, length);
47
- delete[] rxbuf; // NOLINT(cppcoreguidelines-owning-memory)
48
- }
41
+ if (length == 1) {
42
+ this->channel_->transfer(*ptr);
43
+ return;
44
+ }
45
+ #ifdef USE_RP2040
46
+ // avoid overwriting the supplied buffer. Use vector for automatic deallocation
47
+ auto rxbuf = std::vector<uint8_t>(length);
48
+ memcpy(rxbuf.data(), ptr, length);
49
+ this->channel_->transfer((void *) rxbuf.data(), length);
50
+ #elif defined(USE_ESP8266)
51
+ // ESP8266 SPI library requires the pointer to be word aligned, but the data may not be
52
+ // so we need to copy the data to a temporary buffer
53
+ if (reinterpret_cast<uintptr_t>(ptr) & 0x3) {
54
+ ESP_LOGVV(TAG, "SPI write buffer not word aligned, copying to temporary buffer");
55
+ auto txbuf = std::vector<uint8_t>(length);
56
+ memcpy(txbuf.data(), ptr, length);
57
+ this->channel_->writeBytes(txbuf.data(), length);
58
+ } else {
59
+ this->channel_->writeBytes(ptr, length);
60
+ }
49
61
  #else
50
- void write_array(const uint8_t *ptr, size_t length) override { this->channel_->writeBytes(ptr, length); }
62
+ this->channel_->writeBytes(ptr, length);
51
63
  #endif
64
+ }
52
65
 
53
66
  void read_array(uint8_t *ptr, size_t length) override { this->channel_->transfer(ptr, length); }
54
67
 
@@ -9,10 +9,10 @@ namespace status_led {
9
9
  static const char *const TAG = "status_led";
10
10
 
11
11
  void StatusLEDLightOutput::loop() {
12
- uint32_t new_state = App.get_app_state() & STATUS_LED_MASK;
12
+ uint8_t new_state = App.get_app_state() & STATUS_LED_MASK;
13
13
 
14
14
  if (new_state != this->last_app_state_) {
15
- ESP_LOGV(TAG, "New app state 0x%08" PRIX32, new_state);
15
+ ESP_LOGV(TAG, "New app state 0x%02X", new_state);
16
16
  }
17
17
 
18
18
  if ((new_state & STATUS_LED_ERROR) != 0u) {
@@ -36,7 +36,7 @@ class StatusLEDLightOutput : public light::LightOutput, public Component {
36
36
  GPIOPin *pin_{nullptr};
37
37
  output::BinaryOutput *output_{nullptr};
38
38
  light::LightState *lightstate_{};
39
- uint32_t last_app_state_{0xFFFF};
39
+ uint8_t last_app_state_{0xFF};
40
40
  void output_state_(bool state);
41
41
  };
42
42
 
@@ -21,7 +21,7 @@ const int RESTORE_MODE_PERSISTENT_MASK = 0x02;
21
21
  const int RESTORE_MODE_INVERTED_MASK = 0x04;
22
22
  const int RESTORE_MODE_DISABLED_MASK = 0x08;
23
23
 
24
- enum SwitchRestoreMode {
24
+ enum SwitchRestoreMode : uint8_t {
25
25
  SWITCH_ALWAYS_OFF = !RESTORE_MODE_ON_MASK,
26
26
  SWITCH_ALWAYS_ON = RESTORE_MODE_ON_MASK,
27
27
  SWITCH_RESTORE_DEFAULT_OFF = RESTORE_MODE_PERSISTENT_MASK,
@@ -49,12 +49,12 @@ class Switch : public EntityBase, public EntityBase_DeviceClass {
49
49
  */
50
50
  void publish_state(bool state);
51
51
 
52
- /// The current reported state of the binary sensor.
53
- bool state;
54
-
55
52
  /// Indicates whether or not state is to be retrieved from flash and how
56
53
  SwitchRestoreMode restore_mode{SWITCH_RESTORE_DEFAULT_OFF};
57
54
 
55
+ /// The current reported state of the binary sensor.
56
+ bool state;
57
+
58
58
  /** Turn this switch on. This is called by the front-end.
59
59
  *
60
60
  * For implementing switches, please override write_state.
@@ -123,10 +123,16 @@ class Switch : public EntityBase, public EntityBase_DeviceClass {
123
123
  */
124
124
  virtual void write_state(bool state) = 0;
125
125
 
126
- CallbackManager<void(bool)> state_callback_{};
127
- bool inverted_{false};
128
- Deduplicator<bool> publish_dedup_;
126
+ // Pointer first (4 bytes)
129
127
  ESPPreferenceObject rtc_;
128
+
129
+ // CallbackManager (12 bytes on 32-bit - contains vector)
130
+ CallbackManager<void(bool)> state_callback_{};
131
+
132
+ // Small types grouped together
133
+ Deduplicator<bool> publish_dedup_; // 2 bytes (bool has_value_ + bool last_value_)
134
+ bool inverted_{false}; // 1 byte
135
+ // Total: 3 bytes, 1 byte padding
130
136
  };
131
137
 
132
138
  #define LOG_SWITCH(prefix, type, obj) log_switch((TAG), (prefix), LOG_STR_LITERAL(type), (obj))
@@ -110,15 +110,7 @@ void TemplateAlarmControlPanel::loop() {
110
110
  delay = this->arming_night_time_;
111
111
  }
112
112
  if ((millis() - this->last_update_) > delay) {
113
- #ifdef USE_BINARY_SENSOR
114
- for (auto sensor_info : this->sensor_map_) {
115
- // Check for sensors left on and set to bypass automatically and remove them from monitoring
116
- if ((sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_AUTO) && (sensor_info.first->state)) {
117
- ESP_LOGW(TAG, "%s is left on and will be automatically bypassed", sensor_info.first->get_name().c_str());
118
- this->bypassed_sensor_indicies_.push_back(sensor_info.second.store_index);
119
- }
120
- }
121
- #endif
113
+ this->bypass_before_arming();
122
114
  this->publish_state(this->desired_state_);
123
115
  }
124
116
  return;
@@ -259,10 +251,23 @@ void TemplateAlarmControlPanel::arm_(optional<std::string> code, alarm_control_p
259
251
  if (delay > 0) {
260
252
  this->publish_state(ACP_STATE_ARMING);
261
253
  } else {
254
+ this->bypass_before_arming();
262
255
  this->publish_state(state);
263
256
  }
264
257
  }
265
258
 
259
+ void TemplateAlarmControlPanel::bypass_before_arming() {
260
+ #ifdef USE_BINARY_SENSOR
261
+ for (auto sensor_info : this->sensor_map_) {
262
+ // Check for sensors left on and set to bypass automatically and remove them from monitoring
263
+ if ((sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_AUTO) && (sensor_info.first->state)) {
264
+ ESP_LOGW(TAG, "'%s' is left on and will be automatically bypassed", sensor_info.first->get_name().c_str());
265
+ this->bypassed_sensor_indicies_.push_back(sensor_info.second.store_index);
266
+ }
267
+ }
268
+ #endif
269
+ }
270
+
266
271
  void TemplateAlarmControlPanel::control(const AlarmControlPanelCall &call) {
267
272
  if (call.get_state()) {
268
273
  if (call.get_state() == ACP_STATE_ARMED_AWAY) {
@@ -60,6 +60,7 @@ class TemplateAlarmControlPanel : public alarm_control_panel::AlarmControlPanel,
60
60
  bool get_requires_code_to_arm() const override { return this->requires_code_to_arm_; }
61
61
  bool get_all_sensors_ready() { return this->sensors_ready_; };
62
62
  void set_restore_mode(TemplateAlarmControlPanelRestoreMode restore_mode) { this->restore_mode_ = restore_mode; }
63
+ void bypass_before_arming();
63
64
 
64
65
  #ifdef USE_BINARY_SENSOR
65
66
  /** Add a binary_sensor to the alarm_panel.
@@ -7,7 +7,7 @@ namespace text {
7
7
  static const char *const TAG = "text";
8
8
 
9
9
  void Text::publish_state(const std::string &state) {
10
- this->has_state_ = true;
10
+ this->set_has_state(true);
11
11
  this->state = state;
12
12
  if (this->traits.get_mode() == TEXT_MODE_PASSWORD) {
13
13
  ESP_LOGD(TAG, "'%s': Sending state " LOG_SECRET("'%s'"), this->get_name().c_str(), state.c_str());
@@ -28,9 +28,6 @@ class Text : public EntityBase {
28
28
 
29
29
  void publish_state(const std::string &state);
30
30
 
31
- /// Return whether this text input has gotten a full state yet.
32
- bool has_state() const { return has_state_; }
33
-
34
31
  /// Instantiate a TextCall object to modify this text component's state.
35
32
  TextCall make_call() { return TextCall(this); }
36
33
 
@@ -48,7 +45,6 @@ class Text : public EntityBase {
48
45
  virtual void control(const std::string &value) = 0;
49
46
 
50
47
  CallbackManager<void(std::string)> state_callback_;
51
- bool has_state_{false};
52
48
  };
53
49
 
54
50
  } // namespace text
@@ -8,7 +8,9 @@ static const char *const TAG = "text_sensor";
8
8
 
9
9
  void TextSensor::publish_state(const std::string &state) {
10
10
  this->raw_state = state;
11
- this->raw_callback_.call(state);
11
+ if (this->raw_callback_) {
12
+ this->raw_callback_->call(state);
13
+ }
12
14
 
13
15
  ESP_LOGV(TAG, "'%s': Received new state %s", this->name_.c_str(), state.c_str());
14
16
 
@@ -53,20 +55,22 @@ void TextSensor::add_on_state_callback(std::function<void(std::string)> callback
53
55
  this->callback_.add(std::move(callback));
54
56
  }
55
57
  void TextSensor::add_on_raw_state_callback(std::function<void(std::string)> callback) {
56
- this->raw_callback_.add(std::move(callback));
58
+ if (!this->raw_callback_) {
59
+ this->raw_callback_ = make_unique<CallbackManager<void(std::string)>>();
60
+ }
61
+ this->raw_callback_->add(std::move(callback));
57
62
  }
58
63
 
59
64
  std::string TextSensor::get_state() const { return this->state; }
60
65
  std::string TextSensor::get_raw_state() const { return this->raw_state; }
61
66
  void TextSensor::internal_send_state_to_frontend(const std::string &state) {
62
67
  this->state = state;
63
- this->has_state_ = true;
68
+ this->set_has_state(true);
64
69
  ESP_LOGD(TAG, "'%s': Sending state '%s'", this->name_.c_str(), state.c_str());
65
70
  this->callback_.call(state);
66
71
  }
67
72
 
68
73
  std::string TextSensor::unique_id() { return ""; }
69
- bool TextSensor::has_state() { return this->has_state_; }
70
74
 
71
75
  } // namespace text_sensor
72
76
  } // namespace esphome
@@ -6,6 +6,7 @@
6
6
  #include "esphome/components/text_sensor/filter.h"
7
7
 
8
8
  #include <vector>
9
+ #include <memory>
9
10
 
10
11
  namespace esphome {
11
12
  namespace text_sensor {
@@ -33,6 +34,8 @@ namespace text_sensor {
33
34
 
34
35
  class TextSensor : public EntityBase, public EntityBase_DeviceClass {
35
36
  public:
37
+ TextSensor() = default;
38
+
36
39
  /// Getter-syntax for .state.
37
40
  std::string get_state() const;
38
41
  /// Getter-syntax for .raw_state
@@ -67,17 +70,14 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass {
67
70
  */
68
71
  virtual std::string unique_id();
69
72
 
70
- bool has_state();
71
-
72
73
  void internal_send_state_to_frontend(const std::string &state);
73
74
 
74
75
  protected:
75
- CallbackManager<void(std::string)> raw_callback_; ///< Storage for raw state callbacks.
76
- CallbackManager<void(std::string)> callback_; ///< Storage for filtered state callbacks.
76
+ std::unique_ptr<CallbackManager<void(std::string)>>
77
+ raw_callback_; ///< Storage for raw state callbacks (lazy allocated).
78
+ CallbackManager<void(std::string)> callback_; ///< Storage for filtered state callbacks.
77
79
 
78
80
  Filter *filter_list_{nullptr}; ///< Store all active filters.
79
-
80
- bool has_state_{false};
81
81
  };
82
82
 
83
83
  } // namespace text_sensor
@@ -30,7 +30,7 @@ void UpdateEntity::publish_state() {
30
30
  ESP_LOGD(TAG, " Progress: %.0f%%", this->update_info_.progress);
31
31
  }
32
32
 
33
- this->has_state_ = true;
33
+ this->set_has_state(true);
34
34
  this->state_callback_.call();
35
35
  }
36
36
 
@@ -28,8 +28,6 @@ enum UpdateState : uint8_t {
28
28
 
29
29
  class UpdateEntity : public EntityBase, public EntityBase_DeviceClass {
30
30
  public:
31
- bool has_state() const { return this->has_state_; }
32
-
33
31
  void publish_state();
34
32
 
35
33
  void perform() { this->perform(false); }
@@ -44,7 +42,6 @@ class UpdateEntity : public EntityBase, public EntityBase_DeviceClass {
44
42
  protected:
45
43
  UpdateState state_{UPDATE_STATE_UNKNOWN};
46
44
  UpdateInfo update_info_;
47
- bool has_state_{false};
48
45
 
49
46
  CallbackManager<void()> state_callback_{};
50
47
  };
@@ -13,7 +13,7 @@ static const char *const TAG = "uptime.sensor";
13
13
 
14
14
  void UptimeTimestampSensor::setup() {
15
15
  this->time_->add_on_time_sync_callback([this]() {
16
- if (this->has_state_)
16
+ if (this->has_state())
17
17
  return; // No need to update the timestamp if it's already set
18
18
 
19
19
  auto now = this->time_->now();
@@ -8,8 +8,6 @@ CONFIG_SCHEMA = cv.All(
8
8
  cv.only_with_esp_idf,
9
9
  )
10
10
 
11
- AUTO_LOAD = ["web_server"]
12
-
13
11
 
14
12
  async def to_code(config):
15
13
  # Increase the maximum supported size of headers section in HTTP request packet to be processed by the server
@@ -9,10 +9,12 @@
9
9
 
10
10
  #include "utils.h"
11
11
 
12
+ #include "web_server_idf.h"
13
+
14
+ #ifdef USE_WEBSERVER
12
15
  #include "esphome/components/web_server/web_server.h"
13
16
  #include "esphome/components/web_server/list_entities.h"
14
-
15
- #include "web_server_idf.h"
17
+ #endif // USE_WEBSERVER
16
18
 
17
19
  namespace esphome {
18
20
  namespace web_server_idf {
@@ -273,6 +275,7 @@ void AsyncResponseStream::printf(const char *fmt, ...) {
273
275
  this->print(str);
274
276
  }
275
277
 
278
+ #ifdef USE_WEBSERVER
276
279
  AsyncEventSource::~AsyncEventSource() {
277
280
  for (auto *ses : this->sessions_) {
278
281
  delete ses; // NOLINT(cppcoreguidelines-owning-memory)
@@ -511,6 +514,7 @@ void AsyncEventSourceResponse::deferrable_send_state(void *source, const char *e
511
514
  }
512
515
  }
513
516
  }
517
+ #endif
514
518
 
515
519
  } // namespace web_server_idf
516
520
  } // namespace esphome
@@ -1,6 +1,7 @@
1
1
  #pragma once
2
2
  #ifdef USE_ESP_IDF
3
3
 
4
+ #include "esphome/core/defines.h"
4
5
  #include <esp_http_server.h>
5
6
 
6
7
  #include <functional>
@@ -12,10 +13,12 @@
12
13
  #include <vector>
13
14
 
14
15
  namespace esphome {
16
+ #ifdef USE_WEBSERVER
15
17
  namespace web_server {
16
18
  class WebServer;
17
19
  class ListEntitiesIterator;
18
20
  }; // namespace web_server
21
+ #endif
19
22
  namespace web_server_idf {
20
23
 
21
24
  #define F(string_literal) (string_literal)
@@ -220,6 +223,7 @@ class AsyncWebHandler {
220
223
  virtual bool isRequestHandlerTrivial() { return true; }
221
224
  };
222
225
 
226
+ #ifdef USE_WEBSERVER
223
227
  class AsyncEventSource;
224
228
  class AsyncEventSourceResponse;
225
229
 
@@ -307,10 +311,13 @@ class AsyncEventSource : public AsyncWebHandler {
307
311
  connect_handler_t on_connect_{};
308
312
  esphome::web_server::WebServer *web_server_;
309
313
  };
314
+ #endif // USE_WEBSERVER
310
315
 
311
316
  class DefaultHeaders {
312
317
  friend class AsyncWebServerRequest;
318
+ #ifdef USE_WEBSERVER
313
319
  friend class AsyncEventSourceResponse;
320
+ #endif
314
321
 
315
322
  public:
316
323
  // NOLINTNEXTLINE(readability-identifier-naming)
@@ -102,7 +102,7 @@ WeikaiRegister &WeikaiRegister::operator|=(uint8_t value) {
102
102
  // The WeikaiComponent methods
103
103
  ///////////////////////////////////////////////////////////////////////////////
104
104
  void WeikaiComponent::loop() {
105
- if ((this->component_state_ & COMPONENT_STATE_MASK) != COMPONENT_STATE_LOOP)
105
+ if (!this->is_in_loop_state())
106
106
  return;
107
107
 
108
108
  // If there are some bytes in the receive FIFO we transfers them to the ring buffers
esphome/const.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Constants used by esphome."""
2
2
 
3
- __version__ = "2025.6.0b1"
3
+ __version__ = "2025.6.0b3"
4
4
 
5
5
  ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
6
6
  VALID_SUBSTITUTIONS_CHARACTERS = (