esphome 2024.11.2__py3-none-any.whl → 2024.12.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. esphome/__main__.py +1 -1
  2. esphome/components/adc/adc_sensor.h +7 -8
  3. esphome/components/adc/adc_sensor_common.cpp +24 -0
  4. esphome/components/adc/{adc_sensor.cpp → adc_sensor_esp32.cpp} +10 -179
  5. esphome/components/adc/adc_sensor_esp8266.cpp +58 -0
  6. esphome/components/adc/adc_sensor_libretiny.cpp +48 -0
  7. esphome/components/adc/adc_sensor_rp2040.cpp +93 -0
  8. esphome/components/alarm_control_panel/alarm_control_panel_call.cpp +3 -4
  9. esphome/components/animation/__init__.py +1 -2
  10. esphome/components/apds9306/apds9306.cpp +2 -1
  11. esphome/components/audio/audio.h +1 -1
  12. esphome/components/bk72xx/__init__.py +1 -1
  13. esphome/components/cse7766/cse7766.cpp +1 -1
  14. esphome/components/datetime/datetime_entity.cpp +1 -3
  15. esphome/components/deep_sleep/deep_sleep_esp32.cpp +2 -2
  16. esphome/components/dht/dht.cpp +2 -1
  17. esphome/components/display/display.cpp +10 -6
  18. esphome/components/display/display.h +14 -0
  19. esphome/components/display_menu_base/__init__.py +0 -2
  20. esphome/components/display_menu_base/display_menu_base.cpp +1 -1
  21. esphome/components/dsmr/dsmr.cpp +1 -1
  22. esphome/components/esp32/__init__.py +100 -22
  23. esphome/components/esp32/boards.py +222 -14
  24. esphome/components/esp32_ble/__init__.py +22 -2
  25. esphome/components/esp32_ble/ble.cpp +39 -12
  26. esphome/components/esp32_ble/ble.h +2 -0
  27. esphome/components/esp32_ble/ble_advertising.cpp +1 -1
  28. esphome/components/esp32_ble/ble_uuid.cpp +9 -10
  29. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +4 -1
  30. esphome/components/esp32_camera_web_server/camera_web_server.h +1 -1
  31. esphome/components/esp32_rmt_led_strip/light.py +3 -3
  32. esphome/components/esp8266/__init__.py +5 -7
  33. esphome/components/ezo/ezo.cpp +14 -26
  34. esphome/components/font/__init__.py +10 -25
  35. esphome/components/font/font.cpp +5 -3
  36. esphome/components/graphical_display_menu/__init__.py +2 -0
  37. esphome/components/haier/hon_climate.cpp +79 -80
  38. esphome/components/hbridge/switch/__init__.py +44 -0
  39. esphome/components/hbridge/switch/hbridge_switch.cpp +95 -0
  40. esphome/components/hbridge/switch/hbridge_switch.h +50 -0
  41. esphome/components/hitachi_ac344/hitachi_ac344.cpp +4 -2
  42. esphome/components/hitachi_ac424/hitachi_ac424.cpp +4 -2
  43. esphome/components/homeassistant/number/homeassistant_number.cpp +3 -0
  44. esphome/components/hx711/hx711.cpp +1 -1
  45. esphome/components/hx711/hx711.h +1 -1
  46. esphome/components/i2c/i2c_bus_esp_idf.cpp +2 -2
  47. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +61 -59
  48. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -17
  49. esphome/components/ili9xxx/display.py +1 -2
  50. esphome/components/ili9xxx/ili9xxx_display.cpp +3 -2
  51. esphome/components/image/__init__.py +1 -2
  52. esphome/components/logger/logger.cpp +1 -1
  53. esphome/components/ltr501/ltr501.cpp +1 -1
  54. esphome/components/lvgl/defines.py +9 -2
  55. esphome/components/lvgl/lv_validation.py +8 -3
  56. esphome/components/lvgl/lvgl_esphome.cpp +1 -1
  57. esphome/components/lvgl/lvgl_esphome.h +19 -0
  58. esphome/components/lvgl/widgets/animimg.py +12 -17
  59. esphome/components/lvgl/widgets/img.py +1 -3
  60. esphome/components/lvgl/widgets/line.py +6 -0
  61. esphome/components/lvgl/widgets/msgbox.py +2 -1
  62. esphome/components/matrix_keypad/__init__.py +15 -3
  63. esphome/components/matrix_keypad/matrix_keypad.cpp +4 -0
  64. esphome/components/matrix_keypad/matrix_keypad.h +5 -0
  65. esphome/components/max31865/max31865.cpp +4 -2
  66. esphome/components/modbus_controller/modbus_controller.cpp +24 -24
  67. esphome/components/modbus_controller/modbus_controller.h +22 -22
  68. esphome/components/modbus_controller/number/modbus_number.cpp +8 -8
  69. esphome/components/modbus_controller/number/modbus_number.h +4 -4
  70. esphome/components/modbus_controller/output/modbus_output.cpp +7 -6
  71. esphome/components/modbus_controller/output/modbus_output.h +5 -5
  72. esphome/components/modbus_controller/select/modbus_select.cpp +4 -3
  73. esphome/components/modbus_controller/select/modbus_select.h +4 -4
  74. esphome/components/modbus_controller/switch/modbus_switch.cpp +5 -5
  75. esphome/components/modbus_controller/switch/modbus_switch.h +2 -2
  76. esphome/components/mqtt/__init__.py +4 -0
  77. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +2 -5
  78. esphome/components/mqtt/mqtt_backend_esp32.cpp +3 -3
  79. esphome/components/mqtt/mqtt_client.cpp +4 -0
  80. esphome/components/mqtt/mqtt_client.h +6 -0
  81. esphome/components/mqtt/mqtt_climate.cpp +13 -3
  82. esphome/components/mqtt/mqtt_sensor.cpp +2 -0
  83. esphome/components/network/ip_address.h +1 -1
  84. esphome/components/nextion/__init__.py +2 -0
  85. esphome/components/nextion/automation.h +76 -0
  86. esphome/components/nextion/base_component.py +1 -0
  87. esphome/components/nextion/binary_sensor/__init__.py +43 -2
  88. esphome/components/nextion/display.py +15 -0
  89. esphome/components/nextion/nextion.cpp +8 -5
  90. esphome/components/nextion/nextion.h +7 -0
  91. esphome/components/nextion/nextion_upload_idf.cpp +2 -2
  92. esphome/components/nextion/sensor/__init__.py +38 -5
  93. esphome/components/nextion/switch/__init__.py +38 -2
  94. esphome/components/nextion/text_sensor/__init__.py +37 -2
  95. esphome/components/nfc/ndef_record.cpp +3 -3
  96. esphome/components/online_image/__init__.py +1 -0
  97. esphome/components/online_image/png_image.cpp +4 -0
  98. esphome/components/opentherm/hub.cpp +6 -7
  99. esphome/components/opentherm/opentherm.cpp +18 -34
  100. esphome/components/opentherm/opentherm.h +4 -5
  101. esphome/components/ota/automation.h +1 -1
  102. esphome/components/output/float_output.cpp +1 -1
  103. esphome/components/pca6416a/pca6416a.cpp +5 -3
  104. esphome/components/pca9554/pca9554.cpp +4 -4
  105. esphome/components/pipsolar/pipsolar.cpp +2 -2
  106. esphome/components/pipsolar/switch/pipsolar_switch.cpp +2 -2
  107. esphome/components/pn532/pn532_mifare_ultralight.cpp +2 -2
  108. esphome/components/pn7150/pn7150_mifare_ultralight.cpp +2 -2
  109. esphome/components/pn7160/pn7160_mifare_ultralight.cpp +2 -2
  110. esphome/components/qmc5883l/qmc5883l.cpp +45 -19
  111. esphome/components/qmc5883l/qmc5883l.h +1 -1
  112. esphome/components/qspi_dbi/qspi_dbi.cpp +2 -1
  113. esphome/components/remote_base/raw_protocol.cpp +1 -1
  114. esphome/components/remote_receiver/__init__.py +5 -6
  115. esphome/components/rotary_encoder/rotary_encoder.cpp +3 -1
  116. esphome/components/rp2040/__init__.py +1 -1
  117. esphome/components/rtl87xx/__init__.py +1 -1
  118. esphome/components/safe_mode/automation.h +1 -1
  119. esphome/components/seeed_mr60bha2/__init__.py +41 -0
  120. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +173 -0
  121. esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +61 -0
  122. esphome/components/seeed_mr60bha2/sensor.py +57 -0
  123. esphome/components/seeed_mr60fda2/__init__.py +41 -0
  124. esphome/components/seeed_mr60fda2/binary_sensor.py +33 -0
  125. esphome/components/seeed_mr60fda2/button/__init__.py +45 -0
  126. esphome/components/seeed_mr60fda2/button/get_radar_parameters_button.cpp +9 -0
  127. esphome/components/seeed_mr60fda2/button/get_radar_parameters_button.h +18 -0
  128. esphome/components/seeed_mr60fda2/button/reset_radar_button.cpp +9 -0
  129. esphome/components/seeed_mr60fda2/button/reset_radar_button.h +18 -0
  130. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +368 -0
  131. esphome/components/seeed_mr60fda2/seeed_mr60fda2.h +101 -0
  132. esphome/components/seeed_mr60fda2/select/__init__.py +59 -0
  133. esphome/components/seeed_mr60fda2/select/height_threshold_select.cpp +15 -0
  134. esphome/components/seeed_mr60fda2/select/height_threshold_select.h +18 -0
  135. esphome/components/seeed_mr60fda2/select/install_height_select.cpp +15 -0
  136. esphome/components/seeed_mr60fda2/select/install_height_select.h +18 -0
  137. esphome/components/seeed_mr60fda2/select/sensitivity_select.cpp +15 -0
  138. esphome/components/seeed_mr60fda2/select/sensitivity_select.h +18 -0
  139. esphome/components/sen5x/sensor.py +5 -6
  140. esphome/components/sgp30/sensor.py +8 -9
  141. esphome/components/sgp30/sgp30.cpp +2 -6
  142. esphome/components/shelly_dimmer/shelly_dimmer.cpp +1 -1
  143. esphome/components/sim800l/sim800l.cpp +1 -1
  144. esphome/components/sntp/sntp_component.cpp +14 -20
  145. esphome/components/sntp/sntp_component.h +6 -9
  146. esphome/components/sntp/time.py +4 -7
  147. esphome/components/sprinkler/sprinkler.cpp +2 -2
  148. esphome/components/st7735/st7735.cpp +1 -1
  149. esphome/components/st7789v/st7789v.cpp +1 -1
  150. esphome/components/st7920/st7920.cpp +2 -3
  151. esphome/components/stepper/stepper.h +0 -1
  152. esphome/components/sun_gtil2/sun_gtil2.cpp +1 -1
  153. esphome/components/switch/binary_sensor/__init__.py +31 -0
  154. esphome/components/switch/binary_sensor/switch_binary_sensor.cpp +17 -0
  155. esphome/components/switch/binary_sensor/switch_binary_sensor.h +22 -0
  156. esphome/components/sx1509/sx1509_gpio_pin.cpp +2 -1
  157. esphome/components/sx1509/sx1509_gpio_pin.h +5 -5
  158. esphome/components/uart/uart.h +1 -1
  159. esphome/components/udp/udp_component.cpp +32 -16
  160. esphome/components/ufire_ec/sensor.py +4 -4
  161. esphome/components/uln2003/uln2003.cpp +4 -1
  162. esphome/components/waveshare_epaper/display.py +8 -0
  163. esphome/components/waveshare_epaper/waveshare_epaper.cpp +191 -0
  164. esphome/components/waveshare_epaper/waveshare_epaper.h +56 -0
  165. esphome/components/wiegand/__init__.py +3 -4
  166. esphome/components/wifi/__init__.py +42 -0
  167. esphome/components/wifi/wifi_component.cpp +2 -2
  168. esphome/components/wifi/wifi_component.h +82 -1
  169. esphome/components/wifi/wifi_component_esp32_arduino.cpp +1 -1
  170. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  171. esphome/components/wifi/wifi_component_esp_idf.cpp +1 -1
  172. esphome/components/wifi/wifi_component_libretiny.cpp +1 -1
  173. esphome/components/wifi/wifi_component_pico_w.cpp +1 -1
  174. esphome/components/wireguard/wireguard.cpp +2 -2
  175. esphome/components/xiaomi_ble/xiaomi_ble.cpp +1 -1
  176. esphome/config_validation.py +15 -11
  177. esphome/const.py +11 -1
  178. esphome/core/component.cpp +1 -1
  179. esphome/core/config.py +1 -2
  180. esphome/core/defines.h +3 -1
  181. esphome/core/helpers.cpp +20 -2
  182. esphome/core/helpers.h +10 -1
  183. esphome/core/optional.h +2 -2
  184. esphome/core/time.cpp +19 -15
  185. esphome/core/time.h +1 -3
  186. esphome/dashboard/web_server.py +6 -0
  187. {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/METADATA +4 -4
  188. {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/RECORD +192 -162
  189. {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/LICENSE +0 -0
  190. {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/WHEEL +0 -0
  191. {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/entry_points.txt +0 -0
  192. {esphome-2024.11.2.dist-info → esphome-2024.12.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  #include "display.h"
2
- #include "display_color_utils.h"
3
2
  #include <utility>
3
+ #include "display_color_utils.h"
4
4
  #include "esphome/core/hal.h"
5
5
  #include "esphome/core/log.h"
6
6
 
@@ -662,20 +662,24 @@ void DisplayOnPageChangeTrigger::process(DisplayPage *from, DisplayPage *to) {
662
662
  if ((this->from_ == nullptr || this->from_ == from) && (this->to_ == nullptr || this->to_ == to))
663
663
  this->trigger(from, to);
664
664
  }
665
- void Display::strftime(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ESPTime time) {
665
+ void Display::strftime(int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format,
666
+ ESPTime time) {
666
667
  char buffer[64];
667
668
  size_t ret = time.strftime(buffer, sizeof(buffer), format);
668
669
  if (ret > 0)
669
- this->print(x, y, font, color, align, buffer);
670
+ this->print(x, y, font, color, align, buffer, background);
671
+ }
672
+ void Display::strftime(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ESPTime time) {
673
+ this->strftime(x, y, font, color, COLOR_OFF, align, format, time);
670
674
  }
671
675
  void Display::strftime(int x, int y, BaseFont *font, Color color, const char *format, ESPTime time) {
672
- this->strftime(x, y, font, color, TextAlign::TOP_LEFT, format, time);
676
+ this->strftime(x, y, font, color, COLOR_OFF, TextAlign::TOP_LEFT, format, time);
673
677
  }
674
678
  void Display::strftime(int x, int y, BaseFont *font, TextAlign align, const char *format, ESPTime time) {
675
- this->strftime(x, y, font, COLOR_ON, align, format, time);
679
+ this->strftime(x, y, font, COLOR_ON, COLOR_OFF, align, format, time);
676
680
  }
677
681
  void Display::strftime(int x, int y, BaseFont *font, const char *format, ESPTime time) {
678
- this->strftime(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, format, time);
682
+ this->strftime(x, y, font, COLOR_ON, COLOR_OFF, TextAlign::TOP_LEFT, format, time);
679
683
  }
680
684
 
681
685
  void Display::start_clipping(Rect rect) {
@@ -437,6 +437,20 @@ class Display : public PollingComponent {
437
437
  */
438
438
  void printf(int x, int y, BaseFont *font, const char *format, ...) __attribute__((format(printf, 5, 6)));
439
439
 
440
+ /** Evaluate the strftime-format `format` and print the result with the anchor point at [x,y] with `font`.
441
+ *
442
+ * @param x The x coordinate of the text alignment anchor point.
443
+ * @param y The y coordinate of the text alignment anchor point.
444
+ * @param font The font to draw the text with.
445
+ * @param color The color to draw the text with.
446
+ * @param background The background color to draw the text with.
447
+ * @param align The alignment of the text.
448
+ * @param format The format to use.
449
+ * @param ... The arguments to use for the text formatting.
450
+ */
451
+ void strftime(int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format,
452
+ ESPTime time) __attribute__((format(strftime, 8, 0)));
453
+
440
454
  /** Evaluate the strftime-format `format` and print the result with the anchor point at [x,y] with `font`.
441
455
  *
442
456
  * @param x The x coordinate of the text alignment anchor point.
@@ -68,8 +68,6 @@ IsActiveCondition = display_menu_base_ns.class_(
68
68
  "IsActiveCondition", automation.Condition
69
69
  )
70
70
 
71
- MULTI_CONF = True
72
-
73
71
  MenuItemType = display_menu_base_ns.enum("MenuItemType")
74
72
 
75
73
  MENU_ITEM_TYPES = {
@@ -280,7 +280,7 @@ bool DisplayMenuComponent::cursor_down_() {
280
280
  bool DisplayMenuComponent::enter_menu_() {
281
281
  this->displayed_item_->on_leave();
282
282
  this->displayed_item_ = static_cast<MenuItemMenu *>(this->get_selected_item_());
283
- this->selection_stack_.push_front({this->top_index_, this->cursor_index_});
283
+ this->selection_stack_.emplace_front(this->top_index_, this->cursor_index_);
284
284
  this->cursor_index_ = this->top_index_ = 0;
285
285
  this->displayed_item_->on_enter();
286
286
 
@@ -296,7 +296,7 @@ void Dsmr::dump_config() {
296
296
  }
297
297
 
298
298
  void Dsmr::set_decryption_key(const std::string &decryption_key) {
299
- if (decryption_key.length() == 0) {
299
+ if (decryption_key.empty()) {
300
300
  ESP_LOGI(TAG, "Disabling decryption");
301
301
  this->decryption_key_.clear();
302
302
  if (this->crypt_telegram_ != nullptr) {
@@ -65,6 +65,8 @@ _LOGGER = logging.getLogger(__name__)
65
65
  CODEOWNERS = ["@esphome/core"]
66
66
  AUTO_LOAD = ["preferences"]
67
67
 
68
+ CONF_RELEASE = "release"
69
+
68
70
 
69
71
  def set_core_data(config):
70
72
  CORE.data[KEY_ESP32] = {}
@@ -216,11 +218,17 @@ def _format_framework_arduino_version(ver: cv.Version) -> str:
216
218
  return f"~3.{ver.major}{ver.minor:02d}{ver.patch:02d}.0"
217
219
 
218
220
 
219
- def _format_framework_espidf_version(ver: cv.Version) -> str:
221
+ def _format_framework_espidf_version(
222
+ ver: cv.Version, release: str, for_platformio: bool
223
+ ) -> str:
220
224
  # format the given arduino (https://github.com/espressif/esp-idf/releases) version to
221
225
  # a PIO platformio/framework-espidf value
222
226
  # List of package versions: https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
223
- return f"~3.{ver.major}{ver.minor:02d}{ver.patch:02d}.0"
227
+ if for_platformio:
228
+ return f"platformio/framework-espidf@~3.{ver.major}{ver.minor:02d}{ver.patch:02d}.0"
229
+ if release:
230
+ return f"pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v{str(ver)}.{release}/esp-idf-v{str(ver)}.zip"
231
+ return f"pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v{str(ver)}/esp-idf-v{str(ver)}.zip"
224
232
 
225
233
 
226
234
  # NOTE: Keep this in mind when updating the recommended version:
@@ -241,11 +249,33 @@ ARDUINO_PLATFORM_VERSION = cv.Version(5, 4, 0)
241
249
  # The default/recommended esp-idf framework version
242
250
  # - https://github.com/espressif/esp-idf/releases
243
251
  # - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
244
- RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(4, 4, 8)
252
+ RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(5, 1, 5)
245
253
  # The platformio/espressif32 version to use for esp-idf frameworks
246
254
  # - https://github.com/platformio/platform-espressif32/releases
247
255
  # - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
248
- ESP_IDF_PLATFORM_VERSION = cv.Version(5, 4, 0)
256
+ ESP_IDF_PLATFORM_VERSION = cv.Version(51, 3, 7)
257
+
258
+ # List based on https://registry.platformio.org/tools/platformio/framework-espidf/versions
259
+ SUPPORTED_PLATFORMIO_ESP_IDF_5X = [
260
+ cv.Version(5, 3, 1),
261
+ cv.Version(5, 3, 0),
262
+ cv.Version(5, 2, 2),
263
+ cv.Version(5, 2, 1),
264
+ cv.Version(5, 1, 2),
265
+ cv.Version(5, 1, 1),
266
+ cv.Version(5, 1, 0),
267
+ cv.Version(5, 0, 2),
268
+ cv.Version(5, 0, 1),
269
+ cv.Version(5, 0, 0),
270
+ ]
271
+
272
+ # pioarduino versions that don't require a release number
273
+ # List based on https://github.com/pioarduino/esp-idf/releases
274
+ SUPPORTED_PIOARDUINO_ESP_IDF_5X = [
275
+ cv.Version(5, 3, 1),
276
+ cv.Version(5, 3, 0),
277
+ cv.Version(5, 1, 5),
278
+ ]
249
279
 
250
280
 
251
281
  def _arduino_check_versions(value):
@@ -286,8 +316,8 @@ def _arduino_check_versions(value):
286
316
  def _esp_idf_check_versions(value):
287
317
  value = value.copy()
288
318
  lookups = {
289
- "dev": (cv.Version(5, 1, 2), "https://github.com/espressif/esp-idf.git"),
290
- "latest": (cv.Version(5, 1, 2), None),
319
+ "dev": (cv.Version(5, 1, 5), "https://github.com/espressif/esp-idf.git"),
320
+ "latest": (cv.Version(5, 1, 5), None),
291
321
  "recommended": (RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION, None),
292
322
  }
293
323
 
@@ -305,13 +335,51 @@ def _esp_idf_check_versions(value):
305
335
  if version < cv.Version(4, 0, 0):
306
336
  raise cv.Invalid("Only ESP-IDF 4.0+ is supported.")
307
337
 
308
- value[CONF_VERSION] = str(version)
309
- value[CONF_SOURCE] = source or _format_framework_espidf_version(version)
338
+ # flag this for later *before* we set value[CONF_PLATFORM_VERSION] below
339
+ has_platform_ver = CONF_PLATFORM_VERSION in value
310
340
 
311
341
  value[CONF_PLATFORM_VERSION] = value.get(
312
342
  CONF_PLATFORM_VERSION, _parse_platform_version(str(ESP_IDF_PLATFORM_VERSION))
313
343
  )
314
344
 
345
+ if (
346
+ (is_platformio := _platform_is_platformio(value[CONF_PLATFORM_VERSION]))
347
+ and version.major >= 5
348
+ and version not in SUPPORTED_PLATFORMIO_ESP_IDF_5X
349
+ ):
350
+ raise cv.Invalid(
351
+ f"ESP-IDF {str(version)} not supported by platformio/espressif32"
352
+ )
353
+
354
+ if (
355
+ version.major < 5
356
+ or (
357
+ version in SUPPORTED_PLATFORMIO_ESP_IDF_5X
358
+ and version not in SUPPORTED_PIOARDUINO_ESP_IDF_5X
359
+ )
360
+ ) and not has_platform_ver:
361
+ raise cv.Invalid(
362
+ f"ESP-IDF {value[CONF_VERSION]} may be supported by platformio/espressif32; please specify '{CONF_PLATFORM_VERSION}'"
363
+ )
364
+
365
+ if (
366
+ not is_platformio
367
+ and CONF_RELEASE not in value
368
+ and version not in SUPPORTED_PIOARDUINO_ESP_IDF_5X
369
+ ):
370
+ raise cv.Invalid(
371
+ f"ESP-IDF {value[CONF_VERSION]} is not available with pioarduino; you may need to specify '{CONF_RELEASE}'"
372
+ )
373
+
374
+ value[CONF_VERSION] = str(version)
375
+ value[CONF_SOURCE] = source or _format_framework_espidf_version(
376
+ version, value.get(CONF_RELEASE, None), is_platformio
377
+ )
378
+
379
+ if value[CONF_SOURCE].startswith("http"):
380
+ # prefix is necessary or platformio will complain with a cryptic error
381
+ value[CONF_SOURCE] = f"framework-espidf@{value[CONF_SOURCE]}"
382
+
315
383
  if version != RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION:
316
384
  _LOGGER.warning(
317
385
  "The selected ESP-IDF framework version is not the recommended one. "
@@ -323,6 +391,12 @@ def _esp_idf_check_versions(value):
323
391
 
324
392
  def _parse_platform_version(value):
325
393
  try:
394
+ ver = cv.Version.parse(cv.version_number(value))
395
+ if ver.major >= 50: # a pioarduino version
396
+ if "-" in value:
397
+ # maybe a release candidate?...definitely not our default, just use it as-is...
398
+ return f"https://github.com/pioarduino/platform-espressif32.git#{value}"
399
+ return f"https://github.com/pioarduino/platform-espressif32.git#{ver.major}.{ver.minor:02d}.{ver.patch:02d}"
326
400
  # if platform version is a valid version constraint, prefix the default package
327
401
  cv.platformio_version_constraint(value)
328
402
  return f"platformio/espressif32@{value}"
@@ -330,6 +404,14 @@ def _parse_platform_version(value):
330
404
  return value
331
405
 
332
406
 
407
+ def _platform_is_platformio(value):
408
+ try:
409
+ ver = cv.Version.parse(cv.version_number(value))
410
+ return ver.major < 50
411
+ except cv.Invalid:
412
+ return "platformio" in value
413
+
414
+
333
415
  def _detect_variant(value):
334
416
  board = value[CONF_BOARD]
335
417
  if board in BOARDS:
@@ -355,24 +437,20 @@ def _detect_variant(value):
355
437
 
356
438
 
357
439
  def final_validate(config):
358
- if CONF_PLATFORMIO_OPTIONS not in fv.full_config.get()[CONF_ESPHOME]:
440
+ if not (
441
+ pio_options := fv.full_config.get()[CONF_ESPHOME].get(CONF_PLATFORMIO_OPTIONS)
442
+ ):
443
+ # Not specified or empty
359
444
  return config
360
445
 
361
446
  pio_flash_size_key = "board_upload.flash_size"
362
447
  pio_partitions_key = "board_build.partitions"
363
- if (
364
- CONF_PARTITIONS in config
365
- and pio_partitions_key
366
- in fv.full_config.get()[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS]
367
- ):
448
+ if CONF_PARTITIONS in config and pio_partitions_key in pio_options:
368
449
  raise cv.Invalid(
369
450
  f"Do not specify '{pio_partitions_key}' in '{CONF_PLATFORMIO_OPTIONS}' with '{CONF_PARTITIONS}' in esp32"
370
451
  )
371
452
 
372
- if (
373
- pio_flash_size_key
374
- in fv.full_config.get()[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS]
375
- ):
453
+ if pio_flash_size_key in pio_options:
376
454
  raise cv.Invalid(
377
455
  f"Please specify {CONF_FLASH_SIZE} within esp32 configuration only"
378
456
  )
@@ -412,6 +490,7 @@ ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
412
490
  cv.Schema(
413
491
  {
414
492
  cv.Optional(CONF_VERSION, default="recommended"): cv.string_strict,
493
+ cv.Optional(CONF_RELEASE): cv.string_strict,
415
494
  cv.Optional(CONF_SOURCE): cv.string_strict,
416
495
  cv.Optional(CONF_PLATFORM_VERSION): _parse_platform_version,
417
496
  cv.Optional(CONF_SDKCONFIG_OPTIONS, default={}): {
@@ -515,10 +594,9 @@ async def to_code(config):
515
594
  cg.add_build_flag("-DUSE_ESP_IDF")
516
595
  cg.add_build_flag("-DUSE_ESP32_FRAMEWORK_ESP_IDF")
517
596
  cg.add_build_flag("-Wno-nonnull-compare")
518
- cg.add_platformio_option(
519
- "platform_packages",
520
- [f"platformio/framework-espidf@{conf[CONF_SOURCE]}"],
521
- )
597
+
598
+ cg.add_platformio_option("platform_packages", [conf[CONF_SOURCE]])
599
+
522
600
  # platformio/toolchain-esp32ulp does not support linux_aarch64 yet and has not been updated for over 2 years
523
601
  # This is espressif's own published version which is more up to date.
524
602
  cg.add_platformio_option(