esphome 2025.3.2__py3-none-any.whl → 2025.3.3__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.
@@ -555,10 +555,10 @@ void Display::get_text_bounds(int x, int y, const char *text, BaseFont *font, Te
555
555
 
556
556
  switch (x_align) {
557
557
  case TextAlign::RIGHT:
558
- *x1 = x - *width;
558
+ *x1 = x - *width - x_offset;
559
559
  break;
560
560
  case TextAlign::CENTER_HORIZONTAL:
561
- *x1 = x - (*width) / 2;
561
+ *x1 = x - (*width + x_offset) / 2;
562
562
  break;
563
563
  case TextAlign::LEFT:
564
564
  default:
@@ -1,7 +1,9 @@
1
1
  import esphome.codegen as cg
2
- from esphome.components.switch import Switch, new_switch, switch_schema
2
+ from esphome.components.switch import Switch, register_switch, switch_schema
3
3
  import esphome.config_validation as cv
4
+ from esphome.const import CONF_ID
4
5
  from esphome.cpp_generator import MockObj
6
+ from esphome.cpp_types import Component
5
7
 
6
8
  from ..defines import CONF_WIDGET, literal
7
9
  from ..lvcode import (
@@ -18,7 +20,7 @@ from ..lvcode import (
18
20
  from ..types import LV_EVENT, LV_STATE, lv_pseudo_button_t, lvgl_ns
19
21
  from ..widgets import get_widgets, wait_for_widgets
20
22
 
21
- LVGLSwitch = lvgl_ns.class_("LVGLSwitch", Switch)
23
+ LVGLSwitch = lvgl_ns.class_("LVGLSwitch", Switch, Component)
22
24
  CONFIG_SCHEMA = switch_schema(LVGLSwitch).extend(
23
25
  {
24
26
  cv.Required(CONF_WIDGET): cv.use_id(lv_pseudo_button_t),
@@ -27,21 +29,24 @@ CONFIG_SCHEMA = switch_schema(LVGLSwitch).extend(
27
29
 
28
30
 
29
31
  async def to_code(config):
30
- switch = await new_switch(config)
31
32
  widget = await get_widgets(config, CONF_WIDGET)
32
33
  widget = widget[0]
33
34
  await wait_for_widgets()
34
- async with LambdaContext(EVENT_ARG) as checked_ctx:
35
- checked_ctx.add(switch.publish_state(widget.get_value()))
35
+ switch_id = MockObj(config[CONF_ID], "->")
36
+ v = literal("v")
36
37
  async with LambdaContext([(cg.bool_, "v")]) as control:
37
- with LvConditional(MockObj("v")) as cond:
38
+ with LvConditional(v) as cond:
38
39
  widget.add_state(LV_STATE.CHECKED)
39
40
  cond.else_()
40
41
  widget.clear_state(LV_STATE.CHECKED)
41
42
  lv.event_send(widget.obj, API_EVENT, cg.nullptr)
42
- control.add(switch.publish_state(literal("v")))
43
+ control.add(switch_id.publish_state(v))
44
+ switch = cg.new_Pvariable(config[CONF_ID], await control.get_lambda())
45
+ await cg.register_component(switch, config)
46
+ await register_switch(switch, config)
47
+ async with LambdaContext(EVENT_ARG) as checked_ctx:
48
+ checked_ctx.add(switch.publish_state(widget.get_value()))
43
49
  async with LvContext() as ctx:
44
- lv_add(switch.set_control_lambda(await control.get_lambda()))
45
50
  ctx.add(
46
51
  lvgl_static.add_event_cb(
47
52
  widget.obj,
@@ -10,26 +10,15 @@
10
10
  namespace esphome {
11
11
  namespace lvgl {
12
12
 
13
- class LVGLSwitch : public switch_::Switch {
13
+ class LVGLSwitch : public switch_::Switch, public Component {
14
14
  public:
15
- void set_control_lambda(std::function<void(bool)> state_lambda) {
16
- this->state_lambda_ = std::move(state_lambda);
17
- if (this->initial_state_.has_value()) {
18
- this->state_lambda_(this->initial_state_.value());
19
- this->initial_state_.reset();
20
- }
21
- }
15
+ LVGLSwitch(std::function<void(bool)> state_lambda) : state_lambda_(std::move(state_lambda)) {}
16
+
17
+ void setup() override { this->write_state(this->get_initial_state_with_restore_mode().value_or(false)); }
22
18
 
23
19
  protected:
24
- void write_state(bool value) override {
25
- if (this->state_lambda_ != nullptr) {
26
- this->state_lambda_(value);
27
- } else {
28
- this->initial_state_ = value;
29
- }
30
- }
20
+ void write_state(bool value) override { this->state_lambda_(value); }
31
21
  std::function<void(bool)> state_lambda_{};
32
- optional<bool> initial_state_{};
33
22
  };
34
23
 
35
24
  } // namespace lvgl
@@ -91,7 +91,7 @@ async def to_code(config):
91
91
  add_idf_component(
92
92
  name="mdns",
93
93
  repo="https://github.com/espressif/esp-protocols.git",
94
- ref="mdns-v1.8.0",
94
+ ref="mdns-v1.8.2",
95
95
  path="components/mdns",
96
96
  )
97
97
 
@@ -100,7 +100,7 @@ void SpeakerMediaPlayer::setup() {
100
100
 
101
101
  if (!this->single_pipeline_()) {
102
102
  this->media_pipeline_ = make_unique<AudioPipeline>(this->media_speaker_, this->buffer_size_,
103
- this->task_stack_in_psram_, "ann", MEDIA_PIPELINE_TASK_PRIORITY);
103
+ this->task_stack_in_psram_, "med", MEDIA_PIPELINE_TASK_PRIORITY);
104
104
 
105
105
  if (this->media_pipeline_ == nullptr) {
106
106
  ESP_LOGE(TAG, "Failed to create media pipeline");
@@ -170,12 +170,28 @@ void SpeakerMediaPlayer::watch_media_commands_() {
170
170
  // Ensure the loaded next item doesn't start playing, clear the queue, start the file, and unpause
171
171
  this->cancel_timeout("next_media");
172
172
  this->media_playlist_.clear();
173
- if (media_command.file.has_value()) {
174
- this->media_pipeline_->start_file(playlist_item.file.value());
175
- } else if (media_command.url.has_value()) {
176
- this->media_pipeline_->start_url(playlist_item.url.value());
173
+ if (this->is_paused_) {
174
+ // If paused, stop the media pipeline and unpause it after confirming its stopped. This avoids playing a
175
+ // short segment of the paused file before starting the new one.
176
+ this->media_pipeline_->stop();
177
+ this->set_retry("unpause_med", 50, 3, [this](const uint8_t remaining_attempts) {
178
+ if (this->media_pipeline_state_ == AudioPipelineState::STOPPED) {
179
+ this->media_pipeline_->set_pause_state(false);
180
+ this->is_paused_ = false;
181
+ return RetryResult::DONE;
182
+ }
183
+ return RetryResult::RETRY;
184
+ });
185
+ } else {
186
+ // Not paused, just directly start the file
187
+ if (media_command.file.has_value()) {
188
+ this->media_pipeline_->start_file(playlist_item.file.value());
189
+ } else if (media_command.url.has_value()) {
190
+ this->media_pipeline_->start_url(playlist_item.url.value());
191
+ }
192
+ this->media_pipeline_->set_pause_state(false);
193
+ this->is_paused_ = false;
177
194
  }
178
- this->media_pipeline_->set_pause_state(false);
179
195
  }
180
196
  this->media_playlist_.push_back(playlist_item);
181
197
  }
@@ -203,19 +219,37 @@ void SpeakerMediaPlayer::watch_media_commands_() {
203
219
  this->is_paused_ = true;
204
220
  break;
205
221
  case media_player::MEDIA_PLAYER_COMMAND_STOP:
222
+ // Pipelines do not stop immediately after calling the stop command, so confirm its stopped before unpausing.
223
+ // This avoids an audible short segment playing after receiving the stop command in a paused state.
206
224
  if (this->single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
207
225
  if (this->announcement_pipeline_ != nullptr) {
208
226
  this->cancel_timeout("next_ann");
209
227
  this->announcement_playlist_.clear();
210
228
  this->announcement_pipeline_->stop();
229
+ this->set_retry("unpause_ann", 50, 3, [this](const uint8_t remaining_attempts) {
230
+ if (this->announcement_pipeline_state_ == AudioPipelineState::STOPPED) {
231
+ this->announcement_pipeline_->set_pause_state(false);
232
+ return RetryResult::DONE;
233
+ }
234
+ return RetryResult::RETRY;
235
+ });
211
236
  }
212
237
  } else {
213
238
  if (this->media_pipeline_ != nullptr) {
214
239
  this->cancel_timeout("next_media");
215
240
  this->media_playlist_.clear();
216
241
  this->media_pipeline_->stop();
242
+ this->set_retry("unpause_med", 50, 3, [this](const uint8_t remaining_attempts) {
243
+ if (this->media_pipeline_state_ == AudioPipelineState::STOPPED) {
244
+ this->media_pipeline_->set_pause_state(false);
245
+ this->is_paused_ = false;
246
+ return RetryResult::DONE;
247
+ }
248
+ return RetryResult::RETRY;
249
+ });
217
250
  }
218
251
  }
252
+
219
253
  break;
220
254
  case media_player::MEDIA_PLAYER_COMMAND_TOGGLE:
221
255
  if (this->media_pipeline_ != nullptr) {
@@ -332,11 +366,11 @@ void SpeakerMediaPlayer::loop() {
332
366
  }
333
367
 
334
368
  if (timeout_ms > 0) {
335
- // Pause pipeline internally to facilitiate delay between items
369
+ // Pause pipeline internally to facilitate the delay between items
336
370
  this->announcement_pipeline_->set_pause_state(true);
337
- // Internally unpause the pipeline after the delay between playlist items
338
- this->set_timeout("next_ann", timeout_ms,
339
- [this]() { this->announcement_pipeline_->set_pause_state(this->is_paused_); });
371
+ // Internally unpause the pipeline after the delay between playlist items. Announcements do not follow the
372
+ // media player's pause state.
373
+ this->set_timeout("next_ann", timeout_ms, [this]() { this->announcement_pipeline_->set_pause_state(false); });
340
374
  }
341
375
  }
342
376
  } else {
@@ -372,9 +406,10 @@ void SpeakerMediaPlayer::loop() {
372
406
  }
373
407
 
374
408
  if (timeout_ms > 0) {
375
- // Pause pipeline internally to facilitiate delay between items
409
+ // Pause pipeline internally to facilitate the delay between items
376
410
  this->media_pipeline_->set_pause_state(true);
377
- // Internally unpause the pipeline after the delay between playlist items
411
+ // Internally unpause the pipeline after the delay between playlist items, if the media player state is
412
+ // not paused.
378
413
  this->set_timeout("next_media", timeout_ms,
379
414
  [this]() { this->media_pipeline_->set_pause_state(this->is_paused_); });
380
415
  }
esphome/const.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Constants used by esphome."""
2
2
 
3
- __version__ = "2025.3.2"
3
+ __version__ = "2025.3.3"
4
4
 
5
5
  ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
6
6
  VALID_SUBSTITUTIONS_CHARACTERS = (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: esphome
3
- Version: 2025.3.2
3
+ Version: 2025.3.3
4
4
  Summary: ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems.
5
5
  Author-email: The ESPHome Authors <esphome@nabucasa.com>
6
6
  License: MIT
@@ -5,7 +5,7 @@ esphome/codegen.py,sha256=GePHUM7xdXb_Pil59SHVsXg2F4VBPgkH-Fz2PDX8Z54,1873
5
5
  esphome/config.py,sha256=fFrDYbhWY1xn_onAl_0jwlg9D8NkK_FdKULTlnjZtxs,39832
6
6
  esphome/config_helpers.py,sha256=MKf_wzO35nn41FvigXE0iYKDslPgL2ruf8R-EPtTT2I,3256
7
7
  esphome/config_validation.py,sha256=9KOhLHQXmDbahg6zHynXfXDfAL2bciu35_SHxHrzZ2M,63705
8
- esphome/const.py,sha256=rwHb_1x4HaQyAMW_pj8GoImb98c_P3aQF2G5skP1ND8,40762
8
+ esphome/const.py,sha256=-khONIbIZaEVV6rouwuo3K6u9_qn4jMlFdB1EY1Y5HY,40762
9
9
  esphome/coroutine.py,sha256=j_14z8dIIzIBeuNO30D4c1RJvMMt1xZFZ58Evd-EvJA,9344
10
10
  esphome/cpp_generator.py,sha256=1g-y3fxWSrd5Kpbz6DrJXaQajjuwQiTIaTRIz9n7svI,31237
11
11
  esphome/cpp_helpers.py,sha256=6C2vNbOIhZKi43xRVlk5hp9GfshfBn-rc5D_ZFUEYaE,4801
@@ -686,7 +686,7 @@ esphome/components/dht12/dht12.cpp,sha256=l9vUeg6oc_XRIifT6pft_Jjk4WmS08rLkWv_af
686
686
  esphome/components/dht12/dht12.h,sha256=zHdQNIDC7nPMblvyEkTfXMeGCLmYRB7ZL_SXuB2PEWY,788
687
687
  esphome/components/dht12/sensor.py,sha256=9P1JtUF2VRYtEE1j8GHlsob1EHF5n3DC7mGuGV_fE_w,1684
688
688
  esphome/components/display/__init__.py,sha256=cKo4ldiSbNxcJKEITCDODtgS9kKzQJoPtJIc7mMapsQ,6760
689
- esphome/components/display/display.cpp,sha256=sFhBJ90cclkXNTMtx-mvPqVVS0K9diD7NvHLgAJEzkM,32372
689
+ esphome/components/display/display.cpp,sha256=wXZdyEDufmv6QK-R3if2rBl9rPnHU8vzrCaPRQ33_Wk,32394
690
690
  esphome/components/display/display.h,sha256=uIs9FRgOYUXvOuEJ1NWsXtfja0a3SWCdmx-gGbhrfC0,32346
691
691
  esphome/components/display/display_buffer.cpp,sha256=0jL60x2WNyDTNgjK2Iv7R4ZlA57cbIt1-J_QvGFKlbM,1896
692
692
  esphome/components/display/display_buffer.h,sha256=RkFqe72PZtSKR60mWlb79FDqVQQFsefcEOdOMwIjuGc,809
@@ -1541,8 +1541,8 @@ esphome/components/lvgl/number/lvgl_number.h,sha256=UshgT5_EvfaA0nWWChjxoyIPy_0W
1541
1541
  esphome/components/lvgl/select/__init__.py,sha256=KOlRVSjCt8TFrjrGPywpjKmQUUAzJUHuA_acLCp6-EI,1011
1542
1542
  esphome/components/lvgl/select/lvgl_select.h,sha256=_nqOOVDNKcOEph6-EZ40VhjkgMdFRjVJB3OTl6tVIso,1659
1543
1543
  esphome/components/lvgl/sensor/__init__.py,sha256=TCK3N05hAW1OjDYV1S5DUZd5JcmfpzWrcVwuA6PXf1c,1116
1544
- esphome/components/lvgl/switch/__init__.py,sha256=7C81PMNEHFu2jxPHH7Mbthq0iQQz7AZ496eyhIjgnhQ,1713
1545
- esphome/components/lvgl/switch/lvgl_switch.h,sha256=PF9vT-HtLnGTdMRdHhfcgnlKeSUDnkiFJoLok_zurnQ,868
1544
+ esphome/components/lvgl/switch/__init__.py,sha256=d63-MV2Hbz_fNh_qWTEbe0K_g4eJX0x63TW2XyIrhe0,1909
1545
+ esphome/components/lvgl/switch/lvgl_switch.h,sha256=EUG9PQfryUD8EHP_GmYMGElOrBQG0Yd8FHyFFfBEvbw,686
1546
1546
  esphome/components/lvgl/text/__init__.py,sha256=6P8kh6XRVX1Falw3Up0YsN4HIb9CyJShXHjNQb_Rsw4,1544
1547
1547
  esphome/components/lvgl/text/lvgl_text.h,sha256=H0tLRmOMCKTelGj-kLF0J6CGoOPQo142cP-CTOk4Rog,914
1548
1548
  esphome/components/lvgl/text_sensor/__init__.py,sha256=UtZwQ09zNCVaR48v7UodRSa-rY-1XF9YBg-jPTRNKRg,1103
@@ -1700,7 +1700,7 @@ esphome/components/mcp9808/sensor.py,sha256=71l_lBZ7F3dausUP94mdMUx-1QuGJJqi273u
1700
1700
  esphome/components/md5/__init__.py,sha256=UMOzKlaVJtzYULytE5P3aZOdVPKrdJAQb-NLxUQ4UUE,119
1701
1701
  esphome/components/md5/md5.cpp,sha256=4wfJNvWDF_kpq0_mOYpcjSvX3azczAzID3Ow82VFBWk,1711
1702
1702
  esphome/components/md5/md5.h,sha256=eTAX-Ijoj30lVdQQ30wdcYKVNeFvC_0AYOzXw3wGfAQ,1591
1703
- esphome/components/mdns/__init__.py,sha256=W8e7xs4Zl1eRRdvMthYrmHXPUCmbaqTg_vfB7QAG8xw,2909
1703
+ esphome/components/mdns/__init__.py,sha256=FZE-Ry4W8diC96M0af5xgPwN1G51TlctWL0vw5SfzYI,2909
1704
1704
  esphome/components/mdns/mdns_component.cpp,sha256=kSNKYHmAAhHTE0UERqH1ZxGbqaPeEWgQ2ox7u3yjdxo,3675
1705
1705
  esphome/components/mdns/mdns_component.h,sha256=C-95CGy4G0lI3PN97akmKtVnET5iiJze3vAMD1LkJSI,1239
1706
1706
  esphome/components/mdns/mdns_esp32.cpp,sha256=5KEGkIa4M8HyHUDH9CYabLtD_NTVlaDQzZk3Nha1aiI,1710
@@ -2690,7 +2690,7 @@ esphome/components/speaker/media_player/__init__.py,sha256=-bV3Fps2AGFUEW8C35py8
2690
2690
  esphome/components/speaker/media_player/audio_pipeline.cpp,sha256=CxWJFkt3IUb4o1w6ajh2rnINUqUSOK6RigEeFEGkMus,22365
2691
2691
  esphome/components/speaker/media_player/audio_pipeline.h,sha256=MYt7_kp4IJDSTnXWqLaXIkbbNkGx6F_imSryFo2UUkc,5000
2692
2692
  esphome/components/speaker/media_player/automation.h,sha256=I8psUHnJ8T3fkM05h1yEYDxb0yWe6Vjz7i30OSVA3Is,683
2693
- esphome/components/speaker/media_player/speaker_media_player.cpp,sha256=CGytXDR9vWYAcm8Gta-qAfZibGgAa2kLNr6p_419Cpk,21569
2693
+ esphome/components/speaker/media_player/speaker_media_player.cpp,sha256=4qbWSTcEBXKeqxqBF10K_M6C7ONjMev4OAdMyG-HrFo,23489
2694
2694
  esphome/components/speaker/media_player/speaker_media_player.h,sha256=wteJb_rXEK2LUTdehGsAMldDl0KLWpP8aySHsPYIIDc,5533
2695
2695
  esphome/components/speed/__init__.py,sha256=Bfyz1MHHvLHj93TfN53E2uhKXKLYtp0k4st6Xb3760o,74
2696
2696
  esphome/components/speed/fan/__init__.py,sha256=zhurjCYLG9V-soV-LF4mEGxqyrcQuQ_KLdFq0LpyAKA,1798
@@ -3474,9 +3474,9 @@ esphome/dashboard/util/itertools.py,sha256=8eLrWEWmICLtXNxkKdYPQV0c_N4GEz8m9Npnb
3474
3474
  esphome/dashboard/util/password.py,sha256=cQz3b9B-ijTe7zS6BeCW0hc3pWv6JjC78jmnycYYAh8,321
3475
3475
  esphome/dashboard/util/subprocess.py,sha256=T8EW6dbU4LPd2DG1dRrdh8li71tt6J1isn411poMhkk,1022
3476
3476
  esphome/dashboard/util/text.py,sha256=ENDnfN4O0NdA3CKVJjQYabFbwbrsIhVKrAMQe53qYu4,534
3477
- esphome-2025.3.2.dist-info/LICENSE,sha256=HzEjkBInJe44L4WvAOPfhPJJDNj6YbnqFyvGWRzArGM,36664
3478
- esphome-2025.3.2.dist-info/METADATA,sha256=v8Q7uCTovNLcVG6epNDDfKd7kGnQCibWu-8HZV0-w98,3689
3479
- esphome-2025.3.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
3480
- esphome-2025.3.2.dist-info/entry_points.txt,sha256=mIxVNuWtbYzeEcaWCl-AQ-97aBOWbnYBAK8nbF6P4M0,50
3481
- esphome-2025.3.2.dist-info/top_level.txt,sha256=0GSXEW3cnITpgG3qnsSMz0qoqJHAFyfw7Y8MVtEf1Yk,8
3482
- esphome-2025.3.2.dist-info/RECORD,,
3477
+ esphome-2025.3.3.dist-info/LICENSE,sha256=HzEjkBInJe44L4WvAOPfhPJJDNj6YbnqFyvGWRzArGM,36664
3478
+ esphome-2025.3.3.dist-info/METADATA,sha256=zMM-fhpwN7TvL0-7hSWi8VNSeYNlyq-xZUN1oYnFkTk,3689
3479
+ esphome-2025.3.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
3480
+ esphome-2025.3.3.dist-info/entry_points.txt,sha256=mIxVNuWtbYzeEcaWCl-AQ-97aBOWbnYBAK8nbF6P4M0,50
3481
+ esphome-2025.3.3.dist-info/top_level.txt,sha256=0GSXEW3cnITpgG3qnsSMz0qoqJHAFyfw7Y8MVtEf1Yk,8
3482
+ esphome-2025.3.3.dist-info/RECORD,,