esphome 2024.12.0b2__py3-none-any.whl → 2024.12.1__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.
@@ -27,6 +27,9 @@ namespace esp32_ble {
27
27
 
28
28
  static const char *const TAG = "esp32_ble";
29
29
 
30
+ static RAMAllocator<BLEEvent> EVENT_ALLOCATOR( // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
31
+ RAMAllocator<BLEEvent>::ALLOW_FAILURE | RAMAllocator<BLEEvent>::ALLOC_INTERNAL);
32
+
30
33
  void ESP32BLE::setup() {
31
34
  global_ble = this;
32
35
  ESP_LOGCONFIG(TAG, "Setting up BLE...");
@@ -322,7 +325,8 @@ void ESP32BLE::loop() {
322
325
  default:
323
326
  break;
324
327
  }
325
- delete ble_event; // NOLINT(cppcoreguidelines-owning-memory)
328
+ ble_event->~BLEEvent();
329
+ EVENT_ALLOCATOR.deallocate(ble_event, 1);
326
330
  ble_event = this->ble_events_.pop();
327
331
  }
328
332
  if (this->advertising_ != nullptr) {
@@ -331,9 +335,14 @@ void ESP32BLE::loop() {
331
335
  }
332
336
 
333
337
  void ESP32BLE::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
334
- BLEEvent *new_event = new BLEEvent(event, param); // NOLINT(cppcoreguidelines-owning-memory)
338
+ BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
339
+ if (new_event == nullptr) {
340
+ // Memory too fragmented to allocate new event. Can only drop it until memory comes back
341
+ return;
342
+ }
343
+ new (new_event) BLEEvent(event, param);
335
344
  global_ble->ble_events_.push(new_event);
336
- } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
345
+ } // NOLINT(clang-analyzer-unix.Malloc)
337
346
 
338
347
  void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
339
348
  ESP_LOGV(TAG, "(BLE) gap_event_handler - %d", event);
@@ -344,9 +353,14 @@ void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap
344
353
 
345
354
  void ESP32BLE::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
346
355
  esp_ble_gatts_cb_param_t *param) {
347
- BLEEvent *new_event = new BLEEvent(event, gatts_if, param); // NOLINT(cppcoreguidelines-owning-memory)
356
+ BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
357
+ if (new_event == nullptr) {
358
+ // Memory too fragmented to allocate new event. Can only drop it until memory comes back
359
+ return;
360
+ }
361
+ new (new_event) BLEEvent(event, gatts_if, param);
348
362
  global_ble->ble_events_.push(new_event);
349
- } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
363
+ } // NOLINT(clang-analyzer-unix.Malloc)
350
364
 
351
365
  void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
352
366
  esp_ble_gatts_cb_param_t *param) {
@@ -358,9 +372,14 @@ void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if
358
372
 
359
373
  void ESP32BLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
360
374
  esp_ble_gattc_cb_param_t *param) {
361
- BLEEvent *new_event = new BLEEvent(event, gattc_if, param); // NOLINT(cppcoreguidelines-owning-memory)
375
+ BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
376
+ if (new_event == nullptr) {
377
+ // Memory too fragmented to allocate new event. Can only drop it until memory comes back
378
+ return;
379
+ }
380
+ new (new_event) BLEEvent(event, gattc_if, param);
362
381
  global_ble->ble_events_.push(new_event);
363
- } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
382
+ } // NOLINT(clang-analyzer-unix.Malloc)
364
383
 
