esphome 2025.6.3__py3-none-any.whl → 2025.7.0b2__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 (606) hide show
  1. esphome/__main__.py +1 -3
  2. esphome/codegen.py +2 -0
  3. esphome/components/ac_dimmer/ac_dimmer.cpp +6 -6
  4. esphome/components/adc/__init__.py +25 -1
  5. esphome/components/adc/adc_sensor.h +11 -11
  6. esphome/components/adc/adc_sensor_common.cpp +1 -1
  7. esphome/components/adc/adc_sensor_esp32.cpp +16 -8
  8. esphome/components/ade7880/ade7880.h +0 -2
  9. esphome/components/ads1115/ads1115.h +0 -1
  10. esphome/components/ads1118/ads1118.h +0 -1
  11. esphome/components/ags10/ags10.h +0 -2
  12. esphome/components/aic3204/aic3204.h +0 -1
  13. esphome/components/alarm_control_panel/__init__.py +5 -2
  14. esphome/components/alpha3/alpha3.h +0 -1
  15. esphome/components/am43/cover/am43_cover.h +0 -1
  16. esphome/components/am43/sensor/am43_sensor.h +0 -1
  17. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +0 -2
  18. esphome/components/anova/anova.cpp +5 -1
  19. esphome/components/anova/anova.h +0 -1
  20. esphome/components/apds9960/apds9960.cpp +1 -1
  21. esphome/components/api/__init__.py +57 -21
  22. esphome/components/api/api_connection.cpp +344 -539
  23. esphome/components/api/api_connection.h +224 -141
  24. esphome/components/api/api_frame_helper.cpp +91 -127
  25. esphome/components/api/api_frame_helper.h +64 -54
  26. esphome/components/api/api_pb2.cpp +1837 -9044
  27. esphome/components/api/api_pb2.h +532 -685
  28. esphome/components/api/api_pb2_dump.cpp +4432 -0
  29. esphome/components/api/api_pb2_service.cpp +184 -425
  30. esphome/components/api/api_pb2_service.h +13 -6
  31. esphome/components/api/api_server.cpp +131 -167
  32. esphome/components/api/api_server.h +38 -10
  33. esphome/components/api/client.py +8 -2
  34. esphome/components/api/custom_api_device.h +8 -0
  35. esphome/components/api/list_entities.cpp +37 -104
  36. esphome/components/api/list_entities.h +33 -23
  37. esphome/components/api/proto.h +532 -26
  38. esphome/components/api/subscribe_state.cpp +23 -29
  39. esphome/components/api/subscribe_state.h +26 -19
  40. esphome/components/api/user_services.h +2 -0
  41. esphome/components/as5600/as5600.h +0 -1
  42. esphome/components/async_tcp/__init__.py +14 -5
  43. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  44. esphome/components/atm90e32/atm90e32.cpp +2 -1
  45. esphome/components/audio/audio_decoder.cpp +1 -1
  46. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  47. esphome/components/b_parasite/b_parasite.h +0 -1
  48. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  49. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  50. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  51. esphome/components/bh1750/bh1750.cpp +5 -5
  52. esphome/components/binary_sensor/__init__.py +82 -5
  53. esphome/components/binary_sensor/automation.h +19 -1
  54. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  55. esphome/components/binary_sensor/binary_sensor.h +11 -25
  56. esphome/components/binary_sensor/filter.cpp +29 -24
  57. esphome/components/binary_sensor/filter.h +20 -10
  58. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  59. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  60. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  61. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  62. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  63. esphome/components/ble_client/switch/ble_switch.h +0 -1
  64. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  65. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  66. esphome/components/ble_presence/ble_presence_device.h +0 -1
  67. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  68. esphome/components/ble_scanner/ble_scanner.h +0 -1
  69. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  70. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  71. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  72. esphome/components/bme680/sensor.py +1 -1
  73. esphome/components/bmp581/bmp581.h +0 -2
  74. esphome/components/button/__init__.py +5 -2
  75. esphome/components/camera/__init__.py +1 -0
  76. esphome/components/camera/camera.cpp +22 -0
  77. esphome/components/camera/camera.h +80 -0
  78. esphome/components/canbus/__init__.py +1 -0
  79. esphome/components/cap1188/cap1188.h +0 -1
  80. esphome/components/captive_portal/__init__.py +12 -2
  81. esphome/components/captive_portal/captive_portal.cpp +12 -2
  82. esphome/components/captive_portal/captive_portal.h +5 -2
  83. esphome/components/ccs811/ccs811.h +0 -2
  84. esphome/components/climate/__init__.py +5 -2
  85. esphome/components/cm1106/sensor.py +2 -2
  86. esphome/components/const/__init__.py +2 -0
  87. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  88. esphome/components/copy/button/copy_button.h +0 -1
  89. esphome/components/copy/cover/copy_cover.h +0 -1
  90. esphome/components/copy/fan/copy_fan.h +0 -1
  91. esphome/components/copy/lock/copy_lock.h +0 -1
  92. esphome/components/copy/number/copy_number.h +0 -1
  93. esphome/components/copy/select/copy_select.h +0 -1
  94. esphome/components/copy/sensor/copy_sensor.h +0 -1
  95. esphome/components/copy/switch/copy_switch.h +0 -1
  96. esphome/components/copy/text/copy_text.h +0 -1
  97. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  98. esphome/components/cover/__init__.py +5 -2
  99. esphome/components/cs5460a/cs5460a.h +0 -1
  100. esphome/components/datetime/__init__.py +4 -2
  101. esphome/components/debug/__init__.py +20 -0
  102. esphome/components/debug/debug_esp32.cpp +2 -0
  103. esphome/components/deep_sleep/__init__.py +43 -9
  104. esphome/components/demo/__init__.py +2 -2
  105. esphome/components/display/display.cpp +4 -3
  106. esphome/components/display/display.h +0 -2
  107. esphome/components/display/display_buffer.cpp +1 -1
  108. esphome/components/ds2484/__init__.py +1 -0
  109. esphome/components/ds2484/ds2484.cpp +209 -0
  110. esphome/components/ds2484/ds2484.h +43 -0
  111. esphome/components/ds2484/one_wire.py +37 -0
  112. esphome/components/duty_time/duty_time_sensor.h +0 -1
  113. esphome/components/ens160_base/ens160_base.h +0 -1
  114. esphome/components/es7210/es7210.h +0 -1
  115. esphome/components/es7243e/es7243e.h +0 -1
  116. esphome/components/es8156/es8156.h +0 -1
  117. esphome/components/es8311/es8311.h +0 -1
  118. esphome/components/es8388/es8388.h +0 -1
  119. esphome/components/esp32/__init__.py +103 -135
  120. esphome/components/esp32/core.cpp +0 -4
  121. esphome/components/esp32/gpio.h +1 -1
  122. esphome/components/esp32/helpers.cpp +69 -0
  123. esphome/components/esp32_ble/ble.cpp +5 -6
  124. esphome/components/esp32_ble/ble.h +29 -14
  125. esphome/components/esp32_ble/ble_event.h +6 -6
  126. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  127. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  128. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  129. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  130. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  131. esphome/components/esp32_camera/__init__.py +112 -98
  132. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  133. esphome/components/esp32_camera/esp32_camera.h +35 -30
  134. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  135. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  136. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  137. esphome/components/esp32_hall/sensor.py +2 -21
  138. esphome/components/esp32_hosted/__init__.py +101 -0
  139. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  140. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  141. esphome/components/esp32_rmt/__init__.py +0 -58
  142. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  143. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  144. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  145. esphome/components/esp32_touch/esp32_touch.h +174 -28
  146. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  147. esphome/components/esp32_touch/esp32_touch_v1.cpp +240 -0
  148. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  149. esphome/components/esp8266/__init__.py +2 -0
  150. esphome/components/esp8266/gpio.cpp +10 -10
  151. esphome/components/esp8266/helpers.cpp +31 -0
  152. esphome/components/esphome/ota/__init__.py +1 -0
  153. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  154. esphome/components/ethernet/__init__.py +42 -23
  155. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  156. esphome/components/ethernet/ethernet_component.cpp +69 -29
  157. esphome/components/ethernet/ethernet_component.h +18 -10
  158. esphome/components/event/__init__.py +5 -2
  159. esphome/components/ezo/ezo.h +0 -1
  160. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  161. esphome/components/fan/__init__.py +5 -2
  162. esphome/components/feedback/feedback_cover.h +0 -1
  163. esphome/components/font/__init__.py +92 -82
  164. esphome/components/font/font.cpp +9 -2
  165. esphome/components/font/font.h +20 -5
  166. esphome/components/fs3000/fs3000.h +0 -1
  167. esphome/components/gcja5/gcja5.h +0 -1
  168. esphome/components/gl_r01_i2c/__init__.py +0 -0
  169. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  170. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  171. esphome/components/gl_r01_i2c/sensor.py +36 -0
  172. esphome/components/gp8403/gp8403.h +0 -1
  173. esphome/components/gpio/binary_sensor/__init__.py +17 -0
  174. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  175. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  176. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  177. esphome/components/he60r/he60r.h +0 -1
  178. esphome/components/heatpumpir/climate.py +2 -1
  179. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  180. esphome/components/heatpumpir/heatpumpir.h +1 -0
  181. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  182. esphome/components/host/__init__.py +3 -1
  183. esphome/components/host/helpers.cpp +57 -0
  184. esphome/components/http_request/__init__.py +19 -1
  185. esphome/components/http_request/http_request.h +1 -1
  186. esphome/components/http_request/http_request_arduino.h +1 -0
  187. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  188. esphome/components/http_request/update/http_request_update.cpp +28 -9
  189. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
  190. esphome/components/hydreon_rgxx/sensor.py +1 -1
  191. esphome/components/i2c/__init__.py +23 -11
  192. esphome/components/i2c/i2c_bus.h +8 -1
  193. esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
  194. esphome/components/i2c/i2c_bus_arduino.h +6 -3
  195. esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
  196. esphome/components/i2c_device/i2c_device.h +0 -1
  197. esphome/components/i2s_audio/__init__.py +2 -10
  198. esphome/components/i2s_audio/i2s_audio.cpp +1 -5
  199. esphome/components/i2s_audio/media_player/__init__.py +2 -2
  200. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
  201. esphome/components/iaqcore/iaqcore.h +0 -2
  202. esphome/components/image/__init__.py +123 -24
  203. esphome/components/improv_serial/improv_serial_component.cpp +0 -4
  204. esphome/components/ina219/ina219.cpp +7 -0
  205. esphome/components/ina219/ina219.h +1 -0
  206. esphome/components/ina260/ina260.h +0 -2
  207. esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
  208. esphome/components/inkplate6/display.py +15 -0
  209. esphome/components/inkplate6/inkplate.cpp +2 -2
  210. esphome/components/integration/integration_sensor.h +0 -1
  211. esphome/components/internal_temperature/internal_temperature.cpp +8 -27
  212. esphome/components/internal_temperature/sensor.py +0 -26
  213. esphome/components/interval/interval.h +0 -2
  214. esphome/components/ld2410/button/__init__.py +3 -3
  215. esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
  216. esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
  217. esphome/components/ld2410/ld2410.cpp +421 -268
  218. esphome/components/ld2410/ld2410.h +44 -146
  219. esphome/components/ld2410/number/__init__.py +2 -2
  220. esphome/components/ld2410/sensor.py +1 -1
  221. esphome/components/ld2410/switch/__init__.py +1 -1
  222. esphome/components/ld2420/ld2420.cpp +196 -100
  223. esphome/components/ld2420/ld2420.h +46 -118
  224. esphome/components/ld2420/number/__init__.py +2 -2
  225. esphome/components/ld2420/sensor/__init__.py +6 -2
  226. esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
  227. esphome/components/ld2450/button/__init__.py +3 -3
  228. esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
  229. esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
  230. esphome/components/ld2450/ld2450.cpp +384 -232
  231. esphome/components/ld2450/ld2450.h +60 -69
  232. esphome/components/ld2450/switch/__init__.py +1 -1
  233. esphome/components/ledc/ledc_output.cpp +1 -63
  234. esphome/components/libretiny/__init__.py +5 -3
  235. esphome/components/libretiny/const.py +5 -0
  236. esphome/components/libretiny/generate_components.py +1 -0
  237. esphome/components/libretiny/helpers.cpp +35 -0
  238. esphome/components/libretiny/lt_component.cpp +5 -3
  239. esphome/components/light/__init__.py +4 -2
  240. esphome/components/light/addressable_light.h +3 -3
  241. esphome/components/light/light_call.cpp +180 -243
  242. esphome/components/light/light_call.h +72 -20
  243. esphome/components/light/light_color_values.h +14 -14
  244. esphome/components/light/light_state.h +15 -13
  245. esphome/components/light/transformers.h +2 -2
  246. esphome/components/ln882x/__init__.py +52 -0
  247. esphome/components/ln882x/boards.py +285 -0
  248. esphome/components/lock/__init__.py +5 -2
  249. esphome/components/logger/__init__.py +40 -3
  250. esphome/components/logger/logger.cpp +47 -12
  251. esphome/components/logger/logger.h +80 -49
  252. esphome/components/logger/logger_esp32.cpp +3 -3
  253. esphome/components/lps22/__init__.py +0 -0
  254. esphome/components/lps22/lps22.cpp +75 -0
  255. esphome/components/lps22/lps22.h +27 -0
  256. esphome/components/lps22/sensor.py +58 -0
  257. esphome/components/ltr390/ltr390.h +0 -1
  258. esphome/components/ltr501/ltr501.h +0 -1
  259. esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
  260. esphome/components/lvgl/__init__.py +1 -1
  261. esphome/components/lvgl/schemas.py +66 -6
  262. esphome/components/lvgl/styles.py +24 -16
  263. esphome/components/lvgl/widgets/__init__.py +12 -2
  264. esphome/components/lvgl/widgets/lv_bar.py +40 -19
  265. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
  266. esphome/components/max9611/max9611.h +0 -1
  267. esphome/components/mcp23016/__init__.py +1 -1
  268. esphome/components/mcp23xxx_base/__init__.py +1 -1
  269. esphome/components/mcp4461/__init__.py +1 -1
  270. esphome/components/mcp4461/output/__init__.py +3 -2
  271. esphome/components/mcp9600/mcp9600.h +0 -2
  272. esphome/components/md5/md5.cpp +3 -3
  273. esphome/components/md5/md5.h +1 -6
  274. esphome/components/mdns/__init__.py +22 -11
  275. esphome/components/media_player/__init__.py +4 -3
  276. esphome/components/micro_wake_word/__init__.py +1 -5
  277. esphome/components/micro_wake_word/streaming_model.cpp +2 -2
  278. esphome/components/microphone/microphone.cpp +7 -9
  279. esphome/components/microphone/microphone.h +0 -2
  280. esphome/components/mipi_spi/display.py +1 -0
  281. esphome/components/mmc5603/mmc5603.cpp +1 -1
  282. esphome/components/modbus/modbus.cpp +33 -15
  283. esphome/components/modbus/modbus.h +9 -0
  284. esphome/components/modbus_controller/__init__.py +42 -10
  285. esphome/components/modbus_controller/modbus_controller.cpp +92 -11
  286. esphome/components/modbus_controller/modbus_controller.h +61 -7
  287. esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
  288. esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
  289. esphome/components/mpl3115a2/mpl3115a2.h +0 -2
  290. esphome/components/mqtt/__init__.py +16 -0
  291. esphome/components/mqtt/mqtt_backend.h +2 -1
  292. esphome/components/mqtt/mqtt_backend_esp32.cpp +132 -47
  293. esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
  294. esphome/components/mqtt/mqtt_client.cpp +15 -9
  295. esphome/components/mqtt/mqtt_client.h +8 -3
  296. esphome/components/ms8607/ms8607.h +0 -1
  297. esphome/components/neopixelbus/light.py +4 -1
  298. esphome/components/neopixelbus/neopixelbus_light.h +1 -1
  299. esphome/components/network/__init__.py +4 -1
  300. esphome/components/network/ip_address.h +1 -0
  301. esphome/components/nextion/__init__.py +16 -0
  302. esphome/components/nextion/base_component.py +1 -0
  303. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  304. esphome/components/nextion/display.py +14 -4
  305. esphome/components/nextion/nextion.cpp +166 -101
  306. esphome/components/nextion/nextion.h +84 -53
  307. esphome/components/nextion/nextion_commands.cpp +11 -10
  308. esphome/components/nextion/nextion_component.cpp +28 -28
  309. esphome/components/nextion/nextion_component.h +53 -18
  310. esphome/components/nextion/nextion_component_base.h +3 -0
  311. esphome/components/nextion/nextion_upload.cpp +36 -0
  312. esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
  313. esphome/components/nextion/nextion_upload_idf.cpp +9 -33
  314. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  315. esphome/components/nextion/switch/nextion_switch.cpp +1 -1
  316. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  317. esphome/components/nfc/nfc.cpp +3 -22
  318. esphome/components/nfc/nfc.h +3 -3
  319. esphome/components/number/__init__.py +5 -2
  320. esphome/components/online_image/__init__.py +5 -0
  321. esphome/components/online_image/online_image.cpp +6 -2
  322. esphome/components/online_image/online_image.h +4 -1
  323. esphome/components/opentherm/opentherm.cpp +7 -12
  324. esphome/components/openthread/__init__.py +47 -40
  325. esphome/components/openthread/const.py +1 -0
  326. esphome/components/openthread/openthread_esp.cpp +27 -5
  327. esphome/components/opt3001/__init__.py +0 -0
  328. esphome/components/opt3001/opt3001.cpp +122 -0
  329. esphome/components/opt3001/opt3001.h +27 -0
  330. esphome/components/opt3001/sensor.py +35 -0
  331. esphome/components/ota/__init__.py +17 -0
  332. esphome/components/ota/ota_backend.h +27 -1
  333. esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
  334. esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
  335. esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
  336. esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
  337. esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
  338. esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
  339. esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
  340. esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
  341. esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
  342. esphome/components/ota/ota_backend_esp_idf.h +1 -0
  343. esphome/components/packages/__init__.py +5 -2
  344. esphome/components/packet_transport/binary_sensor.py +61 -4
  345. esphome/components/packet_transport/packet_transport.cpp +34 -1
  346. esphome/components/packet_transport/packet_transport.h +11 -5
  347. esphome/components/pcf8574/__init__.py +1 -1
  348. esphome/components/pi4ioe5v6408/__init__.py +84 -0
  349. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
  350. esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
  351. esphome/components/pmsa003i/pmsa003i.h +0 -1
  352. esphome/components/pmsx003/pmsx003.h +0 -1
  353. esphome/components/pn7150/pn7150.cpp +7 -7
  354. esphome/components/pn7150/pn7150.h +0 -1
  355. esphome/components/pn7160/pn7160.cpp +7 -7
  356. esphome/components/pn7160/pn7160.h +0 -1
  357. esphome/components/preferences/syncer.h +2 -0
  358. esphome/components/prometheus/prometheus_handler.h +1 -1
  359. esphome/components/psram/psram.cpp +0 -20
  360. esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
  361. esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
  362. esphome/components/pulse_width/pulse_width.h +0 -1
  363. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
  364. esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
  365. esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
  366. esphome/components/qr_code/__init__.py +13 -10
  367. esphome/components/qwiic_pir/qwiic_pir.h +0 -1
  368. esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
  369. esphome/components/rc522/rc522.h +0 -1
  370. esphome/components/rdm6300/rdm6300.h +0 -2
  371. esphome/components/remote_base/__init__.py +7 -5
  372. esphome/components/remote_base/remote_base.cpp +24 -21
  373. esphome/components/remote_base/remote_base.h +3 -26
  374. esphome/components/remote_receiver/__init__.py +40 -46
  375. esphome/components/remote_receiver/remote_receiver.h +4 -18
  376. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
  377. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
  378. esphome/components/remote_transmitter/__init__.py +42 -43
  379. esphome/components/remote_transmitter/remote_transmitter.h +2 -14
  380. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
  381. esphome/components/resistance/resistance_sensor.h +0 -1
  382. esphome/components/rp2040/__init__.py +2 -0
  383. esphome/components/rp2040/helpers.cpp +55 -0
  384. esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
  385. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
  386. esphome/components/rtttl/__init__.py +4 -4
  387. esphome/components/rtttl/rtttl.cpp +10 -1
  388. esphome/components/ruuvitag/ruuvitag.h +0 -1
  389. esphome/components/safe_mode/safe_mode.cpp +2 -0
  390. esphome/components/safe_mode/safe_mode.h +4 -1
  391. esphome/components/scd30/scd30.h +0 -1
  392. esphome/components/scd30/sensor.py +2 -2
  393. esphome/components/scd4x/scd4x.cpp +61 -54
  394. esphome/components/scd4x/scd4x.h +17 -15
  395. esphome/components/scd4x/sensor.py +4 -4
  396. esphome/components/script/script.h +0 -2
  397. esphome/components/sdp3x/sensor.py +1 -1
  398. esphome/components/select/__init__.py +5 -2
  399. esphome/components/sen5x/sen5x.h +0 -1
  400. esphome/components/senseair/senseair.h +0 -1
  401. esphome/components/sensor/__init__.py +4 -2
  402. esphome/components/sensor/filter.cpp +1 -1
  403. esphome/components/sensor/sensor.cpp +12 -6
  404. esphome/components/sensor/sensor.h +13 -5
  405. esphome/components/servo/servo.h +0 -1
  406. esphome/components/sfa30/sfa30.h +0 -1
  407. esphome/components/sgp30/sgp30.h +0 -1
  408. esphome/components/sgp4x/sgp4x.h +0 -1
  409. esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
  410. esphome/components/sht4x/sht4x.h +0 -1
  411. esphome/components/sm300d2/sm300d2.h +0 -2
  412. esphome/components/smt100/sensor.py +8 -4
  413. esphome/components/smt100/smt100.cpp +5 -5
  414. esphome/components/smt100/smt100.h +3 -3
  415. esphome/components/sn74hc595/__init__.py +1 -1
  416. esphome/components/sn74hc595/sn74hc595.cpp +5 -4
  417. esphome/components/sntp/sntp_component.cpp +9 -3
  418. esphome/components/sntp/time.py +2 -0
  419. esphome/components/socket/__init__.py +17 -0
  420. esphome/components/spi/__init__.py +27 -6
  421. esphome/components/spi/spi.cpp +3 -2
  422. esphome/components/spi/spi.h +9 -3
  423. esphome/components/spi/spi_arduino.cpp +3 -5
  424. esphome/components/spi/spi_esp_idf.cpp +40 -21
  425. esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
  426. esphome/components/sps30/sps30.h +0 -1
  427. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  428. esphome/components/st7701s/st7701s.cpp +0 -4
  429. esphome/components/status/status_binary_sensor.h +0 -2
  430. esphome/components/substitutions/__init__.py +76 -19
  431. esphome/components/substitutions/jinja.py +99 -0
  432. esphome/components/sun/sun.cpp +3 -4
  433. esphome/components/switch/__init__.py +5 -2
  434. esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
  435. esphome/components/sx126x/__init__.py +317 -0
  436. esphome/components/sx126x/automation.h +62 -0
  437. esphome/components/sx126x/packet_transport/__init__.py +26 -0
  438. esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
  439. esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
  440. esphome/components/sx126x/sx126x.cpp +523 -0
  441. esphome/components/sx126x/sx126x.h +140 -0
  442. esphome/components/sx126x/sx126x_reg.h +163 -0
  443. esphome/components/sx127x/__init__.py +325 -0
  444. esphome/components/sx127x/automation.h +62 -0
  445. esphome/components/sx127x/packet_transport/__init__.py +26 -0
  446. esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
  447. esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
  448. esphome/components/sx127x/sx127x.cpp +498 -0
  449. esphome/components/sx127x/sx127x.h +128 -0
  450. esphome/components/sx127x/sx127x_reg.h +295 -0
  451. esphome/components/syslog/esphome_syslog.cpp +5 -3
  452. esphome/components/syslog/esphome_syslog.h +1 -1
  453. esphome/components/tca9555/__init__.py +1 -1
  454. esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
  455. esphome/components/text/__init__.py +5 -2
  456. esphome/components/text_sensor/__init__.py +5 -2
  457. esphome/components/thermostat/thermostat_climate.cpp +34 -31
  458. esphome/components/thermostat/thermostat_climate.h +43 -39
  459. esphome/components/time/__init__.py +16 -2
  460. esphome/components/time/real_time_clock.cpp +4 -0
  461. esphome/components/time/real_time_clock.h +5 -1
  462. esphome/components/tlc5971/tlc5971.cpp +4 -1
  463. esphome/components/tmp1075/tmp1075.h +0 -2
  464. esphome/components/tof10120/tof10120_sensor.h +0 -1
  465. esphome/components/tormatic/tormatic_cover.h +0 -1
  466. esphome/components/total_daily_energy/total_daily_energy.h +0 -1
  467. esphome/components/tsl2591/tsl2591.cpp +1 -1
  468. esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
  469. esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
  470. esphome/components/tx20/tx20.cpp +2 -2
  471. esphome/components/uart/__init__.py +18 -0
  472. esphome/components/uart/uart_component_esp_idf.cpp +0 -4
  473. esphome/components/update/__init__.py +5 -2
  474. esphome/components/update/update_entity.h +8 -0
  475. esphome/components/usb_host/__init__.py +5 -2
  476. esphome/components/usb_host/usb_host_client.cpp +10 -10
  477. esphome/components/usb_uart/cp210x.cpp +1 -1
  478. esphome/components/usb_uart/usb_uart.cpp +41 -44
  479. esphome/components/usb_uart/usb_uart.h +4 -3
  480. esphome/components/valve/__init__.py +5 -2
  481. esphome/components/vbus/vbus.h +0 -1
  482. esphome/components/veml3235/veml3235.h +0 -1
  483. esphome/components/veml7700/veml7700.h +0 -1
  484. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  485. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  486. esphome/components/watchdog/watchdog.cpp +0 -4
  487. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  488. esphome/components/web_server/__init__.py +34 -19
  489. esphome/components/web_server/ota/__init__.py +32 -0
  490. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  491. esphome/components/web_server/ota/ota_web_server.h +26 -0
  492. esphome/components/web_server/web_server.cpp +305 -427
  493. esphome/components/web_server/web_server.h +33 -23
  494. esphome/components/web_server/web_server_v1.cpp +4 -5
  495. esphome/components/web_server_base/__init__.py +5 -2
  496. esphome/components/web_server_base/web_server_base.cpp +2 -94
  497. esphome/components/web_server_base/web_server_base.h +5 -25
  498. esphome/components/web_server_idf/multipart.cpp +254 -0
  499. esphome/components/web_server_idf/multipart.h +86 -0
  500. esphome/components/web_server_idf/utils.cpp +32 -0
  501. esphome/components/web_server_idf/utils.h +10 -0
  502. esphome/components/web_server_idf/web_server_idf.cpp +162 -16
  503. esphome/components/web_server_idf/web_server_idf.h +11 -10
  504. esphome/components/wiegand/wiegand.cpp +2 -2
  505. esphome/components/wifi/__init__.py +18 -0
  506. esphome/components/wifi/wifi_component.cpp +17 -22
  507. esphome/components/wifi/wifi_component.h +27 -23
  508. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  509. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  510. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  511. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  512. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  513. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  514. esphome/components/wireguard/__init__.py +2 -11
  515. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  516. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  517. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  518. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  519. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  520. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  521. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  522. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  523. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  524. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  525. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  526. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  527. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  528. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  529. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  530. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  531. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  532. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  533. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  534. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  535. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  536. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  537. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  538. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  539. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  540. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  541. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  542. esphome/components/zyaura/zyaura.h +0 -1
  543. esphome/config.py +88 -22
  544. esphome/config_helpers.py +74 -1
  545. esphome/config_validation.py +12 -1
  546. esphome/const.py +65 -10
  547. esphome/core/__init__.py +18 -2
  548. esphome/core/application.cpp +163 -10
  549. esphome/core/application.h +145 -165
  550. esphome/core/area.h +19 -0
  551. esphome/core/automation.h +58 -9
  552. esphome/core/color.cpp +3 -5
  553. esphome/core/color.h +16 -16
  554. esphome/core/component.cpp +151 -18
  555. esphome/core/component.h +98 -4
  556. esphome/core/component_iterator.cpp +11 -9
  557. esphome/core/component_iterator.h +12 -10
  558. esphome/core/config.py +155 -6
  559. esphome/core/controller.cpp +4 -2
  560. esphome/core/controller.h +1 -1
  561. esphome/core/datatypes.h +2 -2
  562. esphome/core/defines.h +17 -2
  563. esphome/core/device.h +20 -0
  564. esphome/core/entity_base.cpp +20 -15
  565. esphome/core/entity_base.h +76 -0
  566. esphome/core/entity_helpers.py +168 -1
  567. esphome/core/event_pool.h +81 -0
  568. esphome/core/helpers.cpp +75 -230
  569. esphome/core/helpers.h +164 -104
  570. esphome/core/lock_free_queue.h +151 -0
  571. esphome/core/log.cpp +2 -2
  572. esphome/core/log.h +2 -0
  573. esphome/core/optional.h +5 -0
  574. esphome/core/ring_buffer.cpp +2 -2
  575. esphome/core/scheduler.cpp +275 -103
  576. esphome/core/scheduler.h +154 -17
  577. esphome/core/time.cpp +5 -5
  578. esphome/core/time.h +5 -5
  579. esphome/cpp_generator.py +17 -0
  580. esphome/cpp_helpers.py +0 -22
  581. esphome/cpp_types.py +3 -1
  582. esphome/dashboard/entries.py +1 -1
  583. esphome/dashboard/util/text.py +5 -21
  584. esphome/dashboard/web_server.py +9 -1
  585. esphome/helpers.py +47 -0
  586. esphome/loader.py +15 -1
  587. esphome/pins.py +14 -8
  588. esphome/wizard.py +17 -4
  589. esphome/writer.py +21 -3
  590. esphome/yaml_util.py +0 -2
  591. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/METADATA +10 -9
  592. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/RECORD +597 -538
  593. esphome/components/api/api_pb2_size.h +0 -361
  594. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  595. esphome/components/esp32_ble/queue.h +0 -85
  596. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  597. esphome/components/esp32_hall/esp32_hall.h +0 -23
  598. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  599. esphome/components/ld2410/button/reset_button.cpp +0 -9
  600. esphome/components/ld2450/button/reset_button.cpp +0 -9
  601. esphome/components/openthread/tlv.py +0 -65
  602. /esphome/{dashboard/enum.py → enum.py} +0 -0
  603. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/WHEEL +0 -0
  604. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/entry_points.txt +0 -0
  605. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/licenses/LICENSE +0 -0
  606. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,119 @@
