esphome 2025.9.3__py3-none-any.whl → 2025.10.0b1__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 (343) hide show
  1. esphome/__main__.py +87 -31
  2. esphome/address_cache.py +142 -0
  3. esphome/automation.py +130 -32
  4. esphome/build_gen/platformio.py +1 -3
  5. esphome/codegen.py +1 -0
  6. esphome/components/animation/animation.cpp +2 -2
  7. esphome/components/api/__init__.py +166 -3
  8. esphome/components/api/api_connection.cpp +84 -41
  9. esphome/components/api/api_connection.h +22 -16
  10. esphome/components/api/api_frame_helper.cpp +33 -19
  11. esphome/components/api/api_frame_helper.h +19 -4
  12. esphome/components/api/api_frame_helper_noise.cpp +41 -53
  13. esphome/components/api/api_frame_helper_noise.h +1 -1
  14. esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
  15. esphome/components/api/api_frame_helper_plaintext.h +1 -1
  16. esphome/components/api/api_pb2.cpp +189 -15
  17. esphome/components/api/api_pb2.h +132 -20
  18. esphome/components/api/api_pb2_dump.cpp +97 -9
  19. esphome/components/api/api_pb2_service.cpp +118 -160
  20. esphome/components/api/api_pb2_service.h +31 -3
  21. esphome/components/api/api_server.cpp +68 -10
  22. esphome/components/api/api_server.h +32 -4
  23. esphome/components/api/custom_api_device.h +8 -8
  24. esphome/components/api/homeassistant_service.h +123 -6
  25. esphome/components/api/proto.h +6 -2
  26. esphome/components/api/user_services.h +2 -2
  27. esphome/components/as7341/sensor.py +1 -1
  28. esphome/components/audio/__init__.py +1 -1
  29. esphome/components/audio/audio.cpp +1 -1
  30. esphome/components/audio/audio_decoder.cpp +9 -9
  31. esphome/components/bl0906/bl0906.cpp +2 -2
  32. esphome/components/bl0942/bl0942.cpp +2 -2
  33. esphome/components/ble_client/__init__.py +1 -1
  34. esphome/components/bluetooth_proxy/__init__.py +4 -30
  35. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
  36. esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
  37. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
  38. esphome/components/camera_encoder/__init__.py +2 -4
  39. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
  40. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
  41. esphome/components/canbus/canbus.cpp +7 -5
  42. esphome/components/canbus/canbus.h +4 -4
  43. esphome/components/captive_portal/__init__.py +18 -1
  44. esphome/components/captive_portal/captive_portal.cpp +40 -46
  45. esphome/components/captive_portal/captive_portal.h +20 -22
  46. esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
  47. esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
  48. esphome/components/ccs811/ccs811.cpp +1 -1
  49. esphome/components/climate/climate.cpp +10 -7
  50. esphome/components/cm1106/cm1106.cpp +1 -1
  51. esphome/components/copy/lock/copy_lock.cpp +1 -1
  52. esphome/components/cover/cover.cpp +1 -0
  53. esphome/components/daikin_arc/daikin_arc.cpp +19 -12
  54. esphome/components/deep_sleep/__init__.py +9 -2
  55. esphome/components/deep_sleep/deep_sleep_component.h +11 -9
  56. esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
  57. esphome/components/ektf2232/touchscreen/__init__.py +8 -5
  58. esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
  59. esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
  60. esphome/components/epaper_spi/__init__.py +1 -0
  61. esphome/components/epaper_spi/display.py +80 -0
  62. esphome/components/epaper_spi/epaper_spi.cpp +227 -0
  63. esphome/components/epaper_spi/epaper_spi.h +93 -0
  64. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
  65. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
  66. esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
  67. esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
  68. esphome/components/es7210/es7210.cpp +3 -3
  69. esphome/components/esp32/__init__.py +254 -339
  70. esphome/components/esp32/boards.py +81 -0
  71. esphome/components/esp32/preferences.cpp +23 -17
  72. esphome/components/esp32_ble/__init__.py +159 -44
  73. esphome/components/esp32_ble/ble.cpp +47 -3
  74. esphome/components/esp32_ble/ble.h +18 -0
  75. esphome/components/esp32_ble/ble_advertising.cpp +7 -3
  76. esphome/components/esp32_ble/ble_advertising.h +4 -0
  77. esphome/components/esp32_ble/ble_uuid.cpp +16 -42
  78. esphome/components/esp32_ble_beacon/__init__.py +3 -4
  79. esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
  80. esphome/components/esp32_ble_server/__init__.py +28 -14
  81. esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
  82. esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
  83. esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
  84. esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
  85. esphome/components/esp32_ble_server/ble_server.cpp +59 -24
  86. esphome/components/esp32_ble_server/ble_server.h +38 -20
  87. esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
  88. esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
  89. esphome/components/esp32_ble_tracker/__init__.py +25 -80
  90. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -4
  91. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
  92. esphome/components/esp32_camera/__init__.py +1 -3
  93. esphome/components/esp32_can/esp32_can.cpp +22 -4
  94. esphome/components/esp32_can/esp32_can.h +3 -0
  95. esphome/components/esp32_hosted/__init__.py +2 -1
  96. esphome/components/esp32_improv/esp32_improv_component.cpp +102 -44
  97. esphome/components/esp32_improv/esp32_improv_component.h +6 -1
  98. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  99. esphome/components/esp8266/__init__.py +3 -3
  100. esphome/components/esphome/ota/__init__.py +21 -2
  101. esphome/components/esphome/ota/ota_esphome.cpp +455 -145
  102. esphome/components/esphome/ota/ota_esphome.h +49 -2
  103. esphome/components/ethernet/__init__.py +39 -22
  104. esphome/components/ethernet/ethernet_component.cpp +28 -5
  105. esphome/components/ethernet/ethernet_component.h +5 -1
  106. esphome/components/external_components/__init__.py +8 -6
  107. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  108. esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
  109. esphome/components/font/__init__.py +5 -5
  110. esphome/components/graph/graph.cpp +1 -1
  111. esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
  112. esphome/components/haier/hon_climate.cpp +2 -2
  113. esphome/components/haier/hon_climate.h +1 -1
  114. esphome/components/hdc1080/hdc1080.cpp +42 -34
  115. esphome/components/hdc1080/hdc1080.h +1 -3
  116. esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
  117. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  118. esphome/components/http_request/__init__.py +3 -3
  119. esphome/components/htu21d/htu21d.cpp +13 -18
  120. esphome/components/htu21d/htu21d.h +1 -1
  121. esphome/components/i2s_audio/__init__.py +1 -2
  122. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  123. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
  124. esphome/components/improv_serial/improv_serial_component.cpp +12 -15
  125. esphome/components/improv_serial/improv_serial_component.h +6 -8
  126. esphome/components/json/json_util.cpp +35 -43
  127. esphome/components/json/json_util.h +57 -0
  128. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
  129. esphome/components/key_collector/key_collector.h +4 -4
  130. esphome/components/libretiny/__init__.py +6 -6
  131. esphome/components/libretiny/preferences.cpp +23 -16
  132. esphome/components/light/light_call.cpp +98 -120
  133. esphome/components/light/light_call.h +17 -7
  134. esphome/components/lm75b/__init__.py +0 -0
  135. esphome/components/lm75b/lm75b.cpp +39 -0
  136. esphome/components/lm75b/lm75b.h +19 -0
  137. esphome/components/lm75b/sensor.py +34 -0
  138. esphome/components/lock/lock.h +12 -6
  139. esphome/components/logger/__init__.py +15 -27
  140. esphome/components/logger/logger.cpp +10 -20
  141. esphome/components/logger/logger.h +105 -62
  142. esphome/components/logger/logger_esp32.cpp +0 -48
  143. esphome/components/logger/logger_zephyr.cpp +2 -3
  144. esphome/components/logger/select/logger_level_select.cpp +6 -7
  145. esphome/components/logger/select/logger_level_select.h +7 -0
  146. esphome/components/ltr501/ltr501.cpp +7 -6
  147. esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
  148. esphome/components/matrix_keypad/matrix_keypad.h +4 -4
  149. esphome/components/max7219digit/max7219digit.cpp +1 -1
  150. esphome/components/mcp2515/mcp2515.cpp +31 -3
  151. esphome/components/mcp2515/mcp2515_defs.h +3 -1
  152. esphome/components/md5/md5.cpp +0 -26
  153. esphome/components/md5/md5.h +10 -20
  154. esphome/components/mdns/__init__.py +19 -6
  155. esphome/components/mdns/mdns_component.cpp +27 -59
  156. esphome/components/mdns/mdns_component.h +23 -10
  157. esphome/components/mdns/mdns_esp32.cpp +7 -7
  158. esphome/components/mdns/mdns_esp8266.cpp +6 -6
  159. esphome/components/mdns/mdns_libretiny.cpp +3 -3
  160. esphome/components/mdns/mdns_rp2040.cpp +3 -3
  161. esphome/components/mipi/__init__.py +1 -5
  162. esphome/components/mipi_spi/display.py +24 -8
  163. esphome/components/mipi_spi/mipi_spi.h +3 -3
  164. esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
  165. esphome/components/mmc5603/mmc5603.cpp +3 -3
  166. esphome/components/modbus/modbus.cpp +27 -13
  167. esphome/components/modbus/modbus.h +5 -3
  168. esphome/components/modbus/modbus_definitions.h +86 -0
  169. esphome/components/modbus_controller/__init__.py +29 -1
  170. esphome/components/modbus_controller/const.py +4 -0
  171. esphome/components/modbus_controller/modbus_controller.cpp +38 -13
  172. esphome/components/modbus_controller/modbus_controller.h +18 -29
  173. esphome/components/mpr121/mpr121.cpp +41 -42
  174. esphome/components/mpr121/mpr121.h +0 -1
  175. esphome/components/nau7802/nau7802.cpp +2 -2
  176. esphome/components/network/__init__.py +7 -3
  177. esphome/components/nextion/display.py +4 -4
  178. esphome/components/nextion/nextion.cpp +8 -8
  179. esphome/components/number/__init__.py +2 -0
  180. esphome/components/number/number_call.cpp +23 -12
  181. esphome/components/number/number_call.h +5 -0
  182. esphome/components/online_image/bmp_image.cpp +2 -1
  183. esphome/components/online_image/jpeg_image.cpp +4 -2
  184. esphome/components/openthread/openthread.cpp +6 -7
  185. esphome/components/openthread/openthread.h +0 -1
  186. esphome/components/ota/ota_backend.h +1 -0
  187. esphome/components/packages/__init__.py +10 -8
  188. esphome/components/packet_transport/packet_transport.cpp +2 -0
  189. esphome/components/pid/pid_controller.cpp +1 -1
  190. esphome/components/prometheus/prometheus_handler.cpp +239 -239
  191. esphome/components/psram/__init__.py +30 -28
  192. esphome/components/qmc5883l/qmc5883l.cpp +15 -0
  193. esphome/components/qmc5883l/qmc5883l.h +3 -0
  194. esphome/components/qmc5883l/sensor.py +31 -12
  195. esphome/components/remote_base/gobox_protocol.cpp +3 -3
  196. esphome/components/remote_receiver/__init__.py +14 -2
  197. esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
  198. esphome/components/remote_receiver/remote_receiver.h +4 -0
  199. esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
  200. esphome/components/remote_transmitter/__init__.py +2 -2
  201. esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
  202. esphome/components/rp2040/__init__.py +11 -11
  203. esphome/components/rtttl/rtttl.cpp +2 -2
  204. esphome/components/scd30/sensor.py +1 -1
  205. esphome/components/script/__init__.py +1 -1
  206. esphome/components/script/script.h +7 -7
  207. esphome/components/select/select.cpp +5 -4
  208. esphome/components/select/select_call.cpp +1 -1
  209. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  210. esphome/components/sensor/__init__.py +2 -0
  211. esphome/components/sha256/__init__.py +22 -0
  212. esphome/components/sha256/sha256.cpp +116 -0
  213. esphome/components/sha256/sha256.h +60 -0
  214. esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
  215. esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
  216. esphome/components/spi/__init__.py +0 -3
  217. esphome/components/split_buffer/__init__.py +5 -0
  218. esphome/components/split_buffer/split_buffer.cpp +133 -0
  219. esphome/components/split_buffer/split_buffer.h +40 -0
  220. esphome/components/sps30/sps30.cpp +14 -10
  221. esphome/components/sps30/sps30.h +2 -0
  222. esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
  223. esphome/components/st7789v/st7789v.cpp +3 -2
  224. esphome/components/statsd/statsd.cpp +1 -1
  225. esphome/components/substitutions/__init__.py +3 -1
  226. esphome/components/substitutions/jinja.py +13 -3
  227. esphome/components/sx126x/__init__.py +16 -0
  228. esphome/components/sx126x/sx126x.cpp +15 -1
  229. esphome/components/sx126x/sx126x.h +9 -1
  230. esphome/components/sx126x/sx126x_reg.h +2 -0
  231. esphome/components/text_sensor/text_sensor.cpp +16 -0
  232. esphome/components/text_sensor/text_sensor.h +3 -10
  233. esphome/components/tormatic/tormatic_cover.cpp +1 -1
  234. esphome/components/tuya/select/tuya_select.cpp +1 -1
  235. esphome/components/tuya/tuya.cpp +29 -4
  236. esphome/components/uart/__init__.py +36 -26
  237. esphome/components/uart/uart.h +6 -0
  238. esphome/components/uart/uart_component.cpp +8 -0
  239. esphome/components/uart/uart_component.h +28 -0
  240. esphome/components/uart/uart_component_esp_idf.cpp +64 -10
  241. esphome/components/uart/uart_component_esp_idf.h +5 -2
  242. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  243. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
  244. esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
  245. esphome/components/usb_host/__init__.py +2 -1
  246. esphome/components/usb_host/usb_host.h +82 -13
  247. esphome/components/usb_host/usb_host_client.cpp +180 -24
  248. esphome/components/usb_host/usb_host_component.cpp +1 -1
  249. esphome/components/usb_uart/__init__.py +0 -1
  250. esphome/components/usb_uart/ch34x.cpp +4 -4
  251. esphome/components/usb_uart/cp210x.cpp +3 -3
  252. esphome/components/usb_uart/usb_uart.cpp +88 -32
  253. esphome/components/usb_uart/usb_uart.h +30 -6
  254. esphome/components/valve/valve.cpp +1 -0
  255. esphome/components/veml7700/veml7700.cpp +7 -6
  256. esphome/components/version/version_text_sensor.cpp +2 -1
  257. esphome/components/voice_assistant/voice_assistant.cpp +3 -2
  258. esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
  259. esphome/components/web_server/list_entities.cpp +3 -4
  260. esphome/components/web_server/list_entities.h +8 -10
  261. esphome/components/web_server/ota/__init__.py +1 -1
  262. esphome/components/web_server/ota/ota_web_server.cpp +9 -3
  263. esphome/components/web_server/web_server.cpp +509 -404
  264. esphome/components/web_server/web_server.h +5 -6
  265. esphome/components/web_server/web_server_v1.cpp +21 -19
  266. esphome/components/web_server_base/__init__.py +5 -2
  267. esphome/components/web_server_base/web_server_base.h +27 -7
  268. esphome/components/web_server_idf/__init__.py +1 -1
  269. esphome/components/web_server_idf/multipart.cpp +2 -2
  270. esphome/components/web_server_idf/multipart.h +2 -2
  271. esphome/components/web_server_idf/utils.cpp +2 -2
  272. esphome/components/web_server_idf/utils.h +2 -2
  273. esphome/components/web_server_idf/web_server_idf.cpp +118 -26
  274. esphome/components/web_server_idf/web_server_idf.h +12 -10
  275. esphome/components/wifi/__init__.py +13 -11
  276. esphome/components/wifi/wifi_component.cpp +73 -56
  277. esphome/components/wifi/wifi_component.h +4 -4
  278. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  279. esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
  280. esphome/components/wireguard/__init__.py +1 -1
  281. esphome/components/wts01/__init__.py +0 -0
  282. esphome/components/wts01/sensor.py +41 -0
  283. esphome/components/wts01/wts01.cpp +91 -0
  284. esphome/components/wts01/wts01.h +27 -0
  285. esphome/components/zephyr/__init__.py +5 -5
  286. esphome/components/zwave_proxy/__init__.py +43 -0
  287. esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
  288. esphome/components/zwave_proxy/zwave_proxy.h +93 -0
  289. esphome/config.py +79 -24
  290. esphome/config_validation.py +13 -15
  291. esphome/const.py +9 -2
  292. esphome/core/__init__.py +31 -22
  293. esphome/core/component.cpp +28 -18
  294. esphome/core/component_iterator.h +2 -1
  295. esphome/core/config.py +15 -15
  296. esphome/core/defines.h +19 -0
  297. esphome/core/hash_base.h +56 -0
  298. esphome/core/helpers.cpp +19 -3
  299. esphome/core/helpers.h +26 -0
  300. esphome/core/scheduler.cpp +5 -21
  301. esphome/core/scheduler.h +19 -8
  302. esphome/core/string_ref.h +1 -1
  303. esphome/core/time.cpp +5 -5
  304. esphome/cpp_generator.py +4 -29
  305. esphome/dashboard/const.py +21 -4
  306. esphome/dashboard/core.py +10 -8
  307. esphome/dashboard/dns.py +15 -0
  308. esphome/dashboard/entries.py +15 -21
  309. esphome/dashboard/models.py +76 -0
  310. esphome/dashboard/settings.py +7 -7
  311. esphome/dashboard/status/mdns.py +46 -2
  312. esphome/dashboard/web_server.py +367 -93
  313. esphome/espota2.py +111 -31
  314. esphome/external_files.py +6 -7
  315. esphome/git.py +8 -0
  316. esphome/helpers.py +124 -77
  317. esphome/loader.py +8 -9
  318. esphome/platformio_api.py +25 -18
  319. esphome/storage_json.py +26 -21
  320. esphome/types.py +30 -2
  321. esphome/util.py +32 -16
  322. esphome/vscode.py +8 -8
  323. esphome/wizard.py +10 -10
  324. esphome/writer.py +50 -15
  325. esphome/yaml_util.py +37 -31
  326. esphome/zeroconf.py +12 -3
  327. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/METADATA +11 -11
  328. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/RECORD +332 -312
  329. esphome/components/event_emitter/__init__.py +0 -5
  330. esphome/components/event_emitter/event_emitter.cpp +0 -14
  331. esphome/components/event_emitter/event_emitter.h +0 -63
  332. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
  333. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
  334. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
  335. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
  336. esphome/components/uart/uart_component_esp32_arduino.h +0 -60
  337. esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
  338. esphome/core/string_ref.cpp +0 -12
  339. esphome/dashboard/util/file.py +0 -63
  340. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/WHEEL +0 -0
  341. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/entry_points.txt +0 -0
  342. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/licenses/LICENSE +0 -0
  343. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/top_level.txt +0 -0