365
384
  void ESP32BLE::real_gattc_event_handler_(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
366
385
  esp_ble_gattc_cb_param_t *param) {
@@ -51,8 +51,11 @@ CONF_IGNORE_MISSING_GLYPHS = "ignore_missing_glyphs"
51
51
  # Cache loaded freetype fonts
52
52
  class FontCache(dict):
53
53
  def __missing__(self, key):
54
- res = self[key] = freetype.Face(key)
55
- return res
54
+ try:
55
+ res = self[key] = freetype.Face(key)
56
+ return res
57
+ except freetype.FT_Exception as e:
58
+ raise cv.Invalid(f"Could not load Font file {key}: {e}") from e
56
59
 
57
60
 
58
61
  FONT_CACHE = FontCache()
esphome/const.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Constants used by esphome."""
2
2
 
3
- __version__ = "2024.12.0b2"
3
+ __version__ = "2024.12.1"
4
4
 
5
5
  ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
6
6
  VALID_SUBSTITUTIONS_CHARACTERS = (
@@ -13,8 +13,8 @@ static const char *const TAG = "ring_buffer";
13
13
 
14
14
  RingBuffer::~RingBuffer() {
15
15
  if (this->handle_ != nullptr) {
16
- vStreamBufferDelete(this->handle_);
17
- ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
16
+ vRingbufferDelete(this->handle_);
17
+ RAMAllocator<uint8_t> allocator(RAMAllocator<uint8_t>::ALLOW_FAILURE);
18
18
  allocator.deallocate(this->storage_, this->size_);
19
19
  }
20
20
  }
@@ -22,26 +22,49 @@ RingBuffer::~RingBuffer() {
22
22
  std::unique_ptr<RingBuffer> RingBuffer::create(size_t len) {
23
23
  std::unique_ptr<RingBuffer> rb = make_unique<RingBuffer>();
24
24
 
25
- rb->size_ = len + 1;
25
+ rb->size_ = len;
26
26
 
27
- ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
27
+ RAMAllocator<uint8_t> allocator(RAMAllocator<uint8_t>::ALLOW_FAILURE);
28
28
  rb->storage_ = allocator.allocate(rb->size_);
29
29
  if (rb->storage_ == nullptr) {
30
30
  return nullptr;
31
31
  }
32
32
 
33
- rb->handle_ = xStreamBufferCreateStatic(rb->size_, 1, rb->storage_, &rb->structure_);
33
+ rb->handle_ = xRingbufferCreateStatic(rb->size_, RINGBUF_TYPE_BYTEBUF, rb->storage_, &rb->structure_);
34
34
  ESP_LOGD(TAG, "Created ring buffer with size %u", len);
35
+
35
36
  return rb;
36
37
  }
37
38
 
38
39
  size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) {
39
- if (ticks_to_wait > 0)
40
- xStreamBufferSetTriggerLevel(this->handle_, len);
40
+ size_t bytes_read = 0;
41
+
42
+ void *buffer_data = xRingbufferReceiveUpTo(this->handle_, &bytes_read, ticks_to_wait, len);
43
+
44
+ if (buffer_data == nullptr) {
45
+ return 0;
46
+ }
47
+
48
+ std::memcpy(data, buffer_data, bytes_read);
41
49
 
42
- size_t bytes_read = xStreamBufferReceive(this->handle_, data, len, ticks_to_wait);
50
+ vRingbufferReturnItem(this->handle_, buffer_data);
43
51
 
44
- xStreamBufferSetTriggerLevel(this->handle_, 1);
52
+ if (bytes_read < len) {
53
+ // Data may have wrapped around, so read a second time to receive the remainder
54
+ size_t follow_up_bytes_read = 0;
55
+ size_t bytes_remaining = len - bytes_read;
56
+
57
+ buffer_data = xRingbufferReceiveUpTo(this->handle_, &follow_up_bytes_read, 0, bytes_remaining);
58
+
59
+ if (buffer_data == nullptr) {
60
+ return bytes_read;
61
+ }
62
+
63
+ std::memcpy((void *) ((uint8_t *) (data) + bytes_read), buffer_data, follow_up_bytes_read);
64
+
65
+ vRingbufferReturnItem(this->handle_, buffer_data);
66
+ bytes_read += follow_up_bytes_read;
67
+ }
45
68
 
46
69
  return bytes_read;
47
70
  }
@@ -49,22 +72,55 @@ size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) {
49
72
  size_t RingBuffer::write(const void *data, size_t len) {
50
73
  size_t free = this->free();
51
74
  if (free < len) {
52
- size_t needed = len - free;
53
- uint8_t discard[needed];
54
- xStreamBufferReceive(this->handle_, discard, needed, 0);
75
+ // Free enough space in the ring buffer to fit the new data
76
+ this->discard_bytes_(len - free);
55
77
  }
56
- return xStreamBufferSend(this->handle_, data, len, 0);
78
+ return this->write_without_replacement(data, len, 0);
57
79
  }
58
80
 
59
81
  size_t RingBuffer::write_without_replacement(const void *data, size_t len, TickType_t ticks_to_wait) {
60
- return xStreamBufferSend(this->handle_, data, len, ticks_to_wait);
82
+ if (!xRingbufferSend(this->handle_, data, len, ticks_to_wait)) {
83
+ // Couldn't fit all the data, so only write what will fit
84
+ size_t free = std::min(this->free(), len);
85
+ if (xRingbufferSend(this->handle_, data, free, 0)) {
86
+ return free;
87
+ }
88
+ return 0;
89
+ }
90
+ return len;
91
+ }
92
+
93
+ size_t RingBuffer::available() const {
94
+ UBaseType_t ux_items_waiting = 0;
95
+ vRingbufferGetInfo(this->handle_, nullptr, nullptr, nullptr, nullptr, &ux_items_waiting);
96
+ return ux_items_waiting;
61
97
  }
62
98
 
63
- size_t RingBuffer::available() const { return xStreamBufferBytesAvailable(this->handle_); }
99
+ size_t RingBuffer::free() const { return xRingbufferGetCurFreeSize(this->handle_); }
100
+
101
+ BaseType_t RingBuffer::reset() {
102
+ // Discards all the available data
103
+ return this->discard_bytes_(this->available());
104
+ }
64
105
 
65
- size_t RingBuffer::free() const { return xStreamBufferSpacesAvailable(this->handle_); }
106
+ bool RingBuffer::discard_bytes_(size_t discard_bytes) {
107
+ size_t bytes_read = 0;
66
108
 
67
- BaseType_t RingBuffer::reset() { return xStreamBufferReset(this->handle_); }
109
+ void *buffer_data = xRingbufferReceiveUpTo(this->handle_, &bytes_read, 0, discard_bytes);
110
+ if (buffer_data != nullptr)
111
+ vRingbufferReturnItem(this->handle_, buffer_data);
112
+
113
+ if (bytes_read < discard_bytes) {
114
+ size_t wrapped_bytes_read = 0;
115
+ buffer_data = xRingbufferReceiveUpTo(this->handle_, &wrapped_bytes_read, 0, discard_bytes - bytes_read);
116
+ if (buffer_data != nullptr) {
117
+ vRingbufferReturnItem(this->handle_, buffer_data);
118
+ bytes_read += wrapped_bytes_read;
119
+ }
120
+ }
121
+
122
+ return (bytes_read == discard_bytes);
123
+ }
68
124
 
69
125
  } // namespace esphome
70
126
 
@@ -3,7 +3,7 @@
3
3
  #ifdef USE_ESP32
4
4
 
5
5
  #include <freertos/FreeRTOS.h>
6
- #include <freertos/stream_buffer.h>
6
+ #include <freertos/ringbuf.h>
7
7
 
8
8
  #include <cinttypes>
9
9
  #include <memory>
@@ -82,9 +82,14 @@ class RingBuffer {
82
82
  static std::unique_ptr<RingBuffer> create(size_t len);
83
83
 
84
84
  protected:
85
- StreamBufferHandle_t handle_;
86
- StaticStreamBuffer_t structure_;
87
- uint8_t *storage_;
85
+ /// @brief Discards data from the ring buffer.
86
+ /// @param discard_bytes amount of bytes to discard
87
+ /// @return True if all bytes were successfully discarded, false otherwise
88
+ bool discard_bytes_(size_t discard_bytes);
89
+
90
+ RingbufHandle_t handle_{nullptr};
91
+ StaticRingbuffer_t structure_;
92
+ uint8_t *storage_{nullptr};
88
93
  size_t size_{0};
89
94
  };
90
95
 
@@ -108,6 +108,12 @@ def is_authenticated(handler: BaseHandler) -> bool:
108
108
  return True
109
109
 
110
110
  if settings.using_auth:
111
+ if auth_header := handler.request.headers.get("Authorization"):
112
+ assert isinstance(auth_header, str)
113
+ if auth_header.startswith("Basic "):
114
+ auth_decoded = base64.b64decode(auth_header[6:]).decode()
115
+ username, password = auth_decoded.split(":", 1)
116
+ return settings.check_password(username, password)
111
117
  return handler.get_secure_cookie(AUTH_COOKIE_NAME) == COOKIE_AUTHENTICATED_YES
112
118
 
113
119
  return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: esphome
3
- Version: 2024.12.0b2
3
+ Version: 2024.12.1
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
@@ -36,7 +36,7 @@ Requires-Dist: pyserial ==3.5
36
36
  Requires-Dist: platformio ==6.1.16
37
37
  Requires-Dist: esptool ==4.7.0
38
38
  Requires-Dist: click ==8.1.7
39
- Requires-Dist: esphome-dashboard ==20241120.0
39
+ Requires-Dist: esphome-dashboard ==20241217.1
40
40
  Requires-Dist: aioesphomeapi ==24.6.2
41
41
  Requires-Dist: zeroconf ==0.132.2
42
42
  Requires-Dist: puremagic ==1.27
@@ -5,7 +5,7 @@ esphome/codegen.py,sha256=GePHUM7xdXb_Pil59SHVsXg2F4VBPgkH-Fz2PDX8Z54,1873
5
5
  esphome/config.py,sha256=nOiXPZv8wHtmytkNlGcewp0uuJd9G5rRjkqevYXtjzo,39618
6
6
  esphome/config_helpers.py,sha256=MKf_wzO35nn41FvigXE0iYKDslPgL2ruf8R-EPtTT2I,3256
7
7
  esphome/config_validation.py,sha256=jtqGmSF_0mAIMxRMV3eJj7dQ71Jmlc51NOx6AvWlnqs,66374
8
- esphome/const.py,sha256=loew3PJznRZnI-bAYl6g1mSRhs4Iljrxs0a0HHtWcuU,40646
8
+ esphome/const.py,sha256=sS1ZWXJZo5TVwhs2fLSA8udcqUVTvj5lo41VEoFOIjY,40644
9
9
  esphome/coroutine.py,sha256=j_14z8dIIzIBeuNO30D4c1RJvMMt1xZFZ58Evd-EvJA,9344
10
10
  esphome/cpp_generator.py,sha256=lXPXHYUsFIvBSAoZ93mXYlGcXYg5L18nTtYGHE4_rr8,31203
11
11
  esphome/cpp_helpers.py,sha256=6C2vNbOIhZKi43xRVlk5hp9GfshfBn-rc5D_ZFUEYaE,4801
@@ -789,7 +789,7 @@ esphome/components/esp32/post_build.py.script,sha256=ZBsPNunx2BH4ZiRyXnjTP7D7eN2
789
789
  esphome/components/esp32/preferences.cpp,sha256=6mrR6ziH2dnBcMKPD5RwYYB16tkAy0w75x_mRy4wQCY,6294
790
790
  esphome/components/esp32/preferences.h,sha256=9HIy-BOgjOXJiEgOizZ_Qb8-l6K4eb3VSPW8Y8ffuWM,165
791
791
  esphome/components/esp32_ble/__init__.py,sha256=_icbuq6fiRVExFZe1ETU2GJ6ziR4LxMK3nzeER7gEuY,4321
792
- esphome/components/esp32_ble/ble.cpp,sha256=OtuXz0Qv-YQa-Ghubtvpvon9FzsU3n-P401oFcTB1l8,13082
792
+ esphome/components/esp32_ble/ble.cpp,sha256=w51oEvWeMcYs2CgIlCLTFEMaxxzxW0hAstWhwHl_oQM,13661
793
793
  esphome/components/esp32_ble/ble.h,sha256=1USMpwRwVHc6_CnxieJa55mMPq3GFfkEPPYarySc05Y,5234
794
794
  esphome/components/esp32_ble/ble_advertising.cpp,sha256=DUdZyaNCc4xxyPmB4OM8dtgSxcHkIdju1-j-CJGMtyg,6022
795
795
  esphome/components/esp32_ble/ble_advertising.h,sha256=dLksw168KS1wh3_X7GhesS9nacINphlZUl4nMgYSA8M,1480
@@ -932,7 +932,7 @@ esphome/components/fingerprint_grow/binary_sensor.py,sha256=NeVcqVCpmjGdnfimIIWS
932
932
  esphome/components/fingerprint_grow/fingerprint_grow.cpp,sha256=xtHEpnp1Ei_5s5SS5Vfxt8vG_PoPMmeUjbOQHWrn5G0,18675
933
933
  esphome/components/fingerprint_grow/fingerprint_grow.h,sha256=UEkLR4Cqas_XYlTLAwscXCAMRoprWeQZEZ_3vTsI-BM,11206
934
934
  esphome/components/fingerprint_grow/sensor.py,sha256=eazvZvdtt1Rl8o3Aw6eYKn-kb2sNDfZKHegxpFFdQeg,2244
935
- esphome/components/font/__init__.py,sha256=eixW4XJNfpxcV-_dDGDsC8Z7VgB42u4StDgCSbMxoes,19087
935
+ esphome/components/font/__init__.py,sha256=UffNdpZ8qzYXqi3Z1KN5m2Vf_9q_Q5bjgB-JN_H-MYw,19227
936
936
  esphome/components/font/font.cpp,sha256=xORioLApiap2sPwx4d5uMTQNx5-OUIYSB8pt0uHx0IU,5413
937
937
  esphome/components/font/font.h,sha256=jTeGf7Osax98Tbs9TeZ01Ta3P2FZt-wWar1bybMFc20,2009
938
938
  esphome/components/fs3000/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -3355,8 +3355,8 @@ esphome/core/log.h,sha256=sMwmrs64vOG0G9jIibKJWv_C-COl175T8JymmBVRHWI,6369
3355
3355
  esphome/core/macros.h,sha256=YRip3XYzXw2pg3AFpBFA0Js-Y5GMtPkuCp2km2g5uhc,196
3356
3356
  esphome/core/optional.h,sha256=Di5V9YFV4vvMgVoORXe7Ojd3kLlBF7wTE4KeQGAaLSk,6968
3357
3357
  esphome/core/preferences.h,sha256=RxgWuAi-uo6SZiK8UKX4KTwVfIMnaaLvrZP2rqTn_mE,1959
3358
- esphome/core/ring_buffer.cpp,sha256=HdlCZCNquSJP4Awc9nJZdaLHGj1j2Oj6IYfSBqf5uAg,2036
3359
- esphome/core/ring_buffer.h,sha256=vK_TXVLeXV8ociUyrKqIr7hSqRAQI8W6u1xKLFUruDI,2766
3358
+ esphome/core/ring_buffer.cpp,sha256=8lEn4WbgEU9Mbc1KrR2RLzjbcAA6xsyL9IjZ82-QmB8,3602
3359
+ esphome/core/ring_buffer.h,sha256=4SeN2DYZLCHrLIjSPDsiAynIjwOoItiRUDO-u1wjq-o,2997
3360
3360
  esphome/core/scheduler.cpp,sha256=fH2E-e0jQ0nd90lojK5voee1lBY7rYzLWWjWZj6rbHA,12072
3361
3361
  esphome/core/scheduler.h,sha256=OZaBsLlo2R2nJvYcq7LyUGPXLzLAJdMEmtBewWF_9Ps,2455
3362
3362
  esphome/core/string_ref.cpp,sha256=of1TYMY6t3t4HjjPLSiItuPSa62AMG0lK_CU2HS1RvM,242
@@ -3374,7 +3374,7 @@ esphome/dashboard/dns.py,sha256=zJjzjjuJsnHXW59V-H1QqjwwqJFgtJUIsB2QUcALZns,1369
3374
3374
  esphome/dashboard/entries.py,sha256=jbmvXQ5-zeUBVrd80tupYmStRsTwGp0hbfG7ZIRQF94,13130
3375
3375
  esphome/dashboard/enum.py,sha256=rlQFVVxyBt5Iw7OL0o9F8D5LGgw23tbvi-KYjzP0QUQ,597
3376
3376
  esphome/dashboard/settings.py,sha256=xoN2eLh-t0hmVYLmZm9beVOqonPNqWkzpRsoPbEomoA,2962
3377
- esphome/dashboard/web_server.py,sha256=SnAB_8ndfY91SPmY1cwCYkKxtWF9ppDgbD7soSzs3YQ,41837
3377
+ esphome/dashboard/web_server.py,sha256=cSWc_M4ieUg_O0DpQYBM-bDDkhkSF4wFvDRAUVtf08s,42211
3378
3378
  esphome/dashboard/status/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3379
3379
  esphome/dashboard/status/mdns.py,sha256=FuASYxcQ-LQVK5vqX9ZLs9wIXlmXZh4tjXhg-Zmpq14,3741
3380
3380
  esphome/dashboard/status/mqtt.py,sha256=ZRb18LOvl4975Pzc4Fdr5ErML3WKwV8Pv1sD2qdSJ1s,1965
@@ -3385,9 +3385,9 @@ esphome/dashboard/util/itertools.py,sha256=8eLrWEWmICLtXNxkKdYPQV0c_N4GEz8m9Npnb
3385
3385
  esphome/dashboard/util/password.py,sha256=cQz3b9B-ijTe7zS6BeCW0hc3pWv6JjC78jmnycYYAh8,321
3386
3386
  esphome/dashboard/util/subprocess.py,sha256=T8EW6dbU4LPd2DG1dRrdh8li71tt6J1isn411poMhkk,1022
3387
3387
  esphome/dashboard/util/text.py,sha256=ENDnfN4O0NdA3CKVJjQYabFbwbrsIhVKrAMQe53qYu4,534
3388
- esphome-2024.12.0b2.dist-info/LICENSE,sha256=HzEjkBInJe44L4WvAOPfhPJJDNj6YbnqFyvGWRzArGM,36664
3389
- esphome-2024.12.0b2.dist-info/METADATA,sha256=ua2PrbGevoon-zserr93K2ZRBS1wj39PDAx0sA98iTo,3551
3390
- esphome-2024.12.0b2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
3391
- esphome-2024.12.0b2.dist-info/entry_points.txt,sha256=mIxVNuWtbYzeEcaWCl-AQ-97aBOWbnYBAK8nbF6P4M0,50
3392
- esphome-2024.12.0b2.dist-info/top_level.txt,sha256=0GSXEW3cnITpgG3qnsSMz0qoqJHAFyfw7Y8MVtEf1Yk,8
3393
- esphome-2024.12.0b2.dist-info/RECORD,,
3388
+ esphome-2024.12.1.dist-info/LICENSE,sha256=HzEjkBInJe44L4WvAOPfhPJJDNj6YbnqFyvGWRzArGM,36664
3389
+ esphome-2024.12.1.dist-info/METADATA,sha256=TcKwI2U3CTXq2e0CwlwlGsSESRTq91beQftFo9ZHhqc,3549
3390
+ esphome-2024.12.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
3391
+ esphome-2024.12.1.dist-info/entry_points.txt,sha256=mIxVNuWtbYzeEcaWCl-AQ-97aBOWbnYBAK8nbF6P4M0,50
3392
+ esphome-2024.12.1.dist-info/top_level.txt,sha256=0GSXEW3cnITpgG3qnsSMz0qoqJHAFyfw7Y8MVtEf1Yk,8
3393
+ esphome-2024.12.1.dist-info/RECORD,,