1
- from esphome.const import CONF_ID
1
+ from collections.abc import Callable
2
+ import logging
3
+
4
+ import esphome.codegen as cg
5
+ import esphome.config_validation as cv
6
+ from esphome.const import (
7
+ CONF_DEVICE_ID,
8
+ CONF_DISABLED_BY_DEFAULT,
9
+ CONF_ENTITY_CATEGORY,
10
+ CONF_ICON,
11
+ CONF_ID,
12
+ CONF_INTERNAL,
13
+ CONF_NAME,
14
+ )
15
+ from esphome.core import CORE, ID
16
+ from esphome.cpp_generator import MockObj, add, get_variable
2
17
  import esphome.final_validate as fv
18
+ from esphome.helpers import sanitize, snake_case
19
+ from esphome.types import ConfigType
20
+
21
+ _LOGGER = logging.getLogger(__name__)
22
+
23
+
24
+ def get_base_entity_object_id(
25
+ name: str, friendly_name: str | None, device_name: str | None = None
26
+ ) -> str:
27
+ """Calculate the base object ID for an entity that will be set via set_object_id().
28
+
29
+ This function calculates what object_id_c_str_ should be set to in C++.
30
+
31
+ The C++ EntityBase::get_object_id() (entity_base.cpp lines 38-49) works as:
32
+ - If !has_own_name && is_name_add_mac_suffix_enabled():
33
+ return str_sanitize(str_snake_case(App.get_friendly_name())) // Dynamic
34
+ - Else:
35
+ return object_id_c_str_ ?? "" // What we set via set_object_id()
36
+
37
+ Since we're calculating what to pass to set_object_id(), we always need to
38
+ generate the object_id the same way, regardless of name_add_mac_suffix setting.
39
+
40
+ Args:
41
+ name: The entity name (empty string if no name)
42
+ friendly_name: The friendly name from CORE.friendly_name
43
+ device_name: The device name if entity is on a sub-device
44
+
45
+ Returns:
46
+ The base object ID to use for duplicate checking and to pass to set_object_id()
47
+ """
48
+
49
+ if name:
50
+ # Entity has its own name (has_own_name will be true)
51
+ base_str = name
52
+ elif device_name:
53
+ # Entity has empty name and is on a sub-device
54
+ # C++ EntityBase::set_name() uses device->get_name() when device is set
55
+ base_str = device_name
56
+ elif friendly_name:
57
+ # Entity has empty name (has_own_name will be false)
58
+ # C++ uses App.get_friendly_name() which returns friendly_name or device name
59
+ base_str = friendly_name
60
+ else:
61
+ # Fallback to device name
62
+ base_str = CORE.name
63
+
64
+ return sanitize(snake_case(base_str))
65
+
66
+
67
+ async def setup_entity(var: MockObj, config: ConfigType, platform: str) -> None:
68
+ """Set up generic properties of an Entity.
69
+
70
+ This function sets up the common entity properties like name, icon,
71
+ entity category, etc.
72
+
73
+ Args:
74
+ var: The entity variable to set up
75
+ config: Configuration dictionary containing entity settings
76
+ platform: The platform name (e.g., "sensor", "binary_sensor")
77
+ """
78
+ # Get device info
79
+ device_name: str | None = None
80
+ if CONF_DEVICE_ID in config:
81
+ device_id_obj: ID = config[CONF_DEVICE_ID]
82
+ device: MockObj = await get_variable(device_id_obj)
83
+ add(var.set_device(device))
84
+ # Get device name for object ID calculation
85
+ device_name = device_id_obj.id
86
+
87
+ add(var.set_name(config[CONF_NAME]))
88
+
89
+ # Calculate base object_id using the same logic as C++
90
+ # This must match the C++ behavior in esphome/core/entity_base.cpp
91
+ base_object_id = get_base_entity_object_id(
92
+ config[CONF_NAME], CORE.friendly_name, device_name
93
+ )
94
+
95
+ if not config[CONF_NAME]:
96
+ _LOGGER.debug(
97
+ "Entity has empty name, using '%s' as object_id base", base_object_id
98
+ )
99
+
100
+ # Set the object ID
101
+ add(var.set_object_id(base_object_id))
102
+ _LOGGER.debug(
103
+ "Setting object_id '%s' for entity '%s' on platform '%s'",
104
+ base_object_id,
105
+ config[CONF_NAME],
106
+ platform,
107
+ )
108
+ add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
109
+ if CONF_INTERNAL in config:
110
+ add(var.set_internal(config[CONF_INTERNAL]))
111
+ if CONF_ICON in config:
112
+ # Add USE_ENTITY_ICON define when icons are used
113
+ cg.add_define("USE_ENTITY_ICON")
114
+ add(var.set_icon(config[CONF_ICON]))
115
+ if CONF_ENTITY_CATEGORY in config:
116
+ add(var.set_entity_category(config[CONF_ENTITY_CATEGORY]))
3
117
 