@@ -34,11 +34,12 @@ size_t Select::size() const {
34
34
 
35
35
  optional<size_t> Select::index_of(const std::string &option) const {
36
36
  const auto &options = traits.get_options();
37
- auto it = std::find(options.begin(), options.end(), option);
38
- if (it == options.end()) {
39
- return {};
37
+ for (size_t i = 0; i < options.size(); i++) {
38
+ if (options[i] == option) {
39
+ return i;
40
+ }
40
41
  }
41
- return std::distance(options.begin(), it);
42
+ return {};
42
43
  }
43
44
 
44
45
  optional<size_t> Select::active_index() const {
@@ -107,7 +107,7 @@ void SelectCall::perform() {
107
107
  }
108
108
  }
109
109
 
110
- if (std::find(options.begin(), options.end(), target_value) == options.end()) {
110
+ if (!parent->has_option(target_value)) {
111
111
  ESP_LOGW(TAG, "'%s' - Option %s is not a valid option", name, target_value.c_str());
112
112
  return;
113
113
  }
@@ -76,7 +76,8 @@ bool SensirionI2CDevice::write_command_(uint16_t command, CommandLen command_len
76
76
  temp[raw_idx++] = data[i] >> 8;
77
77
  #endif
78
78
  // Use MSB first since Sensirion devices use CRC-8 with MSB first
79
- temp[raw_idx++] = crc8(&temp[raw_idx - 2], 2, 0xFF, CRC_POLYNOMIAL, true);
79
+ uint8_t crc = crc8(&temp[raw_idx - 2], 2, 0xFF, CRC_POLYNOMIAL, true);
80
+ temp[raw_idx++] = crc;
80
81
  }
81
82
  this->last_error_ = this->write(temp, raw_idx);
82
83
  return this->last_error_ == i2c::ERROR_OK;
@@ -74,6 +74,7 @@ from esphome.const import (
74
74
  DEVICE_CLASS_OZONE,
75
75
  DEVICE_CLASS_PH,
76
76
  DEVICE_CLASS_PM1,
77
+ DEVICE_CLASS_PM4,
77
78
  DEVICE_CLASS_PM10,
78
79
  DEVICE_CLASS_PM25,
79
80
  DEVICE_CLASS_POWER,
@@ -143,6 +144,7 @@ DEVICE_CLASSES = [
143
144
  DEVICE_CLASS_PM1,
144
145
  DEVICE_CLASS_PM10,
145
146
  DEVICE_CLASS_PM25,
147
+ DEVICE_CLASS_PM4,
146
148
  DEVICE_CLASS_POWER,
147
149
  DEVICE_CLASS_POWER_FACTOR,
148
150
  DEVICE_CLASS_PRECIPITATION,
@@ -0,0 +1,22 @@
1
+ import esphome.codegen as cg
2
+ import esphome.config_validation as cv
3
+ from esphome.core import CORE
4
+ from esphome.helpers import IS_MACOS
5
+ from esphome.types import ConfigType
6
+
7
+ CODEOWNERS = ["@esphome/core"]
8
+
9
+ sha256_ns = cg.esphome_ns.namespace("sha256")
10
+
11
+ CONFIG_SCHEMA = cv.Schema({})
12
+
13
+
14
+ async def to_code(config: ConfigType) -> None:
15
+ # Add OpenSSL library for host platform
16
+ if not CORE.is_host:
17
+ return
18
+ if IS_MACOS:
19
+ # macOS needs special handling for Homebrew OpenSSL
20
+ cg.add_build_flag("-I/opt/homebrew/opt/openssl/include")
21
+ cg.add_build_flag("-L/opt/homebrew/opt/openssl/lib")
22
+ cg.add_build_flag("-lcrypto")
@@ -0,0 +1,116 @@
1
+ #include "sha256.h"
2
+
3
+ // Only compile SHA256 implementation on platforms that support it
4
+ #if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_HOST)
5
+
6
+ #include "esphome/core/helpers.h"
7
+ #include <cstring>
8
+
9
+ namespace esphome::sha256 {
10
+
11
+ #if defined(USE_ESP32) || defined(USE_LIBRETINY)
12
+
13
+ // CRITICAL ESP32-S3 HARDWARE SHA ACCELERATION REQUIREMENTS:
14
+ //
15
+ // The ESP32-S3 uses hardware DMA for SHA acceleration. The mbedtls_sha256_context structure contains
16
+ // internal state that the DMA engine references. This imposes two critical constraints:
17
+ //
18
+ // 1. NO VARIABLE LENGTH ARRAYS (VLAs): VLAs corrupt the stack layout, causing the DMA engine to
19
+ // write to incorrect memory locations. This results in null pointer dereferences and crashes.
20
+ // ALWAYS use fixed-size arrays (e.g., char buf[65], not char buf[size+1]).
21
+ //
22
+ // 2. SAME STACK FRAME ONLY: The SHA256 object must be created and used entirely within the same
23
+ // function. NEVER pass the SHA256 object or HashBase pointer to another function. When the stack
24
+ // frame changes (function call/return), the DMA references become invalid and will produce
25
+ // truncated hash output (20 bytes instead of 32) or corrupt memory.
26
+ //
27
+ // CORRECT USAGE:
28
+ // void my_function() {
29
+ // sha256::SHA256 hasher; // Created locally
30
+ // hasher.init();
31
+ // hasher.add(data, len); // Any size, no chunking needed
32
+ // hasher.calculate();
33
+ // bool ok = hasher.equals_hex(expected);
34
+ // // hasher destroyed when function returns
35
+ // }
36
+ //
37
+ // INCORRECT USAGE (WILL FAIL ON ESP32-S3):
38
+ // void my_function() {
39
+ // sha256::SHA256 hasher;
40
+ // helper(&hasher); // WRONG: Passed to different stack frame
41
+ // }
42
+ // void helper(HashBase *h) {
43
+ // h->init(); // WRONG: Will produce truncated/corrupted output
44
+ // }
45
+
46
+ SHA256::~SHA256() { mbedtls_sha256_free(&this->ctx_); }
47
+
48
+ void SHA256::init() {
49
+ mbedtls_sha256_init(&this->ctx_);
50
+ mbedtls_sha256_starts(&this->ctx_, 0); // 0 = SHA256, not SHA224
51
+ }
52
+
53
+ void SHA256::add(const uint8_t *data, size_t len) { mbedtls_sha256_update(&this->ctx_, data, len); }
54
+
55
+ void SHA256::calculate() { mbedtls_sha256_finish(&this->ctx_, this->digest_); }
56
+
57
+ #elif defined(USE_ESP8266) || defined(USE_RP2040)
58
+
59
+ SHA256::~SHA256() = default;
60
+
61
+ void SHA256::init() {
62
+ br_sha256_init(&this->ctx_);
63
+ this->calculated_ = false;
64
+ }
65
+
66
+ void SHA256::add(const uint8_t *data, size_t len) { br_sha256_update(&this->ctx_, data, len); }
67
+
68
+ void SHA256::calculate() {
69
+ if (!this->calculated_) {
70
+ br_sha256_out(&this->ctx_, this->digest_);
71
+ this->calculated_ = true;
72
+ }
73
+ }
74
+
75
+ #elif defined(USE_HOST)
76
+
77
+ SHA256::~SHA256() {
78
+ if (this->ctx_) {
79
+ EVP_MD_CTX_free(this->ctx_);
80
+ }
81
+ }
82
+
83
+ void SHA256::init() {
84
+ if (this->ctx_) {
85
+ EVP_MD_CTX_free(this->ctx_);
86
+ }
87
+ this->ctx_ = EVP_MD_CTX_new();
88
+ EVP_DigestInit_ex(this->ctx_, EVP_sha256(), nullptr);
89
+ this->calculated_ = false;
90
+ }
91
+
92
+ void SHA256::add(const uint8_t *data, size_t len) {
93
+ if (!this->ctx_) {
94
+ this->init();
95
+ }
96
+ EVP_DigestUpdate(this->ctx_, data, len);
97
+ }
98
+
99
+ void SHA256::calculate() {
100
+ if (!this->ctx_) {
101
+ this->init();
102
+ }
103
+ if (!this->calculated_) {
104
+ unsigned int len = 32;
105
+ EVP_DigestFinal_ex(this->ctx_, this->digest_, &len);
106
+ this->calculated_ = true;
107
+ }
108
+ }
109
+
110
+ #else
111
+ #error "SHA256 not supported on this platform"
112
+ #endif
113
+
114
+ } // namespace esphome::sha256
115
+
116
+ #endif // Platform check
@@ -0,0 +1,60 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/defines.h"
4
+
5
+ // Only define SHA256 on platforms that support it
6
+ #if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_HOST)
7
+
8
+ #include <cstdint>
9
+ #include <string>
10
+ #include <memory>
11
+ #include "esphome/core/hash_base.h"
12
+
13
+ #if defined(USE_ESP32) || defined(USE_LIBRETINY)
14
+ #include "mbedtls/sha256.h"
15
+ #elif defined(USE_ESP8266) || defined(USE_RP2040)
16
+ #include <bearssl/bearssl_hash.h>
17
+ #elif defined(USE_HOST)
18
+ #include <openssl/evp.h>
19
+ #else
20
+ #error "SHA256 not supported on this platform"
21
+ #endif
22
+
23
+ namespace esphome::sha256 {
24
+
25
+ class SHA256 : public esphome::HashBase {
26
+ public:
27
+ SHA256() = default;
28
+ ~SHA256() override;
29
+
30
+ void init() override;
31
+ void add(const uint8_t *data, size_t len) override;
32
+ using HashBase::add; // Bring base class overload into scope
33
+ void add(const std::string &data) { this->add((const uint8_t *) data.c_str(), data.length()); }
34
+
35
+ void calculate() override;
36
+
37
+ /// Get the size of the hash in bytes (32 for SHA256)
38
+ size_t get_size() const override { return 32; }
39
+
40
+ protected:
41
+ #if defined(USE_ESP32) || defined(USE_LIBRETINY)
42
+ // CRITICAL: The mbedtls context MUST be stack-allocated (not a pointer) for ESP32-S3 hardware SHA acceleration.
43
+ // The ESP32-S3 DMA engine references this structure's memory addresses. If the context is passed to another
44
+ // function (crossing stack frames) or if VLAs are present, the DMA operations will corrupt memory and produce
45
+ // truncated/incorrect hash results.
46
+ mbedtls_sha256_context ctx_{};
47
+ #elif defined(USE_ESP8266) || defined(USE_RP2040)
48
+ br_sha256_context ctx_{};
49
+ bool calculated_{false};
50
+ #elif defined(USE_HOST)
51
+ EVP_MD_CTX *ctx_{nullptr};
52
+ bool calculated_{false};
53
+ #else
54
+ #error "SHA256 not supported on this platform"
55
+ #endif
56
+ };
57
+
58
+ } // namespace esphome::sha256
59
+
60
+ #endif // Platform check
@@ -9,7 +9,7 @@
9
9
  #include "lwip/tcp.h"
10
10
  #include <cerrno>
11
11
  #include <cstring>
12
- #include <queue>
12
+ #include <array>
13
13
 
14
14
  #include "esphome/core/helpers.h"
15
15
  #include "esphome/core/log.h"
@@ -50,12 +50,18 @@ class LWIPRawImpl : public Socket {
50
50
  errno = EBADF;
51
51
  return nullptr;
52
52
  }
53
- if (accepted_sockets_.empty()) {
53
+ if (this->accepted_socket_count_ == 0) {
54
54
  errno = EWOULDBLOCK;
55
55
  return nullptr;
56
56
  }
57
- std::unique_ptr<LWIPRawImpl> sock = std::move(accepted_sockets_.front());
58
- accepted_sockets_.pop();
57
+ // Take from front for FIFO ordering
58
+ std::unique_ptr<LWIPRawImpl> sock = std::move(this->accepted_sockets_[0]);
59
+ // Shift remaining sockets forward
60
+ for (uint8_t i = 1; i < this->accepted_socket_count_; i++) {
61
+ this->accepted_sockets_[i - 1] = std::move(this->accepted_sockets_[i]);
62
+ }
63
+ this->accepted_socket_count_--;
64
+ LWIP_LOG("Connection accepted by application, queue size: %d", this->accepted_socket_count_);
59
65
  if (addr != nullptr) {
60
66
  sock->getpeername(addr, addrlen);
61
67
  }
@@ -494,9 +500,18 @@ class LWIPRawImpl : public Socket {
494
500
  // nothing to do here, we just don't push it to the queue
495
501
  return ERR_OK;
496
502
  }
503
+ // Check if we've reached the maximum accept queue size
504
+ if (this->accepted_socket_count_ >= MAX_ACCEPTED_SOCKETS) {
505
+ LWIP_LOG("Rejecting connection, queue full (%d)", this->accepted_socket_count_);
506
+ // Abort the connection when queue is full
507
+ tcp_abort(newpcb);
508
+ // Must return ERR_ABRT since we called tcp_abort()
509
+ return ERR_ABRT;
510
+ }
497
511
  auto sock = make_unique<LWIPRawImpl>(family_, newpcb);
498
512
  sock->init();
499
- accepted_sockets_.push(std::move(sock));
513
+ this->accepted_sockets_[this->accepted_socket_count_++] = std::move(sock);
514
+ LWIP_LOG("Accepted connection, queue size: %d", this->accepted_socket_count_);
500
515
  return ERR_OK;
501
516
  }
502
517
  void err_fn(err_t err) {
@@ -587,7 +602,20 @@ class LWIPRawImpl : public Socket {
587
602
  }
588
603
 
589
604
  struct tcp_pcb *pcb_;
590
- std::queue<std::unique_ptr<LWIPRawImpl>> accepted_sockets_;
605
+ // Accept queue - holds incoming connections briefly until the event loop calls accept()
606
+ // This is NOT a connection pool - just a temporary queue between LWIP callbacks and the main loop
607
+ // 3 slots is plenty since connections are pulled out quickly by the event loop
608
+ //
609
+ // Memory analysis: std::array<3> vs original std::queue implementation:
610
+ // - std::queue uses std::deque internally which on 32-bit systems needs:
611
+ // 24 bytes (deque object) + 32+ bytes (map array) + heap allocations
612
+ // Total: ~56+ bytes minimum, plus heap fragmentation
613
+ // - std::array<3>: 12 bytes fixed (3 pointers × 4 bytes)
614
+ // Saves ~44+ bytes RAM per listening socket + avoids ALL heap allocations
615
+ // Used on ESP8266 and RP2040 (platforms using LWIP_TCP implementation)
616
+ static constexpr size_t MAX_ACCEPTED_SOCKETS = 3;
617
+ std::array<std::unique_ptr<LWIPRawImpl>, MAX_ACCEPTED_SOCKETS> accepted_sockets_;
618
+ uint8_t accepted_socket_count_ = 0; // Number of sockets currently in queue
591
619
  bool rx_closed_ = false;
592
620
  pbuf *rx_buf_ = nullptr;
593
621
  size_t rx_buf_offset_ = 0;
@@ -50,7 +50,7 @@ static const char *const TAG = "sonoff_d1";
50
50
 
51
51
  uint8_t SonoffD1Output::calc_checksum_(const uint8_t *cmd, const size_t len) {
52
52
  uint8_t crc = 0;
53
- for (int i = 2; i < len - 1; i++) {
53
+ for (size_t i = 2; i < len - 1; i++) {
54
54
  crc += cmd[i];
55
55
  }
56
56
  return crc;
@@ -276,9 +276,6 @@ def get_spi_interface(index):
276
276
  return ["&SPI", "&SPI1"][index]
277
277
  if index == 0:
278
278
  return "&SPI"
279
- # Following code can't apply to C2, H2 or 8266 since they have only one SPI
280
- if get_target_variant() in (VARIANT_ESP32S3, VARIANT_ESP32S2):
281
- return "new SPIClass(FSPI)"
282
279
  return "new SPIClass(HSPI)"
283
280
 
284
281
 
@@ -0,0 +1,5 @@
1
+ CODEOWNERS = ["@jesserockz"]
2
+
3
+ # Allows split_buffer to be configured in yaml, to allow use of the C++ api.
4
+
5
+ CONFIG_SCHEMA = {}
@@ -0,0 +1,133 @@
1
+ #include "split_buffer.h"
2
+
3
+ #include "esphome/core/helpers.h"
4
+ #include "esphome/core/log.h"
5
+
6
+ namespace esphome::split_buffer {
7
+
8
+ static constexpr const char *const TAG = "split_buffer";
9
+
10
+ SplitBuffer::~SplitBuffer() { this->free(); }
11
+
12
+ bool SplitBuffer::init(size_t total_length) {
13
+ this->free(); // Clean up any existing allocation
14
+
15
+ if (total_length == 0) {
16
+ return false;
17
+ }
18
+
19
+ this->total_length_ = total_length;
20
+ size_t current_buffer_size = total_length;
21
+
22
+ RAMAllocator<uint8_t *> ptr_allocator;
23
+ RAMAllocator<uint8_t> allocator;
24
+
25
+ // Try to allocate the entire buffer first
26
+ while (current_buffer_size > 0) {
27
+ // Calculate how many buffers we need of this size
28
+ size_t needed_buffers = (total_length + current_buffer_size - 1) / current_buffer_size;
29
+
30
+ // Try to allocate array of buffer pointers
31
+ uint8_t **temp_buffers = ptr_allocator.allocate(needed_buffers);
32
+ if (temp_buffers == nullptr) {
33
+ // If we can't even allocate the pointer array, don't need to continue
34
+ ESP_LOGE(TAG, "Failed to allocate pointers");
35
+ return false;
36
+ }
37
+
38
+ // Initialize all pointers to null
39
+ for (size_t i = 0; i < needed_buffers; i++) {
40
+ temp_buffers[i] = nullptr;
41
+ }
42
+
43
+ // Try to allocate all the buffers
44
+ bool allocation_success = true;
45
+ for (size_t i = 0; i < needed_buffers; i++) {
46
+ size_t this_buffer_size = current_buffer_size;
47
+ // Last buffer might be smaller if total_length is not divisible by current_buffer_size
48
+ if (i == needed_buffers - 1 && total_length % current_buffer_size != 0) {
49
+ this_buffer_size = total_length % current_buffer_size;
50
+ }
51
+
52
+ temp_buffers[i] = allocator.allocate(this_buffer_size);
53
+ if (temp_buffers[i] == nullptr) {
54
+ allocation_success = false;
55
+ break;
56
+ }
57
+
58
+ // Initialize buffer to zero
59
+ memset(temp_buffers[i], 0, this_buffer_size);
60
+ }
61
+
62
+ if (allocation_success) {
63
+ // Success! Store the result
64
+ this->buffers_ = temp_buffers;
65
+ this->buffer_count_ = needed_buffers;
66
+ this->buffer_size_ = current_buffer_size;
67
+ ESP_LOGD(TAG, "Allocated %zu * %zu bytes - %zu bytes", this->buffer_count_, this->buffer_size_,
68
+ this->total_length_);
69
+ return true;
70
+ }
71
+
72
+ // Allocation failed, clean up and try smaller buffers
73
+ for (size_t i = 0; i < needed_buffers; i++) {
74
+ if (temp_buffers[i] != nullptr) {
75
+ allocator.deallocate(temp_buffers[i], 0);
76
+ }
77
+ }
78
+ ptr_allocator.deallocate(temp_buffers, 0);
79
+
80
+ // Halve the buffer size and try again
81
+ current_buffer_size = current_buffer_size / 2;
82
+ }
83
+
84
+ ESP_LOGE(TAG, "Failed to allocate %zu bytes", total_length);
85
+ return false;
86
+ }
87
+
88
+ void SplitBuffer::free() {
89
+ if (this->buffers_ != nullptr) {
90
+ RAMAllocator<uint8_t> allocator;
91
+ for (size_t i = 0; i < this->buffer_count_; i++) {
92
+ if (this->buffers_[i] != nullptr) {
93
+ allocator.deallocate(this->buffers_[i], 0);
94
+ }
95
+ }
96
+ RAMAllocator<uint8_t *> ptr_allocator;
97
+ ptr_allocator.deallocate(this->buffers_, 0);
98
+ this->buffers_ = nullptr;
99
+ }
100
+ this->buffer_count_ = 0;
101
+ this->buffer_size_ = 0;
102
+ this->total_length_ = 0;
103
+ }
104
+
105
+ uint8_t &SplitBuffer::operator[](size_t index) {
106
+ if (index >= this->total_length_) {
107
+ ESP_LOGE(TAG, "Out of bounds - %zu >= %zu", index, this->total_length_);
108
+ // Return reference to a static dummy byte to avoid crash
109
+ static uint8_t dummy = 0;
110
+ return dummy;
111
+ }
112
+
113
+ size_t buffer_index = index / this->buffer_size_;
114
+ size_t offset_in_buffer = index - this->buffer_size_ * buffer_index;
115
+
116
+ return this->buffers_[buffer_index][offset_in_buffer];
117
+ }
118
+
119
+ const uint8_t &SplitBuffer::operator[](size_t index) const {
120
+ if (index >= this->total_length_) {
121
+ ESP_LOGE(TAG, "Out of bounds - %zu >= %zu", index, this->total_length_);
122
+ // Return reference to a static dummy byte to avoid crash
123
+ static const uint8_t DUMMY = 0;
124
+ return DUMMY;
125
+ }
126
+
127
+ size_t buffer_index = index / this->buffer_size_;
128
+ size_t offset_in_buffer = index - this->buffer_size_ * buffer_index;
129
+
130
+ return this->buffers_[buffer_index][offset_in_buffer];
131
+ }
132
+
133
+ } // namespace esphome::split_buffer
@@ -0,0 +1,40 @@
1
+ #pragma once
2
+
3
+ #include <cstdint>
4
+ #include <cstdlib>
5
+
6
+ namespace esphome::split_buffer {
7
+
8
+ class SplitBuffer {
9
+ public:
10
+ SplitBuffer() = default;
11
+ ~SplitBuffer();
12
+
13
+ // Initialize the buffer with the desired total length
14
+ bool init(size_t total_length);
15
+
16
+ // Free all allocated buffers
17
+ void free();
18
+
19
+ // Access operators
20
+ uint8_t &operator[](size_t index);
21
+ const uint8_t &operator[](size_t index) const;
22
+
23
+ // Get the total length
24
+ size_t size() const { return this->total_length_; }
25
+
26
+ // Get buffer information
27
+ size_t get_buffer_count() const { return this->buffer_count_; }
28
+ size_t get_buffer_size() const { return this->buffer_size_; }
29
+
30
+ // Check if successfully initialized
31
+ bool is_valid() const { return this->buffers_ != nullptr && this->buffer_count_ > 0; }
32
+
33
+ private:
34
+ uint8_t **buffers_{nullptr};
35
+ size_t buffer_count_{0};
36
+ size_t buffer_size_{0};
37
+ size_t total_length_{0};
38
+ };
39
+
40
+ } // namespace esphome::split_buffer
@@ -52,17 +52,19 @@ void SPS30Component::setup() {
52
52
  } else {
53
53
  result = this->write_command(SPS30_CMD_SET_AUTOMATIC_CLEANING_INTERVAL_SECONDS);
54
54
  }
55
- if (result) {
56
- delay(20);
57
- uint16_t secs[2];
58
- if (this->read_data(secs, 2)) {
59
- this->fan_interval_ = secs[0] << 16 | secs[1];
60
- }
61
- }
62
55
 
63
- this->status_clear_warning();
64
- this->skipped_data_read_cycles_ = 0;
65
- this->start_continuous_measurement_();
56
+ this->set_timeout(20, [this, result]() {
57
+ if (result) {
58
+ uint16_t secs[2];
59
+ if (this->read_data(secs, 2)) {
60
+ this->fan_interval_ = secs[0] << 16 | secs[1];
61
+ }
62
+ }
63
+ this->status_clear_warning();
64
+ this->skipped_data_read_cycles_ = 0;
65
+ this->start_continuous_measurement_();
66
+ this->setup_complete_ = true;
67
+ });
66
68
  });
67
69
  }
68
70
 
@@ -111,6 +113,8 @@ void SPS30Component::dump_config() {
111
113
  }
112
114
 
113
115
  void SPS30Component::update() {
116
+ if (!this->setup_complete_)
117
+ return;
114
118
  /// Check if warning flag active (sensor reconnected?)
115
119
  if (this->status_has_warning()) {
116
120
  ESP_LOGD(TAG, "Reconnecting");
@@ -30,9 +30,11 @@ class SPS30Component : public PollingComponent, public sensirion_common::Sensiri
30
30
  bool start_fan_cleaning();
31
31
 
32
32
  protected:
33
+ bool setup_complete_{false};
33
34
  uint16_t raw_firmware_version_;
34
35
  char serial_number_[17] = {0}; /// Terminating NULL character
35
36
  uint8_t skipped_data_read_cycles_ = 0;
37
+
36
38
  bool start_continuous_measurement_();
37
39
 
38
40
  enum ErrorCode : uint8_t {
@@ -50,8 +50,10 @@ void HOT I2CST7567::write_display_data() {
50
50
 
51
51
  static const size_t BLOCK_SIZE = 64;
52
52
  for (uint8_t x = 0; x < (uint8_t) this->get_width_internal(); x += BLOCK_SIZE) {
53
+ size_t remaining = static_cast<size_t>(this->get_width_internal()) - x;
54
+ size_t chunk = remaining > BLOCK_SIZE ? BLOCK_SIZE : remaining;
53
55
  this->write_register(esphome::st7567_base::ST7567_SET_START_LINE, &buffer_[y * this->get_width_internal() + x],
54
- this->get_width_internal() - x > BLOCK_SIZE ? BLOCK_SIZE : this->get_width_internal() - x);
56
+ chunk);
55
57
  }
56
58
  }
57
59
  }
@@ -176,8 +176,9 @@ void ST7789V::write_display_data() {
176
176
  if (this->eightbitcolor_) {
177
177
  uint8_t temp_buffer[TEMP_BUFFER_SIZE];
178
178
  size_t temp_index = 0;
179
- for (int line = 0; line < this->get_buffer_length_(); line = line + this->get_width_internal()) {
180
- for (int index = 0; index < this->get_width_internal(); ++index) {
179
+ size_t width = static_cast<size_t>(this->get_width_internal());
180
+ for (size_t line = 0; line < this->get_buffer_length_(); line += width) {
181
+ for (size_t index = 0; index < width; ++index) {
181
182
  auto color = display::ColorUtil::color_to_565(
182
183
  display::ColorUtil::to_color(this->buffer_[index + line], display::ColorOrder::COLOR_ORDER_RGB,
183
184
  display::ColorBitness::COLOR_BITNESS_332, true));
@@ -151,7 +151,7 @@ void StatsdComponent::send_(std::string *out) {
151
151
 
152
152
  int n_bytes = this->sock_->sendto(out->c_str(), out->length(), 0, reinterpret_cast<sockaddr *>(&this->destination_),
153
153
  sizeof(this->destination_));
154
- if (n_bytes != out->length()) {
154
+ if (n_bytes != static_cast<int>(out->length())) {
155
155
  ESP_LOGE(TAG, "Failed to send UDP packed (%d of %d)", n_bytes, out->length());
156
156
  }
157
157
  #endif
@@ -4,7 +4,7 @@ from esphome import core
4
4
  from esphome.config_helpers import Extend, Remove, merge_config
5
5
  import esphome.config_validation as cv
6
6
  from esphome.const import CONF_SUBSTITUTIONS, VALID_SUBSTITUTIONS_CHARACTERS
7
- from esphome.yaml_util import ESPHomeDataBase, make_data_base
7
+ from esphome.yaml_util import ESPHomeDataBase, ESPLiteralValue, make_data_base
8
8
 
9
9
  from .jinja import Jinja, JinjaStr, TemplateError, TemplateRuntimeError, has_jinja
10
10
 
@@ -127,6 +127,8 @@ def _expand_substitutions(substitutions, value, path, jinja, ignore_missing):
127
127
 
128
128
 
129
129
  def _substitute_item(substitutions, item, path, jinja, ignore_missing):
130
+ if isinstance(item, ESPLiteralValue):
131
+ return None # do not substitute inside literal blocks
130
132
  if isinstance(item, list):
131
133
  for i, it in enumerate(item):
132
134
  sub = _substitute_item(substitutions, it, path + [i], jinja, ignore_missing)