4
118
 
5
119
  def inherit_property_from(property_to_inherit, parent_id_property, transform=None):
@@ -54,3 +168,56 @@ def inherit_property_from(property_to_inherit, parent_id_property, transform=Non
54
168
  return config
55
169
 
56
170
  return inherit_property
171
+
172
+
173
+ def entity_duplicate_validator(platform: str) -> Callable[[ConfigType], ConfigType]:
174
+ """Create a validator function to check for duplicate entity names.
175
+
176
+ This validator is meant to be used with schema.add_extra() for entity base schemas.
177
+
178
+ Args:
179
+ platform: The platform name (e.g., "sensor", "binary_sensor")
180
+
181
+ Returns:
182
+ A validator function that checks for duplicate names
183
+ """
184
+
185
+ def validator(config: ConfigType) -> ConfigType:
186
+ if CONF_NAME not in config:
187
+ # No name to validate
188
+ return config
189
+
190
+ # Skip validation for internal entities
191
+ # Internal entities are not exposed to Home Assistant and don't use the hash-based
192
+ # entity state tracking system, so name collisions don't matter for them
193
+ if config.get(CONF_INTERNAL, False):
194
+ return config
195
+
196
+ # Get the entity name
197
+ entity_name = config[CONF_NAME]
198
+
199
+ # Get device name if entity is on a sub-device
200
+ device_name = None
201
+ if CONF_DEVICE_ID in config:
202
+ device_id_obj = config[CONF_DEVICE_ID]
203
+ device_name = device_id_obj.id
204
+
205
+ # Calculate what object_id will actually be used
206
+ # This handles empty names correctly by using device/friendly names
207
+ name_key = get_base_entity_object_id(
208
+ entity_name, CORE.friendly_name, device_name
209
+ )
210
+
211
+ # Check for duplicates
212
+ unique_key = (platform, name_key)
213
+ if unique_key in CORE.unique_ids:
214
+ raise cv.Invalid(
215
+ f"Duplicate {platform} entity with name '{entity_name}' found. "
216
+ f"Each entity must have a unique name within its platform across all devices."
217
+ )
218
+
219
+ # Add to tracking set
220
+ CORE.unique_ids.add(unique_key)
221
+ return config
222
+
223
+ return validator
@@ -0,0 +1,81 @@
1
+ #pragma once
2
+
3
+ #if defined(USE_ESP32) || defined(USE_LIBRETINY)
4
+
5
+ #include <atomic>
6
+ #include <cstddef>
7
+ #include "esphome/core/helpers.h"
8
+ #include "esphome/core/lock_free_queue.h"
9
+
10
+ namespace esphome {
11
+
12
+ // Event Pool - On-demand pool of objects to avoid heap fragmentation
13
+ // Events are allocated on first use and reused thereafter, growing to peak usage
14
+ // @tparam T The type of objects managed by the pool (must have a release() method)
15
+ // @tparam SIZE The maximum number of objects in the pool (1-255, limited by uint8_t)
16
+ template<class T, uint8_t SIZE> class EventPool {
17
+ public:
18
+ EventPool() : total_created_(0) {}
19
+
20
+ ~EventPool() {
21
+ // Clean up any remaining events in the free list
22
+ // IMPORTANT: This destructor assumes no concurrent access. The EventPool must not
23
+ // be destroyed while any thread might still call allocate() or release().
24
+ // In practice, this is typically ensured by destroying the pool only during
25
+ // component shutdown when all producer/consumer threads have been stopped.
26
+ T *event;
27
+ RAMAllocator<T> allocator(RAMAllocator<T>::ALLOC_INTERNAL);
28
+ while ((event = this->free_list_.pop()) != nullptr) {
29
+ // Call destructor
30
+ event->~T();
31
+ // Deallocate using RAMAllocator
32
+ allocator.deallocate(event, 1);
33
+ }
34
+ }
35
+
36
+ // Allocate an event from the pool
37
+ // Returns nullptr if pool is full
38
+ T *allocate() {
39
+ // Try to get from free list first
40
+ T *event = this->free_list_.pop();
41
+ if (event != nullptr)
42
+ return event;
43
+
44
+ // Need to create a new event
45
+ if (this->total_created_ >= SIZE) {
46
+ // Pool is at capacity
47
+ return nullptr;
48
+ }
49
+
50
+ // Use internal RAM for better performance
51
+ RAMAllocator<T> allocator(RAMAllocator<T>::ALLOC_INTERNAL);
52
+ event = allocator.allocate(1);
53
+
54
+ if (event == nullptr) {
55
+ // Memory allocation failed
56
+ return nullptr;
57
+ }
58
+
59
+ // Placement new to construct the object
60
+ new (event) T();
61
+ this->total_created_++;
62
+ return event;
63
+ }
64
+
65
+ // Return an event to the pool for reuse
66
+ void release(T *event) {
67
+ if (event != nullptr) {
68
+ // Clean up the event's allocated memory
69
+ event->release();
70
+ this->free_list_.push(event);
71
+ }
72
+ }
73
+
74
+ private:
75
+ LockFreeQueue<T, SIZE> free_list_; // Free events ready for reuse
76
+ uint8_t total_created_; // Total events created (high water mark, max 255)
77
+ };
78
+
79
+ } // namespace esphome
80
+
81
+ #endif // defined(USE_ESP32) || defined(USE_LIBRETINY)
esphome/core/helpers.cpp CHANGED
@@ -4,53 +4,16 @@
4
4
  #include "esphome/core/hal.h"
5
5
  #include "esphome/core/log.h"
6
6
 
7
+ #include <strings.h>
7
8
  #include <algorithm>
8
9
  #include <cctype>
9
10
  #include <cmath>
10
11
  #include <cstdarg>
11
12
  #include <cstdio>
12
13
  #include <cstring>
13
- #include <strings.h>
14
14
 
15
- #ifdef USE_HOST
16
- #ifndef _WIN32
17
- #include <net/if.h>
18
- #include <netinet/in.h>
19
- #include <sys/ioctl.h>
20
- #endif
21
- #include <unistd.h>
22
- #endif
23
- #if defined(USE_ESP8266)
24
- #include <osapi.h>
25
- #include <user_interface.h>
26
- // for xt_rsil()/xt_wsr_ps()
27
- #include <Arduino.h>
28
- #elif defined(USE_ESP32_FRAMEWORK_ARDUINO)
29
- #include <Esp.h>
30
- #elif defined(USE_ESP_IDF)
31
- #include <freertos/FreeRTOS.h>
32
- #include <freertos/portmacro.h>
33
- #include "esp_random.h"
34
- #include "esp_system.h"
35
- #elif defined(USE_RP2040)
36
- #if defined(USE_WIFI)
37
- #include <WiFi.h>
38
- #endif
39
- #include <hardware/structs/rosc.h>
40
- #include <hardware/sync.h>
41
- #elif defined(USE_HOST)
42
- #include <limits>
43
- #include <random>
44
- #endif
45
15
  #ifdef USE_ESP32
46
16
  #include "rom/crc.h"
47
- #include "esp_mac.h"
48
- #include "esp_efuse.h"
49
- #include "esp_efuse_table.h"
50
- #endif
51
-
52
- #ifdef USE_LIBRETINY
53
- #include <WiFi.h> // for macAddress()
54
17
  #endif
55
18
 
56
19
  namespace esphome {
@@ -76,23 +39,8 @@ static const uint16_t CRC16_1021_BE_LUT_H[] = {0x0000, 0x1231, 0x2462, 0x3653, 0
76
39
  0x9188, 0x83b9, 0xb5ea, 0xa7db, 0xd94c, 0xcb7d, 0xfd2e, 0xef1f};
77
40
  #endif
78
41
 
79
- // STL backports
80
-
81
- #if _GLIBCXX_RELEASE < 8
82
- std::string to_string(int value) { return str_snprintf("%d", 32, value); } // NOLINT
83
- std::string to_string(long value) { return str_snprintf("%ld", 32, value); } // NOLINT
84
- std::string to_string(long long value) { return str_snprintf("%lld", 32, value); } // NOLINT
85
- std::string to_string(unsigned value) { return str_snprintf("%u", 32, value); } // NOLINT
86
- std::string to_string(unsigned long value) { return str_snprintf("%lu", 32, value); } // NOLINT
87
- std::string to_string(unsigned long long value) { return str_snprintf("%llu", 32, value); } // NOLINT
88
- std::string to_string(float value) { return str_snprintf("%f", 32, value); }
89
- std::string to_string(double value) { return str_snprintf("%f", 32, value); }
90
- std::string to_string(long double value) { return str_snprintf("%Lf", 32, value); }
91
- #endif
92
-
93
42
  // Mathematics
94
43
 
95
- float lerp(float completion, float start, float end) { return start + (end - start) * completion; }
96
44
  uint8_t crc8(const uint8_t *data, uint8_t len) {
97
45
  uint8_t crc = 0;
98
46
 
@@ -192,70 +140,7 @@ uint32_t fnv1_hash(const std::string &str) {
192
140
  return hash;
193
141
  }
194
142
 
195
- #ifdef USE_ESP32
196
- uint32_t random_uint32() { return esp_random(); }
197
- #elif defined(USE_ESP8266)
198
- uint32_t random_uint32() { return os_random(); }
199
- #elif defined(USE_RP2040)
200
- uint32_t random_uint32() {
201
- uint32_t result = 0;
202
- for (uint8_t i = 0; i < 32; i++) {
203
- result <<= 1;
204
- result |= rosc_hw->randombit;
205
- }
206
- return result;
207
- }
208
- #elif defined(USE_LIBRETINY)
209
- uint32_t random_uint32() { return rand(); }
210
- #elif defined(USE_HOST)
211
- uint32_t random_uint32() {
212
- std::random_device dev;
213
- std::mt19937 rng(dev());
214
- std::uniform_int_distribution<uint32_t> dist(0, std::numeric_limits<uint32_t>::max());
215
- return dist(rng);
216
- }
217
- #endif
218
143
  float random_float() { return static_cast<float>(random_uint32()) / static_cast<float>(UINT32_MAX); }
219
- #ifdef USE_ESP32
220
- bool random_bytes(uint8_t *data, size_t len) {
221
- esp_fill_random(data, len);
222
- return true;
223
- }
224
- #elif defined(USE_ESP8266)
225
- bool random_bytes(uint8_t *data, size_t len) { return os_get_random(data, len) == 0; }
226
- #elif defined(USE_RP2040)
227
- bool random_bytes(uint8_t *data, size_t len) {
228
- while (len-- != 0) {
229
- uint8_t result = 0;
230
- for (uint8_t i = 0; i < 8; i++) {
231
- result <<= 1;
232
- result |= rosc_hw->randombit;
233
- }
234
- *data++ = result;
235
- }
236
- return true;
237
- }
238
- #elif defined(USE_LIBRETINY)
239
- bool random_bytes(uint8_t *data, size_t len) {
240
- lt_rand_bytes(data, len);
241
- return true;
242
- }
243
- #elif defined(USE_HOST)
244
- bool random_bytes(uint8_t *data, size_t len) {
245
- FILE *fp = fopen("/dev/urandom", "r");
246
- if (fp == nullptr) {
247
- ESP_LOGW(TAG, "Could not open /dev/urandom, errno=%d", errno);
248
- exit(1);
249
- }
250
- size_t read = fread(data, 1, len, fp);
251
- if (read != len) {
252
- ESP_LOGW(TAG, "Not enough data from /dev/urandom");
253
- exit(1);
254
- }
255
- fclose(fp);
256
- return true;
257
- }
258
- #endif
259
144
 
260
145
  // Strings
261
146
 
@@ -356,6 +241,10 @@ size_t parse_hex(const char *str, size_t length, uint8_t *data, size_t count) {
356
241
  return chars;
357
242
  }
358
243
 
244
+ std::string format_mac_address_pretty(const uint8_t *mac) {
245
+ return str_snprintf("%02X:%02X:%02X:%02X:%02X:%02X", 17, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
246
+ }
247
+
359
248
  static char format_hex_char(uint8_t v) { return v >= 10 ? 'a' + (v - 10) : '0' + v; }
360
249
  std::string format_hex(const uint8_t *data, size_t length) {
361
250
  std::string ret;
@@ -369,41 +258,63 @@ std::string format_hex(const uint8_t *data, size_t length) {
369
258
  std::string format_hex(const std::vector<uint8_t> &data) { return format_hex(data.data(), data.size()); }
370
259
 
371
260
  static char format_hex_pretty_char(uint8_t v) { return v >= 10 ? 'A' + (v - 10) : '0' + v; }
372
- std::string format_hex_pretty(const uint8_t *data, size_t length) {
373
- if (length == 0)
261
+ std::string format_hex_pretty(const uint8_t *data, size_t length, char separator, bool show_length) {
262
+ if (data == nullptr || length == 0)
374
263
  return "";
375
264
  std::string ret;
376
- ret.resize(3 * length - 1);
265
+ uint8_t multiple = separator ? 3 : 2; // 3 if separator is not \0, 2 otherwise
266
+ ret.resize(multiple * length - (separator ? 1 : 0));
377
267
  for (size_t i = 0; i < length; i++) {
378
- ret[3 * i] = format_hex_pretty_char((data[i] & 0xF0) >> 4);
379
- ret[3 * i + 1] = format_hex_pretty_char(data[i] & 0x0F);
380
- if (i != length - 1)
381
- ret[3 * i + 2] = '.';
268
+ ret[multiple * i] = format_hex_pretty_char((data[i] & 0xF0) >> 4);
269
+ ret[multiple * i + 1] = format_hex_pretty_char(data[i] & 0x0F);
270
+ if (separator && i != length - 1)
271
+ ret[multiple * i + 2] = separator;
382
272
  }
383
- if (length > 4)
384
- return ret + " (" + to_string(length) + ")";
273
+ if (show_length && length > 4)
274
+ return ret + " (" + std::to_string(length) + ")";
385
275
  return ret;
386
276
  }
387
- std::string format_hex_pretty(const std::vector<uint8_t> &data) { return format_hex_pretty(data.data(), data.size()); }
277
+ std::string format_hex_pretty(const std::vector<uint8_t> &data, char separator, bool show_length) {
278
+ return format_hex_pretty(data.data(), data.size(), separator, show_length);
279
+ }
388
280
 
389
- std::string format_hex_pretty(const uint16_t *data, size_t length) {
390
- if (length == 0)
281
+ std::string format_hex_pretty(const uint16_t *data, size_t length, char separator, bool show_length) {
282
+ if (data == nullptr || length == 0)
391
283
  return "";
392
284
  std::string ret;
393
- ret.resize(5 * length - 1);
285
+ uint8_t multiple = separator ? 5 : 4; // 5 if separator is not \0, 4 otherwise
286
+ ret.resize(multiple * length - (separator ? 1 : 0));
394
287
  for (size_t i = 0; i < length; i++) {
395
- ret[5 * i] = format_hex_pretty_char((data[i] & 0xF000) >> 12);
396
- ret[5 * i + 1] = format_hex_pretty_char((data[i] & 0x0F00) >> 8);
397
- ret[5 * i + 2] = format_hex_pretty_char((data[i] & 0x00F0) >> 4);
398
- ret[5 * i + 3] = format_hex_pretty_char(data[i] & 0x000F);
399
- if (i != length - 1)
400
- ret[5 * i + 2] = '.';
288
+ ret[multiple * i] = format_hex_pretty_char((data[i] & 0xF000) >> 12);
289
+ ret[multiple * i + 1] = format_hex_pretty_char((data[i] & 0x0F00) >> 8);
290
+ ret[multiple * i + 2] = format_hex_pretty_char((data[i] & 0x00F0) >> 4);
291
+ ret[multiple * i + 3] = format_hex_pretty_char(data[i] & 0x000F);
292
+ if (separator && i != length - 1)
293
+ ret[multiple * i + 4] = separator;
294
+ }
295
+ if (show_length && length > 4)
296
+ return ret + " (" + std::to_string(length) + ")";
297
+ return ret;
298
+ }
299
+ std::string format_hex_pretty(const std::vector<uint16_t> &data, char separator, bool show_length) {
300
+ return format_hex_pretty(data.data(), data.size(), separator, show_length);
301
+ }
302
+ std::string format_hex_pretty(const std::string &data, char separator, bool show_length) {
303
+ if (data.empty())
304
+ return "";
305
+ std::string ret;
306
+ uint8_t multiple = separator ? 3 : 2; // 3 if separator is not \0, 2 otherwise
307
+ ret.resize(multiple * data.length() - (separator ? 1 : 0));
308
+ for (size_t i = 0; i < data.length(); i++) {
309
+ ret[multiple * i] = format_hex_pretty_char((data[i] & 0xF0) >> 4);
310
+ ret[multiple * i + 1] = format_hex_pretty_char(data[i] & 0x0F);
311
+ if (separator && i != data.length() - 1)
312
+ ret[multiple * i + 2] = separator;
401
313
  }
402
- if (length > 4)
403
- return ret + " (" + to_string(length) + ")";
314
+ if (show_length && data.length() > 4)
315
+ return ret + " (" + std::to_string(data.length()) + ")";
404
316
  return ret;
405
317
  }
406
- std::string format_hex_pretty(const std::vector<uint16_t> &data) { return format_hex_pretty(data.data(), data.size()); }
407
318
 
408
319
  std::string format_bin(const uint8_t *data, size_t length) {
409
320
  std::string result;
@@ -456,9 +367,22 @@ int8_t step_to_accuracy_decimals(float step) {
456
367
  return str.length() - dot_pos - 1;
457
368
  }
458
369
 
459
- static const std::string BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
460
- "abcdefghijklmnopqrstuvwxyz"
461
- "0123456789+/";
370
+ // Use C-style string constant to store in ROM instead of RAM (saves 24 bytes)
371
+ static constexpr const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
372
+ "abcdefghijklmnopqrstuvwxyz"
373
+ "0123456789+/";
374
+
375
+ // Helper function to find the index of a base64 character in the lookup table.
376
+ // Returns the character's position (0-63) if found, or 0 if not found.
377
+ // NOTE: This returns 0 for both 'A' (valid base64 char at index 0) and invalid characters.
378
+ // This is safe because is_base64() is ALWAYS checked before calling this function,
379
+ // preventing invalid characters from ever reaching here. The base64_decode function
380
+ // stops processing at the first invalid character due to the is_base64() check in its
381
+ // while loop condition, making this edge case harmless in practice.
382
+ static inline uint8_t base64_find_char(char c) {
383
+ const char *pos = strchr(BASE64_CHARS, c);
384
+ return pos ? (pos - BASE64_CHARS) : 0;
385
+ }
462
386
 
463
387
  static inline bool is_base64(char c) { return (isalnum(c) || (c == '+') || (c == '/')); }
464
388
 
@@ -480,7 +404,7 @@ std::string base64_encode(const uint8_t *buf, size_t buf_len) {
480
404
  char_array_4[3] = char_array_3[2] & 0x3f;
481
405
 
482
406
  for (i = 0; (i < 4); i++)
483
- ret += BASE64_CHARS[char_array_4[i]];
407
+ ret += BASE64_CHARS[static_cast<uint8_t>(char_array_4[i])];
484
408
  i = 0;
485
409
  }
486
410
  }
@@ -495,7 +419,7 @@ std::string base64_encode(const uint8_t *buf, size_t buf_len) {
495
419
  char_array_4[3] = char_array_3[2] & 0x3f;
496
420
 
497
421
  for (j = 0; (j < i + 1); j++)
498
- ret += BASE64_CHARS[char_array_4[j]];
422
+ ret += BASE64_CHARS[static_cast<uint8_t>(char_array_4[j])];
499
423
 
500
424
  while ((i++ < 3))
501
425
  ret += '=';
@@ -522,12 +446,15 @@ std::vector<uint8_t> base64_decode(const std::string &encoded_string) {
522
446
  uint8_t char_array_4[4], char_array_3[3];
523
447
  std::vector<uint8_t> ret;
524
448
 
449
+ // SAFETY: The loop condition checks is_base64() before processing each character.
450
+ // This ensures base64_find_char() is only called on valid base64 characters,
451
+ // preventing the edge case where invalid chars would return 0 (same as 'A').
525
452
  while (in_len-- && (encoded_string[in] != '=') && is_base64(encoded_string[in])) {
526
453
  char_array_4[i++] = encoded_string[in];
527
454
  in++;
528
455
  if (i == 4) {
529
456
  for (i = 0; i < 4; i++)
530
- char_array_4[i] = BASE64_CHARS.find(char_array_4[i]);
457
+ char_array_4[i] = base64_find_char(char_array_4[i]);
531
458
 
532
459
  char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
533
460
  char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
@@ -544,7 +471,7 @@ std::vector<uint8_t> base64_decode(const std::string &encoded_string) {
544
471
  char_array_4[j] = 0;
545
472
 
546
473
  for (j = 0; j < 4; j++)
547
- char_array_4[j] = BASE64_CHARS.find(char_array_4[j]);
474
+ char_array_4[j] = base64_find_char(char_array_4[j]);
548
475
 
549
476
  char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
550
477
  char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
@@ -640,35 +567,6 @@ void hsv_to_rgb(int hue, float saturation, float value, float &red, float &green
640
567
  blue += delta;
641
568
  }
642
569
 
643
- // System APIs
644
- #if defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_HOST)
645
- // ESP8266 doesn't have mutexes, but that shouldn't be an issue as it's single-core and non-preemptive OS.
646
- Mutex::Mutex() {}
647
- Mutex::~Mutex() {}
648
- void Mutex::lock() {}
649
- bool Mutex::try_lock() { return true; }
650
- void Mutex::unlock() {}
651
- #elif defined(USE_ESP32) || defined(USE_LIBRETINY)
652
- Mutex::Mutex() { handle_ = xSemaphoreCreateMutex(); }
653
- Mutex::~Mutex() {}
654
- void Mutex::lock() { xSemaphoreTake(this->handle_, portMAX_DELAY); }
655
- bool Mutex::try_lock() { return xSemaphoreTake(this->handle_, 0) == pdTRUE; }
656
- void Mutex::unlock() { xSemaphoreGive(this->handle_); }
657
- #endif
658
-
659
- #if defined(USE_ESP8266)
660
- IRAM_ATTR InterruptLock::InterruptLock() { state_ = xt_rsil(15); }
661
- IRAM_ATTR InterruptLock::~InterruptLock() { xt_wsr_ps(state_); }
662
- #elif defined(USE_ESP32) || defined(USE_LIBRETINY)
663
- // only affects the executing core
664
- // so should not be used as a mutex lock, only to get accurate timing
665
- IRAM_ATTR InterruptLock::InterruptLock() { portDISABLE_INTERRUPTS(); }
666
- IRAM_ATTR InterruptLock::~InterruptLock() { portENABLE_INTERRUPTS(); }
667
- #elif defined(USE_RP2040)
668
- IRAM_ATTR InterruptLock::InterruptLock() { state_ = save_and_disable_interrupts(); }
669
- IRAM_ATTR InterruptLock::~InterruptLock() { restore_interrupts(state_); }
670
- #endif
671
-
672
570
  uint8_t HighFrequencyLoopRequester::num_requests = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
673
571
  void HighFrequencyLoopRequester::start() {
674
572
  if (this->started_)
@@ -684,45 +582,6 @@ void HighFrequencyLoopRequester::stop() {
684
582
  }
685
583
  bool HighFrequencyLoopRequester::is_high_frequency() { return num_requests > 0; }
686
584
 
687
- #if defined(USE_HOST)
688
- void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
689
- static const uint8_t esphome_host_mac_address[6] = USE_ESPHOME_HOST_MAC_ADDRESS;
690
- memcpy(mac, esphome_host_mac_address, sizeof(esphome_host_mac_address));
691
- }
692
- #elif defined(USE_ESP32)
693
- void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
694
- #if defined(CONFIG_SOC_IEEE802154_SUPPORTED)
695
- // When CONFIG_SOC_IEEE802154_SUPPORTED is defined, esp_efuse_mac_get_default
696
- // returns the 802.15.4 EUI-64 address, so we read directly from eFuse instead.
697
- if (has_custom_mac_address()) {
698
- esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM, mac, 48);
699
- } else {
700
- esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, mac, 48);
701
- }
702
- #else
703
- if (has_custom_mac_address()) {
704
- esp_efuse_mac_get_custom(mac);
705
- } else {
706
- esp_efuse_mac_get_default(mac);
707
- }
708
- #endif
709
- }
710
- #elif defined(USE_ESP8266)
711
- void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
712
- wifi_get_macaddr(STATION_IF, mac);
713
- }
714
- #elif defined(USE_RP2040)
715
- void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
716
- #ifdef USE_WIFI
717
- WiFi.macAddress(mac);
718
- #endif
719
- }
720
- #elif defined(USE_LIBRETINY)
721
- void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
722
- WiFi.macAddress(mac);
723
- }
724
- #endif
725
-
726
585
  std::string get_mac_address() {
727
586
  uint8_t mac[6];
728
587
  get_mac_address_raw(mac);
@@ -732,26 +591,12 @@ std::string get_mac_address() {
732
591
  std::string get_mac_address_pretty() {
733
592
  uint8_t mac[6];
734
593
  get_mac_address_raw(mac);
735
- return str_snprintf("%02X:%02X:%02X:%02X:%02X:%02X", 17, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
594
+ return format_mac_address_pretty(mac);
736
595
  }
737
596
 
738
- #ifdef USE_ESP32
739
- void set_mac_address(uint8_t *mac) { esp_base_mac_addr_set(mac); }
740
- #endif
741
-
742
- bool has_custom_mac_address() {
743
- #if defined(USE_ESP32) && !defined(USE_ESP32_IGNORE_EFUSE_CUSTOM_MAC)
744
- uint8_t mac[6];
745
- // do not use 'esp_efuse_mac_get_custom(mac)' because it drops an error in the logs whenever it fails
746
- #ifndef USE_ESP32_VARIANT_ESP32
747
- return (esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA_MAC_CUSTOM, mac, 48) == ESP_OK) && mac_address_is_valid(mac);
748
- #else
749
- return (esp_efuse_read_field_blob(ESP_EFUSE_MAC_CUSTOM, mac, 48) == ESP_OK) && mac_address_is_valid(mac);
750
- #endif
751
- #else
752
- return false;
597
+ #ifndef USE_ESP32
598
+ bool has_custom_mac_address() { return false; }
753
599
  #endif
754
- }
755
600
 
756
601
  bool mac_address_is_valid(const uint8_t *mac) {
757
602
  bool is_all_zeros = true;